major updates to .NET OMS server

This commit is contained in:
Michael Becker 2024-11-19 22:36:24 -05:00
parent c64806484b
commit 114687f67f
48 changed files with 2819 additions and 726 deletions

View File

@ -41,7 +41,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "plugins", "plugins", "{B024
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mocha.Plugins.Libraries.McxMini", "mocha-dotnet\src\plugins\Mocha.Plugins.Libraries.McxMini\Mocha.Plugins.Libraries.McxMini.csproj", "{6005DB73-30D8-4398-8B1F-5E23C0F2FFBF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mocha.Oms.Server", "mocha-dotnet\src\app\Mocha.Oms.Server\Mocha.Oms.Server.csproj", "{07828A24-B888-4464-A158-F77AB61F6AD9}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mocha.Oms.Server", "mocha-dotnet\src\app\Mocha.Oms.Server\Mocha.Oms.Server.csproj", "{EB83EE7A-AFFE-4068-B445-9139F2DEA0F6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mocha.Core.UI.Server", "mocha-dotnet\src\lib\Mocha.Core.UI.Server\Mocha.Core.UI.Server.csproj", "{4D1E2156-B1B5-4D15-B347-1F0E07C95891}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -73,10 +75,14 @@ Global
{6005DB73-30D8-4398-8B1F-5E23C0F2FFBF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6005DB73-30D8-4398-8B1F-5E23C0F2FFBF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6005DB73-30D8-4398-8B1F-5E23C0F2FFBF}.Release|Any CPU.Build.0 = Release|Any CPU
{07828A24-B888-4464-A158-F77AB61F6AD9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{07828A24-B888-4464-A158-F77AB61F6AD9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{07828A24-B888-4464-A158-F77AB61F6AD9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{07828A24-B888-4464-A158-F77AB61F6AD9}.Release|Any CPU.Build.0 = Release|Any CPU
{EB83EE7A-AFFE-4068-B445-9139F2DEA0F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EB83EE7A-AFFE-4068-B445-9139F2DEA0F6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EB83EE7A-AFFE-4068-B445-9139F2DEA0F6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EB83EE7A-AFFE-4068-B445-9139F2DEA0F6}.Release|Any CPU.Build.0 = Release|Any CPU
{4D1E2156-B1B5-4D15-B347-1F0E07C95891}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4D1E2156-B1B5-4D15-B347-1F0E07C95891}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4D1E2156-B1B5-4D15-B347-1F0E07C95891}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4D1E2156-B1B5-4D15-B347-1F0E07C95891}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -98,7 +104,8 @@ Global
{20B7D199-322C-4942-85FE-46B90C75E92A} = {27C300F5-5172-4225-A6F7-3503B9007DD8}
{B024FD23-7084-4DDF-A185-D58BEE7A006F} = {66EB3261-A473-41C7-8D40-E1B4DC8ED4B3}
{6005DB73-30D8-4398-8B1F-5E23C0F2FFBF} = {B024FD23-7084-4DDF-A185-D58BEE7A006F}
{07828A24-B888-4464-A158-F77AB61F6AD9} = {11486802-8136-4958-8B32-FC34630B0306}
{EB83EE7A-AFFE-4068-B445-9139F2DEA0F6} = {11486802-8136-4958-8B32-FC34630B0306}
{4D1E2156-B1B5-4D15-B347-1F0E07C95891} = {A2C401E9-FED4-43BA-A928-566239894CEE}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D28A9CF8-0235-4F8F-865F-C460BDCAE16D}

View File

@ -5,6 +5,7 @@
<ProjectReference Include="..\..\..\..\web-framework-dotnet\src\lib\MBS.Web\MBS.Web.csproj" />
<ProjectReference Include="..\..\lib\Mocha.Core\Mocha.Core.csproj" />
<ProjectReference Include="..\..\plugins\Mocha.Plugins.Libraries.McxMini\Mocha.Plugins.Libraries.McxMini.csproj" />
<ProjectReference Include="..\..\lib\Mocha.Core.UI.Server\Mocha.Core.UI.Server.csproj" />
</ItemGroup>
<PropertyGroup>

View File

@ -1,4 +1,4 @@
namespace Mocha.Oms.Server;
namespace Mocha.OMS.Server;
using Mocha.Core;
@ -11,9 +11,27 @@ using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.Json.Nodes;
using Mocha.Core.UI;
using Mocha.Core.Oop;
using MBS.Core;
using MBS.Core.Collections.Generic;
using System.Collections.ObjectModel;
using System.Runtime.CompilerServices;
using Mocha.Core.Responses;
using System.Runtime.Serialization;
using System.Reflection;
using Mocha.Core.UI.Server;
public class Program : WebApplication
{
public class OmsSession
{
}
public Dictionary<string, OmsSession> _Sessions = new Dictionary<string, OmsSession>();
protected override int DefaultPort => 4436;
public Program()
@ -37,6 +55,7 @@ public class Program : WebApplication
protected override void OnStartup(EventArgs e)
{
// this all has to be done before the Web server is started...
oms.Initialize();
TenantHandle th = oms.CreateTenant("super");
oms.SelectTenant(th);
@ -57,407 +76,63 @@ public class Program : WebApplication
LibraryHandle lh2 = oms.LoadLibrary(path + "/net.alcetech.Mocha.Web.mcl");
oms.AddLibraryReference(lh2);
// implement functions to get user IP address
oms.RegisterSystemAttributeRoutine<string>(KnownInstanceGuids.SystemAttributeRoutines.GetIPAddress, delegate (Oms oms2, OmsContext ctx2)
{
// !HACK
return ctx2.GetExtraData<string>("Client.IPAddress");
});
oms.SystemRoutineExecuted += oms_SystemRoutineExecuted;
// now we can start the Web server
base.OnStartup(e);
}
private void oms_SystemRoutineExecuted(object? sender, SystemRoutineExecutedEventArgs e)
{
if (e.SystemRoutine.GlobalIdentifier == KnownInstanceGuids.SystemUpdateRoutines.LoginUser)
{
string token = e.Context.GetWorkData<string>(e.OMS.GetInstance(KnownAttributeGuids.Text.Token));
_Sessions[token] = new OmsSession();
}
}
protected override void OnProcessRequest(WebServerProcessRequestEventArgs e)
{
base.OnProcessRequest(e);
OmsContext ctx = null;
if (!e.Context.Session.ContainsKey("OmsContext"))
{
ctx = oms.CreateContext();
e.Context.Session["OmsContext"] = ctx;
}
ctx = (OmsContext)e.Context.Session["OmsContext"];
Guid clientRequestId = Guid.NewGuid();
// if (!e.Context.Request.Headers.ContainsKey("Cookie"))
{
// e.Context.Response.Cookies.Add("zq-sessionid", Guid.NewGuid().ToString("b"), WebCookieScope.Empty, WebCookieSecurity.None, WebCookieSameSite.None);
}
if (e.Context.Request.Headers.ContainsKey("X-Forwarded-For"))
{
ctx.SetExtraData("Client.IPAddress", e.Context.Request.Headers["X-Forwarded-For"]);
}
e.Context.Response.ResponseCode = 404;
e.Context.Response.ResponseText = "Not Found";
StreamWriter sw = new StreamWriter(e.Context.Response.Stream);
if (e.Context.Request.Path == "/robots.txt")
{
}
else if (e.Context.Request.PathParts.Length > 1)
{
if (e.Context.Request.PathParts.Length == 2 && e.Context.Request.PathParts[1] == "ping")
{
e.Context.Response.ResponseCode = 200;
e.Context.Response.ResponseText = "OK";
e.Context.Response.ContentType = "application/json";
JsonObject obj = new JsonObject();
obj.Add("result", JsonValue.Create("success"));
sw.Write(obj.ToJsonString());
sw.Flush();
sw.Close();
return;
}
if (e.Context.Request.PathParts[1] == "tenants")
{
e.Context.Response.ResponseCode = 200;
e.Context.Response.ResponseText = "OK";
e.Context.Response.ContentType = "application/json";
JsonArray ary = new JsonArray();
IEnumerable<string> tenants = oms.GetTenants();
foreach (string tenant in tenants)
{
ary.Add(JsonValue.Create(tenant));
}
if (e.Context.Request.PathParts.Length == 2)
{
JsonObject obj = new JsonObject();
obj.Add("result", JsonValue.Create("success"));
obj.Add("tenants", ary);
sw.Write(obj.ToJsonString());
}
else if (e.Context.Request.PathParts.Length > 3)
{
// /tenants/{tenantName}/instances
string tenantName = e.Context.Request.PathParts[2];
TenantHandle th = oms.GetTenantByName(tenantName);
if (th == TenantHandle.Empty)
{
e.Context.Response.ResponseCode = 404;
e.Context.Response.ResponseText = "Not Found";
e.Context.Response.ContentType = "application/json";
JsonObject obj = new JsonObject();
obj.Add("result", JsonValue.Create("failure"));
obj.Add("message", JsonValue.Create("tenant does not exist"));
sw.Write(obj.ToJsonString());
sw.Flush();
return;
}
else
{
oms.SelectTenant(th);
}
if (e.Context.Request.PathParts[3] == "instances")
{
if (e.Context.Request.PathParts.Length > 4)
{
if (e.Context.Request.PathParts[4] == "create")
{
// usage:
// POST /tenants/{tenantName}/instances/create
//
// parentClassIid=1$1&title=My+New+Class
if (e.Context.Request.Form.ContainsKey("parentClassIid"))
{
string pclass = e.Context.Request.Form["parentClassIid"];
if (TryParseInstanceRef(pclass, out InstanceHandle ihParentClass))
{
InstanceHandle ihRet = oms.CreateInstanceOf(ihParentClass);
if (e.Context.Request.Form.ContainsKey("title"))
{
oms.SetAttributeValue(ihRet, oms.GetInstance(KnownAttributeGuids.Text.Name), e.Context.Request.Form["title"]);
}
e.Context.Response.ResponseCode = 200;
e.Context.Response.ResponseText = "OK";
e.Context.Response.ContentType = "application/json";
JsonObject obj = new JsonObject();
obj.Add("result", JsonValue.Create("success"));
obj.Add("value", InstanceToJson(ihRet));
sw.Write(obj.ToJsonString());
}
else
{
e.Context.Response.ResponseCode = 422;
e.Context.Response.ResponseText = "Unprocessable Content";
e.Context.Response.ContentType = "application/json";
JsonObject obj = new JsonObject();
obj.Add("result", JsonValue.Create("failure"));
obj.Add("message", JsonValue.Create("parent class instance does not exist"));
sw.Write(obj.ToJsonString());
}
}
}
else if (e.Context.Request.PathParts.Length >= 5)
{
// /tenants/{tenantName}/instances/{instanceKey}/...
TryParseInstanceRef(e.Context.Request.PathParts[4], out InstanceHandle h);
if (h == InstanceHandle.Empty)
{
e.Context.Response.ResponseCode = 404;
e.Context.Response.ResponseText = "Not Found";
e.Context.Response.ContentType = "application/json";
JsonObject obj = new JsonObject();
obj.Add("result", "failure");
obj.Add("message", String.Format("invalid inst id {0} (inst not found)", e.Context.Request.PathParts[4]));
sw.Write(obj.ToJsonString());
sw.Flush();
sw.Close();
return;
}
if (e.Context.Request.PathParts.Length >= 6)
{
string command = e.Context.Request.PathParts[5];
if (command == "attributes")
{
if (e.Context.Request.PathParts.Length > 7)
{
// /tenants/{tenantName}/instances/{iid}/attrbutes/{attkey}/current
TryParseInstanceRef(e.Context.Request.PathParts[6], out InstanceHandle att);
string value;
if (e.Context.Request.Method == "POST" && e.Context.Request.PathParts[7].Equals("update"))
{
value = e.Context.Request.Form["value"];
oms.SetAttributeValue(h, att, value);
e.Context.Response.ResponseCode = 200;
e.Context.Response.ResponseText = "OK";
e.Context.Response.ContentType = "text/plain";
sw.Write(value);
sw.Flush();
sw.Close();
return;
}
DateTime dt = DateTime.Now;
if (e.Context.Request.PathParts[7].Equals("current"))
{
}
value = oms.GetAttributeValue<string>(h, att, String.Empty, dt);
e.Context.Response.ResponseCode = 200;
e.Context.Response.ResponseText = "OK";
e.Context.Response.ContentType = "text/plain";
sw.Write(value);
sw.Flush();
sw.Close();
return;
}
JsonObject obj = new JsonObject();
InstanceHandle hAtt = InstanceHandle.Empty;
if (e.Context.Request.PathParts.Length == 7)
{
TryParseInstanceRef(e.Context.Request.PathParts[6], out hAtt);
}
JsonArray objAttributes = GetAttributesAsJson(h, hAtt);
obj.Add("attributes", objAttributes);
e.Context.Response.ResponseCode = 200;
e.Context.Response.ResponseText = "OK";
e.Context.Response.ContentType = "application/json";
sw.Write(obj.ToJsonString());
}
else if (command == "relationships")
{
if (e.Context.Request.PathParts.Length >= 7)
{
TryParseInstanceRef(e.Context.Request.PathParts[6], out InstanceHandle rel);
DateTime dt = DateTime.Now;
if (e.Context.Request.PathParts.Length > 7)
{
if (e.Context.Request.Method == "POST" && e.Context.Request.PathParts[7].Equals("update"))
{
if (Int32.TryParse(e.Context.Request.Form["count"], out int count))
{
JsonObject obj1 = new JsonObject();
obj1.Add("result", "success");
JsonArray ary1 = new JsonArray();
List<InstanceHandle> list = new List<InstanceHandle>();
for (int i = 0; i < count; i++)
{
string key = String.Format("item{0}", i);
if (e.Context.Request.Form.ContainsKey(key))
{
Console.Error.WriteLine("debug: trying to add inst " + e.Context.Request.Form[key]);
if (TryParseInstanceRef(e.Context.Request.Form[key], out InstanceHandle inst))
{
ary1.Add(InstanceToJson(inst));
list.Add(inst);
}
}
}
Console.Error.WriteLine("ok assigning relationship");
oms.AssignRelationship(h, rel, list.ToArray());
e.Context.Response.ResponseCode = 200;
e.Context.Response.ResponseText = "OK";
e.Context.Response.ContentType = "application/json";
obj1.Add("targetInstances", ary1);
sw.Write(obj1.ToJsonString());
sw.Flush();
sw.Close();
}
return;
}
if (e.Context.Request.PathParts[7].Equals("current"))
{
}
}
IEnumerable<InstanceHandle> rel_insts = oms.GetRelatedInstances(h, rel, dt);
JsonObject obj = new JsonObject();
JsonArray a = new JsonArray();
foreach (InstanceHandle ih in rel_insts)
{
a.Add(InstanceToJson(ih));
}
obj.Add("result", JsonValue.Create("success"));
obj.Add("sourceInstance", InstanceToJson(h));
obj.Add("relationshipInstance", InstanceToJson(rel));
obj.Add("value", a);
e.Context.Response.ResponseCode = 200;
e.Context.Response.ResponseText = "OK";
e.Context.Response.ContentType = "application/json";
sw.Write(obj.ToJsonString());
sw.Flush();
sw.Close();
return;
}
else
{
JsonObject obj = new JsonObject();
obj.Add("relationships", GetRelationshipsAsJson(h));
e.Context.Response.ResponseCode = 200;
e.Context.Response.ResponseText = "OK";
e.Context.Response.ContentType = "application/json";
sw.Write(obj.ToJsonString());
}
}
else if (command == "element")
{
Renderer renderer = new Renderer(oms);
if (oms.IsInstanceOf(h, oms.GetInstance(KnownInstanceGuids.Classes.Element)))
{
Widget widget = renderer.Parse(h);
JsonObject obj3 = widget.ToJSONObject();
JsonObject obj2 = new JsonObject();
obj2.Add("widget", JsonValue.Create("root"));
obj2.Add("body", widget.ToJSONObject());
JsonObject obj = new JsonObject();
obj.Add("result", "success");
obj.Add("value", obj2);
RespondWithJson(sw, e.Context, 200, "OK", obj);
}
}
else
{
JsonObject obj = new JsonObject();
obj.Add("result", "failure");
obj.Add("message", String.Format("unknown cmd '{0}'", command));
RespondWithJson(sw, e.Context, 404, "Not Found", obj);
}
}
else
{
JsonObject obj = new JsonObject();
obj.Add("instanceKey", JsonValue.Create(oms.GetInstanceKey(h).ToString()));
obj.Add("globalIdentifier", JsonValue.Create(oms.GetGlobalIdentifier(h).ToString("b")));
obj.Add("text", JsonValue.Create(oms.GetInstanceText(h)));
obj.Add("attributes", GetAttributesAsJson(h));
obj.Add("relationshps", GetRelationshipsAsJson(h));
e.Context.Response.ResponseCode = 200;
e.Context.Response.ResponseText = "OK";
e.Context.Response.ContentType = "application/json";
sw.Write(obj.ToJsonString());
}
}
}
else
{
e.Context.Response.ResponseCode = 200;
e.Context.Response.ResponseText = "OK";
e.Context.Response.ContentType = "application/json";
JsonObject obj = new JsonObject();
Stopwatch watch = new Stopwatch();
watch.Start();
string query = "";
if (e.Context.Request.Query.ContainsKey("q") && e.Context.Request.Query["q"].Count > 0)
{
query = e.Context.Request.Query["q"][0];
}
string parentClassIid = null;
InstanceHandle ihParentClass = InstanceHandle.Empty;
if (e.Context.Request.Query.ContainsKey("parentClassIid") && e.Context.Request.Query["parentClassIid"].Count > 0)
{
parentClassIid = e.Context.Request.Query["parentClassIid"][0];
TryParseInstanceRef(parentClassIid, out ihParentClass);
}
IEnumerable<InstanceHandle> ihs = null;
if (ihParentClass != InstanceHandle.Empty)
{
ihs = oms.GetInstancesOf(ihParentClass);
}
else
{
ihs = oms.GetInstances();
}
if (!String.IsNullOrEmpty(query))
{
List<InstanceHandle> list = new List<InstanceHandle>();
foreach (InstanceHandle ih in ihs)
{
string text = oms.GetInstanceText(ih);
if (text.ToLower().Contains(query.ToLower()))
{
list.Add(ih);
}
}
ihs = list;
}
e.Context.Response.ResponseCode = 200;
e.Context.Response.ResponseText = "OK";
e.Context.Response.ContentType = "application/json";
JsonArray objInstances = InstancesToJson(ihs);
obj.Add("instances", objInstances);
watch.Stop();
obj.Add("time", JsonValue.Create(watch.ElapsedMilliseconds.ToString()));
sw.Write(obj.ToJsonString());
}
}
}
}
OmsServer server = new OmsServer();
server.ProcessRequest(e, oms, ctx, sw);
}
else
{
@ -472,184 +147,56 @@ public class Program : WebApplication
sw.Close();
}
/*
private JsonObject? ElementContentToJSON(InstanceHandle content)
{
JsonObject? objC = null;
InstanceHandle contentWidget = oms.GetRelatedInstance(content, oms.GetInstance(KnownRelationshipGuids.Element_Content__has__Instance));
/*
private JsonObject? ElementContentToJSON(InstanceHandle content)
{
JsonObject? objC = null;
InstanceHandle contentWidget = oms.GetRelatedInstance(content, oms.GetInstance(KnownRelationshipGuids.Element_Content__has__Instance));
// Mocha.Core.UI.Widget widget = renderer.BuildFromInstance()
if (oms.IsInstanceOf(contentWidget, oms.GetInstance(KnownInstanceGuids.Classes.Element)))
{
objC = ElementToJSON(contentWidget, content);
}
else if (oms.IsInstanceOf(contentWidget, oms.GetInstance(KnownInstanceGuids.Classes.TextAttribute)))
{
objC = TextAttributeToJSON(contentWidget, content);
}
else if (oms.IsInstanceOf(contentWidget, oms.GetInstance(KnownInstanceGuids.Classes.File)))
{
objC = FileToJSON(contentWidget, content);
}
return objC;
}
// Mocha.Core.UI.Widget widget = renderer.BuildFromInstance()
if (oms.IsInstanceOf(contentWidget, oms.GetInstance(KnownInstanceGuids.Classes.Element)))
{
objC = ElementToJSON(contentWidget, content);
}
else if (oms.IsInstanceOf(contentWidget, oms.GetInstance(KnownInstanceGuids.Classes.TextAttribute)))
{
objC = TextAttributeToJSON(contentWidget, content);
}
else if (oms.IsInstanceOf(contentWidget, oms.GetInstance(KnownInstanceGuids.Classes.File)))
{
objC = FileToJSON(contentWidget, content);
}
return objC;
}
private JsonObject? FileToJSON(InstanceHandle contentWidget, InstanceHandle parentElementContent)
{
JsonObject obj3 = new JsonObject();
InsertCommonProperties(obj3, contentWidget, parentElementContent);
private JsonObject? FileToJSON(InstanceHandle contentWidget, InstanceHandle parentElementContent)
{
JsonObject obj3 = new JsonObject();
InsertCommonProperties(obj3, contentWidget, parentElementContent);
string value = oms.GetAttributeValue<string>(contentWidget, oms.GetInstance(KnownAttributeGuids.Text.Value));
if (value != null)
{
obj3.Add("value", JsonValue.Create(value));
}
return obj3;
}
private JsonObject? TextAttributeToJSON(InstanceHandle contentWidget, InstanceHandle parentElementContent)
{
JsonObject obj3 = new JsonObject();
InsertCommonProperties(obj3, contentWidget, parentElementContent);
string value = oms.GetAttributeValue<string>(contentWidget, oms.GetInstance(KnownAttributeGuids.Text.Value));
if (value != null)
{
obj3.Add("value", JsonValue.Create(value));
}
return obj3;
}
private JsonObject? TextAttributeToJSON(InstanceHandle contentWidget, InstanceHandle parentElementContent)
{
JsonObject obj3 = new JsonObject();
InsertCommonProperties(obj3, contentWidget, parentElementContent);
string value = oms.GetAttributeValue<string>(contentWidget, oms.GetInstance(KnownAttributeGuids.Text.Value));
if (value != null)
{
obj3.Add("value", JsonValue.Create(value));
}
return obj3;
}
string value = oms.GetAttributeValue<string>(contentWidget, oms.GetInstance(KnownAttributeGuids.Text.Value));
if (value != null)
{
obj3.Add("value", JsonValue.Create(value));
}
return obj3;
}
*/
*/
private void RespondWithJson(StreamWriter sw, WebContext context, int responseCode, string responseText, JsonObject obj)
{
context.Response.ResponseCode = responseCode;
context.Response.ResponseText = responseText;
context.Response.ContentType = "application/json";
sw.Write(obj.ToJsonString());
}
private bool TryParseInstanceRef(string instanceKeyOrGuid, out InstanceHandle h)
{
h = InstanceHandle.Empty;
if (InstanceKey.TryParse(instanceKeyOrGuid, out InstanceKey k))
{
oms.TryGetInstance(k, out h);
return true;
}
else if (Guid.TryParse(instanceKeyOrGuid, out Guid g))
{
oms.TryGetInstance(g, out h);
return true;
}
else
{
Console.Error.WriteLine("could not parse: {0}", instanceKeyOrGuid);
}
return false;
}
private JsonNode? InstanceToJson(InstanceHandle ih)
{
InstanceHandle parentClass = oms.GetParentClass(ih);
JsonObject objInstance = new JsonObject();
objInstance.Add("iid", JsonValue.Create(oms.GetInstanceKey(ih).ToString()));
objInstance.Add("globalIdentifier", JsonValue.Create(oms.GetGlobalIdentifier(ih).ToString()));
objInstance.Add("text", JsonValue.Create(oms.GetInstanceText(ih)));
JsonObject objParentClass = new JsonObject();
objParentClass.Add("iid", JsonValue.Create(oms.GetInstanceKey(parentClass).ToString()));
objParentClass.Add("globalIdentifier", JsonValue.Create(oms.GetGlobalIdentifier(parentClass).ToString()));
objParentClass.Add("text", JsonValue.Create(oms.GetInstanceText(parentClass)));
objInstance.Add("parentClass", objParentClass);
return objInstance;
}
private JsonArray GetRelationshipsAsJson(InstanceHandle h, InstanceHandle hRel = default(InstanceHandle))
{
JsonArray a = new JsonArray();
IEnumerable<MochaRelationship> rels = oms.GetRelationships(h);
foreach (MochaRelationship rel in rels)
{
if (hRel != InstanceHandle.Empty)
{
if (!rel.RelationshipInstance.Equals(hRel))
{
continue;
}
}
JsonObject o = new JsonObject();
o.Add("iid", JsonValue.Create(oms.GetInstanceKey(rel.RelationshipInstance).ToString()));
string attrText = oms.GetInstanceText(rel.RelationshipInstance);
o.Add("name", JsonValue.Create(attrText));
JsonArray aa = new JsonArray();
foreach (RelationshipValue val in rel.Values)
{
JsonObject ao = new JsonObject();
ao.Add("effectiveDate", JsonValue.Create(val.EffectiveDate));
ao.Add("targetInstances", InstancesToJson(val.TargetInstances));
aa.Add(ao);
}
o.Add("values", aa);
a.Add(o);
}
return a;
}
private JsonArray GetAttributesAsJson(InstanceHandle h, InstanceHandle hAtt = default(InstanceHandle))
{
JsonArray a = new JsonArray();
IEnumerable<MochaAttribute> atts = oms.GetAttributes(h);
foreach (MochaAttribute att in atts)
{
if (hAtt != InstanceHandle.Empty)
{
if (!att.AttributeInstance.Equals(hAtt))
{
continue;
}
}
string iid = oms.GetInstanceKey(att.AttributeInstance).ToString();
JsonObject o = new JsonObject();
o.Add("iid", JsonValue.Create(iid));
string attrText = oms.GetInstanceText(att.AttributeInstance);
o.Add("name", JsonValue.Create(attrText));
JsonArray aa = new JsonArray();
foreach (AttributeValue val in att.Values)
{
JsonObject ao = new JsonObject();
ao.Add("effectiveDate", JsonValue.Create(val.EffectiveDate));
ao.Add("value", JsonValue.Create(val.Value));
aa.Add(ao);
}
o.Add("values", aa);
a.Add(o);
}
return a;
}
private JsonArray InstancesToJson(IEnumerable<InstanceHandle> ihs)
{
JsonArray array = new JsonArray();
foreach (InstanceHandle ih in ihs)
{
array.Add(InstanceToJson(ih));
}
return array;
}
public static int Main(string[] args)
public static int Main(string[] args)
{
return (new Program()).Start();
}

View File

@ -0,0 +1,83 @@
// Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
//
// This file is part of Mocha.NET.
//
// Mocha.NET is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mocha.NET is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
using System.Text.Json.Nodes;
using MBS.Web;
using Mocha.Core;
using Mocha.Core.UI;
namespace Mocha.Core.UI.Server.Commands;
public class AttributesCommand : InstanceCommand
{
public override IEnumerable<string> UriPatterns => new string[] { "/tenants/{tenantName}/instances/{iid}/attributes" };
protected override void ProcessInternal(WebServerProcessRequestEventArgs e, Core.Oms oms, Core.OmsContext ctx, StreamWriter sw)
{
if (e.Context.Request.PathParts.Length > 7)
{
// /tenants/{tenantName}/instances/{iid}/attrbutes/{attkey}/current
oms.TryParseInstanceRef(e.Context.Request.PathParts[6], out InstanceHandle att);
string value;
if (e.Context.Request.Method == "POST" && e.Context.Request.PathParts[7].Equals("update"))
{
value = e.Context.Request.Form["value"];
oms.SetAttributeValue(ProcessingInstance, att, value);
e.Context.Response.ResponseCode = 200;
e.Context.Response.ResponseText = "OK";
e.Context.Response.ContentType = "text/plain";
sw.Write(value);
return;
}
DateTime dt = DateTime.Now;
if (e.Context.Request.PathParts[7].Equals("current"))
{
}
value = oms.GetAttributeValue<string>(ProcessingInstance, att, String.Empty, dt);
e.Context.Response.ResponseCode = 200;
e.Context.Response.ResponseText = "OK";
e.Context.Response.ContentType = "text/plain";
sw.Write(value);
return;
}
JsonObject obj = new JsonObject();
InstanceHandle hAtt = InstanceHandle.Empty;
if (e.Context.Request.PathParts.Length == 7)
{
oms.TryParseInstanceRef(e.Context.Request.PathParts[6], out hAtt);
}
JsonArray objAttributes = JsonRenderer.GetAttributesAsJson(oms, ProcessingInstance, hAtt);
obj.Add("attributes", objAttributes);
e.Context.Response.ResponseCode = 200;
e.Context.Response.ResponseText = "OK";
e.Context.Response.ContentType = "application/json";
sw.Write(obj.ToJsonString());
}
}

View File

@ -0,0 +1,69 @@
// Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
//
// This file is part of Mocha.NET.
//
// Mocha.NET is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mocha.NET is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
using System.Text.Json.Nodes;
using MBS.Web;
using Mocha.Core;
using Mocha.Core.UI;
namespace Mocha.Core.UI.Server.Commands;
public class CreateInstanceCommand : OmsServerCommand
{
public override IEnumerable<string> UriPatterns => new string[] { "/tenants/{tenantName}/instances/create" };
protected override void ProcessInternal(WebServerProcessRequestEventArgs e, Core.Oms oms, Core.OmsContext ctx, StreamWriter sw)
{
// usage:
// POST /tenants/{tenantName}/instances/create
//
// parentClassIid=1$1&title=My+New+Class
if (e.Context.Request.Form.ContainsKey("parentClassIid"))
{
string pclass = e.Context.Request.Form["parentClassIid"];
if (oms.TryParseInstanceRef(pclass, out InstanceHandle ihParentClass))
{
InstanceHandle ihRet = oms.CreateInstanceOf(ihParentClass);
if (e.Context.Request.Form.ContainsKey("title"))
{
oms.SetAttributeValue(ihRet, oms.GetInstance(KnownAttributeGuids.Text.Name), e.Context.Request.Form["title"]);
}
e.Context.Response.ResponseCode = 200;
e.Context.Response.ResponseText = "OK";
e.Context.Response.ContentType = "application/json";
JsonObject obj = new JsonObject();
obj.Add("result", JsonValue.Create("success"));
obj.Add("value", JsonRenderer.InstanceToJson(oms, ihRet));
sw.Write(obj.ToJsonString());
}
else
{
e.Context.Response.ResponseCode = 422;
e.Context.Response.ResponseText = "Unprocessable Content";
e.Context.Response.ContentType = "application/json";
JsonObject obj = new JsonObject();
obj.Add("result", JsonValue.Create("failure"));
obj.Add("message", JsonValue.Create("parent class instance does not exist"));
sw.Write(obj.ToJsonString());
}
}
}
}

View File

@ -0,0 +1,221 @@
// Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
//
// This file is part of Mocha.NET.
//
// Mocha.NET is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mocha.NET is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
using System.Collections.ObjectModel;
using System.Text.Json.Nodes;
using MBS.Web;
using Mocha.Core;
using Mocha.Core.Responses;
using Mocha.Core.UI;
namespace Mocha.Core.UI.Server.Commands;
public class ElementCommand : InstanceCommand
{
public override IEnumerable<string> UriPatterns => new string[] { "/tenants/{tenantName}/instances/{iid}/element" };
protected override void ProcessInternal(WebServerProcessRequestEventArgs e, Core.Oms oms, Core.OmsContext ctx, StreamWriter sw)
{
if (e.Context.Request.Method == "POST")
{
if (oms.IsInstanceOf(ProcessingInstance, oms.GetInstance(KnownInstanceGuids.Classes.Element)))
{
// what we should do, is build a transaction with all updated ECs and fields and values
// if any update fails, the entire transaction should be rolled back
Response resp = ProcessElement(oms, ctx, ProcessingInstance, InstanceHandle.Empty, e.Context.Request.Form);
if (resp != null)
{
JsonObject obj2 = resp.GetResponse(oms, ctx);
RespondWithJson(oms, sw, e.Context, 200, "OK", obj2);
return;
}
else
{
JsonObject obj2 = new JsonObject();
obj2.Add("result", "failure");
obj2.Add("message", "no CT associated with element");
RespondWithJson(oms, sw, e.Context, 400, "Bad Request", obj2);
return;
}
foreach (KeyValuePair<string, string> kvp in e.Context.Request.Form)
{
Console.Error.WriteLine("---> {0} = {1}", kvp.Key, kvp.Value);
}
JsonObject obj = new JsonObject();
obj.Add("result", "failure");
obj.Add("message", "not implemented");
RespondWithJson(oms, sw, e.Context, 500, "Internal Server Error", obj);
}
}
else
{
Renderer renderer = new Renderer(oms);
if (oms.IsInstanceOf(ProcessingInstance, oms.GetInstance(KnownInstanceGuids.Classes.Element)))
{
Widget widget = renderer.Parse(ctx, ProcessingInstance, InstanceHandle.Empty, InstanceHandle.Empty);
JsonObject obj3 = widget.ToJSONObject(ctx);
JsonObject obj2 = new JsonObject();
obj2.Add("widget", JsonValue.Create("root"));
obj2.Add("body", widget.ToJSONObject(ctx));
JsonObject obj = new JsonObject();
obj.Add("result", "success");
obj.Add("value", obj2);
RespondWithJson(oms, sw, e.Context, 200, "OK", obj);
}
else if (oms.IsInstanceOf(ProcessingInstance, oms.GetInstance(KnownInstanceGuids.Classes.Task)))
{
InstanceHandle elem = oms.GetRelatedInstance(ProcessingInstance, oms.GetInstance(KnownRelationshipGuids.Task__has_initiating__Element));
// fill out the initiating element and execute the task
Response r = oms.ProcessElement(ctx, elem, InstanceHandle.Empty);
JsonObject obj = r.GetResponse(oms, ctx);
/*
*/
RespondWithJson(oms, sw, e.Context, 200, "OK", obj);
}
else
{
// render the default task for the given instance
InstanceHandle parentClass = oms.GetParentClass(ProcessingInstance);
// if (!oms.TryParseInstanceRef())//blahh
InstanceHandle defaultTask = oms.GetRelatedInstance(parentClass, oms.GetInstance(KnownRelationshipGuids.Class__has_default__Task));
if (defaultTask != InstanceHandle.Empty)
{
InstanceHandle elem = oms.GetRelatedInstance(defaultTask, oms.GetInstance(KnownRelationshipGuids.Task__has_initiating__Element));
// fill out the initiating element and execute the task
Response r = oms.ProcessElement(ctx, elem, ProcessingInstance);
JsonObject obj = r.GetResponse(oms, ctx);
/*
*/
RespondWithJson(oms, sw, e.Context, 200, "OK", obj);
}
}
}
}
private Response ProcessElement(Core.Oms oms, OmsContext ctx, InstanceHandle element, InstanceHandle elementContent, ReadOnlyDictionary<string, string> form, string fqecidPrefix = "")
{
// first we process the related updates
InstanceHandle processedByPru = oms.GetRelatedInstance(element, oms.GetInstance(KnownRelationshipGuids.Element__processed_by__Process_Related_Updates_Method));
if (processedByPru != InstanceHandle.Empty)
{
// this works... so far
oms.UpdateElementContents(ctx, element, form);
oms.Execute(ctx, processedByPru);
/*
$executesMethod = $oms->getRelatedInstance($usesBRMB, KnownRelationshipGuids::Method_Binding__executes__Method);
if ($executesMethod === null)
{
trigger_error("task_step: 1; uses BRMB " . $usesBRMB . "; executes method is null");
}
$usesElement = $oms->getRelatedInstance($executesMethod, KnownRelationshipGuids::Build_UI_Response_Method__uses__Executable_returning_Element);
$this->updateWorkDataWithElementContents($parentElementContents, $element);
$usesElementContents = $oms->getRelatedInstances($usesElement, KnownRelationshipGuids::Element__has__Element_Content);
if (count($usesElementContents) > 0)
{
$ecInst0 = $oms->getRelatedInstance($usesElementContents[0], KnownRelationshipGuids::Element_Content__has__Instance);
$this->TargetInstance = $this->Context->getWorkData($ecInst0);
$this->renderTaskStep2($parentElementContents, $usesElement);
}
exit();
*/
}
// ... then we process the element contents...
IEnumerable<InstanceHandle> elementContents = oms.GetRelatedInstances(element, oms.GetInstance(KnownRelationshipGuids.Element__has__Element_Content));
foreach (InstanceHandle elementContent2 in elementContents)
{
Response? resp = ProcessElementContent(oms, ctx, elementContent2, form, fqecidPrefix);
if (resp != null)
{
return resp;
}
}
// ... finally we run the CT - Control Transaction Method to return the response
InstanceHandle processedByCt = oms.GetRelatedInstance(element, oms.GetInstance(KnownRelationshipGuids.Element__processed_by__Control_Transaction_Method));
if (processedByCt != InstanceHandle.Empty)
{
string destinationURL = oms.GetAttributeValue<string>(processedByCt, oms.GetInstance(KnownAttributeGuids.Text.TargetURL));
InstanceHandle usesBuildResponseMethodBinding = oms.GetRelatedInstance(processedByCt, oms.GetInstance(KnownRelationshipGuids.Control_Transaction_Method__uses__Build_Response_Method_Binding));
if (usesBuildResponseMethodBinding != InstanceHandle.Empty)
{
}
else if (destinationURL != null)
{
return new RedirectResponse(destinationURL);
}
/*
$executesMethod = $oms->getRelatedInstance($usesBRMB, KnownRelationshipGuids::Method_Binding__executes__Method);
if ($executesMethod === null)
{
trigger_error("task_step: 1; uses BRMB " . $usesBRMB . "; executes method is null");
}
$usesElement = $oms->getRelatedInstance($executesMethod, KnownRelationshipGuids::Build_UI_Response_Method__uses__Executable_returning_Element);
$this->updateWorkDataWithElementContents($parentElementContents, $element);
$usesElementContents = $oms->getRelatedInstances($usesElement, KnownRelationshipGuids::Element__has__Element_Content);
if (count($usesElementContents) > 0)
{
$ecInst0 = $oms->getRelatedInstance($usesElementContents[0], KnownRelationshipGuids::Element_Content__has__Instance);
$this->TargetInstance = $this->Context->getWorkData($ecInst0);
$this->renderTaskStep2($parentElementContents, $usesElement);
}
exit();
*/
return FailureResponse.NotImplemented;
}
return FailureResponse.UnexpectedFailure;
}
private Response? ProcessElementContent(Core.Oms oms, OmsContext context, InstanceHandle elementContent, ReadOnlyDictionary<string, string> form, string fqecidPrefix)
{
InstanceHandle elementContentInstance = oms.GetRelatedInstance(elementContent, oms.GetInstance(KnownRelationshipGuids.Element_Content__has__Instance));
if (oms.IsInstanceOf(elementContentInstance, oms.GetInstance(KnownInstanceGuids.Classes.Element)))
{
return ProcessElement(oms, context, elementContentInstance, elementContent, form, fqecidPrefix + oms.GetInstanceKey(elementContentInstance).ToString() + ":");
}
else if (oms.IsInstanceOf(elementContentInstance, oms.GetInstance(KnownInstanceGuids.Classes.TextAttribute)))
{
string key = fqecidPrefix + oms.GetInstanceKey(elementContent);
string text = oms.GetInstanceText(elementContentInstance);
if (form.ContainsKey(key))
{
string value = form[key];
}
}
return null;
}
}

View File

@ -0,0 +1,73 @@
// Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
//
// This file is part of Mocha.NET.
//
// Mocha.NET is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mocha.NET is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
using System.Text.Json.Nodes;
using MBS.Web;
using Mocha.Core;
namespace Mocha.Core.UI.Server.Commands;
public abstract class InstanceCommand : TenantedCommand
{
public override IEnumerable<string> UriPatterns => new string[] { "/tenants/{tenantName}/instances/{iid}" };
public InstanceHandle ProcessingInstance { get; private set; }
protected override bool BeforeProcessInternal(WebServerProcessRequestEventArgs e, Core.Oms oms, Core.OmsContext ctx, StreamWriter sw)
{
if (e.Context.Request.PathParts.Length < 5)
return true;
string iid = e.Context.Request.PathParts[4];
if (oms.TryParseInstanceRef(iid, out InstanceHandle ih))
{
ProcessingInstance = ih;
}
if (ProcessingInstance == InstanceHandle.Empty)
{
e.Context.Response.ResponseCode = 404;
e.Context.Response.ResponseText = "Not Found";
e.Context.Response.ContentType = "application/json";
JsonObject obj = new JsonObject();
obj.Add("result", "failure");
obj.Add("message", String.Format("invalid inst id {0} (inst not found)", e.Context.Request.PathParts[4]));
sw.Write(obj.ToJsonString());
return false;
}
return true;
}
public void RespondWithJson(Core.Oms oms, StreamWriter sw, WebContext context, int responseCode, string responseText, JsonObject obj)
{
context.Response.ResponseCode = responseCode;
context.Response.ResponseText = responseText;
context.Response.ContentType = "application/json";
if (context.Session.ContainsKey("OmsContext"))
{
OmsContext ctx = (OmsContext)context.Session["OmsContext"];
object? loginToken = ctx.GetWorkData(oms.GetInstance(KnownAttributeGuids.Text.Token));
if (loginToken != null)
{
obj.Add("sessionSecureToken", loginToken.ToString());
}
}
sw.Write(obj.ToJsonString());
}
}

View File

@ -0,0 +1,40 @@
// Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
//
// This file is part of Mocha.NET.
//
// Mocha.NET is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mocha.NET is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
using System.Text.Json.Nodes;
using MBS.Web;
using Mocha.Core.UI;
namespace Mocha.Core.UI.Server.Commands;
public class InstanceDetailsCommand : InstanceCommand
{
public override IEnumerable<string> UriPatterns => new string[] { "/tenants/{tenantName}/instances/{instanceKey}" };
protected override void ProcessInternal(WebServerProcessRequestEventArgs e, Core.Oms oms, Core.OmsContext ctx, StreamWriter sw)
{
JsonObject obj = JsonRenderer.InstanceToJson(oms, ProcessingInstance);
obj.Add("attributes", JsonRenderer.GetAttributesAsJson(oms, ProcessingInstance));
obj.Add("relationshps", JsonRenderer.GetRelationshipsAsJson(oms, ProcessingInstance));
e.Context.Response.ResponseCode = 200;
e.Context.Response.ResponseText = "OK";
e.Context.Response.ContentType = "application/json";
sw.Write(obj.ToJsonString());
}
}

View File

@ -0,0 +1,169 @@
// Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
//
// This file is part of Mocha.NET.
//
// Mocha.NET is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mocha.NET is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
using System.Diagnostics;
using System.Text.Json.Nodes;
using MBS.Web;
using Mocha.Core;
using Mocha.Core.UI;
namespace Mocha.Core.UI.Server.Commands;
public class InstanceListCommand : TenantedCommand
{
public override IEnumerable<string> UriPatterns => new string[] { "/tenants/{tenantName}/instances" };
protected override void ProcessInternal(WebServerProcessRequestEventArgs e, Core.Oms oms, OmsContext ctx, StreamWriter sw)
{
e.Context.Response.ResponseCode = 200;
e.Context.Response.ResponseText = "OK";
e.Context.Response.ContentType = "application/json";
JsonObject obj = new JsonObject();
Stopwatch watch = new Stopwatch();
watch.Start();
string query = "";
string parentClassIid = null;
List<InstanceHandle> ihParentClasses = new List<InstanceHandle>();
if (e.Context.Request.Query.ContainsKey("q") && e.Context.Request.Query["q"].Count > 0)
{
query = e.Context.Request.Query["q"][0];
}
if (e.Context.Request.Query.ContainsKey("parentClassIid") && e.Context.Request.Query["parentClassIid"].Count > 0)
{
parentClassIid = e.Context.Request.Query["parentClassIid"][0];
if (oms.TryParseInstanceRef(parentClassIid, out InstanceHandle ihParentClass))
{
ihParentClasses.Add(ihParentClass);
}
}
if (e.Context.Request.Query.ContainsKey("m") && e.Context.Request.Query["m"].Contains("typeahead"))
{
if (ihParentClasses.Count == 0)
{
ihParentClasses.Add(oms.GetInstance(KnownInstanceGuids.Classes.Task));
ihParentClasses.Add(oms.GetInstance(KnownInstanceGuids.Classes.Class));
ihParentClasses.Add(oms.GetInstance(KnownInstanceGuids.Classes.Report));
}
}
Dictionary<InstanceHandle, object> parms = new Dictionary<InstanceHandle, object>();
if (e.Context.Request.Method == "POST")
{
foreach (KeyValuePair<string, string> kvp in e.Context.Request.Form)
{
if (oms.TryParseInstanceRef(kvp.Key, out InstanceHandle parm))
{
if (oms.TryParseInstanceRef(kvp.Value, out InstanceHandle parmValue))
{
parms[parm] = parmValue;
}
else
{
parms[parm] = kvp.Value;
}
}
}
}
IEnumerable<InstanceHandle>? ihs = null;
List<InstanceHandle> list2 = new List<InstanceHandle>();
if (ihParentClasses.Count > 0)
{
foreach (InstanceHandle ihParentClass in ihParentClasses)
{
if (oms.IsInstanceOf(ihParentClass, oms.GetInstance(KnownInstanceGuids.Classes.ElementContent)))
{
// this is kind of a hack... but oh well
// if it's an EC,
var ecinst = oms.GetRelatedInstance(ihParentClass, oms.GetInstance(KnownRelationshipGuids.Element_Content__has__Instance));
if (ecinst != InstanceHandle.Empty)
{
if (oms.IsInstanceOf(ecinst, oms.GetInstance(KnownInstanceGuids.Classes.Class)))
{
ihs = oms.GetInstancesOf(ecinst);
}
else if (oms.IsInstanceOf(ecinst, oms.GetInstance(KnownInstanceGuids.Classes.Relationship)))
{
var relDestination = oms.GetRelatedInstance(ecinst, oms.GetInstance(KnownRelationshipGuids.Relationship__has_destination__Class));
ihs = oms.GetInstancesOf(relDestination);
}
}
}
else
{
// should we just assume it is a Class ?
ihs = oms.GetInstancesOf(ihParentClass, true);
}
if (ihs != null)
{
list2.AddRange(ihs);
}
}
ihs = list2;
}
else
{
ihs = oms.GetInstances();
}
List<InstanceHandle> list = new List<InstanceHandle>();
foreach (InstanceHandle ih in ihs)
{
bool ignore = false;
foreach (KeyValuePair<InstanceHandle, object> kvp in parms)
{
object? val = oms.UnsafeGetAttributeValue(ih, kvp.Key, null);
if (val == null) val = "";
if (!val.ToString().Equals(kvp.Value.ToString()))
{
Console.Error.WriteLine("ignoring '{0}' = '{1}'", val, kvp.Value);
ignore = true;
break;
}
}
if (ignore) continue;
if (!String.IsNullOrEmpty(query))
{
string text = oms.GetInstanceText(ih);
if (!text.ToLower().Contains(query.ToLower())) continue;
}
list.Add(ih);
}
ihs = list;
e.Context.Response.ResponseCode = 200;
e.Context.Response.ResponseText = "OK";
e.Context.Response.ContentType = "application/json";
JsonArray objInstances = JsonRenderer.InstancesToJson(oms, ihs);
obj.Add("instances", objInstances);
watch.Stop();
obj.Add("time", JsonValue.Create(watch.ElapsedMilliseconds.ToString()));
sw.Write(obj.ToJsonString());
}
}

View File

@ -0,0 +1,41 @@
// Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
//
// This file is part of Mocha.NET.
//
// Mocha.NET is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mocha.NET is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
using System.Text.Json.Nodes;
using MBS.Web;
using Mocha.Core;
namespace Mocha.Core.UI.Server.Commands;
public class PingCommand : OmsServerCommand
{
public override IEnumerable<string> UriPatterns => new string[] { "/ping" };
protected override void ProcessInternal(WebServerProcessRequestEventArgs e, Core.Oms oms, OmsContext ctx, StreamWriter sw)
{
if (e.Context.Request.PathParts.Length == 2 && e.Context.Request.PathParts[1] == "ping")
{
e.Context.Response.ResponseCode = 200;
e.Context.Response.ResponseText = "OK";
e.Context.Response.ContentType = "application/json";
JsonObject obj = new JsonObject();
obj.Add("result", JsonValue.Create("success"));
sw.Write(obj.ToJsonString());
}
}
}

View File

@ -0,0 +1,120 @@
// Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
//
// This file is part of Mocha.NET.
//
// Mocha.NET is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mocha.NET is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
using System.Text.Json.Nodes;
using MBS.Web;
using Mocha.Core;
using Mocha.Core.UI;
namespace Mocha.Core.UI.Server.Commands;
public class RelationshipsCommand : InstanceCommand
{
public override IEnumerable<string> UriPatterns => new string[]
{
"/tenants/{tenantName}/instances/{iid}/relationships",
"/tenants/{tenantName}/instances/{iid}/relationships/{reliid}"
};
protected override void ProcessInternal(WebServerProcessRequestEventArgs e, Core.Oms oms, Core.OmsContext ctx, StreamWriter sw)
{
if (e.Context.Request.PathParts.Length >= 7)
{
oms.TryParseInstanceRef(e.Context.Request.PathParts[6], out InstanceHandle rel);
DateTime dt = DateTime.Now;
if (e.Context.Request.PathParts.Length > 7)
{
if (e.Context.Request.Method == "POST" && e.Context.Request.PathParts[7].Equals("update"))
{
if (Int32.TryParse(e.Context.Request.Form["count"], out int count))
{
JsonObject obj1 = new JsonObject();
obj1.Add("result", "success");
JsonArray ary1 = new JsonArray();
List<InstanceHandle> list = new List<InstanceHandle>();
for (int i = 0; i < count; i++)
{
string key = String.Format("item{0}", i);
if (e.Context.Request.Form.ContainsKey(key))
{
Console.Error.WriteLine("debug: trying to add inst " + e.Context.Request.Form[key]);
if (oms.TryParseInstanceRef(e.Context.Request.Form[key], out InstanceHandle inst))
{
ary1.Add(JsonRenderer.InstanceToJson(oms, inst));
list.Add(inst);
}
}
}
Console.Error.WriteLine("ok assigning relationship");
oms.AssignRelationship(ProcessingInstance, rel, list.ToArray());
e.Context.Response.ResponseCode = 200;
e.Context.Response.ResponseText = "OK";
e.Context.Response.ContentType = "application/json";
obj1.Add("targetInstances", ary1);
sw.Write(obj1.ToJsonString());
}
return;
}
if (e.Context.Request.PathParts[7].Equals("current"))
{
}
}
IEnumerable<InstanceHandle> rel_insts = oms.GetRelatedInstances(ProcessingInstance, rel, dt);
JsonObject obj = new JsonObject();
JsonArray a = new JsonArray();
foreach (InstanceHandle ih in rel_insts)
{
a.Add(JsonRenderer.InstanceToJson(oms, ih));
}
obj.Add("result", JsonValue.Create("success"));
obj.Add("sourceInstance", JsonRenderer.InstanceToJson(oms, ProcessingInstance));
obj.Add("relationshipInstance", JsonRenderer.InstanceToJson(oms, rel));
obj.Add("value", a);
e.Context.Response.ResponseCode = 200;
e.Context.Response.ResponseText = "OK";
e.Context.Response.ContentType = "application/json";
sw.Write(obj.ToJsonString());
return;
}
else
{
JsonObject obj = new JsonObject();
obj.Add("relationships", JsonRenderer.GetRelationshipsAsJson(oms, ProcessingInstance));
e.Context.Response.ResponseCode = 200;
e.Context.Response.ResponseText = "OK";
e.Context.Response.ContentType = "application/json";
sw.Write(obj.ToJsonString());
}
}
}

View File

@ -0,0 +1,55 @@
// Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
//
// This file is part of Mocha.NET.
//
// Mocha.NET is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mocha.NET is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
using System.Text.Json.Nodes;
using MBS.Web;
using Mocha.Core;
namespace Mocha.Core.UI.Server.Commands;
public abstract class TenantedCommand : OmsServerCommand
{
protected override bool BeforeProcessInternal(WebServerProcessRequestEventArgs e, Core.Oms oms, OmsContext ctx, StreamWriter sw)
{
if (e.Context.Request.PathParts.Length > 3)
{
// /tenants/{tenantName}/instances
string tenantName = e.Context.Request.PathParts[2];
TenantHandle th = oms.GetTenantByName(tenantName);
if (th == TenantHandle.Empty)
{
e.Context.Response.ResponseCode = 404;
e.Context.Response.ResponseText = "Not Found";
e.Context.Response.ContentType = "application/json";
JsonObject obj = new JsonObject();
obj.Add("result", JsonValue.Create("failure"));
obj.Add("message", JsonValue.Create("tenant does not exist"));
sw.Write(obj.ToJsonString());
sw.Flush();
return false;
}
else
{
oms.SelectTenant(th);
}
}
return base.BeforeProcessInternal(e, oms, ctx, sw);
}
}

View File

@ -0,0 +1,111 @@
// Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
//
// This file is part of Mocha.NET.
//
// Mocha.NET is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mocha.NET is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
using System.Text.Json.Nodes;
using MBS.Web;
using Mocha.Core;
namespace Mocha.Core.UI.Server.Commands;
public class TenantsListCommand : OmsServerCommand
{
public override IEnumerable<string> UriPatterns => new string[] { "/tenants" };
protected override void ProcessInternal(WebServerProcessRequestEventArgs e, Core.Oms oms, Core.OmsContext ctx, StreamWriter sw)
{
e.Context.Response.ResponseCode = 200;
e.Context.Response.ResponseText = "OK";
e.Context.Response.ContentType = "application/json";
JsonArray ary = new JsonArray();
IEnumerable<string> tenants = oms.GetTenants();
foreach (string tenant in tenants)
{
ary.Add(JsonValue.Create(tenant));
}
if (e.Context.Request.PathParts.Length == 2)
{
JsonObject obj = new JsonObject();
obj.Add("result", JsonValue.Create("success"));
obj.Add("tenants", ary);
sw.Write(obj.ToJsonString());
}
else if (e.Context.Request.PathParts.Length > 3)
{
if (e.Context.Request.PathParts[3] == "instances")
{
if (e.Context.Request.PathParts.Length > 4)
{
if (e.Context.Request.PathParts[4] == "create")
{
}
else if (e.Context.Request.PathParts.Length >= 5)
{
//
oms.TryParseInstanceRef(e.Context.Request.PathParts[4], out InstanceHandle h);
if (e.Context.Request.PathParts.Length >= 6)
{
string command = e.Context.Request.PathParts[5];
if (command == "relatedTasks")
{
/*
InstanceHandle instParent = oms.GetParentClass(ih);
List<InstanceHandle> relatedTasks = new List<InstanceHandle>();
$instInstance = $this->getInstanceByGlobalIdentifier(KnownClassGuids::Instance);
$relatedTasks0 = $this->getRelatedInstances($instInstance, KnownRelationshipGuids::Class__has_related__Task);
foreach ($relatedTasks0 as $task)
{
$relatedTasks[] = $task;
}
$relatedTasks1 = $this->getRelatedInstances($instParent, KnownRelationshipGuids::Class__has_related__Task);
foreach ($relatedTasks1 as $task)
{
$relatedTasks[] = $task;
}
$superclasses = $this->getRelatedInstances($instParent, KnownRelationshipGuids::Class__has_super__Class);
foreach ($superclasses as $superclass)
{
$relatedTasks2 = $this->getRelatedInstances($superclass, KnownRelationshipGuids::Class__has_related__Task);
foreach ($relatedTasks2 as $task)
{
$relatedTasks[] = $task;
}
}
return $relatedTasks;
*/
}
}
else
{
}
}
}
else
{
}
}
}
}
}

View File

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\..\..\..\web-framework-dotnet\src\lib\MBS.Web\MBS.Web.csproj" />
<ProjectReference Include="..\Mocha.Core\Mocha.Core.csproj" />
</ItemGroup>
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

View File

@ -0,0 +1,239 @@
// Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
//
// This file is part of Mocha.NET.
//
// Mocha.NET is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mocha.NET is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
using System.Collections.Immutable;
using System.Reflection;
using System.Text.Json.Nodes;
using MBS.Core.Collections.Generic;
using MBS.Web;
namespace Mocha.Core.UI.Server;
public class OmsServer
{
private bool MatchUriPattern(string path, string template, out Dictionary<string, string> vars)
{
vars = new Dictionary<string, string>();
int l = template.Length;
int l2 = path.Length;
int i = 0;
int j = 0;
bool escape = false;
bool insideVariable = false;
string? varname = null;
string? varvalue = null;
while (i < l && j < l2)
{
if (template[i] == '\\')
{
escape = true;
i++;
continue;
}
if (!escape && (template[i] == '{' || (template[i] == '$' && (template.Length - i) > 0 && template[i + 1] == '(')))
{
insideVariable = true;
varname = "";
varvalue = "";
i++;
continue;
}
else if (!escape && (insideVariable && (template[i] == '}' || template[i] == ')')))
{
insideVariable = false;
i++;
continue;
}
else
{
if (insideVariable)
{
varname += template[i];
i++;
continue;
}
else
{
if (template[i] == path[j])
{
// yay, we match
// save the last-known variable, if any...
if (varname != null && varvalue != null)
{
vars[varname] = varvalue;
// don't forget to reset it
varname = null;
varvalue = null;
}
// ... and keep going
i++;
j++;
}
else
{
// no match
if (varname != null)
{
if (j + 1 < path.Length)
{
// we are currently reading a variable value
varvalue += path[j];
j++;
}
else
{
// don't even question it, just return false since we should never reach this point
return false;
}
continue;
}
else
{
// we do not match!
return false;
}
if (varvalue != null)
{
// we are in a variable
varvalue += path[j];
j++;
continue;
}
}
}
}
escape = false;
}
if (varvalue != null && j < path.Length)
{
while (j < path.Length)
{
varvalue += path[j];
j++;
}
vars[varname] = varvalue;
varname = null;
varvalue = null;
}
if (i < l)
{
// entire template was not parsed, so not a match
return false;
}
return true;
}
private struct OmsServerCommandEntry
{
public string Uri { get; }
public OmsServerCommand Command { get; }
public OmsServerCommandEntry(string uri, OmsServerCommand command)
{
Uri = uri;
Command = command;
}
}
private class OmsServerCommandComparer : IComparer<OmsServerCommandEntry>
{
public int Compare(OmsServerCommandEntry x, OmsServerCommandEntry y)
{
return y.Uri.Length.CompareTo(x.Uri.Length);
}
}
private IEnumerable<OmsServerCommandEntry> Flatten(IEnumerable<OmsServerCommand> cmds)
{
List<OmsServerCommandEntry> list = new List<OmsServerCommandEntry>();
foreach (OmsServerCommand cmd in cmds)
{
foreach (string uri in cmd.UriPatterns)
{
list.Add(new OmsServerCommandEntry(uri, cmd));
}
}
list.Sort(comparer);
return list;
}
private OmsServerCommandComparer comparer = new OmsServerCommandComparer();
private OmsServerCommand? FindCommand(string path)
{
Console.Error.WriteLine("findcommand: for path '{0}'", path);
OmsServerCommand[] commands = MBS.Core.Reflection.TypeLoader.GetAvailableTypes<OmsServerCommand>(new Assembly[] { typeof(OmsServer).Assembly }, true);
IEnumerable<OmsServerCommandEntry> commandsFlat = Flatten(commands);
foreach (OmsServerCommandEntry cmd in commandsFlat)
{
Console.Error.WriteLine("findcommand: checking '{0}'", cmd.Uri);
if (MatchUriPattern(path, cmd.Uri, out Dictionary<string, string> vars))
{
Console.Error.WriteLine("OK!");
cmd.Command.Variables.AddRange(vars);
return cmd.Command;
}
}
return null;
}
public void ProcessRequest(WebServerProcessRequestEventArgs e, Oms oms, OmsContext ctx, StreamWriter sw)
{
OmsServerCommand? cmd = FindCommand(e.Context.Request.Path);
if (cmd != null)
{
cmd.Process(e, oms, ctx, sw);
}
else
{
JsonObject obj = new JsonObject();
obj.Add("result", "failure");
// obj.Add("message", String.Format("unknown cmd '{0}'", command));
RespondWithJson(oms, sw, e.Context, 404, "Not Found", obj);
}
}
public void RespondWithJson(Oms oms, StreamWriter sw, WebContext context, int responseCode, string responseText, JsonObject obj)
{
context.Response.ResponseCode = responseCode;
context.Response.ResponseText = responseText;
context.Response.ContentType = "application/json";
if (context.Session.ContainsKey("OmsContext"))
{
OmsContext ctx = (OmsContext)context.Session["OmsContext"];
object? loginToken = ctx.GetWorkData(oms.GetInstance(KnownAttributeGuids.Text.Token));
if (loginToken != null)
{
obj.Add("sessionSecureToken", loginToken.ToString());
}
}
sw.Write(obj.ToJsonString());
}
}

View File

@ -0,0 +1,43 @@
// Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
//
// This file is part of Mocha.NET.
//
// Mocha.NET is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mocha.NET is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
using System.Text.Json.Nodes;
using MBS.Web;
using Mocha.Core;
namespace Mocha.Core.UI.Server;
public abstract class OmsServerCommand
{
public abstract IEnumerable<string> UriPatterns { get; }
public Dictionary<string, string> Variables { get; } = new Dictionary<string, string>();
protected virtual bool BeforeProcessInternal(WebServerProcessRequestEventArgs e, Core.Oms oms, Core.OmsContext ctx, StreamWriter sw)
{
return true;
}
protected abstract void ProcessInternal(WebServerProcessRequestEventArgs e, Core.Oms oms, Core.OmsContext ctx, StreamWriter sw);
public void Process(WebServerProcessRequestEventArgs e, Core.Oms oms, Core.OmsContext ctx, StreamWriter sw)
{
if (!BeforeProcessInternal(e, oms, ctx, sw))
return;
ProcessInternal(e, oms, ctx, sw);
}
}

View File

@ -1,27 +1,10 @@
// Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
//
// This file is part of Mocha.NET.
//
// Mocha.NET is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mocha.NET is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
//
//
// InstanceKey.cs
//
// Author:
// Michael Becker <alcexhim@gmail.com>
//
// Copyright (c) 2020 Mike Becker's Software
// Copyright (c) 2020-2024 Mike Becker's Software
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@ -46,6 +29,8 @@ namespace Mocha.Core
private bool _isNotEmpty;
public bool IsEmpty { get { return !_isNotEmpty; } }
public bool IsDerived { get; }
public static readonly InstanceKey Empty = new InstanceKey();
public static InstanceKey Parse(string instanceKey)
@ -67,17 +52,30 @@ namespace Mocha.Core
return false;
}
public InstanceKey(string instanceKey)
public InstanceKey(string? instanceKey)
{
if (instanceKey == null)
{
ClassIndex = 0;
InstanceIndex = 0;
IsDerived = false;
_isNotEmpty = false;
}
else
{
char splitChar = '\0';
if (instanceKey.Contains("$"))
{
splitChar = '$';
IsDerived = false;
}
else if (instanceKey.Contains("!"))
{
splitChar = '!';
IsDerived = true;
}
if (splitChar != '\0')
{
string[] split = instanceKey.Split(new char[] { '$' });
if (split.Length == 2)
@ -92,7 +90,7 @@ namespace Mocha.Core
}
}
}
throw new ArgumentException("must be a string containing two integers separated by a '$'");
throw new ArgumentException("must be a string containing two integers separated by a '$' or a '!'");
}
public InstanceKey(int classIndex, int instanceIndex)
{
@ -103,7 +101,7 @@ namespace Mocha.Core
public override bool Equals(object obj)
{
return (obj is InstanceKey) && ((InstanceKey)obj).ClassIndex == ClassIndex && ((InstanceKey)obj).InstanceIndex == InstanceIndex && ((InstanceKey)obj).IsEmpty == IsEmpty;
return (obj is InstanceKey) && ((InstanceKey)obj).ClassIndex == ClassIndex && ((InstanceKey)obj).InstanceIndex == InstanceIndex && ((InstanceKey)obj).IsEmpty == IsEmpty && ((InstanceKey)obj).IsDerived == IsDerived;
}
public static bool operator ==(InstanceKey left, InstanceKey right)
{
@ -116,6 +114,10 @@ namespace Mocha.Core
public override string ToString()
{
if (IsDerived)
{
return String.Format("{0}!{1}", ClassIndex, InstanceIndex);
}
return String.Format("{0}${1}", ClassIndex, InstanceIndex);
}
}

View File

@ -112,6 +112,7 @@ namespace Mocha.Core
public static Guid SystemRoutine { get; } = new Guid("{6e5265af-f73d-420c-b9d5-cf2fdc90363d}");
public static Guid SystemInstanceSetRoutine { get; } = new Guid("{d17a6d27-da03-4b5d-9256-f67f978f403d}");
public static Guid SystemAttributeRoutine { get; } = new Guid("{117f4b9c-2678-4747-aced-78d93c25dcd7}");
public static Guid SystemUpdateRoutine { get; } = new Guid("{0dad3e78-084f-4894-a4a3-006aab2035df}");
public static Guid Report { get; } = new Guid("{19D947B6-CE82-4EEE-92EC-A4E01E27F2DB}");
public static Guid ReportColumn { get; } = new Guid("{BEFE99A1-B2EB-4365-A2C9-061C6609037B}");
@ -242,7 +243,11 @@ namespace Mocha.Core
// GSP - Get Instance Set from Parameters Method - 51
// SA - Select Attribute Method - 52
// PRU - Process Related Updates Method - 54
/// <summary>
/// PRU - Process Related Updates Method [1$54]
/// </summary>
/// <returns></returns>
public static Guid ProcessRelatedUpdatesMethod { get; } = new Guid("{2953e698-03c5-4752-a1eb-cbbfa8f13905}");
/// <summary>
/// BUIR - Build UI Response Method [1$62]
/// </summary>
@ -256,7 +261,11 @@ namespace Mocha.Core
/// <returns></returns>
public static Guid GetAttributeBySystemRoutineMethod { get; } = new Guid("{9d45eb8c-1fb5-4260-a69c-f99a8f7a70b8}");
// GES - Get Element by System Routine Method - 67
// US - Update by System Routine Method - 68
/// <summary>
/// US - Update by System Routine Method - 68
/// </summary>
/// <returns></returns>
public static Guid UpdateBySystemRoutineMethod { get; } = new Guid("{dfdf1541-90c8-415a-b4f3-6e87dd037e12}");
/// <summary>
/// AA - Asssign Attribute Method - 73
/// </summary>
@ -274,19 +283,24 @@ namespace Mocha.Core
public static Guid ConditionalSelectAttributeMethod { get; } = new Guid("{d534a369-321e-4c32-bd7f-8ff2017f191e}"); // 13038
// SSC - Conditional Select from Instance Set Method - 13039
public static Guid ConditionalSelectFromInstanceSetMethod { get; } = new Guid("{ffea8e52-06e5-4e95-8c40-da3ba54ce95f}"); // 13039
}
}
public static class SystemAttributeRoutines
{
public static Guid GetRuntimeVersion { get; } = new Guid("{dc4e6c8d-936d-457f-90e9-af47e229b80c}");
// public static Guid SystemInstanceSetRoutine { get; } = new Guid("{d17a6d27-da03-4b5d-9256-f67f978f403d}");
public static Guid GetInstanceText { get; } = new Guid("{b024abd6-1f2b-495a-9da3-c9ce29fb0c2f}");
public static Guid GetRandomNumber { get; } = new Guid("{8f7945da-4cad-49cb-9838-85f3524a5adb}");
}
public static Guid GetIPAddress { get; } = new Guid("{45411e57-ef6e-44f5-8801-603e567d73d4}");
}
public static class SystemInstanceSetRoutines
{
// public static Guid SystemInstanceSetRoutine { get; } = new Guid("{d17a6d27-da03-4b5d-9256-f67f978f403d}");
public static Guid GetCurrentUser { get; } = new Guid("{9ee8edda-aa1b-4766-8c31-1331be5ffb41}");
}
public static class SystemUpdateRoutines
{
public static Guid LoginUser { get; } = new Guid("{f36f8f87-0d2b-4e62-b85f-abb7e94d952c}");
}
public static class PromptValueClasses
{
public static Guid InstancePromptValue { get; } = new Guid("{0A6E2CF2-97B6-4339-B1DA-1DBBFE9806C6}");
@ -436,6 +450,15 @@ namespace Mocha.Core
public static Guid NotExactMatchWithSelectionList { get; } = new Guid("{f08a632a-1f3e-4979-8ec5-17fefc33b865}");
public static Guid ExactMatchWithSelectionList { get; } = new Guid("{93611da1-e21e-4021-9ddd-f7575e0c79ec}");
}
public class LogicalOperators
{
public static Guid EqualTo { get; } = new Guid("{733e1fb4-6366-4813-bebb-1e6a7bf504db}");
public static Guid NotEqualTo { get; } = new Guid("{c357f835-6b3c-446c-922e-6e867e116fb5}");
public static Guid GreaterThan { get; } = new Guid("{f79b96b7-3c57-455f-87ce-1a3372be65b8}");
public static Guid LessThan { get; } = new Guid("{8b7b92d4-6297-4f1d-ba11-7cad9d33f517}");
public static Guid GreaterThanOrEqualTo { get; } = new Guid("{3a4eb7be-f96b-45ac-b97a-bb8fbfc35923}");
public static Guid LessThanOrEqualTo { get; } = new Guid("{528e5637-f995-4a6d-93c3-f5e1e62b4517}");
}
public static class Languages
{
public static Guid English { get; } = new Guid ("{68BB6038-A4B5-4EE1-AAE9-326494942062}");

View File

@ -86,7 +86,9 @@ namespace Mocha.Core
public static Guid Instance_Attribute_String_Component__has__Attribute { get; } = new Guid("{E15D4277-69FB-4F19-92DB-8D087F361484}");
public static Guid String_Component__has_source__Method { get; } = new Guid("{1ef1c965-e120-48be-b682-aa040573b5fb}");
public static Guid Class__instance_labeled_by__Return_Attribute_Method_Binding { get; } = new Guid("{F52FC851-D655-48A9-B526-C5FE0D7A29D2}");
// public static Guid Class__instance_labeled_by__Return_Attribute_Method_Binding { get; } = new Guid("{F52FC851-D655-48A9-B526-C5FE0D7A29D2}");
public static Guid Class__instances_labeled_by__Executable_returning_Attribute { get; } = new Guid("{c22fc17f-0c92-47dc-9a8b-28db0db68985}");
public static Guid Class__has_summary__Report_Field { get; } = new Guid("{D11050AD-7376-4AB7-84DE-E8D0336B74D2}");
public static Guid Class__has_related__Task { get; } = new Guid("{4D8670E1-2AF1-4E7C-9C87-C910BD7B319B}");
@ -141,6 +143,9 @@ namespace Mocha.Core
public static Guid Build_Attribute_Method__returns__Attribute { get; } = new Guid("{dadbf0f3-7af0-4387-a6b7-a1724a216d88}");
public static Guid Attribute__returned_by__Build_Attribute_Method { get; } = new Guid("{d5a6062b-2e84-46a1-8f54-da630ef6a48c}");
public static Guid Build_Attribute_Method__builds_with__Build_Attribute_Method_Component { get; } = new Guid("{b4fad1b8-711c-4e84-82d0-e9a9e41e8aa7}");
public static Guid Build_Attribute_Method_Component__uses__Executable_returning_Attribute { get; } = new Guid("{9d2acd01-5c6d-4a95-b77e-5261ba109540}");
public static Guid Get_Attribute_Method__returns__Attribute { get; } = new Guid("{5eca9b3f-be75-4f6e-8495-781480774833}");
public static Guid Attribute__returned_by__Get_Attribute_Method { get; } = new Guid("{e82ace2e-84b7-4912-89ed-7b8efd63bb5d}");
@ -154,6 +159,7 @@ namespace Mocha.Core
public static Guid Get_Instance_Set_by_System_Routine_Method__uses__System_Instance_Set_Routine { get; } = new Guid("{085bd706-eece-4604-ac04-b7af114d1d21}");
public static Guid System_Instance_Set_Routine__used_by__Get_Instance_Set_by_System_Routine_Method { get; } = new Guid("{6fb6534c-2a46-4d6d-b9df-fd581f19efed}");
public static Guid Update_by_System_Routine_Method__uses__System_Update_Routine { get; } = new Guid("{9424a253-cb40-4c7d-bebd-0d0373458154}");
public static Guid Get_Referenced_Instance_Set_Method__returns__Work_Set { get; } = new Guid("{72057f5b-9b49-497d-852f-cd7e5e258d6c}");
public static Guid Get_Referenced_Instance_Set_Method__uses_reference__Executable_returning_Instance_Set { get; } = new Guid("{2978238f-7cb0-4ba3-8c6f-473df782cfef}");
@ -319,6 +325,13 @@ namespace Mocha.Core
public static Guid Element_Content__has__Layout { get; } = new Guid("{1ab74120-05ea-4aca-b6d3-c7e0133e0c4f}");
public static Guid Element_Content__built_from__BEM_Process { get; } = new Guid("{3d7094ff-33e5-4800-9e4e-93dde0d1d331}");
public static Guid Element__has__Layout { get; } = new Guid("{11070799-46bd-4201-ba09-6109c68e61ad}");
public static Guid Layout__for__Element { get; } = new Guid("{05ced0ff-1dc2-41bc-b460-4773da080fc0}");
public static Guid Layout__has__Style { get; } = new Guid("{e684bb26-7e78-4a21-b8b4-5a550f3053d5}");
public static Guid Group_Layout__uses__Group_Layout_Option { get; } = new Guid("{5bea01b6-c33e-4f37-a940-579712ab47c7}");
@ -415,5 +428,12 @@ namespace Mocha.Core
public static Guid Route__secured_to__Domain { get; } = new Guid("{2d085cbe-103b-49ea-b6fe-738357e75912}");
public static Guid Domain__secures__Route { get; } = new Guid("{95725379-7b45-4e0c-a04e-b06eead84c60}");
}
public static Guid Element__processed_by__Process_Related_Updates_Method { get; } = new Guid("{ed9c836a-04a4-4505-8953-3c567e841c66}");
public static Guid Process_Related_Updates_Method__uses__Executable_for_PUMB { get; } = new Guid("{50e1f14a-d6e5-4c71-b7ab-1755442728dc}");
public static Guid BEM_Process__uses_loop__Executable_returning_Instance_Set { get; } = new Guid("{0fb2b538-eacb-418a-b7d8-43a584b85952}");
public static Guid Get_Instances_Method__returns__Work_Set { get; } = new Guid("{7d0f93b1-8c93-464e-a44d-d674f910b589}");
public static Guid Get_Instances_Method__selects_instances_of__Class { get; } = new Guid("{c0b85d90-de8c-44c2-9420-c5e724ccdf2c}");
}
}

View File

@ -23,8 +23,13 @@ public class AssignAttributeMethodImplementation : MethodImplementation
protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method)
{
InstanceHandle irForClass = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Method__for__Class));
InstanceHandle irForInstance = (InstanceHandle) context.GetWorkData(irForClass);
object wdForClass = context.GetWorkData(irForClass);
if (wdForClass == null)
{
throw new NullReferenceException(String.Format("work data not set for `Method.for Class` {0}", oms.GetGlobalIdentifier(irForClass)));
}
InstanceHandle irForInstance = (InstanceHandle)wdForClass;
InstanceHandle assignsAttribute = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Assign_Attribute_Method__assigns__Attribute));
if (assignsAttribute == InstanceHandle.Empty)
@ -33,7 +38,16 @@ public class AssignAttributeMethodImplementation : MethodImplementation
}
InstanceHandle assignsFrom = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Assign_Attribute_Method__uses__Executable_returning_Attribute));
InstanceHandle assignsFromValue = oms.Execute(context, assignsFrom);
// ! FIXME: these should not be equal?? idk
InstanceHandle assignsFromValue = InstanceHandle.Empty;
if (oms.IsInstanceOf(assignsFrom, oms.GetInstance(KnownInstanceGuids.Classes.Executable)))
{
assignsFromValue = oms.Execute(context, assignsFrom);
}
else
{
assignsFromValue = assignsFrom;
}
// InstanceHandle forInstance = (InstanceHandle) context.GetWorkData(irForClass);
object? value = context.GetWorkData(assignsFromValue);

View File

@ -31,7 +31,33 @@ public class BuildAttributeMethodImplementation : MethodImplementation
}
// InstanceHandle forInstance = (InstanceHandle) context.GetWorkData(irForClass);
object? value = oms.UnsafeGetAttributeValue(method, oms.GetInstance(KnownAttributeGuids.Text.Value));
object? value = oms.UnsafeGetAttributeValue(method, oms.GetInstance(KnownAttributeGuids.Text.Value)); // initial value
if (value is string)
{
IEnumerable<InstanceHandle> buildsWithRambs = oms.GetRelatedInstances(method, oms.GetInstance(KnownRelationshipGuids.Build_Attribute_Method__builds_with__Build_Attribute_Method_Component));
foreach (InstanceHandle ihComponent in buildsWithRambs)
{
InstanceHandle ihRamb = oms.GetRelatedInstance(ihComponent, oms.GetInstance(KnownRelationshipGuids.Build_Attribute_Method_Component__uses__Executable_returning_Attribute));
object? val = null;
if (oms.IsInstanceOf(ihRamb, oms.GetInstance(KnownInstanceGuids.Classes.Attribute)))
{
val = null;
}
else if (oms.IsInstanceOf(ihRamb, oms.GetInstance(KnownInstanceGuids.Classes.Executable)))
{
InstanceHandle wd = oms.Execute(context, ihRamb);
val = context.GetWorkData(wd);
}
if (val is string)
{
value = ((string)value) + (string)val;
}
}
}
context.SetWorkData(returnsAttribute, value);
return returnsAttribute;
}

View File

@ -62,15 +62,19 @@ public class EvaluateBooleanExpressionMethodImplementation : MethodImplementatio
rsource_value = new InstanceHandle[] { (InstanceHandle)rsource_valueraw };
}
if (oms.IsInstanceOf(target, c_Class))
if (oms.IsInstanceOf(target, oms.GetInstance(KnownInstanceGuids.Classes.Attribute)))
{
rtarget_value = new InstanceHandle[] { target };
}
else
else if (oms.IsInstanceOf(target, oms.GetInstance(KnownInstanceGuids.Classes.Executable)))
{
InstanceHandle rtarget = oms.Execute(context, target);
object? rtarget_valueraw = context.GetWorkData(rtarget);
}
else
{
rtarget_value = new InstanceHandle[] { target };
}
bool value = false;
@ -105,9 +109,14 @@ public class EvaluateBooleanExpressionMethodImplementation : MethodImplementatio
value = false;
}
}
else if (comparison == oms.GetInstance(KnownInstanceGuids.LogicalOperators.EqualTo))
{
// ! FIXME ! Implement This !
value = false;
}
else
{
throw new NotImplementedException(String.Format("relational operator '{0}' not implemented", comparison));
throw new NotImplementedException(String.Format("relational operator '{0}' not implemented @@ {1}, {2}", comparison, oms.GetGlobalIdentifier(method).ToString("B"), context.StackTrace.ToString()));
}
context.SetWorkData(returnsAttribute, value);

View File

@ -35,6 +35,11 @@ public class GetAttributeMethodImplementation : MethodImplementation
{
throw new NullReferenceException(String.Format("non-static method call without instance reference {0}", oms.GetGlobalIdentifier(irForClass)));
}
if (oms.IsInstanceOf(forInstance.Value, oms.GetInstance(KnownInstanceGuids.Classes.WorkSet)))
{
forInstance = (InstanceHandle?) context.GetWorkData(forInstance.Value);
}
object? value = oms.UnsafeGetAttributeValue((InstanceHandle) forInstance, returnsAttribute);
context.SetWorkData(returnsAttribute, value);

View File

@ -0,0 +1,39 @@
// Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
//
// This file is part of Mocha.NET.
//
// Mocha.NET is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mocha.NET is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
namespace Mocha.Core.MethodImplementations;
public class GetInstancesMethodImplementation : MethodImplementation
{
public override Guid MethodClassGuid => new Guid("{0a379314-9d0f-432d-ae59-63194ab32dd3}");
protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method)
{
InstanceHandle returnsWorkSet = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Get_Instances_Method__returns__Work_Set));
InstanceHandle selectsInstanceOfClass = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Get_Instances_Method__selects_instances_of__Class));
IEnumerable<InstanceHandle> list = new InstanceHandle[0];
if (selectsInstanceOfClass != InstanceHandle.Empty)
{
list = oms.GetInstancesOf(selectsInstanceOfClass);
}
context.SetWorkData(returnsWorkSet, list);
return returnsWorkSet;
}
}

View File

@ -39,9 +39,13 @@ public class GetReferencedAttributeMethodImplementation : MethodImplementation
InstanceHandle referenceInstanceSetWS = oms.Execute(context, referenceInstanceSet);
object? referenceInstanceSetValue = context.GetWorkData(referenceInstanceSetWS);
if (referenceInstanceSetValue is IReadOnlyCollection<InstanceHandle>)
if (referenceInstanceSetValue is InstanceHandle)
{
referenceInstanceSetValue = new InstanceHandle[] { (InstanceHandle)referenceInstanceSetValue };
}
if (referenceInstanceSetValue is IEnumerable<InstanceHandle> list)
{
IReadOnlyCollection<InstanceHandle> list = (IReadOnlyCollection<InstanceHandle>)referenceInstanceSetValue;
object? retval = null;
int avg_c = 0;

View File

@ -48,9 +48,8 @@ public class GetReferencedInstanceSetMethodImplementation : MethodImplementation
referenceInstanceSetValue = new InstanceHandle[] { (InstanceHandle)referenceInstanceSetValue };
}
if (referenceInstanceSetValue is IReadOnlyCollection<InstanceHandle>)
if (referenceInstanceSetValue is IEnumerable<InstanceHandle> list)
{
IReadOnlyCollection<InstanceHandle> list = (IReadOnlyCollection<InstanceHandle>)referenceInstanceSetValue;
object? retval = null;
foreach (InstanceHandle inst in list)
@ -62,10 +61,18 @@ public class GetReferencedInstanceSetMethodImplementation : MethodImplementation
if (oms.IsInstanceOf(answerInstanceSet, oms.GetInstance(KnownInstanceGuids.Classes.Executable)))
{
answerInstanceSetWD = oms.Execute(context, answerInstanceSet);
object? answerInstanceSetValue = context.GetWorkData(answerInstanceSetWD);
retval = answerInstanceSetValue;
}
else if (oms.IsInstanceOf(answerInstanceSet, oms.GetInstance(KnownInstanceGuids.Classes.Relationship)))
{
object? answerInstanceSetValue = oms.GetRelatedInstance(inst, answerInstanceSet);
retval = answerInstanceSetValue;
}
object? answerInstanceSetValue = context.GetWorkData(answerInstanceSetWD);
retval = answerInstanceSetValue;
// ! FIXME ! multiple instances not yet supported
break;
}
context.SetWorkData(returnsWorkSet, retval);
}

View File

@ -54,7 +54,7 @@ public class GetRelationshipMethodImplementation : MethodImplementation
}
else
{
context.SetWorkData(returnsRelationship, null);
context.SetWorkData(returnsRelationship, (object)null);
}
}
else

View File

@ -0,0 +1,34 @@
// Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
//
// This file is part of Mocha.NET.
//
// Mocha.NET is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mocha.NET is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
namespace Mocha.Core.MethodImplementations;
public class ProcessRelatedUpdatesMethodImplementation : MethodImplementation
{
public override Guid MethodClassGuid => KnownInstanceGuids.MethodClasses.ProcessRelatedUpdatesMethod;
protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method)
{
InstanceHandle forClass = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Method__for__Class));
IEnumerable<InstanceHandle> usesExecutableForPUMB = oms.GetRelatedInstances(method, oms.GetInstance(KnownRelationshipGuids.Process_Related_Updates_Method__uses__Executable_for_PUMB));
foreach (InstanceHandle pumb in usesExecutableForPUMB)
{
oms.Execute(context, pumb);
}
return InstanceHandle.Empty;
}
}

View File

@ -0,0 +1,36 @@
// Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
//
// This file is part of Mocha.NET.
//
// Mocha.NET is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mocha.NET is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
namespace Mocha.Core.MethodImplementations;
public class UpdateBySystemRoutineMethodImplementation : MethodImplementation
{
public override Guid MethodClassGuid => KnownInstanceGuids.MethodClasses.UpdateBySystemRoutineMethod;
protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method)
{
InstanceHandle irForClass = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Method__for__Class));
InstanceHandle usesSystemUpdateRoutine = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Update_by_System_Routine_Method__uses__System_Update_Routine));
if (usesSystemUpdateRoutine == InstanceHandle.Empty)
{
throw new InvalidOperationException("no System Update Routine specified for method");
}
oms.ExecuteSystemRoutine(context, usesSystemUpdateRoutine);
return InstanceHandle.Empty;
}
}

View File

@ -17,19 +17,26 @@
namespace Mocha.Core;
using System.Collections.ObjectModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.SqlTypes;
using System.Diagnostics.Contracts;
using System.Net;
using System.Numerics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json.Nodes;
using System.Xml.XPath;
using MBS.Core;
using MBS.Core.Extensibility;
using MBS.Core.IO;
using Mocha.Core.MethodImplementations;
using Mocha.Core.Oop;
using Mocha.Core.Responses;
using Mocha.Core.UI;
public abstract class Oms
{
@ -65,11 +72,21 @@ public abstract class Oms
UpdateSyntacticSugar();
RegisterSystemRoutine(KnownInstanceGuids.SystemAttributeRoutines.GetRuntimeVersion, new SystemAttributeRoutine<string>(this, KnownInstanceGuids.SystemAttributeRoutines.GetRuntimeVersion, delegate (Oms oms, OmsContext context)
RegisterSystemAttributeRoutine(KnownInstanceGuids.SystemAttributeRoutines.GetInstanceText, delegate (Oms oms, OmsContext context)
{
object? val = context.GetWorkData(oms.GetInstance(KnownInstanceGuids.Classes.Instance));
if (val is InstanceHandle ih)
{
return oms.GetInstanceText(ih);
}
return "";
});
RegisterSystemAttributeRoutine(KnownInstanceGuids.SystemAttributeRoutines.GetRuntimeVersion, delegate (Oms oms, OmsContext context)
{
return RuntimeVersion.ToString();
}));
RegisterSystemRoutine(KnownInstanceGuids.SystemAttributeRoutines.GetRandomNumber, new SystemAttributeRoutine<decimal>(this, KnownInstanceGuids.SystemAttributeRoutines.GetRuntimeVersion, delegate (Oms oms, OmsContext context)
});
RegisterSystemAttributeRoutine(KnownInstanceGuids.SystemAttributeRoutines.GetRandomNumber, delegate (Oms oms, OmsContext context)
{
object? oSeed = context.GetWorkData(oms.GetInstance(KnownAttributeGuids.Numeric.Seed));
@ -83,7 +100,64 @@ public abstract class Oms
r = new Random();
}
return (decimal)r.NextDouble();
}));
});
RegisterSystemUpdateRoutine(KnownInstanceGuids.SystemUpdateRoutines.LoginUser, delegate (Oms oms, OmsContext context)
{
// FIXME: these are ECs for now, they should probably be Text Attributes (or parms?) passed into the US method
Guid userNameGuid = new Guid("{c67f305e-bd4d-4628-816b-55fb85ea1b67}");
Guid passwordGuid = new Guid("{51b51be3-44fd-48f1-971f-682aee0a6132}");
string userName = context.GetWorkData<string>(oms.GetInstance(userNameGuid));
string password = context.GetWorkData<string>(oms.GetInstance(passwordGuid));
HashAlgorithm hashAlgorithm = SHA512.Create();
InstanceHandle clsUser = oms.GetInstance(KnownInstanceGuids.Classes.User);
IEnumerable<InstanceHandle> users = oms.GetInstancesOf(clsUser);
string? sessionSecureToken = null;
InstanceHandle actualSystemUser = InstanceHandle.Empty;
foreach (InstanceHandle user in users)
{
string expectedUserName = oms.GetAttributeValue<string>(user, oms.GetInstance(KnownAttributeGuids.Text.UserName));
if (expectedUserName == null)
continue;
if (expectedUserName != userName)
continue;
string expectedPasswordHash = oms.GetAttributeValue<string>(user, oms.GetInstance(KnownAttributeGuids.Text.PasswordHash));
if (expectedPasswordHash == null)
continue;
expectedPasswordHash = expectedPasswordHash.ToLowerInvariant();
string passwordSalt = oms.GetAttributeValue<string>(user, oms.GetInstance(KnownAttributeGuids.Text.PasswordSalt));
byte[] hash = hashAlgorithm.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password + passwordSalt));
string actualPasswordHash = Convert.ToHexString(hash).ToLowerInvariant();
if (actualPasswordHash.Equals(expectedPasswordHash))
{
actualSystemUser = user;
sessionSecureToken = Guid.NewGuid().ToString("B").ToLowerInvariant();
break;
}
}
if (sessionSecureToken != null)
{
context.SetWorkData(oms.GetInstance(KnownInstanceGuids.Classes.User), actualSystemUser);
context.SetWorkData(oms.GetInstance(KnownAttributeGuids.Text.Token), sessionSecureToken);
// FIXME: this should be processed in the PRU
InstanceHandle clsSystemAccountSignon = GetInstance(KnownInstanceGuids.Classes.UserLogin);
InstanceHandle systemAccountSignon = CreateInstanceOf(clsSystemAccountSignon);
AssignRelationship(systemAccountSignon, GetInstance(KnownRelationshipGuids.User_Login__has__User), actualSystemUser);
SetAttributeValue(systemAccountSignon, GetInstance(KnownAttributeGuids.Text.Token), sessionSecureToken);
SetAttributeValue(systemAccountSignon, GetInstance(KnownAttributeGuids.Text.IPAddress), context.GetExtraData<string>("Client.IPAddress"));
}
});
DebugOms = this;
}
@ -416,7 +490,7 @@ public abstract class Oms
return HasAttributeValueInternal(source, attribute, effectiveDate.GetValueOrDefault(DateTime.Now));
}
protected abstract object? GetAttributeValueInternal(InstanceHandle source, InstanceHandle attribute, DateTime effectiveDate);
protected internal object? UnsafeGetAttributeValue(InstanceHandle source, InstanceHandle attribute, DateTime? effectiveDate = null)
public object? UnsafeGetAttributeValue(InstanceHandle source, InstanceHandle attribute, DateTime? effectiveDate = null)
{
object? val = GetAttributeValueInternal(source, attribute, effectiveDate.GetValueOrDefault(DateTime.Now));
return val;
@ -486,6 +560,12 @@ public abstract class Oms
if (!ValidateConstraints)
return;
if (value == null || value == "")
{
// all we can do really is verify if it's supposed to be `Not Empty`
return;
}
InstanceHandle a_TextAttribute = GetInstance(KnownInstanceGuids.Classes.TextAttribute);
InstanceHandle a_BooleanAttribute = GetInstance(KnownInstanceGuids.Classes.BooleanAttribute);
InstanceHandle a_NumericAttribute = GetInstance(KnownInstanceGuids.Classes.NumericAttribute);
@ -608,6 +688,16 @@ public abstract class Oms
return value;
}
public bool IsSubclassOf(InstanceHandle subclasz, InstanceHandle clasz, bool exactMatch = false)
{
bool value = Object.Equals(subclasz, clasz);
if (!value && !exactMatch)
{
return RecursiveClassHasSuperclass(subclasz, clasz);
}
return value;
}
public string GetAttachmentUrl(InstanceHandle fileInstance)
{
string accessKey = BuildAccessKeyForOmsAttachment(fileInstance);
@ -927,10 +1017,26 @@ public abstract class Oms
AssignRelationship(inheritsFrom, GetInstance(KnownRelationshipGuids.Class__has_sub__Class), classInstance);
}
public IReadOnlyCollection<InstanceHandle> GetInstancesOf(InstanceHandle classInstance)
public IReadOnlyCollection<InstanceHandle> GetInstancesOf(InstanceHandle classInstance, bool includeSubclasses = false)
{
IReadOnlyCollection<InstanceHandle> insts = GetRelatedInstances(classInstance, GetInstance(KnownRelationshipGuids.Class__has__Instance));
return insts;
List<InstanceHandle> list = new List<InstanceHandle>();
list.Add(classInstance);
if (includeSubclasses)
{
IEnumerable<InstanceHandle> subclasses = GetRelatedInstances(classInstance, GetInstance(KnownRelationshipGuids.Class__has_sub__Class));
list.AddRange(subclasses);
}
return GetInstancesOf(list);
}
public IReadOnlyCollection<InstanceHandle> GetInstancesOf(IEnumerable<InstanceHandle> classInstances)
{
List<InstanceHandle> list = new List<InstanceHandle>();
foreach (InstanceHandle ih in classInstances)
{
IReadOnlyCollection<InstanceHandle> insts = GetRelatedInstances(ih, GetInstance(KnownRelationshipGuids.Class__has__Instance));
list.AddRange(insts);
}
return list;
}
public string GetInstanceText(InstanceWrapper inst)
@ -942,15 +1048,19 @@ public abstract class Oms
InstanceHandle parentClass = GetParentClass(inst);
InstanceHandle ihLabeledByRAMB = InstanceHandle.Empty;
if (TryGetInstance(KnownRelationshipGuids.Class__instance_labeled_by__Return_Attribute_Method_Binding, out ihLabeledByRAMB))
if (TryGetInstance(KnownRelationshipGuids.Class__instances_labeled_by__Executable_returning_Attribute, out ihLabeledByRAMB))
{
InstanceHandle ramb = GetRelatedInstance(parentClass, ihLabeledByRAMB);
OmsContext context = CreateContext();
InstanceHandle wd = Execute(context, ramb);
string value = context.GetWorkData<string>(wd);
return value;
if (ramb != InstanceHandle.Empty)
{
OmsContext context = CreateContext();
context.SetWorkData(parentClass, inst);
InstanceHandle wd = Execute(context, ramb);
string value = context.GetWorkData<string>(wd);
return value;
}
}
// FIXME: remove when we have Class@get Instance Text implemented
@ -1042,15 +1152,61 @@ public abstract class Oms
}
private Dictionary<Guid, SystemRoutine> _systemRoutinesByInstance = new Dictionary<Guid, SystemRoutine>();
internal void RegisterSystemRoutine(Guid globalIdentifier, SystemRoutine routine)
[Obsolete("Please use RegisterSystemAttributeRoutine or RegisterSystemInstanceSetRoutine instead")]
internal void RegisterSystemRoutine(SystemRoutine routine)
{
_systemRoutinesByInstance[globalIdentifier] = routine;
_systemRoutinesByInstance[routine.GlobalIdentifier] = routine;
}
/// <summary>
/// Registers a new System Attribute Routine with the given delegate.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="globalIdentifier"></param>
/// <param name="func"></param>
public void RegisterSystemAttributeRoutine<T>(Guid globalIdentifier, Func<Oms, OmsContext, T> func)
{
_systemRoutinesByInstance[globalIdentifier] = new SystemAttributeRoutine<T>(this, globalIdentifier, func);
}
/// <summary>
/// Registers a new System Instance Set Routine with the given delegate.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="globalIdentifier"></param>
/// <param name="func"></param>
public void RegisterSystemInstanceSetRoutine(Guid globalIdentifier, Func<Oms, OmsContext, IEnumerable<InstanceHandle>> func)
{
_systemRoutinesByInstance[globalIdentifier] = new SystemInstanceSetRoutine(this, globalIdentifier, func);
}
/// <summary>
/// Registers a new System Update Routine with the given delegate.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="globalIdentifier"></param>
/// <param name="func"></param>
public void RegisterSystemUpdateRoutine(Guid globalIdentifier, Action<Oms, OmsContext> func)
{
_systemRoutinesByInstance[globalIdentifier] = new SystemUpdateRoutine(this, globalIdentifier, func);
}
internal object? ExecuteSystemRoutine(OmsContext context, InstanceHandle handle)
{
Guid globalIdentifier = this.GetGlobalIdentifier(handle);
object? value = _systemRoutinesByInstance[globalIdentifier].Execute(this, context);
SystemRoutine sr = _systemRoutinesByInstance[globalIdentifier];
SystemRoutineExecutingEventArgs ee = new SystemRoutineExecutingEventArgs(this, context, sr, null);
OnSystemRoutineExecuting(ee);
if (ee.Cancel)
{
return ee.ReturnValue;
}
object? value = sr.Execute(this, context);
OnSystemRoutineExecuted(new SystemRoutineExecutedEventArgs(this, context, sr, value));
return value;
}
@ -1309,7 +1465,7 @@ public abstract class Oms
Library lib = new Library();
// _libraries[name] = lh;
if (!File.Exists(filename) && !Directory.Exists(filename))
if (!System.IO.File.Exists(filename) && !Directory.Exists(filename))
{
throw new FileNotFoundException(null, filename);
}
@ -1350,8 +1506,19 @@ public abstract class Oms
}
private Dictionary<LibraryHandle, string> _libraryFileNames = new Dictionary<LibraryHandle, string>();
public event EventHandler<SystemRoutineExecutingEventArgs> SystemRoutineExecuting;
protected virtual void OnSystemRoutineExecuting(SystemRoutineExecutingEventArgs e)
{
SystemRoutineExecuting?.Invoke(this, e);
}
public event EventHandler<SystemRoutineExecutedEventArgs> SystemRoutineExecuted;
protected virtual void OnSystemRoutineExecuted(SystemRoutineExecutedEventArgs e)
{
SystemRoutineExecuted?.Invoke(this, e);
}
public LibraryHandle LoadLibrary(Type type, string manifestResourceStreamName)
public LibraryHandle LoadLibrary(Type type, string manifestResourceStreamName)
{
Stream? st = type.Assembly.GetManifestResourceStream(manifestResourceStreamName);
if (st != null)
@ -1421,4 +1588,134 @@ public abstract class Oms
{
return _tenantsByName.Keys;
}
public bool TryParseInstanceRef(string instanceKeyOrGuid, out InstanceHandle h)
{
h = InstanceHandle.Empty;
if (InstanceKey.TryParse(instanceKeyOrGuid, out InstanceKey k))
{
return TryGetInstance(k, out h);
}
else if (Guid.TryParse(instanceKeyOrGuid, out Guid g))
{
return TryGetInstance(g, out h);
}
else
{
Console.Error.WriteLine("could not parse: {0}", instanceKeyOrGuid);
}
return false;
}
public void UpdateElementContents(OmsContext context, InstanceHandle element, ReadOnlyDictionary<string, string> values)
{
IEnumerable<InstanceHandle> elementContents = GetRelatedInstances(element, GetInstance(KnownRelationshipGuids.Element__has__Element_Content));
foreach (InstanceHandle elementContent in elementContents)
{
object? value = null;
InstanceHandle instance = GetRelatedInstance(elementContent, GetInstance(KnownRelationshipGuids.Element_Content__has__Instance));
InstanceHandle updateWithRWMB = GetRelatedInstance(elementContent, GetInstance(KnownRelationshipGuids.Derived_Element_Content__update_with__Executable_returning_Work_Data));
if (updateWithRWMB != InstanceHandle.Empty)
{
if (IsInstanceOf(updateWithRWMB, GetInstance(KnownInstanceGuids.Classes.Executable)))
{
value = Execute(context, updateWithRWMB);
}
else
{
value = updateWithRWMB;
}
if (value is InstanceHandle)
{
context.SetWorkData(instance, (InstanceHandle)value);
}
}
}
foreach (KeyValuePair<string, string> kvp in values)
{
object newValue = kvp.Value;
if (TryParseInstanceRef(kvp.Key, out InstanceHandle parm__IS))
{
if (IsInstanceOf(parm__IS, GetInstance(KnownInstanceGuids.Classes.ElementContent)))
{
InstanceHandle hasInstance = GetRelatedInstance(parm__IS, GetInstance(KnownRelationshipGuids.Element_Content__has__Instance));
if (IsInstanceOf(hasInstance, GetInstance(KnownInstanceGuids.Classes.Class)))
{
if (TryParseInstanceRef(kvp.Value, out InstanceHandle h))
{
newValue = h;
context.SetWorkData(hasInstance, newValue);
}
}
if (false)
// if (GetAttributeValue<bool>(parm__IS, GetInstance(KnownAttributeGuids.Boolean.DoNotUpdateOnSubmit)))
{
// do not update on submit
continue;
}
}
context.SetWorkData(parm__IS, newValue);
}
}
}
public Response ProcessElement(OmsContext context, InstanceHandle initiatingElement, InstanceHandle parmInstance)
{
if (parmInstance != InstanceHandle.Empty)
{
InstanceHandle processedByCt = GetRelatedInstance(initiatingElement, GetInstance(KnownRelationshipGuids.Element__processed_by__Control_Transaction_Method));
InstanceHandle forClassId = GetRelatedInstance(processedByCt, GetInstance(KnownRelationshipGuids.Method__for__Class));
InstanceHandle buildsResponseWithMB = GetRelatedInstance(processedByCt, GetInstance(KnownRelationshipGuids.Control_Transaction_Method__uses__Build_Response_Method_Binding));
InstanceHandle executesMethod = GetRelatedInstance(buildsResponseWithMB, GetInstance(KnownRelationshipGuids.Method_Binding__executes__Method));
InstanceHandle usesExecutableReturningElement = GetRelatedInstance(executesMethod, GetInstance(KnownRelationshipGuids.Build_UI_Response_Method__uses__Executable_returning_Element));
context.SetWorkData(forClassId, parmInstance);
return ProcessElement(context, usesExecutableReturningElement, InstanceHandle.Empty);
}
else
{
Renderer renderer = new Renderer(this);
Widget widget = renderer.Parse(context, initiatingElement, InstanceHandle.Empty, InstanceHandle.Empty);
if (widget == null)
{
return FailureResponse.UnexpectedFailure;
}
return new PageResponse(delegate (Oms oms, OmsContext ctx)
{
JsonObject obj3 = widget.ToJSONObject(ctx);
JsonObject obj2 = new JsonObject();
obj2.Add("widget", JsonValue.Create("root"));
obj2.Add("body", widget.ToJSONObject(ctx));
JsonObject obj = new JsonObject();
obj.Add("result", "success");
obj.Add("value", obj2);
return obj;
});
}
return FailureResponse.UnexpectedFailure;
}
public string GetLabelForUIElement(InstanceHandle parentElementContent)
{
InstanceHandle parentInstance = GetRelatedInstance(parentElementContent, GetInstance(KnownRelationshipGuids.Element_Content__has__Instance));
string label = GetAttributeValue<string>(parentElementContent, GetInstance(KnownAttributeGuids.Text.LabelOverride));
if (label == null)
{
label = GetAttributeValue<string>(parentElementContent, GetInstance(KnownAttributeGuids.Text.Label));
if (label == null)
{
label = GetInstanceText(parentInstance);
}
}
return label;
}
}

View File

@ -42,7 +42,7 @@ public class OmsContext
if (_WorkData.ContainsKey(parm))
return _WorkData[parm];
Console.Error.WriteLine("work data not found for parm {0}", Oms.GetGlobalIdentifier(parm));
// Console.Error.WriteLine("work data not found for parm {0}", Oms.GetGlobalIdentifier(parm));
return null;
}
@ -66,39 +66,22 @@ public class OmsContext
}
public void SetWorkData(InstanceHandle parm, object? value)
{
if (Oms.IsInstanceOf(parm, Oms.GetInstance(KnownInstanceGuids.Classes.WorkSet)))
if (value != null)
{
bool singular = false;
if (!Oms.TryGetAttributeValue<bool>(parm, Oms.GetInstance(KnownAttributeGuids.Boolean.Singular), out singular))
if (Oms.IsInstanceOf(parm, Oms.GetInstance(KnownInstanceGuids.Classes.WorkSet)))
{
singular = false;
}
bool singular = false;
if (!Oms.TryGetAttributeValue<bool>(parm, Oms.GetInstance(KnownAttributeGuids.Boolean.Singular), out singular))
{
singular = false;
}
if (value is InstanceHandle)
{
IReadOnlyCollection<InstanceHandle> irs = Oms.GetRelatedInstances(parm, Oms.GetInstance(KnownRelationshipGuids.Work_Set__has_valid__Class));
if (irs.Count > 0)
if (value is InstanceHandle)
{
InstanceHandle ir = (InstanceHandle)value;
InstanceHandle parentClass = Oms.GetParentClass(ir);
if (!irs.Contains(parentClass))
{
throw new ArgumentException("instance reference must be an instance of appropriate class");
}
}
}
else if (value is IEnumerable<InstanceHandle>)
{
IEnumerable<InstanceHandle> insts = (IEnumerable<InstanceHandle>)value;
if (singular && insts.Count() > 1)
{
throw new InvalidOperationException("Singular Work Set must only contain a single InstanceReference or be an array of InstanceReference that contains exactly zero or one item.");
}
IEnumerable<InstanceHandle> irs = Oms.GetRelatedInstances(parm, Oms.GetInstance(KnownRelationshipGuids.Work_Set__has_valid__Class));
if (irs != null)
{
foreach (InstanceHandle ir in insts)
IReadOnlyCollection<InstanceHandle> irs = Oms.GetRelatedInstances(parm, Oms.GetInstance(KnownRelationshipGuids.Work_Set__has_valid__Class));
if (irs.Count > 0)
{
InstanceHandle ir = (InstanceHandle)value;
InstanceHandle parentClass = Oms.GetParentClass(ir);
if (!irs.Contains(parentClass))
{
@ -106,22 +89,18 @@ public class OmsContext
}
}
}
}
else if (value is IEnumerable<InstanceWrapper>)
{
IEnumerable<InstanceWrapper> insts = (IEnumerable<InstanceWrapper>)value;
if (singular && insts.Count() > 1)
{
throw new InvalidOperationException("Singular Work Set must only contain a single InstanceReference or be an array of InstanceReference that contains exactly zero or one item.");
}
IEnumerable<InstanceHandle> irs = Oms.GetRelatedInstances(parm, Oms.GetInstance(KnownRelationshipGuids.Work_Set__has_valid__Class));
if (irs != null)
else if (value is IEnumerable<InstanceHandle>)
{
IEnumerable<InstanceHandle> insts = (IEnumerable<InstanceHandle>)value;
if (singular && insts.Count() > 1)
{
throw new InvalidOperationException("Singular Work Set must only contain a single InstanceReference or be an array of InstanceReference that contains exactly zero or one item.");
}
IEnumerable<InstanceHandle> irs = Oms.GetRelatedInstances(parm, Oms.GetInstance(KnownRelationshipGuids.Work_Set__has_valid__Class));
if (irs.Count() > 0)
{
foreach (InstanceWrapper iw in insts)
foreach (InstanceHandle ir in insts)
{
InstanceHandle ir = iw.Handle;
InstanceHandle parentClass = Oms.GetParentClass(ir);
if (!irs.Contains(parentClass))
{
@ -130,10 +109,34 @@ public class OmsContext
}
}
}
}
else
{
throw new ArgumentException(String.Format("cannot assign literal data '{0}' to a Work Set", value));
else if (value is IEnumerable<InstanceWrapper>)
{
IEnumerable<InstanceWrapper> insts = (IEnumerable<InstanceWrapper>)value;
if (singular && insts.Count() > 1)
{
throw new InvalidOperationException("Singular Work Set must only contain a single InstanceReference or be an array of InstanceReference that contains exactly zero or one item.");
}
IEnumerable<InstanceHandle> irs = Oms.GetRelatedInstances(parm, Oms.GetInstance(KnownRelationshipGuids.Work_Set__has_valid__Class));
if (irs != null)
{
if (irs.Count() > 0)
{
foreach (InstanceWrapper iw in insts)
{
InstanceHandle ir = iw.Handle;
InstanceHandle parentClass = Oms.GetParentClass(ir);
if (!irs.Contains(parentClass))
{
throw new ArgumentException("instance reference must be an instance of appropriate class");
}
}
}
}
}
else
{
throw new ArgumentException(String.Format("cannot assign literal data '{0}' to a Work Set", value));
}
}
}
_WorkData[parm] = value;

View File

@ -32,7 +32,7 @@ public class OmsSystemRoutineBuilder
InstanceHandle handle = Oms.CreateInstanceOf(Oms.GetInstance(KnownInstanceGuids.Classes.SystemAttributeRoutine), globalIdentifier);
SystemAttributeRoutine routine = new SystemAttributeRoutine(Oms, globalIdentifier, func);
Oms.RegisterSystemRoutine(globalIdentifier, routine);
Oms.RegisterSystemRoutine(routine);
return routine;
}
public SystemAttributeRoutine<T> CreateSystemAttributeRoutine<T>(Guid globalIdentifier, Func<Oms, OmsContext, T> func)
@ -40,7 +40,7 @@ public class OmsSystemRoutineBuilder
InstanceHandle handle = Oms.CreateInstanceOf(Oms.GetInstance(KnownInstanceGuids.Classes.SystemAttributeRoutine), globalIdentifier);
SystemAttributeRoutine<T> routine = new SystemAttributeRoutine<T>(Oms, globalIdentifier, func);
Oms.RegisterSystemRoutine(globalIdentifier, routine);
Oms.RegisterSystemRoutine(routine);
return routine;
}
public SystemInstanceSetRoutine CreateSystemInstanceSetRoutine(Guid globalIdentifier, Func<Oms, OmsContext, IEnumerable<InstanceHandle>> func)
@ -48,7 +48,7 @@ public class OmsSystemRoutineBuilder
InstanceHandle handle = Oms.CreateInstanceOf(Oms.GetInstance(KnownInstanceGuids.Classes.SystemInstanceSetRoutine), globalIdentifier);
SystemInstanceSetRoutine routine = new SystemInstanceSetRoutine(Oms, globalIdentifier, func);
Oms.RegisterSystemRoutine(globalIdentifier, routine);
Oms.RegisterSystemRoutine(routine);
return routine;
}
}

View File

@ -20,15 +20,16 @@ namespace Mocha.Core.Oop;
public abstract class DeferredInstanceWrapper : InstanceWrapper
{
private Oms oms;
private Guid globalIdentifier;
public Guid GlobalIdentifier { get; private set; }
public DeferredInstanceWrapper(Oms oms, Guid globalIdentifier)
{
this.oms = oms;
this.globalIdentifier = globalIdentifier;
GlobalIdentifier = globalIdentifier;
}
protected override InstanceHandle GetHandleInternal()
{
return oms.GetInstance(globalIdentifier);
return oms.GetInstance(GlobalIdentifier);
}
}

View File

@ -0,0 +1,25 @@
// Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
//
// This file is part of Mocha.NET.
//
// Mocha.NET is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mocha.NET is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
namespace Mocha.Core.Oop.Methods;
public class UpdateBySystemRoutineMethod : Method
{
public override Guid ClassId => KnownInstanceGuids.MethodClasses.UpdateBySystemRoutineMethod;
internal UpdateBySystemRoutineMethod(InstanceHandle handle) : base(handle) { }
}

View File

@ -0,0 +1,34 @@
// Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
//
// This file is part of Mocha.NET.
//
// Mocha.NET is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mocha.NET is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
namespace Mocha.Core.Oop;
public class SystemUpdateRoutine : SystemRoutine
{
public override Guid ClassId => KnownInstanceGuids.Classes.SystemUpdateRoutine;
private Action<Oms, OmsContext> Func { get; }
internal SystemUpdateRoutine(Oms oms, Guid globalIdentifier, Action<Oms, OmsContext> func) : base(oms, globalIdentifier)
{
Func = func;
}
protected override object? ExecuteInternal(Oms oms, OmsContext context)
{
Func?.Invoke(oms, context);
return null;
}
}

View File

@ -0,0 +1,30 @@
// Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
//
// This file is part of Mocha.NET.
//
// Mocha.NET is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mocha.NET is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
using System.Text.Json.Nodes;
using Mocha.Core.Responses;
namespace Mocha.Core;
public abstract class Response
{
protected abstract JsonObject GetResponseInternal(Oms oms, OmsContext context);
public JsonObject GetResponse(Oms oms, OmsContext context)
{
return GetResponseInternal(oms, context);
}
}

View File

@ -0,0 +1,41 @@
// Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
//
// This file is part of Mocha.NET.
//
// Mocha.NET is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mocha.NET is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
using System.Text.Json.Nodes;
namespace Mocha.Core.Responses;
public sealed class FailureResponse : Response
{
public static Response NotImplemented { get; } = new FailureResponse("The method or operation is not implemented.");
public static Response UnexpectedFailure { get; } = new FailureResponse("An unexpected error occurred.");
public FailureResponse(string message)
{
Message = message;
}
public string Message { get; } = String.Empty;
protected override JsonObject GetResponseInternal(Oms oms, OmsContext context)
{
JsonObject obj = new JsonObject();
obj.Add("result", "failure");
obj.Add("message", Message);
return obj;
}
}

View File

@ -0,0 +1,35 @@
// Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
//
// This file is part of Mocha.NET.
//
// Mocha.NET is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mocha.NET is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
using System.Text.Json.Nodes;
namespace Mocha.Core.Responses;
public class PageResponse : Response
{
private Func<Oms, OmsContext, JsonObject> _func;
public PageResponse(Func<Oms, OmsContext, JsonObject> func)
{
_func = func;
}
protected override JsonObject GetResponseInternal(Oms oms, OmsContext context)
{
JsonObject obj = _func(oms, context);
return obj;
}
}

View File

@ -0,0 +1,38 @@
// Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
//
// This file is part of Mocha.NET.
//
// Mocha.NET is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mocha.NET is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
using System.Text.Json.Nodes;
namespace Mocha.Core.Responses;
public class RedirectResponse : Response
{
public RedirectResponse(string destinationUrl)
{
DestinationUrl = destinationUrl;
}
public string DestinationUrl { get; }
protected override JsonObject GetResponseInternal(Oms oms, OmsContext context)
{
JsonObject obj = new JsonObject();
obj.Add("result", "success");
obj.Add("type", "redirect");
obj.Add("destinationUrl", DestinationUrl);
return obj;
}
}

View File

@ -0,0 +1,36 @@
// Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
//
// This file is part of Mocha.NET.
//
// Mocha.NET is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mocha.NET is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
using Mocha.Core.Oop;
namespace Mocha.Core;
public class SystemRoutineExecutedEventArgs : EventArgs
{
public Oms OMS { get; }
public OmsContext Context { get; }
public SystemRoutine SystemRoutine { get; }
public object? ReturnValue { get; }
internal SystemRoutineExecutedEventArgs(Oms oms, OmsContext context, SystemRoutine systemRoutine, object? returnValue)
{
OMS = oms;
Context = context;
SystemRoutine = systemRoutine;
ReturnValue = returnValue;
}
}

View File

@ -0,0 +1,37 @@
// Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
//
// This file is part of Mocha.NET.
//
// Mocha.NET is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mocha.NET is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
using System.ComponentModel;
using Mocha.Core.Oop;
namespace Mocha.Core;
public class SystemRoutineExecutingEventArgs : CancelEventArgs
{
public Oms OMS { get; }
public OmsContext Context { get; }
public SystemRoutine SystemRoutine { get; }
public object? ReturnValue { get; set; }
internal SystemRoutineExecutingEventArgs(Oms oms, OmsContext context, SystemRoutine systemRoutine, object? returnValue)
{
OMS = oms;
Context = context;
SystemRoutine = systemRoutine;
ReturnValue = returnValue;
}
}

View File

@ -0,0 +1,141 @@
// Copyright (C) 2024 Michael Becker <alcexhim@gmail.com>
//
// This file is part of Mocha.NET.
//
// Mocha.NET is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mocha.NET is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
using System.Text.Json.Nodes;
namespace Mocha.Core.UI;
public class JsonRenderer : Renderer
{
public JsonRenderer(Oms oms) : base(oms)
{
}
public JsonArray InstancesToJson(IEnumerable<InstanceHandle> ihs)
{
return JsonRenderer.InstancesToJson(OMS, ihs);
}
public static JsonArray InstancesToJson(Oms oms, IEnumerable<InstanceHandle> ihs)
{
JsonArray array = new JsonArray();
foreach (InstanceHandle ih in ihs)
{
array.Add(InstanceToJson(oms, ih));
}
return array;
}
public JsonObject InstanceToJson(InstanceHandle ih)
{
return JsonRenderer.InstanceToJson(OMS, ih);
}
public static JsonObject InstanceToJson(Oms oms, InstanceHandle ih, bool includeParentClass = true)
{
JsonObject objInstance = new JsonObject();
objInstance.Add("iid", JsonValue.Create(oms.GetInstanceKey(ih).ToString()));
objInstance.Add("globalIdentifier", JsonValue.Create(oms.GetGlobalIdentifier(ih).ToString()));
objInstance.Add("text", JsonValue.Create(oms.GetInstanceText(ih)));
if (includeParentClass)
{
InstanceHandle parentClass = oms.GetParentClass(ih);
JsonObject objParentClass = new JsonObject();
objParentClass.Add("iid", JsonValue.Create(oms.GetInstanceKey(parentClass).ToString()));
objParentClass.Add("globalIdentifier", JsonValue.Create(oms.GetGlobalIdentifier(parentClass).ToString()));
objParentClass.Add("text", JsonValue.Create(oms.GetInstanceText(parentClass)));
InstanceHandle defaultTask = oms.GetRelatedInstance(parentClass, oms.GetInstance(KnownRelationshipGuids.Class__has_default__Task));
objParentClass.Add("defaultTask", InstanceToJson(oms, defaultTask, false));
objInstance.Add("parentClass", objParentClass);
}
return objInstance;
}
public static JsonArray GetAttributesAsJson(Core.Oms oms, InstanceHandle h, InstanceHandle hAtt = default(InstanceHandle))
{
JsonArray a = new JsonArray();
IEnumerable<MochaAttribute> atts = oms.GetAttributes(h);
foreach (MochaAttribute att in atts)
{
if (hAtt != InstanceHandle.Empty)
{
if (!att.AttributeInstance.Equals(hAtt))
{
continue;
}
}
string iid = oms.GetInstanceKey(att.AttributeInstance).ToString();
JsonObject o = new JsonObject();
o.Add("iid", JsonValue.Create(iid));
string attrText = oms.GetInstanceText(att.AttributeInstance);
o.Add("name", JsonValue.Create(attrText));
JsonArray aa = new JsonArray();
foreach (AttributeValue val in att.Values)
{
JsonObject ao = new JsonObject();
ao.Add("effectiveDate", JsonValue.Create(val.EffectiveDate));
ao.Add("value", JsonValue.Create(val.Value));
aa.Add(ao);
}
o.Add("values", aa);
a.Add(o);
}
return a;
}
public static JsonArray GetRelationshipsAsJson(Oms oms, InstanceHandle h, InstanceHandle hRel = default(InstanceHandle))
{
JsonArray a = new JsonArray();
IEnumerable<MochaRelationship> rels = oms.GetRelationships(h);
foreach (MochaRelationship rel in rels)
{
if (hRel != InstanceHandle.Empty)
{
if (!rel.RelationshipInstance.Equals(hRel))
{
continue;
}
}
JsonObject o = new JsonObject();
o.Add("iid", JsonValue.Create(oms.GetInstanceKey(rel.RelationshipInstance).ToString()));
string attrText = oms.GetInstanceText(rel.RelationshipInstance);
o.Add("name", JsonValue.Create(attrText));
JsonArray aa = new JsonArray();
foreach (RelationshipValue val in rel.Values)
{
JsonObject ao = new JsonObject();
ao.Add("effectiveDate", JsonValue.Create(val.EffectiveDate));
ao.Add("targetInstances", JsonRenderer.InstancesToJson(oms, val.TargetInstances));
aa.Add(ao);
}
o.Add("values", aa);
a.Add(o);
}
return a;
}
}

View File

@ -27,26 +27,49 @@ public class Renderer
OMS = oms;
}
public Widget Parse(InstanceHandle h)
public Widget Parse(OmsContext context, InstanceHandle instance, InstanceHandle parentElementContent, InstanceHandle parentElement)
{
return Parse(h, InstanceHandle.Empty);
return Parse(context, instance, parentElementContent, parentElement, InstanceHandle.Empty);
}
public Widget Parse(InstanceHandle h, InstanceHandle parentElementContent)
public Widget Parse(OmsContext context, InstanceHandle instance, InstanceHandle parentElementContent, InstanceHandle parentElement, InstanceHandle processingInstance)
{
Widget[] availableWidgets = MBS.Core.Reflection.TypeLoader.GetAvailableTypes<Widget>();
Widget[] availableWidgets = MBS.Core.Reflection.TypeLoader.GetAvailableTypes<Widget>(new System.Reflection.Assembly[] { typeof(Widget).Assembly }, true);
Console.Error.WriteLine("got {0} available widgets", availableWidgets.Length);
InstanceHandle parentClassInstance = OMS.GetParentClass(h);
InstanceHandle parentClassInstance = OMS.GetParentClass(instance);
Guid gid = OMS.GetGlobalIdentifier(parentClassInstance);
InstanceHandle layoutInstance = OMS.GetRelatedInstance(parentElementContent, OMS.GetInstance(KnownRelationshipGuids.Element_Content__has__Layout));
Guid gidLayout = OMS.GetGlobalIdentifier(layoutInstance);
Widget? useWidget = null;
foreach (Widget w in availableWidgets)
{
if (w.SupportedClassGuids.Contains(gid))
if (instance != InstanceHandle.Empty)
{
useWidget = w;
break;
foreach (Guid gid2 in w.SupportedClassGuids)
{
if (OMS.IsSubclassOf(OMS.GetInstance(gid), OMS.GetInstance(gid2)))
{
useWidget = w;
break;
}
}
}
if (layoutInstance != InstanceHandle.Empty)
{
foreach (Guid gid2 in w.SupportedLayoutGuids)
{
if (OMS.IsSubclassOf(OMS.GetInstance(gid), OMS.GetInstance(gid2)))
{
useWidget = w;
break;
}
}
}
if (useWidget != null)
break;
}
if (useWidget == null)
@ -55,16 +78,98 @@ public class Renderer
return null;
}
object? value = null;
InstanceHandle updateWithRWMB = OMS.GetRelatedInstance(parentElementContent, OMS.GetInstance(KnownRelationshipGuids.Derived_Element_Content__update_with__Executable_returning_Work_Data));
if (updateWithRWMB != InstanceHandle.Empty)
{
if (OMS.IsInstanceOf(updateWithRWMB, OMS.GetInstance(KnownInstanceGuids.Classes.Executable)))
{
value = OMS.Execute(context, updateWithRWMB);
}
else
{
value = updateWithRWMB;
}
}
else
{
if (processingInstance != InstanceHandle.Empty)
{
InstanceHandle ecinst = OMS.GetRelatedInstance(parentElementContent, OMS.GetInstance(KnownRelationshipGuids.Element_Content__has__Instance));
if (OMS.IsInstanceOf(processingInstance, ecinst))
{
value = processingInstance;
}
else if (OMS.IsInstanceOf(ecinst, OMS.GetInstance(KnownInstanceGuids.Classes.Attribute)))
{
value = OMS.UnsafeGetAttributeValue(processingInstance, ecinst);
}
else
{
if (OMS.IsInstanceOf(ecinst, OMS.GetInstance(KnownInstanceGuids.Classes.Relationship)))
{
value = OMS.GetRelatedInstances(processingInstance, ecinst);
}
else if (OMS.IsInstanceOf(ecinst, OMS.GetInstance(KnownInstanceGuids.Classes.Class)))
{
value = context.GetWorkData(ecinst);
}
else
{
// executable returning instance set?
InstanceHandle workSet = OMS.Execute(context, ecinst);
value = context.GetWorkData(workSet);
}
}
}
}
if (useWidget is MonikerList)
{
if (value is InstanceHandle)
{
((MonikerList)useWidget).SelectedInstances.Add((InstanceHandle)value);
context.SetWorkData(instance, (InstanceHandle)value);
}
else if (value is IEnumerable<InstanceHandle> ee)
{
((MonikerList)useWidget).SelectedInstances.AddRange(ee);
}
}
useWidget.OMS = OMS;
useWidget.ParentInstance = h;
if (parentElement != InstanceHandle.Empty)
{
IEnumerable<InstanceHandle> elementContents = OMS.GetRelatedInstances(parentElement, OMS.GetInstance(KnownRelationshipGuids.Element__has__Element_Content));
InstanceHandle firstElementContent = elementContents.First();
if (firstElementContent != parentElementContent)
{
InstanceHandle firstElementContentInstance = OMS.GetRelatedInstance(firstElementContent, OMS.GetInstance(KnownRelationshipGuids.Element_Content__has__Instance));
// InstanceHandle realInstance = OMS.GetInstancesOf(firstElementContentInstance).First();
object realInstance = context.GetWorkData(firstElementContentInstance);
if (realInstance is InstanceHandle)
{
useWidget.TargetInstance = (InstanceHandle)realInstance;
}
}
}
else
{
useWidget.TargetInstance = processingInstance;
}
useWidget.ParentInstance = instance;
useWidget.ParentElementContent = parentElementContent;
useWidget.Renderer = this;
return useWidget;
}
public Widget ParseElementContent(InstanceHandle content)
public Widget ParseElementContent(OmsContext context, InstanceHandle element, InstanceHandle content)
{
InstanceHandle h = OMS.GetRelatedInstance(content, OMS.GetInstance(KnownRelationshipGuids.Element_Content__has__Instance));
return Parse(h, content);
InstanceHandle elementContentInstance = OMS.GetRelatedInstance(content, OMS.GetInstance(KnownRelationshipGuids.Element_Content__has__Instance));
return Parse(context, elementContentInstance, content, element);
}
}

View File

@ -21,21 +21,33 @@ namespace Mocha.Core.UI;
public abstract class Widget
{
protected abstract void RenderJSONInternal(JsonObject obj);
protected abstract void RenderJSONInternal(OmsContext context, JsonObject obj);
protected abstract string GetWidgetName();
/// <summary>
/// The instance on which to retrieve attributes. If empty, the Parent Instance is used.
/// </summary>
/// <value></value>
public InstanceHandle TargetInstance { get; internal set; } = InstanceHandle.Empty;
/// <summary>
/// The instance of the Attribute to retrieve.
/// </summary>
/// <value></value>
public InstanceHandle ParentInstance { get; internal set; } = InstanceHandle.Empty;
public InstanceHandle ParentElementContent { get; internal set; } = InstanceHandle.Empty;
public JsonObject ToJSONObject()
public bool? Enabled { get; set; } = null;
public JsonObject ToJSONObject(OmsContext context)
{
JsonObject obj = new JsonObject();
InsertCommonProperties(obj);
RenderJSONInternal(obj);
RenderJSONInternal(context, obj);
return obj;
}
public virtual Guid[] SupportedClassGuids { get; } = new Guid[0];
public virtual Guid[] SupportedLayoutGuids { get; } = new Guid[0];
public Oms OMS { get; internal set; }
public Renderer Renderer { get; internal set; }
@ -45,6 +57,12 @@ public abstract class Widget
return displayOptions;
}
protected virtual bool ShouldBeEnabled()
{
IEnumerable<InstanceHandle> displayOptions = GetDisplayOptions();
return !displayOptions.Contains(OMS.GetInstance(KnownInstanceGuids.ElementContentDisplayOptions.NotEnterable));
}
private void InsertCommonProperties(JsonObject obj)
{
obj.Add("widget", GetWidgetName());
@ -56,18 +74,10 @@ public abstract class Widget
if (!displayOptions.Contains(OMS.GetInstance(KnownInstanceGuids.ElementContentDisplayOptions.DoNotShowLabel)))
{
string label = OMS.GetAttributeValue<string>(ParentElementContent, OMS.GetInstance(KnownAttributeGuids.Text.LabelOverride));
if (label == null)
{
label = OMS.GetAttributeValue<string>(ParentElementContent, OMS.GetInstance(KnownAttributeGuids.Text.Label));
if (label == null)
{
label = OMS.GetInstanceText(ParentInstance);
}
}
string label = OMS.GetLabelForUIElement(ParentElementContent);
obj.Add("label", label);
}
if (displayOptions.Contains(OMS.GetInstance(KnownInstanceGuids.ElementContentDisplayOptions.NotEnterable)))
if (!ShouldBeEnabled())
{
obj.Add("enabled", false);
}

View File

@ -24,7 +24,45 @@ public class Element : Widget
{
protected override string GetWidgetName()
{
InstanceHandle layout = OMS.GetRelatedInstance(ParentElementContent, OMS.GetInstance(KnownRelationshipGuids.Element_Content__has__Layout));
IEnumerable<InstanceHandle> displayOptions = OMS.GetRelatedInstances(ParentElementContent, OMS.GetInstance(KnownRelationshipGuids.Element_Content__has__Element_Content_Display_Option));
InstanceHandle doSingular = OMS.GetInstance(KnownInstanceGuids.ElementContentDisplayOptions.Singular);
InstanceHandle doShowSubelementsVertically = OMS.GetInstance(KnownInstanceGuids.ElementContentDisplayOptions.ShowSubelementsVertically);
InstanceHandle layout = OMS.GetRelatedInstance(ParentInstance, OMS.GetInstance(KnownRelationshipGuids.Element__has__Layout));
if (layout == InstanceHandle.Empty)
{
Console.Error.WriteLine("!!! FIXME !!! Replace `Element Content.has Layout` with `Element.has Layout`");
layout = OMS.GetRelatedInstance(ParentElementContent, OMS.GetInstance(KnownRelationshipGuids.Element_Content__has__Layout));
}
if (layout == InstanceHandle.Empty)
{
// if we hae `Show Subelements Vertically`, we are a vbox
if (displayOptions.Contains(doShowSubelementsVertically))
{
return "vbox";
}
else
{
// if we have no layout, and we have multiple instances, we are a grid view
if (!displayOptions.Contains(doSingular))
{
if (ParentElementContent != InstanceHandle.Empty)
{
if (OMS.GetRelatedInstances(ParentInstance, OMS.GetInstance(KnownRelationshipGuids.Element__has__Element_Content)).Count() > 1)
{
Console.Error.WriteLine("FIXME: 'grid' returned for Element {0}", OMS.GetGlobalIdentifier(ParentInstance));
return "grid";
}
}
}
// otherwise, we are a hbox
// return "hbox";
return "vbox";
}
}
if (OMS.IsInstanceOf(layout, OMS.GetInstance(KnownInstanceGuids.Classes.GroupLayout)))
{
InstanceHandle ihGLOFieldSet = OMS.GetInstance(KnownInstanceGuids.GroupLayoutOptions.FieldSet);
@ -39,29 +77,149 @@ public class Element : Widget
public override Guid[] SupportedClassGuids => new Guid[] { KnownInstanceGuids.Classes.Element };
protected override void RenderJSONInternal(JsonObject obj)
protected override void RenderJSONInternal(OmsContext context, JsonObject obj)
{
JsonArray objA = new JsonArray();
IEnumerable<InstanceHandle> displayOptions = OMS.GetRelatedInstances(ParentElementContent, OMS.GetInstance(KnownRelationshipGuids.Element_Content__has__Element_Content_Display_Option));
InstanceHandle doSingular = OMS.GetInstance(KnownInstanceGuids.ElementContentDisplayOptions.Singular);
InstanceHandle doDoNotShow = OMS.GetInstance(KnownInstanceGuids.ElementContentDisplayOptions.DoNotShow);
InstanceHandle doDoNotShowIfEmpty = OMS.GetInstance(KnownInstanceGuids.ElementContentDisplayOptions.DoNotShowIfEmpty);
IEnumerable<InstanceHandle> contents = OMS.GetRelatedInstances(ParentInstance, OMS.GetInstance(KnownRelationshipGuids.Element__has__Element_Content));
foreach (InstanceHandle content in contents)
if (!displayOptions.Contains(doSingular) && ParentElementContent != InstanceHandle.Empty && contents.Count() > 1)
{
Widget widget = Renderer.ParseElementContent(content);
if (widget == null)
JsonArray objColumns = new JsonArray();
int i = 1;
foreach (InstanceHandle ec in contents)
{
JsonObject objC = new JsonObject();
objC.Add("widget", JsonValue.Create("error"));
objC.Add("text", JsonValue.Create("could not create EC"));
objC.Add("ecid", JsonValue.Create(OMS.GetInstanceKey(content).ToString()));
objC.Add("iid", JsonValue.Create(OMS.GetInstanceKey(OMS.GetRelatedInstance(content, OMS.GetInstance(KnownRelationshipGuids.Element_Content__has__Instance))).ToString()));
objA.Add(objC);
IEnumerable<InstanceHandle> ecDisplayOptions = OMS.GetRelatedInstances(ec, OMS.GetInstance(KnownRelationshipGuids.Element_Content__has__Element_Content_Display_Option));
InstanceHandle inst = OMS.GetRelatedInstance(ec, OMS.GetInstance(KnownRelationshipGuids.Element_Content__has__Instance));
JsonObject objColumn = new JsonObject();
objColumn.Add("widget", "column");
objColumn.Add("ecid", OMS.GetInstanceKey(ec).ToString());
objColumn.Add("iid", OMS.GetInstanceKey(inst).ToString());
objColumn.Add("enabled", false);
objColumn.Add("label", OMS.GetLabelForUIElement(ec));
objColumn.Add("columnId", i.ToString());
if (ecDisplayOptions.Contains(doDoNotShow))
{
objColumn.Add("visible", false);
}
objColumns.Add(objColumn);
i++;
}
else
obj.Add("columns", objColumns);
obj.Add("compareWorkboxId", OMS.GetInstanceKey(ParentElementContent).ToString());
int deepRowCount = 0;
obj.Add("deepRowCount", deepRowCount);
int subtotalRowCount = 0;
obj.Add("subtotalRowCount", subtotalRowCount);
obj.Add("gridType", "LIST");
JsonArray? ary = BuildElement(context, ParentElementContent);
if (ary != null)
{
objA.Add(widget.ToJSONObject());
int rowCount = ary.Count;
obj.Add("rowCount", rowCount);
obj.Add("rows", ary);
}
}
else
{
JsonArray objA = new JsonArray();
obj.Add("children", objA);
foreach (InstanceHandle content in contents)
{
Widget widget = Renderer.ParseElementContent(context, ParentInstance, content);
if (widget == null)
{
JsonObject objC = new JsonObject();
objC.Add("widget", JsonValue.Create("error"));
objC.Add("text", JsonValue.Create("could not create EC"));
objC.Add("ecid", JsonValue.Create(OMS.GetInstanceKey(content).ToString()));
objC.Add("iid", JsonValue.Create(OMS.GetInstanceKey(OMS.GetRelatedInstance(content, OMS.GetInstance(KnownRelationshipGuids.Element_Content__has__Instance))).ToString()));
objA.Add(objC);
}
else
{
objA.Add(widget.ToJSONObject(context));
}
}
obj.Add("children", objA);
}
}
private JsonArray? BuildElement(OmsContext context, InstanceHandle elementContent)
{
InstanceHandle bemProcess = OMS.GetRelatedInstance(elementContent, OMS.GetInstance(KnownRelationshipGuids.Element_Content__built_from__BEM_Process));
InstanceHandle parentInstance = OMS.GetRelatedInstance(elementContent, OMS.GetInstance(KnownRelationshipGuids.Element_Content__has__Instance));
IEnumerable<InstanceHandle> parentECDisplayOptions = OMS.GetRelatedInstances(elementContent, OMS.GetInstance(KnownRelationshipGuids.Element_Content__has__Element_Content_Display_Option));
bool disabled = parentECDisplayOptions.Contains(OMS.GetInstance(KnownInstanceGuids.ElementContentDisplayOptions.NotEnterable));
IEnumerable<InstanceHandle> contents = OMS.GetRelatedInstances(parentInstance, OMS.GetInstance(KnownRelationshipGuids.Element__has__Element_Content));
InstanceHandle loopExecutable = OMS.GetRelatedInstance(bemProcess, OMS.GetInstance(KnownRelationshipGuids.BEM_Process__uses_loop__Executable_returning_Instance_Set));
int gridId = 468;
InstanceHandle workSet = OMS.Execute(context, loopExecutable);
object? obj = context.GetWorkData(workSet);
if (obj is IEnumerable<InstanceHandle> list)
{
JsonArray ary = new JsonArray();
foreach (InstanceHandle ih in list)
{
JsonObject jo = new JsonObject();
jo.Add("widget", "row");
jo.Add("ecid", "");
jo.Add("iid", "");
JsonObject cellMap = new JsonObject();
int i = 1;
foreach (InstanceHandle ec in contents)
{
InstanceHandle ecinst = OMS.GetRelatedInstance(ec, OMS.GetInstance(KnownRelationshipGuids.Element_Content__has__Instance));
Widget parsed = Renderer.Parse(context, ecinst, ec, InstanceHandle.Empty, ih);
JsonObject cell;
if (parsed == null)
{
cell = new JsonObject();
cell.Add("widget", JsonValue.Create("error"));
cell.Add("text", JsonValue.Create("could not create EC"));
cell.Add("ecid", JsonValue.Create(OMS.GetInstanceKey(ec).ToString()));
cell.Add("iid", JsonValue.Create(OMS.GetInstanceKey(OMS.GetRelatedInstance(ec, OMS.GetInstance(KnownRelationshipGuids.Element_Content__has__Instance))).ToString()));
}
else
{
cell = parsed.ToJSONObject(context);
if (disabled)
{
if (cell.ContainsKey("enabled"))
{
cell.Remove("enabled");
}
cell.Add("enabled", false);
}
}
cellMap.Add(String.Format("{0}.{1}", gridId, i), cell);
i++;
}
jo.Add("cellsMap", cellMap);
ary.Add(jo);
}
return ary;
}
return null;
}
}

View File

@ -25,7 +25,7 @@ public class File : Widget
protected override string GetWidgetName() => "image";
public override Guid[] SupportedClassGuids => new Guid[] { KnownInstanceGuids.Classes.File };
protected override void RenderJSONInternal(JsonObject obj)
protected override void RenderJSONInternal(OmsContext context, JsonObject obj)
{
obj.Add("target", OMS.BuildAccessKeyForOmsAttachment(ParentInstance));
if (ParentElementContent != null)

View File

@ -22,9 +22,36 @@ namespace Mocha.Core.UI;
public class MonikerList : Widget
{
protected override string GetWidgetName() => "monikerList";
public override Guid[] SupportedClassGuids => new Guid[] { KnownInstanceGuids.Classes.WorkSet };
public override Guid[] SupportedClassGuids => new Guid[] { KnownInstanceGuids.Classes.WorkSet, KnownInstanceGuids.Classes.Class, KnownInstanceGuids.Classes.ReturnInstanceSetMethodBinding };
protected override void RenderJSONInternal(JsonObject obj)
public List<InstanceHandle> SelectedInstances { get; } = new List<InstanceHandle>();
protected override void RenderJSONInternal(OmsContext context, JsonObject obj)
{
JsonArray aryInstances = new JsonArray();
foreach (InstanceHandle ih in SelectedInstances)
{
JsonObject obj2 = new JsonObject();
obj2.Add("widget", "moniker");
obj2.Add("instanceId", OMS.GetInstanceKey(ih).ToString());
obj2.Add("text", OMS.GetInstanceText(ih));
obj2.Add("rt", true); // related task?
obj2.Add("pv", true); // preview?
obj2.Add("v", true); // view?
aryInstances.Add(obj2);
}
obj.Add("instances", aryInstances);
if (SelectedInstances.Any())
{
obj.Add("selfUriTemplate", String.Format("/{0}/inst/{1}/{2}", OMS.GetTenantName(OMS.CurrentTenant), OMS.GetInstanceKey(ParentInstance).ToString(), OMS.GetInstanceKey(SelectedInstances.First()).ToString()));
obj.Add("relatedTasksUriTemplate", String.Format("/{0}/inst/{1}/rel-tasks", OMS.GetTenantName(OMS.CurrentTenant), OMS.GetInstanceKey(SelectedInstances.First()).ToString()));
}
obj.Add("text", OMS.GetInstanceText(ParentInstance));
obj.Add("singular", true);
}
protected override bool ShouldBeEnabled()
{
return base.ShouldBeEnabled() && !(OMS.IsInstanceOf(ParentInstance, OMS.GetInstance(KnownInstanceGuids.Classes.ReturnInstanceSetMethodBinding)));
}
}

View File

@ -34,16 +34,39 @@ public class Text : Widget
}
return "text";
}
public override Guid[] SupportedClassGuids => new Guid[] { KnownInstanceGuids.Classes.TextAttribute };
public override Guid[] SupportedClassGuids => new Guid[] { KnownInstanceGuids.Classes.TextAttribute, KnownInstanceGuids.Classes.ExecutableReturningAttribute };
protected override void RenderJSONInternal(JsonObject obj)
protected override void RenderJSONInternal(OmsContext context, JsonObject obj)
{
string value = OMS.GetAttributeValue<string>(ParentInstance, OMS.GetInstance(KnownAttributeGuids.Text.Value));
if (value != null)
string? value = null;
if (OMS.IsInstanceOf(ParentInstance, OMS.GetInstance(KnownInstanceGuids.Classes.TextAttribute)))
{
obj.Add("value", value);
if (TargetInstance != InstanceHandle.Empty)
{
// first check our target instance for the attribute. this MAY be empty
value = OMS.GetAttributeValue<string>(TargetInstance, ParentInstance);
}
}
else
{
InstanceHandle workData = OMS.Execute(context, ParentInstance);
object? val = context.GetWorkData(workData);
value = val?.ToString();
}
if (value == null)
{
// no value specified for the target instance, so get default value of the Text Attribute
value = OMS.GetAttributeValue<string>(ParentInstance, OMS.GetInstance(KnownAttributeGuids.Text.Value));
}
if (value != null)
{
// if we finally have a value, use it
obj.Add("value", value);
}
if (OMS.TryGetAttributeValue<decimal>(ParentInstance, OMS.GetInstance(KnownAttributeGuids.Numeric.MaximumLength), out decimal maximumLength))
{
obj.Add("maximumLength", maximumLength);