Merge branch 'master' of gitea.azcona-becker.net:mochapowered/mocha-dotnet
This commit is contained in:
commit
4c9d44a8d8
3
.gitignore
vendored
3
.gitignore
vendored
@ -418,3 +418,6 @@ FodyWeavers.xsd
|
|||||||
# Mocha CUP output directory
|
# Mocha CUP output directory
|
||||||
output
|
output
|
||||||
|
|
||||||
|
# Backups (made by Notepad++)
|
||||||
|
*.bak
|
||||||
|
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
Subproject commit 65c6b698a3dd1215ccd51de45ea3349f231bbf70
|
Subproject commit 569e302f3000e236ba562f17bc83d9e70a54fbf5
|
||||||
@ -13,6 +13,7 @@ using System.Text.Json.Nodes;
|
|||||||
using Mocha.Core.UI;
|
using Mocha.Core.UI;
|
||||||
using Mocha.Core.Oop;
|
using Mocha.Core.Oop;
|
||||||
using MBS.Core;
|
using MBS.Core;
|
||||||
|
|
||||||
using MBS.Core.Collections.Generic;
|
using MBS.Core.Collections.Generic;
|
||||||
|
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
@ -23,6 +24,10 @@ using System.Reflection;
|
|||||||
|
|
||||||
using Mocha.Core.UI.Server;
|
using Mocha.Core.UI.Server;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides the entry point for a simple application which starts a Web server
|
||||||
|
/// and provisions one or more Mocha tenants from a configuration file.
|
||||||
|
/// </summary>
|
||||||
public class Program : WebApplication
|
public class Program : WebApplication
|
||||||
{
|
{
|
||||||
public class OmsSession
|
public class OmsSession
|
||||||
@ -54,27 +59,54 @@ public class Program : WebApplication
|
|||||||
|
|
||||||
protected override void OnStartup(EventArgs e)
|
protected override void OnStartup(EventArgs e)
|
||||||
{
|
{
|
||||||
|
string pidfile = "/var/run/mocha/mocha-oms.pid";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
System.IO.File.WriteAllText(pidfile, System.Environment.ProcessId.ToString());
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine("oms: error: failed to write PID file; graceful control will be unavailable");
|
||||||
|
}
|
||||||
|
|
||||||
// this all has to be done before the Web server is started...
|
// this all has to be done before the Web server is started...
|
||||||
oms.Initialize();
|
oms.Initialize();
|
||||||
|
|
||||||
TenantHandle th = oms.CreateTenant("super");
|
TenantHandle th = oms.CreateTenant("super");
|
||||||
oms.SelectTenant(th);
|
oms.SelectTenant(th);
|
||||||
|
|
||||||
string path = "/home/beckermj/Documents/Projects/mochapowered/mocha-dotnet/mocha-common/mocha-common/output";
|
string path;
|
||||||
|
if (System.Environment.OSVersion.Platform == PlatformID.Win32NT)
|
||||||
|
{
|
||||||
|
path = System.IO.Path.Combine(new string[]
|
||||||
|
{
|
||||||
|
System.Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),
|
||||||
|
"Mocha"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
path = "/home/beckermj/Documents/Projects/mochapowered/mocha-dotnet/mocha-common/mocha-common/output";
|
||||||
if (!System.IO.Directory.Exists(path))
|
if (!System.IO.Directory.Exists(path))
|
||||||
{
|
{
|
||||||
path = "/usr/share/mocha/system";
|
path = "/usr/share/mocha/system";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!System.IO.Directory.Exists(path))
|
if (!System.IO.Directory.Exists(path))
|
||||||
{
|
{
|
||||||
Console.Error.WriteLine("path not found: " + path);
|
Console.Error.WriteLine("path not found: " + path);
|
||||||
}
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LibraryHandle lh = oms.LoadLibrary(path + "/net.alcetech.Mocha.System.mcl");
|
if (!TryLoadLibrary(oms, path, "net.alcetech.Mocha.System.mcl"))
|
||||||
oms.AddLibraryReference(lh);
|
{
|
||||||
|
return;
|
||||||
LibraryHandle lh2 = oms.LoadLibrary(path + "/net.alcetech.Mocha.Web.mcl");
|
}
|
||||||
oms.AddLibraryReference(lh2);
|
if (!TryLoadLibrary(oms, path, "net.alcetech.Mocha.Web.mcl"))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// implement functions to get user IP address
|
// implement functions to get user IP address
|
||||||
oms.RegisterSystemAttributeRoutine<string>(KnownInstanceGuids.SystemAttributeRoutines.GetIPAddress, delegate (Oms oms2, OmsContext ctx2)
|
oms.RegisterSystemAttributeRoutine<string>(KnownInstanceGuids.SystemAttributeRoutines.GetIPAddress, delegate (Oms oms2, OmsContext ctx2)
|
||||||
@ -88,11 +120,33 @@ public class Program : WebApplication
|
|||||||
base.OnStartup(e);
|
base.OnStartup(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool TryLoadLibrary(Oms oms, string path, string fileName)
|
||||||
|
{
|
||||||
|
string fullyQualifiedFileName = System.IO.Path.Combine(new string[] { path, fileName });
|
||||||
|
if (!System.IO.File.Exists(fullyQualifiedFileName))
|
||||||
|
{
|
||||||
|
Console.WriteLine("file not found: {0}", fullyQualifiedFileName);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LibraryHandle lh = oms.LoadLibrary(fullyQualifiedFileName);
|
||||||
|
if (lh == LibraryHandle.Empty)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
oms.AddLibraryReference(lh);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private void oms_SystemRoutineExecuted(object? sender, SystemRoutineExecutedEventArgs e)
|
private void oms_SystemRoutineExecuted(object? sender, SystemRoutineExecutedEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.SystemRoutine.GlobalIdentifier == KnownInstanceGuids.SystemUpdateRoutines.LoginUser)
|
if (e.SystemRoutine.GlobalIdentifier == KnownInstanceGuids.SystemUpdateRoutines.LoginUser)
|
||||||
{
|
{
|
||||||
string token = e.Context.GetWorkData<string>(e.OMS.GetInstance(KnownAttributeGuids.Text.Token));
|
string token = e.Context.GetWorkData<string>(e.OMS.GetInstance(KnownAttributeGuids.Text.Token));
|
||||||
|
if (token == null)
|
||||||
|
return;
|
||||||
|
|
||||||
_Sessions[token] = new OmsSession();
|
_Sessions[token] = new OmsSession();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,6 +26,9 @@ using Mocha.Core.Oop.Methods;
|
|||||||
|
|
||||||
namespace Mocha.ServerApplication;
|
namespace Mocha.ServerApplication;
|
||||||
|
|
||||||
|
/// Provides the entry point for a simple application which starts a Web server
|
||||||
|
/// and provisions one or more Mocha tenants from a configuration file.
|
||||||
|
/// </summary>
|
||||||
public class Program : MochaWebApplication
|
public class Program : MochaWebApplication
|
||||||
{
|
{
|
||||||
protected override int DefaultPort => 10020;
|
protected override int DefaultPort => 10020;
|
||||||
|
|||||||
@ -1 +0,0 @@
|
|||||||
/home/beckermj/Documents/Projects/mochapowered/mocha-dotnet/mocha-dotnet/src/app/Mocha.ServerApplication/bin/Debug/net8.0/assets
|
|
||||||
@ -36,7 +36,7 @@ public class ElementCommand : InstanceCommand
|
|||||||
{
|
{
|
||||||
// what we should do, is build a transaction with all updated ECs and fields and values
|
// 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
|
// if any update fails, the entire transaction should be rolled back
|
||||||
Response resp = ProcessElement(oms, ctx, ProcessingInstance, InstanceHandle.Empty, e.Context.Request.Form);
|
Response resp = oms.ProcessElement(ctx, ProcessingInstance, e.Context.Request.Form);
|
||||||
if (resp != null)
|
if (resp != null)
|
||||||
{
|
{
|
||||||
JsonObject obj2 = resp.GetResponse(oms, ctx);
|
JsonObject obj2 = resp.GetResponse(oms, ctx);
|
||||||
@ -75,6 +75,15 @@ public class ElementCommand : InstanceCommand
|
|||||||
obj2.Add("widget", JsonValue.Create("root"));
|
obj2.Add("widget", JsonValue.Create("root"));
|
||||||
obj2.Add("body", widget.ToJSONObject(ctx));
|
obj2.Add("body", widget.ToJSONObject(ctx));
|
||||||
|
|
||||||
|
JsonObject objTitle = new JsonObject();
|
||||||
|
string label = oms.GetAttributeValue<string>(widget.ParentInstance, oms.GetInstance(KnownAttributeGuids.Text.Label));
|
||||||
|
if (label == null)
|
||||||
|
{
|
||||||
|
label = oms.GetInstanceText(widget.ParentInstance);
|
||||||
|
}
|
||||||
|
objTitle.Add("label", label);
|
||||||
|
obj2.Add("title", objTitle);
|
||||||
|
|
||||||
JsonObject obj = new JsonObject();
|
JsonObject obj = new JsonObject();
|
||||||
obj.Add("result", "success");
|
obj.Add("result", "success");
|
||||||
obj.Add("value", obj2);
|
obj.Add("value", obj2);
|
||||||
@ -85,7 +94,7 @@ public class ElementCommand : InstanceCommand
|
|||||||
InstanceHandle elem = oms.GetRelatedInstance(ProcessingInstance, oms.GetInstance(KnownRelationshipGuids.Task__has_initiating__Element));
|
InstanceHandle elem = oms.GetRelatedInstance(ProcessingInstance, oms.GetInstance(KnownRelationshipGuids.Task__has_initiating__Element));
|
||||||
|
|
||||||
// fill out the initiating element and execute the task
|
// fill out the initiating element and execute the task
|
||||||
Response r = oms.ProcessElement(ctx, elem, InstanceHandle.Empty);
|
Response r = oms.ProcessElement(ctx, elem, null);
|
||||||
JsonObject obj = r.GetResponse(oms, ctx);
|
JsonObject obj = r.GetResponse(oms, ctx);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -105,7 +114,7 @@ public class ElementCommand : InstanceCommand
|
|||||||
InstanceHandle elem = oms.GetRelatedInstance(defaultTask, oms.GetInstance(KnownRelationshipGuids.Task__has_initiating__Element));
|
InstanceHandle elem = oms.GetRelatedInstance(defaultTask, oms.GetInstance(KnownRelationshipGuids.Task__has_initiating__Element));
|
||||||
|
|
||||||
// fill out the initiating element and execute the task
|
// fill out the initiating element and execute the task
|
||||||
Response r = oms.ProcessElement(ctx, elem, ProcessingInstance);
|
Response r = oms.ProcessElement(ctx, elem, null);
|
||||||
JsonObject obj = r.GetResponse(oms, ctx);
|
JsonObject obj = r.GetResponse(oms, ctx);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -117,105 +126,4 @@ public class ElementCommand : InstanceCommand
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -61,7 +61,7 @@ public abstract class InstanceCommand : TenantedCommand
|
|||||||
if (context.Session.ContainsKey("OmsContext"))
|
if (context.Session.ContainsKey("OmsContext"))
|
||||||
{
|
{
|
||||||
OmsContext ctx = (OmsContext)context.Session["OmsContext"];
|
OmsContext ctx = (OmsContext)context.Session["OmsContext"];
|
||||||
object? loginToken = ctx.GetWorkData(oms.GetInstance(KnownAttributeGuids.Text.Token));
|
string? loginToken = ctx.GetGlobal<string?>(oms.GetInstance(KnownAttributeGuids.Text.Token));
|
||||||
if (loginToken != null)
|
if (loginToken != null)
|
||||||
{
|
{
|
||||||
obj.Add("sessionSecureToken", loginToken.ToString());
|
obj.Add("sessionSecureToken", loginToken.ToString());
|
||||||
|
|||||||
@ -23,7 +23,7 @@ namespace Mocha.Core.UI.Server.Commands;
|
|||||||
|
|
||||||
public class InstanceDetailsCommand : InstanceCommand
|
public class InstanceDetailsCommand : InstanceCommand
|
||||||
{
|
{
|
||||||
public override IEnumerable<string> UriPatterns => new string[] { "/tenants/{tenantName}/instances/{instanceKey}" };
|
public override IEnumerable<string> UriPatterns => new string[] { "/tenants/{tenantName}/instances/{iid}" };
|
||||||
protected override void ProcessInternal(WebServerProcessRequestEventArgs e, Core.Oms oms, Core.OmsContext ctx, StreamWriter sw)
|
protected override void ProcessInternal(WebServerProcessRequestEventArgs e, Core.Oms oms, Core.OmsContext ctx, StreamWriter sw)
|
||||||
{
|
{
|
||||||
JsonObject obj = JsonRenderer.InstanceToJson(oms, ProcessingInstance);
|
JsonObject obj = JsonRenderer.InstanceToJson(oms, ProcessingInstance);
|
||||||
|
|||||||
@ -0,0 +1,143 @@
|
|||||||
|
// 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 InstancePreviewCommand : InstanceCommand
|
||||||
|
{
|
||||||
|
public override IEnumerable<string> UriPatterns => new string[] { "/tenants/{tenantName}/instances/{iid}/preview" };
|
||||||
|
|
||||||
|
private struct RelatedTask
|
||||||
|
{
|
||||||
|
public InstanceKey InstanceKey;
|
||||||
|
public string Label;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void ProcessInternal(WebServerProcessRequestEventArgs e, Core.Oms oms, Core.OmsContext ctx, StreamWriter sw)
|
||||||
|
{
|
||||||
|
JsonObject obj = new JsonObject();
|
||||||
|
obj.Add("result", "success");
|
||||||
|
|
||||||
|
JsonObject objPreview = new JsonObject();
|
||||||
|
objPreview.Add("widget", "root");
|
||||||
|
obj.Add("preview", objPreview);
|
||||||
|
|
||||||
|
JsonObject objRelatedTasks = new JsonObject();
|
||||||
|
objRelatedTasks.Add("widget", "relatedTasks");
|
||||||
|
|
||||||
|
Dictionary<string, List<RelatedTask>> relatedTasks = new Dictionary<string, List<RelatedTask>>();
|
||||||
|
|
||||||
|
InstanceHandle parentClass = oms.GetParentClass(ProcessingInstance);
|
||||||
|
|
||||||
|
InstanceHandle c_Instance = oms.GetInstance(KnownInstanceGuids.Classes.Instance);
|
||||||
|
IEnumerable<InstanceHandle> relatedTasksINSTANCE = oms.GetRelatedInstances(c_Instance, oms.GetInstance(KnownRelationshipGuids.Class__has_related__Task));
|
||||||
|
|
||||||
|
IEnumerable<InstanceHandle> relatedTasksIH = oms.GetRelatedInstances(parentClass, oms.GetInstance(KnownRelationshipGuids.Class__has_related__Task));
|
||||||
|
AddRelatedTasks(oms, relatedTasks, relatedTasksINSTANCE);
|
||||||
|
AddRelatedTasks(oms, relatedTasks, relatedTasksIH);
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
relatedTasks["Preferences"] = new List<RelatedTask>();
|
||||||
|
relatedTasks["Preferences"].Add(new RelatedTask() { InstanceKey = new InstanceKey(1924, 264), Label = "Export Preferences" });
|
||||||
|
|
||||||
|
relatedTasks["System Account"] = new List<RelatedTask>();
|
||||||
|
*/
|
||||||
|
|
||||||
|
InstanceKey ik = oms.GetInstanceKey(ProcessingInstance);
|
||||||
|
|
||||||
|
JsonArray aryTaskGroups = new JsonArray();
|
||||||
|
foreach (KeyValuePair<string, List<RelatedTask>> kvp in relatedTasks)
|
||||||
|
{
|
||||||
|
JsonObject objTaskGroup = new JsonObject();
|
||||||
|
objTaskGroup.Add("widget", "relatedTaskGroup");
|
||||||
|
objTaskGroup.Add("renderDifferently", false);
|
||||||
|
|
||||||
|
JsonArray aryTaskGroups1 = new JsonArray();
|
||||||
|
{
|
||||||
|
JsonObject objTaskGroup1 = new JsonObject();
|
||||||
|
objTaskGroup1.Add("widget", "relatedTaskGroup");
|
||||||
|
objTaskGroup1.Add("label", kvp.Key);
|
||||||
|
objTaskGroup1.Add("renderDifferently", false);
|
||||||
|
|
||||||
|
JsonArray aryTaskGroups2 = new JsonArray();
|
||||||
|
foreach (RelatedTask task in kvp.Value)
|
||||||
|
{
|
||||||
|
JsonObject objTaskGroup2 = new JsonObject();
|
||||||
|
objTaskGroup2.Add("widget", "relatedTaskGroup");
|
||||||
|
|
||||||
|
JsonArray aryTasks = new JsonArray();
|
||||||
|
JsonObject objTask = new JsonObject();
|
||||||
|
objTask.Add("widget", "relatedTask");
|
||||||
|
objTask.Add("uri", String.Format("/{0}/inst/{1}/rel-task/{2}", "super", ik, task.InstanceKey));
|
||||||
|
objTask.Add("view", true);
|
||||||
|
objTask.Add("webService", false);
|
||||||
|
objTask.Add("iid", task.InstanceKey.ToString());
|
||||||
|
objTask.Add("label", task.Label);
|
||||||
|
aryTasks.Add(objTask);
|
||||||
|
|
||||||
|
objTaskGroup2.Add("tasks", aryTasks);
|
||||||
|
objTaskGroup2.Add("renderDifferently", false);
|
||||||
|
|
||||||
|
aryTaskGroups2.Add(objTaskGroup2);
|
||||||
|
}
|
||||||
|
|
||||||
|
objTaskGroup1.Add("taskGroups", aryTaskGroups2);
|
||||||
|
aryTaskGroups1.Add(objTaskGroup1);
|
||||||
|
}
|
||||||
|
|
||||||
|
objTaskGroup.Add("taskGroups", aryTaskGroups1);
|
||||||
|
|
||||||
|
aryTaskGroups.Add(objTaskGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
objRelatedTasks.Add("taskGroups", aryTaskGroups);
|
||||||
|
|
||||||
|
JsonObject objInstance = new JsonObject();
|
||||||
|
objInstance.Add("instanceId", ik.ToString());
|
||||||
|
objInstance.Add("label", oms.GetInstanceText(parentClass));
|
||||||
|
objRelatedTasks.Add("instance", objInstance);
|
||||||
|
|
||||||
|
obj.Add("relatedTasks", objRelatedTasks);
|
||||||
|
|
||||||
|
|
||||||
|
e.Context.Response.ResponseCode = 200;
|
||||||
|
e.Context.Response.ResponseText = "OK";
|
||||||
|
e.Context.Response.ContentType = "application/json";
|
||||||
|
|
||||||
|
sw.Write(obj.ToJsonString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddRelatedTasks(Oms oms, Dictionary<string, List<RelatedTask>> relatedTasks, IEnumerable<InstanceHandle> relatedTasksIH)
|
||||||
|
{
|
||||||
|
foreach (InstanceHandle ih in relatedTasksIH)
|
||||||
|
{
|
||||||
|
InstanceHandle taskCategory = oms.GetRelatedInstance(ih, oms.GetInstance(KnownRelationshipGuids.Task__has__Task_Category));
|
||||||
|
string categoryTitle = oms.GetInstanceText(taskCategory);
|
||||||
|
if (!relatedTasks.ContainsKey(categoryTitle))
|
||||||
|
{
|
||||||
|
relatedTasks[categoryTitle] = new List<RelatedTask>();
|
||||||
|
}
|
||||||
|
|
||||||
|
relatedTasks[categoryTitle].Add(new RelatedTask() { InstanceKey = oms.GetInstanceKey(ih), Label = oms.GetInstanceText(ih) });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -170,6 +170,10 @@ public class OmsServer
|
|||||||
|
|
||||||
private IEnumerable<OmsServerCommandEntry> Flatten(IEnumerable<OmsServerCommand> cmds)
|
private IEnumerable<OmsServerCommandEntry> Flatten(IEnumerable<OmsServerCommand> cmds)
|
||||||
{
|
{
|
||||||
|
// !FIXME! this returns weird results if the length of the one string is longer
|
||||||
|
// ! ! INCLUDING length of {variable} names, when these should be replaced
|
||||||
|
// ! ! by a single char '?' (like in Phast) to avoid this issue
|
||||||
|
|
||||||
List<OmsServerCommandEntry> list = new List<OmsServerCommandEntry>();
|
List<OmsServerCommandEntry> list = new List<OmsServerCommandEntry>();
|
||||||
foreach (OmsServerCommand cmd in cmds)
|
foreach (OmsServerCommand cmd in cmds)
|
||||||
{
|
{
|
||||||
@ -218,6 +222,7 @@ public class OmsServer
|
|||||||
// obj.Add("message", String.Format("unknown cmd '{0}'", command));
|
// obj.Add("message", String.Format("unknown cmd '{0}'", command));
|
||||||
RespondWithJson(oms, sw, e.Context, 404, "Not Found", obj);
|
RespondWithJson(oms, sw, e.Context, 404, "Not Found", obj);
|
||||||
}
|
}
|
||||||
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
public void RespondWithJson(Oms oms, StreamWriter sw, WebContext context, int responseCode, string responseText, JsonObject obj)
|
public void RespondWithJson(Oms oms, StreamWriter sw, WebContext context, int responseCode, string responseText, JsonObject obj)
|
||||||
{
|
{
|
||||||
@ -228,7 +233,7 @@ public class OmsServer
|
|||||||
if (context.Session.ContainsKey("OmsContext"))
|
if (context.Session.ContainsKey("OmsContext"))
|
||||||
{
|
{
|
||||||
OmsContext ctx = (OmsContext)context.Session["OmsContext"];
|
OmsContext ctx = (OmsContext)context.Session["OmsContext"];
|
||||||
object? loginToken = ctx.GetWorkData(oms.GetInstance(KnownAttributeGuids.Text.Token));
|
string? loginToken = ctx.GetGlobal<string?>(oms.GetInstance(KnownAttributeGuids.Text.Token));
|
||||||
if (loginToken != null)
|
if (loginToken != null)
|
||||||
{
|
{
|
||||||
obj.Add("sessionSecureToken", loginToken.ToString());
|
obj.Add("sessionSecureToken", loginToken.ToString());
|
||||||
|
|||||||
@ -19,6 +19,8 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
using System;
|
using System;
|
||||||
|
using MBS.Core;
|
||||||
|
|
||||||
namespace Mocha.Core
|
namespace Mocha.Core
|
||||||
{
|
{
|
||||||
public struct InstanceKey
|
public struct InstanceKey
|
||||||
@ -29,7 +31,25 @@ namespace Mocha.Core
|
|||||||
private bool _isNotEmpty;
|
private bool _isNotEmpty;
|
||||||
public bool IsEmpty { get { return !_isNotEmpty; } }
|
public bool IsEmpty { get { return !_isNotEmpty; } }
|
||||||
|
|
||||||
public bool IsDerived { get; }
|
public bool IsDerived { get { return _derivedDataString != null; } }
|
||||||
|
|
||||||
|
internal Oms? _oms;
|
||||||
|
internal InstanceHandle _inst;
|
||||||
|
internal InstanceHandle _parentClassInstance;
|
||||||
|
private string? _derivedDataString = null;
|
||||||
|
internal void SetDerivedData(Oms oms, InstanceHandle inst, Dictionary<InstanceHandle, object?> derivedData)
|
||||||
|
{
|
||||||
|
_oms = oms;
|
||||||
|
_inst = inst;
|
||||||
|
_parentClassInstance = oms.GetParentClass(inst);
|
||||||
|
|
||||||
|
Dictionary<InstanceHandle, object?> _derivedData = new Dictionary<InstanceHandle, object?>();
|
||||||
|
foreach (KeyValuePair<InstanceHandle, object?> kvp in derivedData)
|
||||||
|
{
|
||||||
|
_derivedData[kvp.Key] = kvp.Value;
|
||||||
|
}
|
||||||
|
_derivedDataString = GetDerivedDataString(_derivedData);
|
||||||
|
}
|
||||||
|
|
||||||
public static readonly InstanceKey Empty = new InstanceKey();
|
public static readonly InstanceKey Empty = new InstanceKey();
|
||||||
|
|
||||||
@ -58,7 +78,6 @@ namespace Mocha.Core
|
|||||||
{
|
{
|
||||||
ClassIndex = 0;
|
ClassIndex = 0;
|
||||||
InstanceIndex = 0;
|
InstanceIndex = 0;
|
||||||
IsDerived = false;
|
|
||||||
_isNotEmpty = false;
|
_isNotEmpty = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -67,18 +86,29 @@ namespace Mocha.Core
|
|||||||
if (instanceKey.Contains("$"))
|
if (instanceKey.Contains("$"))
|
||||||
{
|
{
|
||||||
splitChar = '$';
|
splitChar = '$';
|
||||||
IsDerived = false;
|
|
||||||
}
|
}
|
||||||
else if (instanceKey.Contains("!"))
|
else if (instanceKey.Contains("!"))
|
||||||
{
|
{
|
||||||
splitChar = '!';
|
splitChar = '!';
|
||||||
IsDerived = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (splitChar != '\0')
|
if (splitChar != '\0')
|
||||||
{
|
{
|
||||||
string[] split = instanceKey.Split(new char[] { '$' });
|
string[] split = instanceKey.Split(new char[] { splitChar });
|
||||||
if (split.Length == 2)
|
if (split.Length == 2)
|
||||||
|
{
|
||||||
|
if (splitChar == '!')
|
||||||
|
{
|
||||||
|
if (Int32.TryParse(split[0], out int ci))
|
||||||
|
{
|
||||||
|
ClassIndex = ci;
|
||||||
|
InstanceIndex = -1;
|
||||||
|
SetDerivedDataString(split[1]);
|
||||||
|
_isNotEmpty = true;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (Int32.TryParse(split[0], out int ci) && Int32.TryParse(split[1], out int ii))
|
if (Int32.TryParse(split[0], out int ci) && Int32.TryParse(split[1], out int ii))
|
||||||
{
|
{
|
||||||
@ -90,8 +120,15 @@ namespace Mocha.Core
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
throw new ArgumentException("must be a string containing two integers separated by a '$' or a '!'");
|
throw new ArgumentException("must be a string containing two integers separated by a '$' or a '!'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SetDerivedDataString(string base64String)
|
||||||
|
{
|
||||||
|
_derivedDataString = base64String;
|
||||||
|
}
|
||||||
|
|
||||||
public InstanceKey(int classIndex, int instanceIndex)
|
public InstanceKey(int classIndex, int instanceIndex)
|
||||||
{
|
{
|
||||||
ClassIndex = classIndex;
|
ClassIndex = classIndex;
|
||||||
@ -116,9 +153,70 @@ namespace Mocha.Core
|
|||||||
{
|
{
|
||||||
if (IsDerived)
|
if (IsDerived)
|
||||||
{
|
{
|
||||||
return String.Format("{0}!{1}", ClassIndex, InstanceIndex);
|
return String.Format("{0}!{1}", ClassIndex, _derivedDataString);
|
||||||
}
|
}
|
||||||
return String.Format("{0}${1}", ClassIndex, InstanceIndex);
|
return String.Format("{0}${1}", ClassIndex, InstanceIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal string GetDerivedDataString(Dictionary<InstanceHandle, object?>? derivedData = null)
|
||||||
|
{
|
||||||
|
MemoryStream ms = new MemoryStream();
|
||||||
|
BinaryWriter bw = new BinaryWriter(ms);
|
||||||
|
|
||||||
|
if (derivedData == null)
|
||||||
|
{
|
||||||
|
derivedData = GetDerivedData();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (KeyValuePair<InstanceHandle, object?> kvp in derivedData)
|
||||||
|
{
|
||||||
|
if (kvp.Value is string)
|
||||||
|
{
|
||||||
|
string value = (string)kvp.Value;
|
||||||
|
bw.Write((int)value.Length);
|
||||||
|
bw.Write((string)value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bw.Flush();
|
||||||
|
bw.Close();
|
||||||
|
byte[] data = ms.ToArray();
|
||||||
|
|
||||||
|
string b64 = Convert.ToBase64String(data);
|
||||||
|
return b64;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal Dictionary<InstanceHandle, object?>? GetDerivedData()
|
||||||
|
{
|
||||||
|
Dictionary<InstanceHandle, object?> derivedData = new Dictionary<InstanceHandle, object?>();
|
||||||
|
|
||||||
|
InstanceKey ikParentClass = new InstanceKey(1, ClassIndex);
|
||||||
|
_parentClassInstance = _oms.GetInstance(ikParentClass);
|
||||||
|
|
||||||
|
if (_derivedDataString != null)
|
||||||
|
{
|
||||||
|
byte[] data = Convert.FromBase64String(_derivedDataString);
|
||||||
|
MemoryStream ms = new MemoryStream(data);
|
||||||
|
BinaryReader br = new BinaryReader(ms);
|
||||||
|
|
||||||
|
IEnumerable<InstanceHandle> attributes = _oms.GetRelatedInstances(_parentClassInstance, _oms.GetInstance(KnownRelationshipGuids.Class__has__Attribute));
|
||||||
|
foreach (InstanceHandle att in attributes)
|
||||||
|
{
|
||||||
|
if (_oms.IsInstanceOf(att, _oms.GetInstance(KnownInstanceGuids.Classes.TextAttribute)))
|
||||||
|
{
|
||||||
|
if (br.BaseStream.EndOfStream())
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int length = br.ReadInt32();
|
||||||
|
string value = br.ReadString();
|
||||||
|
derivedData[att] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return derivedData;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -60,6 +60,7 @@ namespace Mocha.Core
|
|||||||
public static Guid UseAnyCondition { get; } = new Guid("{31a8a2c2-1f55-4dfe-b177-427a2219ef8c}");
|
public static Guid UseAnyCondition { get; } = new Guid("{31a8a2c2-1f55-4dfe-b177-427a2219ef8c}");
|
||||||
public static Guid ValidateOnlyOnSubmit { get; } = new Guid("{400fcd8e-823b-4f4a-aa38-b444f763259b}");
|
public static Guid ValidateOnlyOnSubmit { get; } = new Guid("{400fcd8e-823b-4f4a-aa38-b444f763259b}");
|
||||||
public static Guid UserIsLoggedIn { get; } = new Guid("{8e93d9f3-a897-4c97-935c-b3427f90633b}");
|
public static Guid UserIsLoggedIn { get; } = new Guid("{8e93d9f3-a897-4c97-935c-b3427f90633b}");
|
||||||
|
public static Guid Derived { get; } = new Guid("{66991ca1-ef08-4f30-846c-4984c2a3139d}");
|
||||||
}
|
}
|
||||||
public static class Numeric
|
public static class Numeric
|
||||||
{
|
{
|
||||||
|
|||||||
@ -481,5 +481,12 @@ namespace Mocha.Core
|
|||||||
public static Guid Far { get; } = new Guid("{f19d16c7-99ff-48a3-b86a-7db8f400d869}");
|
public static Guid Far { get; } = new Guid("{f19d16c7-99ff-48a3-b86a-7db8f400d869}");
|
||||||
public static Guid Center { get; } = new Guid("{63179b92-9a6a-495b-a823-f45e353be9d8}");
|
public static Guid Center { get; } = new Guid("{63179b92-9a6a-495b-a823-f45e353be9d8}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class Modules
|
||||||
|
{
|
||||||
|
public static Guid MochaBaseSystem { get; } = new Guid("{3ffd3a31-208c-49c9-905d-2a69362902ca}");
|
||||||
|
public static Guid OOP { get; } = new Guid("{818dfe8d-96ea-4339-8d18-a0e9a5f50908}");
|
||||||
|
public static Guid OOPMethodExamples { get; } = new Guid("{5017c102-c154-4ef0-b117-e42bd1c756c1}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,32 +34,8 @@ public class ConditionalSelectAttributeMethodImplementation : MethodImplementati
|
|||||||
IEnumerable<InstanceHandle> trueConditions = oms.GetRelatedInstances(cas, oms.GetInstance(KnownRelationshipGuids.Condition_Group__has_true_condition__Executable_returning_Work_Data));
|
IEnumerable<InstanceHandle> trueConditions = oms.GetRelatedInstances(cas, oms.GetInstance(KnownRelationshipGuids.Condition_Group__has_true_condition__Executable_returning_Work_Data));
|
||||||
IEnumerable<InstanceHandle> falseConditions = oms.GetRelatedInstances(cas, oms.GetInstance(KnownRelationshipGuids.Condition_Group__has_false_condition__Executable_returning_Work_Data));
|
IEnumerable<InstanceHandle> falseConditions = oms.GetRelatedInstances(cas, oms.GetInstance(KnownRelationshipGuids.Condition_Group__has_false_condition__Executable_returning_Work_Data));
|
||||||
bool useAnyCondition = oms.GetAttributeValue<bool>(cas, oms.GetInstance(KnownAttributeGuids.Boolean.UseAnyCondition));
|
bool useAnyCondition = oms.GetAttributeValue<bool>(cas, oms.GetInstance(KnownAttributeGuids.Boolean.UseAnyCondition));
|
||||||
if (trueConditions != null)
|
|
||||||
{
|
value = oms.EvaluateConditions(context, trueConditions, falseConditions, useAnyCondition);
|
||||||
foreach (InstanceHandle trueCondition in trueConditions)
|
|
||||||
{
|
|
||||||
InstanceHandle ret = oms.Execute(context, trueCondition);
|
|
||||||
object? retval = context.GetWorkData(ret);
|
|
||||||
if (retval is bool && ((bool)retval))
|
|
||||||
{
|
|
||||||
value = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (falseConditions != null)
|
|
||||||
{
|
|
||||||
foreach (InstanceHandle falseCondition in falseConditions)
|
|
||||||
{
|
|
||||||
InstanceHandle ret = oms.Execute(context, falseCondition);
|
|
||||||
object? retval = context.GetWorkData(ret);
|
|
||||||
if (retval is bool && (!(bool)retval))
|
|
||||||
{
|
|
||||||
value = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value)
|
if (value)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -45,13 +45,54 @@ public class EvaluateBooleanExpressionMethodImplementation : MethodImplementatio
|
|||||||
|
|
||||||
InstanceHandle source = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Evaluate_Boolean_Expression_Method__has_source__Executable_returning_Work_Data));
|
InstanceHandle source = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Evaluate_Boolean_Expression_Method__has_source__Executable_returning_Work_Data));
|
||||||
InstanceHandle comparison = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Evaluate_Boolean_Expression_Method__uses__Boolean_Operator));
|
InstanceHandle comparison = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Evaluate_Boolean_Expression_Method__uses__Boolean_Operator));
|
||||||
InstanceHandle target = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Evaluate_Boolean_Expression_Method__has_target__Executable_returning_Work_Data));
|
|
||||||
|
|
||||||
InstanceHandle[] rtarget_value = new InstanceHandle[0];
|
Console.Error.WriteLine("EBE - source {0}", oms.GetGlobalIdentifier(source));
|
||||||
|
|
||||||
InstanceHandle rsource = oms.Execute(context, source);
|
InstanceHandle rsource = oms.Execute(context, source);
|
||||||
object? rsource_valueraw = context.GetWorkData(rsource);
|
object? rsource_valueraw = context.GetWorkData(rsource);
|
||||||
|
|
||||||
|
bool value = false;
|
||||||
|
if (comparison == oms.GetInstance(KnownInstanceGuids.RelationalOperators.IsNotEmpty))
|
||||||
|
{
|
||||||
|
if (rsource_valueraw is InstanceHandle)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine("EBE - is not empty - {0} ?", oms.GetGlobalIdentifier((InstanceHandle)rsource_valueraw));
|
||||||
|
|
||||||
|
value = ((InstanceHandle)rsource_valueraw) != InstanceHandle.Empty;
|
||||||
|
}
|
||||||
|
else if (rsource_valueraw is IEnumerable<InstanceHandle>)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine("EBE - is not empty - count = {0} ?", ((IEnumerable<InstanceHandle>)rsource_valueraw).Count());
|
||||||
|
|
||||||
|
value = ((IEnumerable<InstanceHandle>)rsource_valueraw).Any();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine("EBE - is not empty - {0} ?", rsource_valueraw);
|
||||||
|
|
||||||
|
value = rsource_valueraw != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (comparison == oms.GetInstance(KnownInstanceGuids.RelationalOperators.IsEmpty))
|
||||||
|
{
|
||||||
|
if (rsource_valueraw is InstanceHandle)
|
||||||
|
{
|
||||||
|
value = ((InstanceHandle)rsource_valueraw) == InstanceHandle.Empty;
|
||||||
|
}
|
||||||
|
else if (rsource_valueraw is IEnumerable<InstanceHandle>)
|
||||||
|
{
|
||||||
|
value = !((IEnumerable<InstanceHandle>)rsource_valueraw).Any();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
value = rsource_valueraw == null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
InstanceHandle target = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Evaluate_Boolean_Expression_Method__has_target__Executable_returning_Work_Data));
|
||||||
|
InstanceHandle[] rtarget_value = new InstanceHandle[0];
|
||||||
|
|
||||||
InstanceHandle[] rsource_value = new InstanceHandle[0];
|
InstanceHandle[] rsource_value = new InstanceHandle[0];
|
||||||
if (rsource_valueraw is InstanceHandle[])
|
if (rsource_valueraw is InstanceHandle[])
|
||||||
{
|
{
|
||||||
@ -76,8 +117,6 @@ public class EvaluateBooleanExpressionMethodImplementation : MethodImplementatio
|
|||||||
rtarget_value = new InstanceHandle[] { target };
|
rtarget_value = new InstanceHandle[] { target };
|
||||||
}
|
}
|
||||||
|
|
||||||
bool value = false;
|
|
||||||
|
|
||||||
if (comparison == oms.GetInstance(KnownInstanceGuids.RelationalOperators.InSelectionList))
|
if (comparison == oms.GetInstance(KnownInstanceGuids.RelationalOperators.InSelectionList))
|
||||||
{
|
{
|
||||||
if (rtarget_value.ContainsAny(rsource_value))
|
if (rtarget_value.ContainsAny(rsource_value))
|
||||||
@ -118,6 +157,7 @@ public class EvaluateBooleanExpressionMethodImplementation : MethodImplementatio
|
|||||||
{
|
{
|
||||||
throw new NotImplementedException(String.Format("relational operator '{0}' not implemented @@ {1}, {2}", comparison, oms.GetGlobalIdentifier(method).ToString("B"), context.StackTrace.ToString()));
|
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);
|
context.SetWorkData(returnsAttribute, value);
|
||||||
return returnsAttribute;
|
return returnsAttribute;
|
||||||
|
|||||||
@ -41,8 +41,15 @@ public class GetAttributeMethodImplementation : MethodImplementation
|
|||||||
forInstance = (InstanceHandle?) context.GetWorkData(forInstance.Value);
|
forInstance = (InstanceHandle?) context.GetWorkData(forInstance.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
object? value = oms.UnsafeGetAttributeValue((InstanceHandle) forInstance, returnsAttribute);
|
if (forInstance is InstanceHandle forInstanceHandle)
|
||||||
|
{
|
||||||
|
object? value = oms.UnsafeGetAttributeValue((InstanceHandle)forInstanceHandle, returnsAttribute);
|
||||||
context.SetWorkData(returnsAttribute, value);
|
context.SetWorkData(returnsAttribute, value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine("no for instance IS");
|
||||||
|
}
|
||||||
return returnsAttribute;
|
return returnsAttribute;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -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/>.
|
||||||
|
|
||||||
|
namespace Mocha.Core.MethodImplementations;
|
||||||
|
|
||||||
|
public class GetInstanceSetBySystemRoutineMethodImplementation : MethodImplementation
|
||||||
|
{
|
||||||
|
public override Guid MethodClassGuid => KnownInstanceGuids.MethodClasses.GetInstanceSetBySystemRoutineMethod;
|
||||||
|
protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method)
|
||||||
|
{
|
||||||
|
InstanceHandle irForClass = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Method__for__Class));
|
||||||
|
InstanceHandle returnsWorkSet = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Get_Instance_Set_by_System_Routine_Method__returns__Work_Set));
|
||||||
|
InstanceHandle usesSystemInstanceSetRoutine = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Get_Instance_Set_by_System_Routine_Method__uses__System_Instance_Set_Routine));
|
||||||
|
|
||||||
|
if (returnsWorkSet == InstanceHandle.Empty)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("no return Attribute specified for method");
|
||||||
|
}
|
||||||
|
|
||||||
|
object? value = oms.ExecuteSystemRoutine(context, usesSystemInstanceSetRoutine);
|
||||||
|
context.SetWorkData(returnsWorkSet, value);
|
||||||
|
return returnsWorkSet;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -25,9 +25,12 @@ public class ProcessRelatedUpdatesMethodImplementation : MethodImplementation
|
|||||||
InstanceHandle forClass = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Method__for__Class));
|
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));
|
IEnumerable<InstanceHandle> usesExecutableForPUMB = oms.GetRelatedInstances(method, oms.GetInstance(KnownRelationshipGuids.Process_Related_Updates_Method__uses__Executable_for_PUMB));
|
||||||
|
Console.Error.WriteLine("---> has {0} PUMBs", usesExecutableForPUMB.Count());
|
||||||
|
|
||||||
foreach (InstanceHandle pumb in usesExecutableForPUMB)
|
foreach (InstanceHandle pumb in usesExecutableForPUMB)
|
||||||
{
|
{
|
||||||
oms.Execute(context, pumb);
|
Console.Error.WriteLine("---> executing PUMB {0}", pumb.GlobalIdentifier);
|
||||||
|
oms.Execute(context, pumb) ;
|
||||||
}
|
}
|
||||||
return InstanceHandle.Empty;
|
return InstanceHandle.Empty;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,27 @@
|
|||||||
|
namespace Mocha.Core.Modeling.ImplicitAttributes;
|
||||||
|
|
||||||
|
public class TextAttribute
|
||||||
|
{
|
||||||
|
private OmsDatabase omsdb;
|
||||||
|
public TextAttribute(OmsDatabase omsdb)
|
||||||
|
{
|
||||||
|
this.omsdb = omsdb;
|
||||||
|
}
|
||||||
|
|
||||||
|
private InstanceHandle sourceInstance;
|
||||||
|
private InstanceHandle attributeInstance;
|
||||||
|
|
||||||
|
private string GetAttributeValueStr()
|
||||||
|
{
|
||||||
|
return omsdb.Oms.GetAttributeValue<string>(sourceInstance, attributeInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static implicit operator string(TextAttribute source)
|
||||||
|
{
|
||||||
|
return source.GetAttributeValueStr();
|
||||||
|
}
|
||||||
|
public static implicit operator TextAttribute(string source)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -104,6 +104,7 @@ public class OmsInstanceList<T> : OmsInstanceList, IList<T> where T : OmsClass
|
|||||||
{
|
{
|
||||||
Guid localClassGuid = OmsDatabase.GetGlobalIdentifierForClass(item.GetType());
|
Guid localClassGuid = OmsDatabase.GetGlobalIdentifierForClass(item.GetType());
|
||||||
Guid localInstanceGuid = Guid.NewGuid();
|
Guid localInstanceGuid = Guid.NewGuid();
|
||||||
|
item.GlobalIdentifier = localInstanceGuid;
|
||||||
|
|
||||||
omsdb.CreateClass(item, localClassGuid, localInstanceGuid);
|
omsdb.CreateClass(item, localClassGuid, localInstanceGuid);
|
||||||
item.omsdb = omsdb;
|
item.omsdb = omsdb;
|
||||||
|
|||||||
@ -20,4 +20,8 @@ namespace Mocha.Core.Modeling;
|
|||||||
public class OmsRelationshipTargetAttribute : OmsNativeRelationship
|
public class OmsRelationshipTargetAttribute : OmsNativeRelationship
|
||||||
{
|
{
|
||||||
public OmsRelationshipTargetAttribute(string targetClassGlobalIdentifier) : base(KnownRelationshipGuids.Relationship__has_destination__Class, targetClassGlobalIdentifier) { }
|
public OmsRelationshipTargetAttribute(string targetClassGlobalIdentifier) : base(KnownRelationshipGuids.Relationship__has_destination__Class, targetClassGlobalIdentifier) { }
|
||||||
|
public OmsRelationshipTargetAttribute(Type targetClassType) : base(KnownRelationshipGuids.Relationship__has_destination__Class, null)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -21,6 +21,7 @@ using System.Collections.ObjectModel;
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
using System.Data.SqlTypes;
|
using System.Data.SqlTypes;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Diagnostics.Contracts;
|
using System.Diagnostics.Contracts;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
@ -72,6 +73,37 @@ public abstract class Oms
|
|||||||
|
|
||||||
UpdateSyntacticSugar();
|
UpdateSyntacticSugar();
|
||||||
|
|
||||||
|
RegisterSystemInstanceSetRoutine(KnownInstanceGuids.SystemInstanceSetRoutines.GetCurrentUser, delegate (Oms oms, OmsContext context)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine("oms: executing system instance set routine {0}", KnownInstanceGuids.SystemUpdateRoutines.LoginUser);
|
||||||
|
|
||||||
|
InstanceHandle a_Token = oms.GetInstance(KnownAttributeGuids.Text.Token);
|
||||||
|
string token = context.GetGlobal<string>(a_Token);
|
||||||
|
if (token != null)
|
||||||
|
{
|
||||||
|
IEnumerable<InstanceHandle> userLogins = oms.GetInstancesOf(oms.GetInstance(KnownInstanceGuids.Classes.UserLogin));
|
||||||
|
InstanceHandle r_User_Login__has__User = oms.GetInstance(KnownRelationshipGuids.User_Login__has__User);
|
||||||
|
|
||||||
|
foreach (InstanceHandle userLogin in userLogins)
|
||||||
|
{
|
||||||
|
string compareToken = oms.GetAttributeValue<string>(userLogin, a_Token);
|
||||||
|
Console.Error.WriteLine("oms: token {0} == {1} ???", token, compareToken);
|
||||||
|
|
||||||
|
if (compareToken.Equals(token))
|
||||||
|
{
|
||||||
|
InstanceHandle user = oms.GetRelatedInstance(userLogin, r_User_Login__has__User);
|
||||||
|
Console.Error.WriteLine("yes, returning {0}", user.GlobalIdentifier);
|
||||||
|
|
||||||
|
return new InstanceHandle[] { user };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine("oms: error: login token not set");
|
||||||
|
}
|
||||||
|
return new InstanceHandle[0];
|
||||||
|
});
|
||||||
RegisterSystemAttributeRoutine(KnownInstanceGuids.SystemAttributeRoutines.GetInstanceText, delegate (Oms oms, OmsContext context)
|
RegisterSystemAttributeRoutine(KnownInstanceGuids.SystemAttributeRoutines.GetInstanceText, delegate (Oms oms, OmsContext context)
|
||||||
{
|
{
|
||||||
object? val = context.GetWorkData(oms.GetInstance(KnownInstanceGuids.Classes.Instance));
|
object? val = context.GetWorkData(oms.GetInstance(KnownInstanceGuids.Classes.Instance));
|
||||||
@ -103,6 +135,8 @@ public abstract class Oms
|
|||||||
});
|
});
|
||||||
RegisterSystemUpdateRoutine(KnownInstanceGuids.SystemUpdateRoutines.LoginUser, delegate (Oms oms, OmsContext context)
|
RegisterSystemUpdateRoutine(KnownInstanceGuids.SystemUpdateRoutines.LoginUser, delegate (Oms oms, OmsContext context)
|
||||||
{
|
{
|
||||||
|
Console.Error.WriteLine("oms: executing system update routine {0}", KnownInstanceGuids.SystemUpdateRoutines.LoginUser);
|
||||||
|
|
||||||
// FIXME: these are ECs for now, they should probably be Text Attributes (or parms?) passed into the US method
|
// 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 userNameGuid = new Guid("{c67f305e-bd4d-4628-816b-55fb85ea1b67}");
|
||||||
Guid passwordGuid = new Guid("{51b51be3-44fd-48f1-971f-682aee0a6132}");
|
Guid passwordGuid = new Guid("{51b51be3-44fd-48f1-971f-682aee0a6132}");
|
||||||
@ -120,10 +154,14 @@ public abstract class Oms
|
|||||||
|
|
||||||
foreach (InstanceHandle user in users)
|
foreach (InstanceHandle user in users)
|
||||||
{
|
{
|
||||||
|
Console.Error.WriteLine("looking at user {0}", user.GlobalIdentifier);
|
||||||
|
|
||||||
string expectedUserName = oms.GetAttributeValue<string>(user, oms.GetInstance(KnownAttributeGuids.Text.UserName));
|
string expectedUserName = oms.GetAttributeValue<string>(user, oms.GetInstance(KnownAttributeGuids.Text.UserName));
|
||||||
if (expectedUserName == null)
|
if (expectedUserName == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
Console.Error.WriteLine("... expected user name '{0}', actual user name '{1}'", expectedUserName, userName);
|
||||||
|
|
||||||
if (expectedUserName != userName)
|
if (expectedUserName != userName)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -137,6 +175,8 @@ public abstract class Oms
|
|||||||
byte[] hash = hashAlgorithm.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password + passwordSalt));
|
byte[] hash = hashAlgorithm.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password + passwordSalt));
|
||||||
string actualPasswordHash = Convert.ToHexString(hash).ToLowerInvariant();
|
string actualPasswordHash = Convert.ToHexString(hash).ToLowerInvariant();
|
||||||
|
|
||||||
|
Console.Error.WriteLine("... expected password hash '{0}'\n... actual password hash '{1}'", expectedPasswordHash, actualPasswordHash);
|
||||||
|
|
||||||
if (actualPasswordHash.Equals(expectedPasswordHash))
|
if (actualPasswordHash.Equals(expectedPasswordHash))
|
||||||
{
|
{
|
||||||
actualSystemUser = user;
|
actualSystemUser = user;
|
||||||
@ -147,8 +187,12 @@ public abstract class Oms
|
|||||||
|
|
||||||
if (sessionSecureToken != null)
|
if (sessionSecureToken != null)
|
||||||
{
|
{
|
||||||
|
Console.Error.WriteLine("!! success !! set secure token {0}", sessionSecureToken);
|
||||||
|
Console.Error.WriteLine("!! success !! current system user is {0}", actualSystemUser.GlobalIdentifier);
|
||||||
|
|
||||||
context.SetWorkData(oms.GetInstance(KnownInstanceGuids.Classes.User), actualSystemUser);
|
context.SetWorkData(oms.GetInstance(KnownInstanceGuids.Classes.User), actualSystemUser);
|
||||||
context.SetWorkData(oms.GetInstance(KnownAttributeGuids.Text.Token), sessionSecureToken);
|
context.SetWorkData(oms.GetInstance(KnownAttributeGuids.Text.Token), sessionSecureToken);
|
||||||
|
context.SetGlobal(oms.GetInstance(KnownAttributeGuids.Text.Token), sessionSecureToken);
|
||||||
|
|
||||||
// FIXME: this should be processed in the PRU
|
// FIXME: this should be processed in the PRU
|
||||||
InstanceHandle clsSystemAccountSignon = GetInstance(KnownInstanceGuids.Classes.UserLogin);
|
InstanceHandle clsSystemAccountSignon = GetInstance(KnownInstanceGuids.Classes.UserLogin);
|
||||||
@ -257,6 +301,15 @@ public abstract class Oms
|
|||||||
{
|
{
|
||||||
return new InstanceKey(1, 1);
|
return new InstanceKey(1, 1);
|
||||||
}
|
}
|
||||||
|
if (IsDerivedInstance(instance))
|
||||||
|
{
|
||||||
|
InstanceHandle parent = GetParentClass(instance);
|
||||||
|
InstanceKey ikParent = GetInstanceKeyInternal(parent);
|
||||||
|
|
||||||
|
InstanceKey ik = new InstanceKey(ikParent.InstanceIndex, -1);
|
||||||
|
ik.SetDerivedData(this, instance, GetDerivedData(instance));
|
||||||
|
return ik;
|
||||||
|
}
|
||||||
return GetInstanceKeyInternal(instance);
|
return GetInstanceKeyInternal(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,8 +397,42 @@ public abstract class Oms
|
|||||||
}
|
}
|
||||||
throw new KeyNotFoundException(String.Format("inst not found: {0}", globalIdentifier));
|
throw new KeyNotFoundException(String.Format("inst not found: {0}", globalIdentifier));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Dictionary<string, InstanceHandle> _derivedInstances = new Dictionary<string, InstanceHandle>();
|
||||||
public InstanceHandle GetInstance(InstanceKey ik)
|
public InstanceHandle GetInstance(InstanceKey ik)
|
||||||
{
|
{
|
||||||
|
if (ik.IsDerived)
|
||||||
|
{
|
||||||
|
ik._oms = this;
|
||||||
|
InstanceHandle inst;
|
||||||
|
if (!_derivedInstances.ContainsKey(ik.ToString()))
|
||||||
|
{
|
||||||
|
InstanceHandle pclass = GetInstance(new InstanceKey(1, ik.ClassIndex));
|
||||||
|
|
||||||
|
inst = InstanceHandle.Create();
|
||||||
|
_derivedInstances[ik.ToString()] = inst;
|
||||||
|
|
||||||
|
SetParentClass(inst, pclass);
|
||||||
|
ik._inst = inst;
|
||||||
|
ik._parentClassInstance = pclass;
|
||||||
|
|
||||||
|
_derivedData[inst] = new Dictionary<InstanceHandle, object?>();
|
||||||
|
IEnumerable<KeyValuePair<InstanceHandle, object?>>? kvps = ik.GetDerivedData();
|
||||||
|
if (kvps != null)
|
||||||
|
{
|
||||||
|
foreach (KeyValuePair<InstanceHandle, object?> kvp in kvps)
|
||||||
|
{
|
||||||
|
_derivedData[inst][kvp.Key] = kvp.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
inst = _derivedInstances[ik.ToString()];
|
||||||
|
}
|
||||||
|
return inst;
|
||||||
|
}
|
||||||
|
|
||||||
if (TryGetInstance(ik, out InstanceHandle ih))
|
if (TryGetInstance(ik, out InstanceHandle ih))
|
||||||
{
|
{
|
||||||
return ih;
|
return ih;
|
||||||
@ -540,8 +627,61 @@ public abstract class Oms
|
|||||||
value = default(T);
|
value = default(T);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Dictionary<InstanceHandle, Dictionary<InstanceHandle, object?>?> _derivedData = new Dictionary<InstanceHandle, Dictionary<InstanceHandle, object?>?>();
|
||||||
|
public Dictionary<InstanceHandle, object?>? GetDerivedData(InstanceHandle source)
|
||||||
|
{
|
||||||
|
if (IsDerivedInstance(source))
|
||||||
|
{
|
||||||
|
if (!_derivedData.ContainsKey(source))
|
||||||
|
{
|
||||||
|
_derivedData[source] = new Dictionary<InstanceHandle, object?>();
|
||||||
|
}
|
||||||
|
return _derivedData[source];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsDerivedInstance(InstanceHandle source)
|
||||||
|
{
|
||||||
|
// !!! we cannot use GetAttributeValue here !!!
|
||||||
|
InstanceHandle pclass = GetParentClass(source);
|
||||||
|
object? o = GetAttributeValueInternal(pclass, GetInstance(KnownAttributeGuids.Boolean.Derived), DateTime.Now);
|
||||||
|
if (o is bool b && b)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T GetAttributeValue<T>(InstanceKey source, InstanceHandle attribute, T defaultValue = default(T), DateTime? effectiveDate = null)
|
||||||
|
{
|
||||||
|
if (source.IsDerived)
|
||||||
|
{
|
||||||
|
source._oms = this;
|
||||||
|
Dictionary<InstanceHandle, object?> derivedData = source.GetDerivedData();
|
||||||
|
if (derivedData.ContainsKey(attribute))
|
||||||
|
{
|
||||||
|
return (T) derivedData[attribute];
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
InstanceHandle hSource = GetInstance(source);
|
||||||
|
return GetAttributeValue<T>(hSource, attribute, defaultValue, effectiveDate);
|
||||||
|
}
|
||||||
|
}
|
||||||
public T GetAttributeValue<T>(InstanceHandle source, InstanceHandle attribute, T defaultValue = default(T), DateTime? effectiveDate = null)
|
public T GetAttributeValue<T>(InstanceHandle source, InstanceHandle attribute, T defaultValue = default(T), DateTime? effectiveDate = null)
|
||||||
{
|
{
|
||||||
|
Dictionary<InstanceHandle, object>? derivedData = GetDerivedData(source);
|
||||||
|
if (derivedData != null)
|
||||||
|
{
|
||||||
|
if (derivedData.ContainsKey(attribute))
|
||||||
|
{
|
||||||
|
return (T)derivedData[attribute];
|
||||||
|
}
|
||||||
|
}
|
||||||
if (TryGetAttributeValue(source, attribute, effectiveDate, out T value))
|
if (TryGetAttributeValue(source, attribute, effectiveDate, out T value))
|
||||||
{
|
{
|
||||||
return value;
|
return value;
|
||||||
@ -552,6 +692,16 @@ public abstract class Oms
|
|||||||
public void SetAttributeValue(InstanceHandle source, InstanceHandle attribute, object value, DateTime? effectiveDate = null)
|
public void SetAttributeValue(InstanceHandle source, InstanceHandle attribute, object value, DateTime? effectiveDate = null)
|
||||||
{
|
{
|
||||||
ValidateConstraintsForAttribute(source, attribute, value);
|
ValidateConstraintsForAttribute(source, attribute, value);
|
||||||
|
|
||||||
|
if (IsDerivedInstance(source))
|
||||||
|
{
|
||||||
|
if (!_derivedData.ContainsKey(source))
|
||||||
|
{
|
||||||
|
_derivedData[source] = new Dictionary<InstanceHandle, object>();
|
||||||
|
}
|
||||||
|
_derivedData[source][attribute] = value;
|
||||||
|
return;
|
||||||
|
}
|
||||||
SetAttributeValueInternal(source, attribute, value, effectiveDate.GetValueOrDefault(DateTime.Now));
|
SetAttributeValueInternal(source, attribute, value, effectiveDate.GetValueOrDefault(DateTime.Now));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -905,7 +1055,8 @@ public abstract class Oms
|
|||||||
InstanceHandle parentClass = GetParentClass(methodOrMethodBinding);
|
InstanceHandle parentClass = GetParentClass(methodOrMethodBinding);
|
||||||
Guid parentClassId = GetGlobalIdentifier(parentClass);
|
Guid parentClassId = GetGlobalIdentifier(parentClass);
|
||||||
|
|
||||||
context.StackTrace.Push(methodOrMethodBinding);
|
context.Push(methodOrMethodBinding);
|
||||||
|
// context.StackTrace.Push(methodOrMethodBinding);
|
||||||
|
|
||||||
InstanceHandle? retval = null;
|
InstanceHandle? retval = null;
|
||||||
|
|
||||||
@ -949,7 +1100,14 @@ public abstract class Oms
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
context.StackTrace.Pop();
|
// context.StackTrace.Pop();
|
||||||
|
IDictionary<InstanceHandle, object?> dict = context.GetAllWorkData();
|
||||||
|
context.Pop();
|
||||||
|
|
||||||
|
if (dict.ContainsKey(retval.Value))
|
||||||
|
{
|
||||||
|
context.SetWorkData(retval.Value, dict[retval.Value]);
|
||||||
|
}
|
||||||
return retval.Value;
|
return retval.Value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -965,7 +1123,7 @@ public abstract class Oms
|
|||||||
return new OmsContext(this);
|
return new OmsContext(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IReadOnlyCollection<InstanceHandle> ExecuteStaticMethodReturningInstanceSet(OmsContext context, ReturnInstanceSetMethodBinding methodBinding)
|
public IEnumerable<InstanceHandle> ExecuteStaticMethodReturningInstanceSet(OmsContext context, ReturnInstanceSetMethodBinding methodBinding)
|
||||||
{
|
{
|
||||||
InstanceHandle method = GetRelatedInstance(methodBinding.Handle, GetInstance(KnownRelationshipGuids.Method_Binding__executes__Method));
|
InstanceHandle method = GetRelatedInstance(methodBinding.Handle, GetInstance(KnownRelationshipGuids.Method_Binding__executes__Method));
|
||||||
if (TryGetAttributeValue<bool>(method, GetInstance(KnownAttributeGuids.Boolean.Static), out bool is_static))
|
if (TryGetAttributeValue<bool>(method, GetInstance(KnownAttributeGuids.Boolean.Static), out bool is_static))
|
||||||
@ -975,10 +1133,14 @@ public abstract class Oms
|
|||||||
InstanceHandle result = Execute(context, methodBinding);
|
InstanceHandle result = Execute(context, methodBinding);
|
||||||
object? value = context.GetWorkData(result);
|
object? value = context.GetWorkData(result);
|
||||||
|
|
||||||
if (value is IReadOnlyCollection<InstanceHandle> res)
|
if (value is IEnumerable<InstanceHandle> res)
|
||||||
{
|
{
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
else if (value is InstanceHandle res_singular)
|
||||||
|
{
|
||||||
|
return new InstanceHandle[] { res_singular };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new InvalidOperationException("cannot call a non-static Method in a static context");
|
throw new InvalidOperationException("cannot call a non-static Method in a static context");
|
||||||
@ -1607,7 +1769,7 @@ public abstract class Oms
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateElementContents(OmsContext context, InstanceHandle element, ReadOnlyDictionary<string, string> values)
|
private void UpdateElementContents(OmsContext context, InstanceHandle element, IDictionary<string, string> values)
|
||||||
{
|
{
|
||||||
IEnumerable<InstanceHandle> elementContents = GetRelatedInstances(element, GetInstance(KnownRelationshipGuids.Element__has__Element_Content));
|
IEnumerable<InstanceHandle> elementContents = GetRelatedInstances(element, GetInstance(KnownRelationshipGuids.Element__has__Element_Content));
|
||||||
foreach (InstanceHandle elementContent in elementContents)
|
foreach (InstanceHandle elementContent in elementContents)
|
||||||
@ -1664,24 +1826,139 @@ public abstract class Oms
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Response ProcessElement(OmsContext context, InstanceHandle initiatingElement, InstanceHandle parmInstance)
|
public string GetLabelForUIElement(InstanceHandle parentElementContent)
|
||||||
{
|
{
|
||||||
if (parmInstance != InstanceHandle.Empty)
|
InstanceHandle parentInstance = GetRelatedInstance(parentElementContent, GetInstance(KnownRelationshipGuids.Element_Content__has__Instance));
|
||||||
|
string label = GetAttributeValue<string>(parentElementContent, GetInstance(KnownAttributeGuids.Text.LabelOverride));
|
||||||
|
if (label == null)
|
||||||
{
|
{
|
||||||
InstanceHandle processedByCt = GetRelatedInstance(initiatingElement, GetInstance(KnownRelationshipGuids.Element__processed_by__Control_Transaction_Method));
|
label = GetAttributeValue<string>(parentElementContent, GetInstance(KnownAttributeGuids.Text.Label));
|
||||||
InstanceHandle forClassId = GetRelatedInstance(processedByCt, GetInstance(KnownRelationshipGuids.Method__for__Class));
|
if (label == null)
|
||||||
|
{
|
||||||
|
label = GetInstanceText(parentInstance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
InstanceHandle buildsResponseWithMB = GetRelatedInstance(processedByCt, GetInstance(KnownRelationshipGuids.Control_Transaction_Method__uses__Build_Response_Method_Binding));
|
|
||||||
|
|
||||||
|
public Response ProcessElement(OmsContext ctx, InstanceHandle element, IDictionary<string, string>? form = null, string fqecidPrefix = "")
|
||||||
|
{
|
||||||
|
if (form != null)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
InstanceHandle processedByCt2 = GetRelatedInstance(element, GetInstance(KnownRelationshipGuids.Element__processed_by__Control_Transaction_Method));
|
||||||
|
InstanceHandle forClassId = GetRelatedInstance(processedByCt2, GetInstance(KnownRelationshipGuids.Method__for__Class));
|
||||||
|
|
||||||
|
InstanceHandle buildsResponseWithMB = GetRelatedInstance(processedByCt2, GetInstance(KnownRelationshipGuids.Control_Transaction_Method__uses__Build_Response_Method_Binding));
|
||||||
InstanceHandle executesMethod = GetRelatedInstance(buildsResponseWithMB, GetInstance(KnownRelationshipGuids.Method_Binding__executes__Method));
|
InstanceHandle executesMethod = GetRelatedInstance(buildsResponseWithMB, GetInstance(KnownRelationshipGuids.Method_Binding__executes__Method));
|
||||||
InstanceHandle usesExecutableReturningElement = GetRelatedInstance(executesMethod, GetInstance(KnownRelationshipGuids.Build_UI_Response_Method__uses__Executable_returning_Element));
|
InstanceHandle usesExecutableReturningElement = GetRelatedInstance(executesMethod, GetInstance(KnownRelationshipGuids.Build_UI_Response_Method__uses__Executable_returning_Element));
|
||||||
|
|
||||||
context.SetWorkData(forClassId, parmInstance);
|
ctx.SetWorkData(forClassId, processingInstance);
|
||||||
return ProcessElement(context, usesExecutableReturningElement, InstanceHandle.Empty);
|
return ProcessElement(ctx, usesExecutableReturningElement, InstanceHandle.Empty, form);
|
||||||
|
*/
|
||||||
|
|
||||||
|
// first we process the related updates
|
||||||
|
InstanceHandle processedByPru = GetRelatedInstance(element, GetInstance(KnownRelationshipGuids.Element__processed_by__Process_Related_Updates_Method));
|
||||||
|
if (processedByPru != InstanceHandle.Empty)
|
||||||
|
{
|
||||||
|
// this works... so far
|
||||||
|
Console.Error.WriteLine("oms: processing element with PRU {0}", processedByPru.GlobalIdentifier);
|
||||||
|
// hack
|
||||||
|
UpdateElementContents(ctx, element, form);
|
||||||
|
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 = GetRelatedInstances(element, GetInstance(KnownRelationshipGuids.Element__has__Element_Content));
|
||||||
|
foreach (InstanceHandle elementContent2 in elementContents)
|
||||||
|
{
|
||||||
|
Response? resp = ProcessElementContent(ctx, elementContent2, form, fqecidPrefix);
|
||||||
|
if (resp != null)
|
||||||
|
{
|
||||||
|
return resp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ... finally we run the CT - Control Transaction Method to return the response
|
||||||
|
InstanceHandle processedByCt = GetRelatedInstance(element, GetInstance(KnownRelationshipGuids.Element__processed_by__Control_Transaction_Method));
|
||||||
|
if (processedByCt != InstanceHandle.Empty)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine("oms: processing element with CT {0}", processedByCt.GlobalIdentifier);
|
||||||
|
// hack
|
||||||
|
IEnumerable<InstanceHandle> usesBuildResponseMethodBindings = GetRelatedInstances(processedByCt, GetInstance(KnownRelationshipGuids.Control_Transaction_Method__uses__Build_Response_Method_Binding));
|
||||||
|
Console.Error.WriteLine("---> has {0} BRMBs", usesBuildResponseMethodBindings.Count());
|
||||||
|
|
||||||
|
foreach (InstanceHandle usesBuildResponseMethodBinding in usesBuildResponseMethodBindings)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine("oms: evaluating BRMB {0}", usesBuildResponseMethodBinding.GlobalIdentifier);
|
||||||
|
|
||||||
|
IEnumerable<InstanceHandle> trueConditions = GetRelatedInstances(usesBuildResponseMethodBinding, GetInstance(KnownRelationshipGuids.Condition_Group__has_true_condition__Executable_returning_Work_Data));
|
||||||
|
IEnumerable<InstanceHandle> falseConditions = GetRelatedInstances(usesBuildResponseMethodBinding, GetInstance(KnownRelationshipGuids.Condition_Group__has_false_condition__Executable_returning_Work_Data));
|
||||||
|
bool useAnyCondition = GetAttributeValue<bool>(usesBuildResponseMethodBinding, GetInstance(KnownAttributeGuids.Boolean.UseAnyCondition));
|
||||||
|
|
||||||
|
if (EvaluateConditions(ctx, trueConditions, falseConditions, useAnyCondition))
|
||||||
|
{
|
||||||
|
InstanceHandle executesMethod = GetRelatedInstance(usesBuildResponseMethodBinding, GetInstance(KnownRelationshipGuids.Method_Binding__executes__Method));
|
||||||
|
Console.Error.WriteLine("----> ok, executing method {0}", executesMethod.GlobalIdentifier);
|
||||||
|
|
||||||
|
// execute BRMB
|
||||||
|
string targetURL = GetAttributeValue<string>(executesMethod, GetInstance(KnownAttributeGuids.Text.TargetURL));
|
||||||
|
if (targetURL != null)
|
||||||
|
{
|
||||||
|
return new RedirectResponse(targetURL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
$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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Renderer renderer = new Renderer(this);
|
Renderer renderer = new Renderer(this);
|
||||||
Widget widget = renderer.Parse(context, initiatingElement, InstanceHandle.Empty, InstanceHandle.Empty);
|
Widget widget = renderer.Parse(ctx, element, InstanceHandle.Empty, InstanceHandle.Empty);
|
||||||
if (widget == null)
|
if (widget == null)
|
||||||
{
|
{
|
||||||
return FailureResponse.UnexpectedFailure;
|
return FailureResponse.UnexpectedFailure;
|
||||||
@ -1704,18 +1981,74 @@ public abstract class Oms
|
|||||||
return FailureResponse.UnexpectedFailure;
|
return FailureResponse.UnexpectedFailure;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetLabelForUIElement(InstanceHandle parentElementContent)
|
private Response? ProcessElementContent(OmsContext context, InstanceHandle elementContent, IDictionary<string, string> form, string fqecidPrefix)
|
||||||
{
|
{
|
||||||
InstanceHandle parentInstance = GetRelatedInstance(parentElementContent, GetInstance(KnownRelationshipGuids.Element_Content__has__Instance));
|
InstanceHandle elementContentInstance = GetRelatedInstance(elementContent, GetInstance(KnownRelationshipGuids.Element_Content__has__Instance));
|
||||||
string label = GetAttributeValue<string>(parentElementContent, GetInstance(KnownAttributeGuids.Text.LabelOverride));
|
if (IsInstanceOf(elementContentInstance, GetInstance(KnownInstanceGuids.Classes.Element)))
|
||||||
if (label == null)
|
|
||||||
{
|
{
|
||||||
label = GetAttributeValue<string>(parentElementContent, GetInstance(KnownAttributeGuids.Text.Label));
|
return ProcessElement(context, elementContentInstance, form, fqecidPrefix + GetInstanceKey(elementContentInstance).ToString() + ":");
|
||||||
if (label == null)
|
}
|
||||||
|
else if (IsInstanceOf(elementContentInstance, GetInstance(KnownInstanceGuids.Classes.TextAttribute)))
|
||||||
{
|
{
|
||||||
label = GetInstanceText(parentInstance);
|
string key = fqecidPrefix + GetInstanceKey(elementContent);
|
||||||
|
string text = GetInstanceText(elementContentInstance);
|
||||||
|
if (form.ContainsKey(key))
|
||||||
|
{
|
||||||
|
string value = form[key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return label;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private HashAlgorithm hashAlgorithm = System.Security.Cryptography.SHA512.Create();
|
||||||
|
|
||||||
|
public InstanceHandle CreateUser(string username, string password)
|
||||||
|
{
|
||||||
|
InstanceHandle c_User = GetInstance(KnownInstanceGuids.Classes.User);
|
||||||
|
InstanceHandle a_UserName = GetInstance(KnownAttributeGuids.Text.UserName);
|
||||||
|
InstanceHandle a_PasswordSalt = GetInstance(KnownAttributeGuids.Text.PasswordSalt);
|
||||||
|
InstanceHandle a_PasswordHash = GetInstance(KnownAttributeGuids.Text.PasswordHash);
|
||||||
|
|
||||||
|
string salt = Guid.NewGuid().ToString("N").ToLowerInvariant();
|
||||||
|
string hash = Convert.ToHexString(hashAlgorithm.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password + salt))).ToLowerInvariant();
|
||||||
|
|
||||||
|
InstanceHandle i_User = CreateInstanceOf(c_User);
|
||||||
|
SetAttributeValue(i_User, a_UserName, username);
|
||||||
|
SetAttributeValue(i_User, a_PasswordSalt, salt);
|
||||||
|
SetAttributeValue(i_User, a_PasswordHash, hash);
|
||||||
|
|
||||||
|
return i_User;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool EvaluateConditions(OmsContext context, IEnumerable<InstanceHandle> trueConditions, IEnumerable<InstanceHandle> falseConditions, bool useAnyCondition)
|
||||||
|
{
|
||||||
|
bool value = false;
|
||||||
|
if (trueConditions != null)
|
||||||
|
{
|
||||||
|
foreach (InstanceHandle trueCondition in trueConditions)
|
||||||
|
{
|
||||||
|
InstanceHandle ret = Execute(context, trueCondition);
|
||||||
|
object? retval = context.GetWorkData(ret);
|
||||||
|
if (retval is bool && ((bool)retval))
|
||||||
|
{
|
||||||
|
value = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (falseConditions != null)
|
||||||
|
{
|
||||||
|
foreach (InstanceHandle falseCondition in falseConditions)
|
||||||
|
{
|
||||||
|
InstanceHandle ret = Execute(context, falseCondition);
|
||||||
|
object? retval = context.GetWorkData(ret);
|
||||||
|
if (retval is bool && (!(bool)retval))
|
||||||
|
{
|
||||||
|
value = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,6 +25,7 @@ public class OmsContext
|
|||||||
{
|
{
|
||||||
public Oms Oms { get; }
|
public Oms Oms { get; }
|
||||||
public OmsStackTrace StackTrace { get; }
|
public OmsStackTrace StackTrace { get; }
|
||||||
|
private Stack<Dictionary<InstanceHandle, object>> WorkDataSets = new Stack<Dictionary<InstanceHandle, object>>();
|
||||||
|
|
||||||
internal OmsContext(Oms oms)
|
internal OmsContext(Oms oms)
|
||||||
{
|
{
|
||||||
@ -33,6 +34,7 @@ public class OmsContext
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Dictionary<InstanceHandle, object?> _WorkData = new Dictionary<InstanceHandle, object?>();
|
private Dictionary<InstanceHandle, object?> _WorkData = new Dictionary<InstanceHandle, object?>();
|
||||||
|
private Dictionary<InstanceHandle, object?> _GlobalData = new Dictionary<InstanceHandle, object?>();
|
||||||
public object? GetWorkData(WorkSet parm)
|
public object? GetWorkData(WorkSet parm)
|
||||||
{
|
{
|
||||||
return GetWorkData(parm.Handle);
|
return GetWorkData(parm.Handle);
|
||||||
@ -42,6 +44,12 @@ public class OmsContext
|
|||||||
if (_WorkData.ContainsKey(parm))
|
if (_WorkData.ContainsKey(parm))
|
||||||
return _WorkData[parm];
|
return _WorkData[parm];
|
||||||
|
|
||||||
|
foreach (Dictionary<InstanceHandle, object> set in WorkDataSets)
|
||||||
|
{
|
||||||
|
if (set.ContainsKey(parm))
|
||||||
|
return set[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;
|
return null;
|
||||||
}
|
}
|
||||||
@ -108,6 +116,7 @@ public class OmsContext
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// value = ((IEnumerable<InstanceHandle>)value).FirstOrDefault();
|
||||||
}
|
}
|
||||||
else if (value is IEnumerable<InstanceWrapper>)
|
else if (value is IEnumerable<InstanceWrapper>)
|
||||||
{
|
{
|
||||||
@ -141,4 +150,39 @@ public class OmsContext
|
|||||||
}
|
}
|
||||||
_WorkData[parm] = value;
|
_WorkData[parm] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Push(InstanceHandle methodOrMethodBinding)
|
||||||
|
{
|
||||||
|
StackTrace.Push(methodOrMethodBinding);
|
||||||
|
WorkDataSets.Push(_WorkData);
|
||||||
|
|
||||||
|
_WorkData = new Dictionary<InstanceHandle, object?>();
|
||||||
|
}
|
||||||
|
public InstanceHandle Pop()
|
||||||
|
{
|
||||||
|
InstanceHandle methodOrMethodBinding = StackTrace.Pop();
|
||||||
|
_WorkData = WorkDataSets.Pop();
|
||||||
|
return methodOrMethodBinding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IDictionary<InstanceHandle, object?> GetAllWorkData()
|
||||||
|
{
|
||||||
|
return _WorkData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T GetGlobal<T>(InstanceHandle parm, T defaultValue = default(T))
|
||||||
|
{
|
||||||
|
if (_GlobalData.ContainsKey(parm))
|
||||||
|
{
|
||||||
|
if (_GlobalData[parm] is T)
|
||||||
|
{
|
||||||
|
return (T)(_GlobalData[parm]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
public void SetGlobal(InstanceHandle parm, object? value)
|
||||||
|
{
|
||||||
|
_GlobalData[parm] = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -73,10 +73,13 @@ public abstract class Widget
|
|||||||
obj.Add("ecid", JsonValue.Create(OMS.GetInstanceKey(ParentElementContent).ToString()));
|
obj.Add("ecid", JsonValue.Create(OMS.GetInstanceKey(ParentElementContent).ToString()));
|
||||||
|
|
||||||
if (!displayOptions.Contains(OMS.GetInstance(KnownInstanceGuids.ElementContentDisplayOptions.DoNotShowLabel)))
|
if (!displayOptions.Contains(OMS.GetInstance(KnownInstanceGuids.ElementContentDisplayOptions.DoNotShowLabel)))
|
||||||
|
{
|
||||||
|
if (!OMS.IsInstanceOf(ParentInstance, OMS.GetInstance(KnownInstanceGuids.Classes.Element)))
|
||||||
{
|
{
|
||||||
string label = OMS.GetLabelForUIElement(ParentElementContent);
|
string label = OMS.GetLabelForUIElement(ParentElementContent);
|
||||||
obj.Add("label", label);
|
obj.Add("label", label);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!ShouldBeEnabled())
|
if (!ShouldBeEnabled())
|
||||||
{
|
{
|
||||||
obj.Add("enabled", false);
|
obj.Add("enabled", false);
|
||||||
|
|||||||
@ -59,7 +59,7 @@ public class Element : Widget
|
|||||||
|
|
||||||
// otherwise, we are a hbox
|
// otherwise, we are a hbox
|
||||||
// return "hbox";
|
// return "hbox";
|
||||||
return "vbox";
|
return "fieldSet";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,8 +172,21 @@ public class Element : Widget
|
|||||||
|
|
||||||
InstanceHandle workSet = OMS.Execute(context, loopExecutable);
|
InstanceHandle workSet = OMS.Execute(context, loopExecutable);
|
||||||
object? obj = context.GetWorkData(workSet);
|
object? obj = context.GetWorkData(workSet);
|
||||||
if (obj is IEnumerable<InstanceHandle> list)
|
|
||||||
|
IEnumerable<InstanceHandle> list;
|
||||||
|
if (obj is IEnumerable<InstanceHandle> list2)
|
||||||
{
|
{
|
||||||
|
list = list2;
|
||||||
|
}
|
||||||
|
else if (obj is InstanceHandle)
|
||||||
|
{
|
||||||
|
list = new InstanceHandle[] { (InstanceHandle)obj };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
list = new InstanceHandle[0];
|
||||||
|
}
|
||||||
|
|
||||||
JsonArray ary = new JsonArray();
|
JsonArray ary = new JsonArray();
|
||||||
foreach (InstanceHandle ih in list)
|
foreach (InstanceHandle ih in list)
|
||||||
{
|
{
|
||||||
@ -219,7 +232,4 @@ public class Element : Widget
|
|||||||
}
|
}
|
||||||
return ary;
|
return ary;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
54
mocha-dotnet/tests/Mocha.Core.Tests/DerivedInstanceTests.cs
Normal file
54
mocha-dotnet/tests/Mocha.Core.Tests/DerivedInstanceTests.cs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
using System;
|
||||||
|
using Newtonsoft.Json.Serialization;
|
||||||
|
|
||||||
|
namespace Mocha.Core.Tests;
|
||||||
|
|
||||||
|
public class DerivedInstanceTests : OmsTestsBase
|
||||||
|
{
|
||||||
|
InstanceHandle TEST_CLASS_DERIVED;
|
||||||
|
protected override void AfterSetup()
|
||||||
|
{
|
||||||
|
base.AfterSetup();
|
||||||
|
|
||||||
|
TEST_CLASS_DERIVED = Oms.CreateClass("Test Class (Derived)");
|
||||||
|
Oms.SetAttributeValue(TEST_CLASS_DERIVED, Oms.GetInstance(KnownAttributeGuids.Boolean.Derived), true);
|
||||||
|
|
||||||
|
// Derived classes are represented only by InstanceKeys with the form {ClassId}!{DerivedData}, where
|
||||||
|
// {DerivedData} is a Base64 string encoding all the attributes and relationships associated with the
|
||||||
|
// derived instance.
|
||||||
|
|
||||||
|
// ? Should we be concerned with memory leaks given the lazy implementation of GetInstance on a derived
|
||||||
|
// ? InstanceKey essentially allocates a new InstanceHandle each time it's called ???
|
||||||
|
Oms.AddAttribute(TEST_CLASS_DERIVED, Oms.GetInstance(KnownAttributeGuids.Text.Name));
|
||||||
|
}
|
||||||
|
|
||||||
|
const string TEST_DERIVED_VALUE = "Test Class Derived #1";
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Derived_Instance_Test_get_Text_Attribute_Value()
|
||||||
|
{
|
||||||
|
InstanceHandle iTestClassDerived = Oms.CreateInstanceOf(TEST_CLASS_DERIVED);
|
||||||
|
Oms.SetAttributeValue(iTestClassDerived, Oms.GetInstance(KnownAttributeGuids.Text.Name), TEST_DERIVED_VALUE);
|
||||||
|
|
||||||
|
InstanceKey ik = Oms.GetInstanceKey(iTestClassDerived);
|
||||||
|
|
||||||
|
InstanceHandle h2 = Oms.GetInstance(ik);
|
||||||
|
Dictionary<InstanceHandle, object?>? dict = Oms.GetDerivedData(h2);
|
||||||
|
|
||||||
|
string attVName = Oms.GetAttributeValue<string>(h2, Oms.GetInstance(KnownAttributeGuids.Text.Name));
|
||||||
|
Assert.That(attVName, Is.EqualTo(TEST_DERIVED_VALUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Derived_Instance_Test__instance_key_Parse()
|
||||||
|
{
|
||||||
|
string ikStr = "154!FQAAABVUZXN0IENsYXNzIERlcml2ZWQgIzE=";
|
||||||
|
InstanceKey ik = InstanceKey.Parse(ikStr);
|
||||||
|
|
||||||
|
InstanceHandle ih = Oms.GetInstance(ik);
|
||||||
|
|
||||||
|
string attVName = Oms.GetAttributeValue<string>(ik, Oms.GetInstance(KnownAttributeGuids.Text.Name));
|
||||||
|
Assert.That(attVName, Is.EqualTo(TEST_DERIVED_VALUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -41,7 +41,7 @@ public class CommonTests : MethodTestsBase
|
|||||||
|
|
||||||
Assert.That(delegate ()
|
Assert.That(delegate ()
|
||||||
{
|
{
|
||||||
IReadOnlyCollection<InstanceHandle> specifiedInstances = Oms.ExecuteStaticMethodReturningInstanceSet(context, dummyMethodRsmb);
|
IEnumerable<InstanceHandle> specifiedInstances = Oms.ExecuteStaticMethodReturningInstanceSet(context, dummyMethodRsmb);
|
||||||
}, Throws.InvalidOperationException);
|
}, Throws.InvalidOperationException);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -44,7 +44,7 @@ public class GetSpecifiedInstancesMethodTests : MethodTestsBase
|
|||||||
nom = Oms.GetInstanceText(gsiMethodRsmb);
|
nom = Oms.GetInstanceText(gsiMethodRsmb);
|
||||||
|
|
||||||
OmsContext context = Oms.CreateContext();
|
OmsContext context = Oms.CreateContext();
|
||||||
IReadOnlyCollection<InstanceHandle> specifiedInstances = Oms.ExecuteStaticMethodReturningInstanceSet(context, gsiMethodRsmb);
|
IEnumerable<InstanceHandle> specifiedInstances = Oms.ExecuteStaticMethodReturningInstanceSet(context, gsiMethodRsmb);
|
||||||
|
|
||||||
Assert.That(specifiedInstances, Contains.Item(irTestClassInstance));
|
Assert.That(specifiedInstances, Contains.Item(irTestClassInstance));
|
||||||
}
|
}
|
||||||
|
|||||||
94
mocha-dotnet/tests/Mocha.Core.Tests/ModuleTests.cs
Normal file
94
mocha-dotnet/tests/Mocha.Core.Tests/ModuleTests.cs
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
using System;
|
||||||
|
using Mocha.Core.Oop;
|
||||||
|
|
||||||
|
namespace Mocha.Core.Tests;
|
||||||
|
|
||||||
|
[TestFixture]
|
||||||
|
public class ModuleTests : OmsTestsBase
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void ToplevelModuleInstanceText()
|
||||||
|
{
|
||||||
|
InstanceHandle ihMochaBaseSystem = Oms.GetInstance(KnownInstanceGuids.Modules.MochaBaseSystem);
|
||||||
|
|
||||||
|
string text = Oms.GetInstanceText(ihMochaBaseSystem);
|
||||||
|
Assert.That(text, Is.EqualTo("Mocha Base System"));
|
||||||
|
}
|
||||||
|
[Test]
|
||||||
|
public void SublevelModuleInstanceText()
|
||||||
|
{
|
||||||
|
InstanceHandle ihOOPMethodExamples = Oms.GetInstance(KnownInstanceGuids.Modules.OOPMethodExamples);
|
||||||
|
string text = Oms.GetInstanceText(ihOOPMethodExamples);
|
||||||
|
Assert.That(text, Is.EqualTo("Mocha Base System:OOP:OOP Method Examples"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TopLevelModuleName()
|
||||||
|
{
|
||||||
|
InstanceHandle ihMochaBaseSystem = Oms.GetInstance(KnownInstanceGuids.Modules.MochaBaseSystem);
|
||||||
|
|
||||||
|
InstanceHandle c_Module = Oms.GetInstance(KnownInstanceGuids.Classes.Module);
|
||||||
|
Method Module__get__Name = Oms.GetMethod(c_Module, "get", "Name");
|
||||||
|
Assert.That(Module__get__Name, Is.Not.Null);
|
||||||
|
//
|
||||||
|
OmsContext context = Oms.CreateContext();
|
||||||
|
InstanceHandle ret = Oms.Execute(context, Module__get__Name, ihMochaBaseSystem);
|
||||||
|
object? val = context.GetWorkData(ret);
|
||||||
|
Assert.That(val, Is.TypeOf<string>().And.EqualTo("Mocha Base System"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void OOPMethodExamples_ParentModuleIs_OOP()
|
||||||
|
{
|
||||||
|
InstanceHandle ihOOPMethodExamples = Oms.GetInstance(KnownInstanceGuids.Modules.OOPMethodExamples);
|
||||||
|
InstanceHandle ihOOP = Oms.GetInstance(KnownInstanceGuids.Modules.OOP);
|
||||||
|
|
||||||
|
InstanceHandle c_Module = Oms.GetInstance(KnownInstanceGuids.Classes.Module);
|
||||||
|
Method Module__get__Parent_Module = Oms.GetMethod(c_Module, "get", "Parent Module");
|
||||||
|
Assert.That(Module__get__Parent_Module, Is.Not.Null);
|
||||||
|
|
||||||
|
OmsContext context = Oms.CreateContext();
|
||||||
|
InstanceHandle ret = Oms.Execute(context, Module__get__Parent_Module, ihOOPMethodExamples);
|
||||||
|
object? val = context.GetWorkData(ret);
|
||||||
|
|
||||||
|
Assert.That(val, Is.TypeOf<InstanceHandle>().And.EqualTo(ihOOP));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void MochaBaseSystem_ParentModuleIs_Empty()
|
||||||
|
{
|
||||||
|
InstanceHandle ihMochaBaseSystem = Oms.GetInstance(KnownInstanceGuids.Modules.MochaBaseSystem);
|
||||||
|
|
||||||
|
InstanceHandle c_Module = Oms.GetInstance(KnownInstanceGuids.Classes.Module);
|
||||||
|
Method Module__get__Parent_Module = Oms.GetMethod(c_Module, "get", "Parent Module");
|
||||||
|
Assert.That(Module__get__Parent_Module, Is.Not.Null);
|
||||||
|
|
||||||
|
OmsContext context = Oms.CreateContext();
|
||||||
|
InstanceHandle ret = Oms.Execute(context, Module__get__Parent_Module, ihMochaBaseSystem);
|
||||||
|
object? val = context.GetWorkData(ret);
|
||||||
|
|
||||||
|
Assert.That(val, Is.Null.Or.EqualTo(InstanceHandle.Empty));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Module__get__Fully_Qualified_Name__method_components()
|
||||||
|
{
|
||||||
|
InstanceHandle ihMochaBaseSystem = Oms.GetInstance(KnownInstanceGuids.Modules.MochaBaseSystem);
|
||||||
|
|
||||||
|
InstanceHandle c_Module = Oms.GetInstance(KnownInstanceGuids.Classes.Module);
|
||||||
|
InstanceHandle method = Oms.GetInstance(new Guid("{0ab85e0b-5577-475a-b914-4578ffb928d7}"));
|
||||||
|
|
||||||
|
IEnumerable<InstanceHandle> ms = Oms.GetRelatedInstances(method, Oms.GetInstance(KnownRelationshipGuids.Build_Attribute_Method__builds_with__Build_Attribute_Method_Component));
|
||||||
|
|
||||||
|
InstanceHandle m2 = Oms.GetInstance(new Guid("{27b070c9-7130-414b-960d-511f2836ef06}"));
|
||||||
|
|
||||||
|
IEnumerable<InstanceHandle> ms2 = Oms.GetRelatedInstances(method, Oms.GetInstance(KnownRelationshipGuids.Build_Attribute_Method__builds_with__Build_Attribute_Method_Component));
|
||||||
|
|
||||||
|
OmsContext context = Oms.CreateContext();
|
||||||
|
InstanceHandle ret = Oms.Execute(context, method, ihMochaBaseSystem);
|
||||||
|
object? val = context.GetWorkData(ret);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
73
mocha-dotnet/tests/Mocha.Core.Tests/UI/UITests.cs
Normal file
73
mocha-dotnet/tests/Mocha.Core.Tests/UI/UITests.cs
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
using System;
|
||||||
|
using System.Text.Json.Nodes;
|
||||||
|
|
||||||
|
namespace Mocha.Core.Tests.UI;
|
||||||
|
|
||||||
|
[TestFixture]
|
||||||
|
public class UITests : OmsTestsBase
|
||||||
|
{
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void LoginPageElement()
|
||||||
|
{
|
||||||
|
InstanceHandle loginPage = Oms.GetInstance(KnownInstanceGuids.Pages.LoginPage);
|
||||||
|
|
||||||
|
OmsContext context = Oms.CreateContext();
|
||||||
|
Response pageOutput = Oms.ProcessElement(context, loginPage);
|
||||||
|
|
||||||
|
JsonObject json = pageOutput.GetResponse(Oms, context);
|
||||||
|
|
||||||
|
Assert.That(json["result"].GetValue<string>(), Is.EqualTo("success"));
|
||||||
|
Assert.That(json["value"]["body"]["widget"].GetValue<string>(), Is.EqualTo("fieldSet"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void LoginPageElementSubmit()
|
||||||
|
{
|
||||||
|
Oms.CreateUser("testing", "testing");
|
||||||
|
|
||||||
|
InstanceHandle loginPage = Oms.GetInstance(KnownInstanceGuids.Pages.LoginPage);
|
||||||
|
|
||||||
|
InstanceHandle loginPageSubedit = Oms.GetInstance(new Guid("{2b7d4481-b7c2-4e26-a917-e3ff7c367a8a}"));
|
||||||
|
OmsContext context = Oms.CreateContext();
|
||||||
|
|
||||||
|
Dictionary<string, string> dict = new Dictionary<string, string>();
|
||||||
|
dict["{c67f305e-bd4d-4628-816b-55fb85ea1b67}"] = "testing";
|
||||||
|
dict["{51b51be3-44fd-48f1-971f-682aee0a6132}"] = "testing";
|
||||||
|
|
||||||
|
Response pageOutput = Oms.ProcessElement(context, loginPageSubedit, dict);
|
||||||
|
JsonObject json = pageOutput.GetResponse(Oms, context);
|
||||||
|
|
||||||
|
string s_Token = context.GetGlobal<string>(Oms.GetInstance(KnownAttributeGuids.Text.Token));
|
||||||
|
Assert.That(s_Token, Is.Not.Empty);
|
||||||
|
|
||||||
|
Assert.That(json["result"].GetValue<string>(), Is.EqualTo("success"));
|
||||||
|
Assert.That(json["type"].GetValue<string>(), Is.EqualTo("redirect"));
|
||||||
|
Assert.That(json["destinationUrl"].GetValue<string>(), Is.EqualTo("~/d/home.htmld"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void LoginPageElementSubmitBadPassword()
|
||||||
|
{
|
||||||
|
InstanceHandle loginPage = Oms.GetInstance(KnownInstanceGuids.Pages.LoginPage);
|
||||||
|
|
||||||
|
InstanceHandle loginPageSubedit = Oms.GetInstance(new Guid("{2b7d4481-b7c2-4e26-a917-e3ff7c367a8a}"));
|
||||||
|
OmsContext context = Oms.CreateContext();
|
||||||
|
|
||||||
|
Dictionary<string, string> dict = new();
|
||||||
|
dict["{c67f305e-bd4d-4628-816b-55fb85ea1b67}"] = "superuser";
|
||||||
|
dict["{51b51be3-44fd-48f1-971f-682aee0a6132}"] = "testing";
|
||||||
|
|
||||||
|
Response pageOutput = Oms.ProcessElement(context, loginPageSubedit, dict);
|
||||||
|
|
||||||
|
object i_User = context.GetWorkData(Oms.GetInstance(KnownInstanceGuids.Classes.User));
|
||||||
|
Assert.That(i_User, Is.Null);
|
||||||
|
|
||||||
|
JsonObject json = pageOutput.GetResponse(Oms, context);
|
||||||
|
|
||||||
|
// ??? should this return a result=failure?
|
||||||
|
Assert.That(json["result"].GetValue<string>(), Is.EqualTo("success"));
|
||||||
|
Assert.That(json["type"].GetValue<string>(), Is.EqualTo("redirect"));
|
||||||
|
Assert.That(json["destinationUrl"].GetValue<string>(), Does.StartWith("~/d/logout.htmld"));
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user