Compare commits

...

12 Commits

Author SHA1 Message Date
b8401520ff update mocha-common 2025-10-27 19:57:54 -04:00
0e40deb35b don't reinvent the wheel; move attribute validation logic from Oms to AttributeImplementation 2025-10-26 09:43:38 -04:00
3a96529a21 improve strongly typed validations for Work Set and other Work Data 2025-10-26 09:26:09 -04:00
79d86a933c preliminary implementation of inheritable method binding definitions and properly choosing the appropriate implementing method 2025-10-26 00:03:43 -04:00
2b4b8b8408 improvements to dynamic code generation and interface modeling 2025-10-25 14:14:44 -04:00
9cda89829c improvements to OMS method builder and tests 2025-10-22 20:06:47 -04:00
d555ac984f move parameter assignment logic into separate function 2025-10-22 14:37:48 -04:00
2bd8ad8b0e refactor method binding base and assign parameter assignments 2025-10-22 14:37:03 -04:00
d15f7066e5 refactor out class implementation registry into separate class 2025-10-21 14:10:21 -04:00
9eebbef630 refactor MethodImplementations as subclass of ClassImplementation 2025-10-21 11:26:37 -04:00
6e99d815eb move attribute conversion and handling code into separate AttributeImplementation class for ease of adding new attribute types 2025-10-21 08:43:07 -04:00
c97b8b0b1f add user info to returned JSON (placeholder for now) 2025-10-21 08:42:29 -04:00
58 changed files with 1450 additions and 357 deletions

@ -1 +1 @@
Subproject commit 5a411ddf69be2a2f32c601fe57004e839e3805c0 Subproject commit 4581cd44fa4c70c8b596cc50d056152b7498a6d9

View File

@ -0,0 +1,74 @@
// Copyright (C) 2025 Michael Becker <alcexhim@gmail.com>
//
// This file is part of Mocha.NET.
//
// Mocha.NET is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mocha.NET is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
using System.Text.Json.Nodes;
namespace Mocha.Core;
public abstract class AttributeImplementation<T> : AttributeImplementation
{
public T ConvertFrom(Oms oms, object? value, T defaultValue = default(T))
{
object? converted = ConvertFromInternal(oms, value);
if (converted is T)
{
return (T)converted;
}
return defaultValue;
}
protected override IEnumerable<Type>? ValidDataTypes => [ typeof(T) ];
}
public abstract class AttributeImplementation : ClassImplementation
{
protected virtual IEnumerable<Type>? ValidDataTypes { get; }
protected abstract object? ConvertFromInternal(Oms oms, object? value);
public object? ReadDerivedData(BinaryReader br)
{
return ReadDerivedDataInternal(br);
}
protected abstract object? ReadDerivedDataInternal(BinaryReader br);
protected abstract object? ExecuteBuildAttributeMethodInternal(Oms oms, OmsContext context, InstanceHandle method);
public object? ExecuteBuildAttributeMethod(Oms oms, OmsContext context, InstanceHandle method)
{
return ExecuteBuildAttributeMethodInternal(oms, context, method);
}
protected abstract void ExecuteBuildElementInternal(Oms oms, InstanceHandle targetInstance, InstanceHandle elementContent, InstanceHandle elementContentInstance, JsonObject objCell);
public void ExecuteBuildElement(Oms oms, InstanceHandle targetInstance, InstanceHandle elementContent, InstanceHandle elementContentInstance, JsonObject objCell)
{
ExecuteBuildElementInternal(oms, targetInstance, elementContent, elementContentInstance, objCell);
}
protected virtual void ValidateInternal(Oms oms, InstanceHandle attributeInstance, object value)
{
// do nothing by default
}
public void Validate(Oms oms, InstanceHandle attributeInstance, object value)
{
if (ValidDataTypes != null)
{
if (value != null && !ValidDataTypes.Contains(value.GetType()))
{
throw new ArgumentException(String.Format("value {0} cannot be converted to attribute type `{1}`", value is string ? "\"" + value.ToString() + "\"" : value, oms.GetInstanceText(attributeInstance)));
}
}
ValidateInternal(oms, attributeInstance, value);
}
}

View File

@ -0,0 +1,57 @@
// Copyright (C) 2025 Michael Becker <alcexhim@gmail.com>
//
// This file is part of Mocha.NET.
//
// Mocha.NET is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mocha.NET is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
using System.Text.Json.Nodes;
namespace Mocha.Core.AttributeImplementations;
public class BooleanAttributeImplementation : AttributeImplementation<bool>
{
public override Guid ClassGuid => KnownInstanceGuids.Classes.BooleanAttribute;
protected override object? ConvertFromInternal(Oms oms, object? value)
{
if (value is string)
{
return Boolean.Parse((string)value);
}
return value;
}
protected override object? ReadDerivedDataInternal(BinaryReader br)
{
throw new NotImplementedException();
}
protected override object? ExecuteBuildAttributeMethodInternal(Oms oms, OmsContext context, InstanceHandle method)
{
object? value = oms.UnsafeGetAttributeValue(method, oms.GetInstance(KnownAttributeGuids.Text.Value)); // initial value
if (value is string)
{
bool val = Boolean.Parse((string)value);
return val;
}
return null;
}
protected override void ExecuteBuildElementInternal(Oms oms, InstanceHandle targetInstance, InstanceHandle elementContent, InstanceHandle elementContentInstance, JsonObject objCell)
{
objCell.Add("widget", "checkBox");
objCell.Add("value", oms.GetAttributeValue<bool>(targetInstance, elementContentInstance));
objCell.Add("text", oms.GetAttributeValue<bool>(targetInstance, elementContentInstance) ? "Yes" : "No");
}
}

View File

@ -0,0 +1,64 @@
// Copyright (C) 2025 Michael Becker <alcexhim@gmail.com>
//
// This file is part of Mocha.NET.
//
// Mocha.NET is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mocha.NET is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
using System.Text.Json.Nodes;
namespace Mocha.Core.AttributeImplementations;
public class DateAttributeImplementation : AttributeImplementation<DateTime>
{
public override Guid ClassGuid => KnownInstanceGuids.Classes.DateAttribute;
protected override object? ConvertFromInternal(Oms oms, object? value)
{
if (value is string)
{
return Boolean.Parse((string)value);
}
return value;
}
protected override object? ReadDerivedDataInternal(BinaryReader br)
{
throw new NotImplementedException();
}
protected override object? ExecuteBuildAttributeMethodInternal(Oms oms, OmsContext context, InstanceHandle method)
{
object? value = oms.UnsafeGetAttributeValue(method, oms.GetInstance(KnownAttributeGuids.Text.Value)); // initial value
if (value is string)
{
DateTime val = DateTime.Parse((string)value);
return val;
}
return null;
}
protected override void ExecuteBuildElementInternal(Oms oms, InstanceHandle targetInstance, InstanceHandle elementContent, InstanceHandle elementContentInstance, JsonObject objCell)
{
objCell.Add("widget", "date");
DateTime dt = oms.GetAttributeValue<DateTime>(targetInstance, elementContentInstance);
JsonObject objDate = new JsonObject();
objDate.Add("Y", dt.Year.ToString());
objDate.Add("M", dt.Month.ToString().PadLeft(2, '0'));
objDate.Add("D", dt.Day.ToString().PadLeft(2, '0'));
objCell.Add("value", objDate);
objCell.Add("text", dt.ToString());
objCell.Add("dateTimePrecision", "DAY");
}
}

View File

@ -0,0 +1,75 @@
// Copyright (C) 2025 Michael Becker <alcexhim@gmail.com>
//
// This file is part of Mocha.NET.
//
// Mocha.NET is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mocha.NET is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
using System.Text.Json.Nodes;
namespace Mocha.Core.AttributeImplementations;
public class NumericAttributeImplementation : AttributeImplementation<decimal>
{
public override Guid ClassGuid => KnownInstanceGuids.Classes.NumericAttribute;
protected override object? ConvertFromInternal(Oms oms, object? value)
{
if (value is string)
{
return Boolean.Parse((string)value);
}
return value;
}
protected override object? ReadDerivedDataInternal(BinaryReader br)
{
throw new NotImplementedException();
}
protected override object? ExecuteBuildAttributeMethodInternal(Oms oms, OmsContext context, InstanceHandle method)
{
object? value = oms.UnsafeGetAttributeValue(method, oms.GetInstance(KnownAttributeGuids.Numeric.Value)); // initial value
if (value is decimal)
{
return value;
}
return null;
}
protected override void ExecuteBuildElementInternal(Oms oms, InstanceHandle targetInstance, InstanceHandle elementContent, InstanceHandle elementContentInstance, JsonObject objCell)
{
objCell.Add("widget", "number");
objCell.Add("value", oms.GetAttributeValue<decimal>(targetInstance, elementContentInstance));
objCell.Add("text", oms.GetAttributeValue<decimal>(targetInstance, elementContentInstance).ToString());
objCell.Add("precision", 6);
objCell.Add("format", "#0.######");
}
protected override void ValidateInternal(Oms oms, InstanceHandle attributeInstance, object value)
{
if (oms.TryGetAttributeValue(attributeInstance, oms.GetInstance(KnownAttributeGuids.Numeric.MinimumValue), out decimal minimumValue))
{
if (((decimal)value) < minimumValue)
{
throw new ArgumentOutOfRangeException(String.Format("value for NumericAttribute must be greater than {0}", minimumValue - 1));
}
}
if (oms.TryGetAttributeValue(attributeInstance, oms.GetInstance(KnownAttributeGuids.Numeric.MaximumValue), out decimal maximumValue))
{
if (((decimal)value) > maximumValue)
{
throw new ArgumentOutOfRangeException(String.Format("value for NumericAttribute must be greater than {0}", maximumValue - 1));
}
}
}
}

View File

@ -0,0 +1,102 @@
// Copyright (C) 2025 Michael Becker <alcexhim@gmail.com>
//
// This file is part of Mocha.NET.
//
// Mocha.NET is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mocha.NET is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
using System.Text.Json.Nodes;
namespace Mocha.Core.AttributeImplementations;
public class TextAttributeImplementation : AttributeImplementation<string>
{
public override Guid ClassGuid => KnownInstanceGuids.Classes.TextAttribute;
protected override object? ConvertFromInternal(Oms oms, object? value)
{
return (string)value; //! ???
}
protected override object? ReadDerivedDataInternal(BinaryReader br)
{
int length = br.ReadInt32();
string value = br.ReadString();
return value;
}
protected override object? ExecuteBuildAttributeMethodInternal(Oms oms, OmsContext context, InstanceHandle method)
{
object? value = oms.UnsafeGetAttributeValue(method, oms.GetInstance(KnownAttributeGuids.Text.Value)); // initial value
if (value is string)
{
IEnumerable<InstanceHandle> buildsWithRambs = oms.GetRelatedInstances(method, oms.GetInstance(KnownRelationshipGuids.Build_Attribute_Method__builds_with__Build_Attribute_Method_Component));
foreach (InstanceHandle ihComponent in buildsWithRambs)
{
InstanceHandle ihRamb = oms.GetRelatedInstance(ihComponent, oms.GetInstance(KnownRelationshipGuids.Build_Attribute_Method_Component__uses__Executable_returning_Attribute));
object? val = null;
if (oms.IsInstanceOf(ihRamb, oms.GetInstance(KnownInstanceGuids.Classes.Attribute)))
{
val = null;
}
else if (oms.IsInstanceOf(ihRamb, oms.GetInstance(KnownInstanceGuids.Classes.Executable)))
{
InstanceHandle wd = oms.Execute(context, ihRamb);
val = context.GetWorkData(wd);
}
if (val is string)
{
value = ((string)value) + (string)val;
}
}
return value;
}
return null;
}
protected override void ExecuteBuildElementInternal(Oms oms, InstanceHandle targetInstance, InstanceHandle elementContent, InstanceHandle elementContentInstance, JsonObject objCell)
{
objCell.Add("widget", "text");
if (targetInstance == InstanceHandle.Empty)
{
objCell.Add("value", oms.GetAttributeValue<string>(elementContentInstance, oms.GetInstance(KnownAttributeGuids.Text.Value)));
}
else
{
objCell.Add("value", oms.GetAttributeValue<string>(targetInstance, elementContentInstance));
}
}
protected override void ValidateInternal(Oms oms, InstanceHandle attributeInstance, object value)
{
if (!(value is string))
{
throw new ArgumentException("value for TextAttribute must be System.String");
}
if (oms.TryGetAttributeValue(attributeInstance, oms.GetInstance(KnownAttributeGuids.Numeric.MinimumLength), out decimal minimumLength))
{
if (((string)value).Length < minimumLength)
{
throw new ArgumentOutOfRangeException(String.Format("value for TextAttribute must be greater than {0} characters", minimumLength - 1));
}
}
if (oms.TryGetAttributeValue(attributeInstance, oms.GetInstance(KnownAttributeGuids.Numeric.MaximumLength), out decimal maximumLength))
{
if (((string)value).Length > maximumLength)
{
throw new ArgumentOutOfRangeException(String.Format("value for TextAttribute must be less than {0} characters", maximumLength + 1));
}
}
}
}

View File

@ -15,7 +15,7 @@
// 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 Mocha.NET. If not, see <https://www.gnu.org/licenses/>. // along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
namespace Mocha.Core; namespace Mocha.Core;
public struct AttributeValue public struct AttributeValue
{ {

View File

@ -0,0 +1,24 @@
// Copyright (C) 2025 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;
public abstract class ClassImplementation
{
public abstract Guid ClassGuid { get; }
}

View File

@ -0,0 +1,84 @@
// Copyright (C) 2025 Michael Becker <alcexhim@gmail.com>
//
// This file is part of Mocha.NET.
//
// Mocha.NET is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Mocha.NET is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
using Mocha.Core.Oop;
namespace Mocha.Core;
public class ClassImplementationRegistry
{
private Dictionary<Guid, ClassImplementation> implementations = new Dictionary<Guid, ClassImplementation>();
public void Register<T>(Guid methodClassId, T implementation) where T : ClassImplementation
{
implementations[methodClassId] = implementation;
}
public bool Contains(Guid classGuid)
{
return implementations.ContainsKey(classGuid);
}
public bool Contains<T>(Guid classGuid) where T : ClassImplementation
{
if (implementations.ContainsKey(classGuid))
{
if (implementations[classGuid] is T)
{
return true;
}
}
return false;
}
public T Get<T>(Guid classGuid) where T : ClassImplementation
{
if (implementations.ContainsKey(classGuid))
{
if (implementations[classGuid] is T obj)
{
return obj;
}
}
throw new NotImplementedException(String.Format("implementation for class {0} not found or incorrect type", classGuid));
}
public bool TryGet<T>(Guid classGuid, out T? implementation) where T : ClassImplementation
{
if (implementations.ContainsKey(classGuid))
{
if (implementations[classGuid] is T obj)
{
implementation = obj;
return true;
}
}
implementation = null;
return false;
}
public IEnumerable<T> GetAll<T>() where T : ClassImplementation
{
List<T> list = new List<T>();
foreach (KeyValuePair<Guid, ClassImplementation> kvp in implementations)
{
if (kvp.Value is T)
{
list.Add((T)kvp.Value);
}
}
return list;
}
}

View File

@ -203,15 +203,15 @@ namespace Mocha.Core
IEnumerable<InstanceHandle> attributes = oms.GetRelatedInstances(_parentClassInstance, oms.GetInstance(KnownRelationshipGuids.Class__has__Attribute)); IEnumerable<InstanceHandle> attributes = oms.GetRelatedInstances(_parentClassInstance, oms.GetInstance(KnownRelationshipGuids.Class__has__Attribute));
foreach (InstanceHandle att in attributes) foreach (InstanceHandle att in attributes)
{ {
if (oms.IsInstanceOf(att, oms.GetInstance(KnownInstanceGuids.Classes.TextAttribute))) AttributeImplementation? impl = oms.GetAttributeImplementation(att);
if (impl != null)
{ {
if (br.BaseStream.EndOfStream()) if (br.BaseStream.EndOfStream())
{ {
break; break;
} }
int length = br.ReadInt32(); object? value = impl.ReadDerivedData(br);
string value = br.ReadString();
derivedData[att] = value; derivedData[att] = value;
} }
} }

View File

@ -28,6 +28,7 @@ namespace Mocha.Core
public static Guid CSSValue { get; } = new Guid("{C0DD4A42-F503-4EB3-8034-7C428B1B8803}"); public static Guid CSSValue { get; } = new Guid("{C0DD4A42-F503-4EB3-8034-7C428B1B8803}");
public static Guid RelationshipType { get; } = new Guid("{71106B12-1934-4834-B0F6-D894637BAEED}"); public static Guid RelationshipType { get; } = new Guid("{71106B12-1934-4834-B0F6-D894637BAEED}");
public static Guid Order { get; } = new Guid("{49423f66-8837-430d-8cac-7892ebdcb1fe}"); public static Guid Order { get; } = new Guid("{49423f66-8837-430d-8cac-7892ebdcb1fe}");
public static Guid HelpText { get; } = new Guid("{edfe6493-0adf-4d49-9f19-babbe9a99acf}");
public static Guid TargetURL { get; } = new Guid("{970F79A0-9EFE-4E7D-9286-9908C6F06A67}"); public static Guid TargetURL { get; } = new Guid("{970F79A0-9EFE-4E7D-9286-9908C6F06A67}");
public static Guid ReferralURL { get; } = new Guid("{6daaa721-db70-43ad-b373-6a8038e69d2e}"); public static Guid ReferralURL { get; } = new Guid("{6daaa721-db70-43ad-b373-6a8038e69d2e}");
@ -49,6 +50,8 @@ namespace Mocha.Core
} }
public static class Boolean public static class Boolean
{ {
// {989b5a95-d5bb-470c-b067-487316d22da2}
public static Guid Abstract { get; } = new Guid("{868d682b-f77b-4ed4-85a9-337f338635c1}");
public static Guid EvaluateWorkSet { get; } = new Guid("{62c28f9e-5ce8-4ce5-8a56-1e80f1af7f6a}"); public static Guid EvaluateWorkSet { get; } = new Guid("{62c28f9e-5ce8-4ce5-8a56-1e80f1af7f6a}");
public static Guid MethodIsOfTypeSpecified { get; } = new Guid("{6e9df667-0f95-4320-a4be-5cdb00f1d4ee}"); public static Guid MethodIsOfTypeSpecified { get; } = new Guid("{6e9df667-0f95-4320-a4be-5cdb00f1d4ee}");
public static Guid DisplayVersionInBadge { get; } = new Guid("{BE5966A4-C4CA-49A6-B504-B6E8759F392D}"); public static Guid DisplayVersionInBadge { get; } = new Guid("{BE5966A4-C4CA-49A6-B504-B6E8759F392D}");
@ -63,6 +66,7 @@ namespace Mocha.Core
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 Guid Derived { get; } = new Guid("{66991ca1-ef08-4f30-846c-4984c2a3139d}");
public static Guid IncludeSubclasses { get; } = new Guid("{bc95f90e-d373-48be-b71e-283695afed5a}");
} }
public static class Numeric public static class Numeric
{ {
@ -84,5 +88,9 @@ namespace Mocha.Core
public static Guid SecondaryOperandValue { get; } = new Guid("{253a04bb-feb7-474d-b608-43219a753ef8}"); // {e666aa75-6b53-47ea-9afa-369378e17b5d} public static Guid SecondaryOperandValue { get; } = new Guid("{253a04bb-feb7-474d-b608-43219a753ef8}"); // {e666aa75-6b53-47ea-9afa-369378e17b5d}
} }
public static class Date
{
public static Guid DateAndTime { get; } = new Guid("{ea71cc92-a5e9-49c1-b487-8ad178b557d2}");
}
} }
} }

View File

@ -84,6 +84,8 @@ namespace Mocha.Core
public static Guid ReturnInstanceSetMethodBinding { get; } = new Guid("{AADC20F9-7559-429B-AEF0-97E059295C76}"); public static Guid ReturnInstanceSetMethodBinding { get; } = new Guid("{AADC20F9-7559-429B-AEF0-97E059295C76}");
public static Guid ReturnElementMethodBinding { get; } = new Guid("{f8944cc1-1306-4c60-8079-93448ca01fd0}"); public static Guid ReturnElementMethodBinding { get; } = new Guid("{f8944cc1-1306-4c60-8079-93448ca01fd0}");
public static Guid BuildResponseMethodBinding { get; } = new Guid("{b457f34f-1f54-4cda-be03-2da48ec747ab}"); public static Guid BuildResponseMethodBinding { get; } = new Guid("{b457f34f-1f54-4cda-be03-2da48ec747ab}");
public static Guid ExecuteUpdateMethodBinding { get; } = new Guid("{b831bdaf-72d8-4585-a9a8-8341ab1005cb}");
public static Guid ProcessUpdatesMethodBinding { get; } = new Guid("{a7eb8676-2e47-4981-96a7-f20158660d26}");
public static Guid Executable { get; } = new Guid("{6A1F66F7-8EA6-43D1-B2AF-198F63B84710}"); public static Guid Executable { get; } = new Guid("{6A1F66F7-8EA6-43D1-B2AF-198F63B84710}");
public static Guid ExecutableReturningAttribute { get; } = new Guid("{50b2db7a-3623-4be4-b40d-98fab89d3ff5}"); public static Guid ExecutableReturningAttribute { get; } = new Guid("{50b2db7a-3623-4be4-b40d-98fab89d3ff5}");
@ -194,6 +196,7 @@ namespace Mocha.Core
public static Guid RouteTable { get; } = new Guid("{76e5ce90-5f64-4355-a0ee-f659cf615a63}"); public static Guid RouteTable { get; } = new Guid("{76e5ce90-5f64-4355-a0ee-f659cf615a63}");
public static Guid Domain { get; } = new Guid("{49bbe159-0901-4788-b683-fd8f6d41b222}"); public static Guid Domain { get; } = new Guid("{49bbe159-0901-4788-b683-fd8f6d41b222}");
public static Guid PUMProcess { get; } = new Guid("{2cdb2169-7c26-4adb-bc26-e9e75ab1b246}");
} }
public static class Methods public static class Methods
{ {

View File

@ -114,6 +114,8 @@ namespace Mocha.Core
public static Guid Method_Binding__executes__Method { get; } = new Guid("{B782A592-8AF5-4228-8296-E3D0B24C70A8}"); public static Guid Method_Binding__executes__Method { get; } = new Guid("{B782A592-8AF5-4228-8296-E3D0B24C70A8}");
public static Guid Method__has_return_type__Class { get; } = new Guid("{1241c599-e55d-4dcf-9200-d0e48c217ef8}"); public static Guid Method__has_return_type__Class { get; } = new Guid("{1241c599-e55d-4dcf-9200-d0e48c217ef8}");
public static Guid Method__implements__Method { get; } = new Guid("{83c992d7-03ec-483f-b6f1-225083f201e3}");
public static Guid Method__implemented_by__Method { get; } = new Guid("{f19e7779-a6b6-4914-a5cc-3c48fa1c9491}");
public static Guid Method_Binding__has__Parameter_Assignment { get; } = new Guid("{24938109-94f1-463a-9314-c49e667cf45b}"); public static Guid Method_Binding__has__Parameter_Assignment { get; } = new Guid("{24938109-94f1-463a-9314-c49e667cf45b}");
public static Guid Parameter_Assignment__for__Method_Binding { get; } = new Guid("{19c4a5db-fd26-44b8-b431-e081e6ffff8a}"); public static Guid Parameter_Assignment__for__Method_Binding { get; } = new Guid("{19c4a5db-fd26-44b8-b431-e081e6ffff8a}");
@ -481,5 +483,6 @@ namespace Mocha.Core
public static Guid Invoke_Web_Service_Method__uses__Executable_returning_Element { get; } = new Guid("{020e26ba-565d-47a4-bdcc-f0050ff6b848}"); public static Guid Invoke_Web_Service_Method__uses__Executable_returning_Element { get; } = new Guid("{020e26ba-565d-47a4-bdcc-f0050ff6b848}");
public static Guid Invoke_Web_Service_Method__correlated_instances_from__Executable_returning_Instance_Set { get; } = new Guid("{8f1406b4-f48f-45fb-a6ef-2ad51998735f}"); public static Guid Invoke_Web_Service_Method__correlated_instances_from__Executable_returning_Instance_Set { get; } = new Guid("{8f1406b4-f48f-45fb-a6ef-2ad51998735f}");
public static Guid Invoke_Web_Service_Method__has_error__Executable_returning_Element { get; } = new Guid("{86aa5338-d913-4044-af8d-7aa4e1a9ddbc}"); public static Guid Invoke_Web_Service_Method__has_error__Executable_returning_Element { get; } = new Guid("{86aa5338-d913-4044-af8d-7aa4e1a9ddbc}");
}
}
} }

View File

@ -17,10 +17,8 @@
namespace Mocha.Core; namespace Mocha.Core;
public abstract class MethodImplementation public abstract class MethodImplementation : ClassImplementation
{ {
public abstract Guid MethodClassGuid { get; }
protected abstract InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method); protected abstract InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method);
public InstanceHandle Execute(Oms oms, OmsContext context, InstanceHandle method) public InstanceHandle Execute(Oms oms, OmsContext context, InstanceHandle method)
{ {

View File

@ -19,7 +19,7 @@ namespace Mocha.Core.MethodImplementations;
public class AssignAttributeMethodImplementation : MethodImplementation public class AssignAttributeMethodImplementation : MethodImplementation
{ {
public override Guid MethodClassGuid => KnownInstanceGuids.MethodClasses.AssignAttributeMethod; public override Guid ClassGuid => KnownInstanceGuids.MethodClasses.AssignAttributeMethod;
protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method) protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method)
{ {
InstanceHandle irForClass = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Method__for__Class)); InstanceHandle irForClass = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Method__for__Class));

View File

@ -19,7 +19,7 @@ namespace Mocha.Core.MethodImplementations;
public class BuildAttributeMethodImplementation : MethodImplementation public class BuildAttributeMethodImplementation : MethodImplementation
{ {
public override Guid MethodClassGuid => KnownInstanceGuids.MethodClasses.BuildAttributeMethod; public override Guid ClassGuid => KnownInstanceGuids.MethodClasses.BuildAttributeMethod;
protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method) protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method)
{ {
InstanceHandle irForClass = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Method__for__Class)); InstanceHandle irForClass = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Method__for__Class));
@ -32,59 +32,12 @@ public class BuildAttributeMethodImplementation : MethodImplementation
// InstanceHandle forInstance = (InstanceHandle) context.GetWorkData(irForClass); // InstanceHandle forInstance = (InstanceHandle) context.GetWorkData(irForClass);
if (oms.IsInstanceOf(returnsAttribute, oms.GetInstance(KnownInstanceGuids.Classes.TextAttribute))) AttributeImplementation impl = oms.GetAttributeImplementation(returnsAttribute);
object? value = impl.ExecuteBuildAttributeMethod(oms, context, method);
if (value != null)
{ {
object? value = oms.UnsafeGetAttributeValue(method, oms.GetInstance(KnownAttributeGuids.Text.Value)); // initial value
if (value is string)
{
IEnumerable<InstanceHandle> buildsWithRambs = oms.GetRelatedInstances(method, oms.GetInstance(KnownRelationshipGuids.Build_Attribute_Method__builds_with__Build_Attribute_Method_Component));
foreach (InstanceHandle ihComponent in buildsWithRambs)
{
InstanceHandle ihRamb = oms.GetRelatedInstance(ihComponent, oms.GetInstance(KnownRelationshipGuids.Build_Attribute_Method_Component__uses__Executable_returning_Attribute));
object? val = null;
if (oms.IsInstanceOf(ihRamb, oms.GetInstance(KnownInstanceGuids.Classes.Attribute)))
{
val = null;
}
else if (oms.IsInstanceOf(ihRamb, oms.GetInstance(KnownInstanceGuids.Classes.Executable)))
{
InstanceHandle wd = oms.Execute(context, ihRamb);
val = context.GetWorkData(wd);
}
if (val is string)
{
value = ((string)value) + (string)val;
}
}
}
context.SetWorkData(returnsAttribute, value); context.SetWorkData(returnsAttribute, value);
} }
else if (oms.IsInstanceOf(returnsAttribute, oms.GetInstance(KnownInstanceGuids.Classes.BooleanAttribute)))
{
object? value = oms.UnsafeGetAttributeValue(method, oms.GetInstance(KnownAttributeGuids.Text.Value)); // initial value
if (value is string)
{
bool val = Boolean.Parse((string)value);
context.SetWorkData(returnsAttribute, val);
}
}
else if (oms.IsInstanceOf(returnsAttribute, oms.GetInstance(KnownInstanceGuids.Classes.NumericAttribute)))
{
object? value = oms.UnsafeGetAttributeValue(method, oms.GetInstance(KnownAttributeGuids.Numeric.Value)); // initial value
if (value is decimal)
{
context.SetWorkData(returnsAttribute, value);
}
}
else
{
throw new NotImplementedException();
}
return returnsAttribute; return returnsAttribute;
} }

View File

@ -6,7 +6,7 @@ namespace Mocha.Core.MethodImplementations;
public class BuildElementMethodImplementation : MethodImplementation public class BuildElementMethodImplementation : MethodImplementation
{ {
public override Guid MethodClassGuid => KnownInstanceGuids.MethodClasses.BuildElementMethod; public override Guid ClassGuid => KnownInstanceGuids.MethodClasses.BuildElementMethod;
protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method) protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method)
{ {
@ -138,46 +138,17 @@ public class BuildElementMethodImplementation : MethodImplementation
{ {
objCell.Add("enabled", false); objCell.Add("enabled", false);
} }
// objCell.Add("helpText", "blah blah");
if (oms.IsInstanceOf(ecInst, oms.GetInstance(KnownInstanceGuids.Classes.TextAttribute))) string? helpText = oms.GetAttributeValue<string>(elementContent, oms.GetInstance(KnownAttributeGuids.Text.HelpText));
if (helpText != null)
{ {
objCell.Add("widget", "text"); objCell.Add("helpText", helpText);
if (targetInstance == InstanceHandle.Empty)
{
objCell.Add("value", oms.GetAttributeValue<string>(ecInst, oms.GetInstance(KnownAttributeGuids.Text.Value)));
}
else
{
objCell.Add("value", oms.GetAttributeValue<string>(targetInstance, ecInst));
}
} }
else if (oms.IsInstanceOf(ecInst, oms.GetInstance(KnownInstanceGuids.Classes.BooleanAttribute)))
{
objCell.Add("widget", "checkBox");
objCell.Add("value", oms.GetAttributeValue<bool>(targetInstance, ecInst));
objCell.Add("text", oms.GetAttributeValue<bool>(targetInstance, ecInst) ? "Yes" : "No");
}
else if (oms.IsInstanceOf(ecInst, oms.GetInstance(KnownInstanceGuids.Classes.NumericAttribute)))
{
objCell.Add("widget", "number");
objCell.Add("value", oms.GetAttributeValue<decimal>(targetInstance, ecInst));
objCell.Add("text", oms.GetAttributeValue<decimal>(targetInstance, ecInst).ToString());
objCell.Add("precision", 6);
objCell.Add("format", "#0.######");
}
else if (oms.IsInstanceOf(ecInst, oms.GetInstance(KnownInstanceGuids.Classes.DateAttribute)))
{
objCell.Add("widget", "date");
DateTime dt = oms.GetAttributeValue<DateTime>(targetInstance, ecInst); if (oms.IsInstanceOf(ecInst, oms.GetInstance(KnownInstanceGuids.Classes.Attribute)))
JsonObject objDate = new JsonObject(); {
objDate.Add("Y", dt.Year.ToString()); AttributeImplementation impl = oms.GetAttributeImplementation(ecInst);
objDate.Add("M", dt.Month.ToString().PadLeft(2, '0')); impl.ExecuteBuildElement(oms, targetInstance, elementContent, ecInst, objCell);
objDate.Add("D", dt.Day.ToString().PadLeft(2, '0'));
objCell.Add("value", objDate);
objCell.Add("text", dt.ToString());
objCell.Add("dateTimePrecision", "DAY");
} }
else else
{ {

View File

@ -21,7 +21,7 @@ namespace Mocha.Core.MethodImplementations;
public class BuildUIResponseMethodImplementation : MethodImplementation public class BuildUIResponseMethodImplementation : MethodImplementation
{ {
public override Guid MethodClassGuid => KnownInstanceGuids.MethodClasses.BuildUIResponseMethod; public override Guid ClassGuid => KnownInstanceGuids.MethodClasses.BuildUIResponseMethod;
protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method) protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method)
{ {
InstanceHandle irForClass = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Method__for__Class)); InstanceHandle irForClass = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Method__for__Class));
@ -39,6 +39,7 @@ public class BuildUIResponseMethodImplementation : MethodImplementation
JsonObject objRoot = new JsonObject(); JsonObject objRoot = new JsonObject();
objRoot.Add("widget", "root"); objRoot.Add("widget", "root");
objRoot.Add("body", objChild); objRoot.Add("body", objChild);
objRoot.Add("currentUser", CreateUserInfo(oms, oms.GetInstancesOf(oms.GetInstance(KnownInstanceGuids.Classes.User)).First()));
JsonObject objTitle = new JsonObject(); JsonObject objTitle = new JsonObject();
// task like 2501$6 (View Organization) has EC which has display option `Display as Page Title`, in which // task like 2501$6 (View Organization) has EC which has display option `Display as Page Title`, in which
@ -61,6 +62,30 @@ public class BuildUIResponseMethodImplementation : MethodImplementation
return element; return element;
} }
private JsonNode? CreateUserInfo(Oms oms, InstanceHandle userInstance)
{
JsonObject objUser = new JsonObject();
objUser.Add("widget", "currentUser");
objUser.Add("iid", oms.GetInstanceKey(userInstance).ToString());
objUser.Add("label", oms.GetInstanceText(userInstance));
JsonObject objLink = new JsonObject();
objLink.Add("widget", "link");
objLink.Add("rel", "related-tasks");
objLink.Add("uri", String.Format("/{0}/inst/{1}/rel-tasks", oms.GetTenantName(oms.CurrentTenant), oms.GetInstanceKey(userInstance).ToString()));
objLink.Add("pv", true);
objLink.Add("rt", true);
objUser.Add("relatedTasksLink", objLink);
objLink = new JsonObject();
objLink.Add("widget", "link");
objLink.Add("rel", "self");
objLink.Add("uri", String.Format("/{0}/inst/{1}/{2}", oms.GetTenantName(oms.CurrentTenant), "1$37", oms.GetInstanceKey(userInstance).ToString()));
objLink.Add("v", true);
objUser.Add("selfLink", objLink);
return objUser;
}
private JsonObject CreateMoniker(Oms oms, InstanceHandle inst) private JsonObject CreateMoniker(Oms oms, InstanceHandle inst)
{ {
JsonObject obj = new JsonObject(); JsonObject obj = new JsonObject();

View File

@ -23,7 +23,7 @@ namespace Mocha.Core.MethodImplementations;
public class CalculateNumericMethodImplementation : MethodImplementation public class CalculateNumericMethodImplementation : MethodImplementation
{ {
public override Guid MethodClassGuid => KnownInstanceGuids.MethodClasses.CalculateNumericMethod; public override Guid ClassGuid => KnownInstanceGuids.MethodClasses.CalculateNumericMethod;
protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method) protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method)
{ {
InstanceHandle irForClass = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Method__for__Class)); InstanceHandle irForClass = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Method__for__Class));

View File

@ -20,7 +20,7 @@ namespace Mocha.Core.MethodImplementations;
public class ConditionalSelectAttributeMethodImplementation : MethodImplementation public class ConditionalSelectAttributeMethodImplementation : MethodImplementation
{ {
public override Guid MethodClassGuid => KnownInstanceGuids.MethodClasses.ConditionalSelectAttributeMethod; public override Guid ClassGuid => KnownInstanceGuids.MethodClasses.ConditionalSelectAttributeMethod;
protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method) protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method)
{ {

View File

@ -20,7 +20,7 @@ namespace Mocha.Core.MethodImplementations;
public class ConditionalSelectFromInstanceSetMethodImplementation : MethodImplementation public class ConditionalSelectFromInstanceSetMethodImplementation : MethodImplementation
{ {
public override Guid MethodClassGuid => KnownInstanceGuids.MethodClasses.ConditionalSelectFromInstanceSetMethod; public override Guid ClassGuid => KnownInstanceGuids.MethodClasses.ConditionalSelectFromInstanceSetMethod;
protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method) protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method)
{ {

View File

@ -23,7 +23,7 @@ namespace Mocha.Core.MethodImplementations;
public class EvaluateBooleanExpressionMethodImplementation : MethodImplementation public class EvaluateBooleanExpressionMethodImplementation : MethodImplementation
{ {
public override Guid MethodClassGuid => KnownInstanceGuids.MethodClasses.EvaluateBooleanExpressionMethod; public override Guid ClassGuid => KnownInstanceGuids.MethodClasses.EvaluateBooleanExpressionMethod;
protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method) protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method)
{ {
InstanceHandle c_Class = oms.GetInstance(KnownInstanceGuids.Classes.Class); InstanceHandle c_Class = oms.GetInstance(KnownInstanceGuids.Classes.Class);

View File

@ -19,7 +19,7 @@ namespace Mocha.Core.MethodImplementations;
public class GetAttributeBySystemRoutineMethodImplementation : MethodImplementation public class GetAttributeBySystemRoutineMethodImplementation : MethodImplementation
{ {
public override Guid MethodClassGuid => KnownInstanceGuids.MethodClasses.GetAttributeBySystemRoutineMethod; public override Guid ClassGuid => KnownInstanceGuids.MethodClasses.GetAttributeBySystemRoutineMethod;
protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method) protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method)
{ {
InstanceHandle irForClass = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Method__for__Class)); InstanceHandle irForClass = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Method__for__Class));

View File

@ -19,7 +19,7 @@ namespace Mocha.Core.MethodImplementations;
public class GetAttributeMethodImplementation : MethodImplementation public class GetAttributeMethodImplementation : MethodImplementation
{ {
public override Guid MethodClassGuid => KnownInstanceGuids.MethodClasses.GetAttributeMethod; public override Guid ClassGuid => KnownInstanceGuids.MethodClasses.GetAttributeMethod;
protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method) protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method)
{ {
InstanceHandle irForClass = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Method__for__Class)); InstanceHandle irForClass = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Method__for__Class));

View File

@ -19,7 +19,7 @@ namespace Mocha.Core.MethodImplementations;
public class GetInstanceSetBySystemRoutineMethodImplementation : MethodImplementation public class GetInstanceSetBySystemRoutineMethodImplementation : MethodImplementation
{ {
public override Guid MethodClassGuid => KnownInstanceGuids.MethodClasses.GetInstanceSetBySystemRoutineMethod; public override Guid ClassGuid => KnownInstanceGuids.MethodClasses.GetInstanceSetBySystemRoutineMethod;
protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method) protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method)
{ {
InstanceHandle irForClass = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Method__for__Class)); InstanceHandle irForClass = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Method__for__Class));

View File

@ -20,7 +20,7 @@ namespace Mocha.Core.MethodImplementations;
public class GetInstancesMethodImplementation : MethodImplementation public class GetInstancesMethodImplementation : MethodImplementation
{ {
public override Guid MethodClassGuid => new Guid("{0a379314-9d0f-432d-ae59-63194ab32dd3}"); public override Guid ClassGuid => new Guid("{0a379314-9d0f-432d-ae59-63194ab32dd3}");
protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method) protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method)
{ {

View File

@ -19,7 +19,7 @@ namespace Mocha.Core.MethodImplementations;
public class GetReferencedAttributeMethodImplementation : MethodImplementation public class GetReferencedAttributeMethodImplementation : MethodImplementation
{ {
public override Guid MethodClassGuid => KnownInstanceGuids.MethodClasses.GetReferencedAttributeMethod; public override Guid ClassGuid => KnownInstanceGuids.MethodClasses.GetReferencedAttributeMethod;
protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method) protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method)
{ {
Guid methodId = oms.GetGlobalIdentifier(method); Guid methodId = oms.GetGlobalIdentifier(method);

View File

@ -19,7 +19,7 @@ namespace Mocha.Core.MethodImplementations;
public class GetReferencedInstanceSetMethodImplementation : MethodImplementation public class GetReferencedInstanceSetMethodImplementation : MethodImplementation
{ {
public override Guid MethodClassGuid => KnownInstanceGuids.MethodClasses.GetReferencedInstanceSetMethod; public override Guid ClassGuid => KnownInstanceGuids.MethodClasses.GetReferencedInstanceSetMethod;
protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method) protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method)
{ {
Guid methodId = oms.GetGlobalIdentifier(method); Guid methodId = oms.GetGlobalIdentifier(method);

View File

@ -21,7 +21,7 @@ namespace Mocha.Core.MethodImplementations;
public class GetRelationshipMethodImplementation : MethodImplementation public class GetRelationshipMethodImplementation : MethodImplementation
{ {
public override Guid MethodClassGuid => KnownInstanceGuids.MethodClasses.GetRelationshipMethod; public override Guid ClassGuid => KnownInstanceGuids.MethodClasses.GetRelationshipMethod;
protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method) protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method)
{ {
Guid methodId = oms.GetGlobalIdentifier(method); Guid methodId = oms.GetGlobalIdentifier(method);

View File

@ -19,7 +19,7 @@ namespace Mocha.Core.MethodImplementations;
public class GetSpecifiedInstancesMethodImplementation : MethodImplementation public class GetSpecifiedInstancesMethodImplementation : MethodImplementation
{ {
public override Guid MethodClassGuid => KnownInstanceGuids.MethodClasses.GetSpecifiedInstancesMethod; public override Guid ClassGuid => KnownInstanceGuids.MethodClasses.GetSpecifiedInstancesMethod;
protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method) protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method)

View File

@ -19,7 +19,7 @@ namespace Mocha.Core.MethodImplementations;
public class InstanceOpMethodImplementation : MethodImplementation public class InstanceOpMethodImplementation : MethodImplementation
{ {
public override Guid MethodClassGuid => KnownInstanceGuids.MethodClasses.InstanceOpMethod; public override Guid ClassGuid => KnownInstanceGuids.MethodClasses.InstanceOpMethod;
protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method) protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method)
{ {
InstanceHandle op = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Op_Scope__invokes__Instance_Op)); InstanceHandle op = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Op_Scope__invokes__Instance_Op));

View File

@ -21,7 +21,7 @@ namespace Mocha.Core.MethodImplementations;
public class InvokeWebServiceMethodImplementation : MethodImplementation public class InvokeWebServiceMethodImplementation : MethodImplementation
{ {
public override Guid MethodClassGuid => KnownInstanceGuids.MethodClasses.InvokeWebServiceMethod; public override Guid ClassGuid => KnownInstanceGuids.MethodClasses.InvokeWebServiceMethod;
protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method) protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method)

View File

@ -19,7 +19,7 @@ namespace Mocha.Core.MethodImplementations;
public class ProcessRelatedUpdatesMethodImplementation : MethodImplementation public class ProcessRelatedUpdatesMethodImplementation : MethodImplementation
{ {
public override Guid MethodClassGuid => KnownInstanceGuids.MethodClasses.ProcessRelatedUpdatesMethod; public override Guid ClassGuid => KnownInstanceGuids.MethodClasses.ProcessRelatedUpdatesMethod;
protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method) protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method)
{ {
InstanceHandle forClass = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Method__for__Class)); InstanceHandle forClass = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Method__for__Class));

View File

@ -19,7 +19,7 @@ namespace Mocha.Core.MethodImplementations;
public class ProcessUpdatesMethodImplementation : MethodImplementation public class ProcessUpdatesMethodImplementation : MethodImplementation
{ {
public override Guid MethodClassGuid => KnownInstanceGuids.MethodClasses.ProcessUpdatesMethod; public override Guid ClassGuid => KnownInstanceGuids.MethodClasses.ProcessUpdatesMethod;
protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method) protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method)
{ {
InstanceHandle forClass = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Method__for__Class)); InstanceHandle forClass = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Method__for__Class));

View File

@ -30,7 +30,7 @@ public class SelectFromInstanceSetMethodImplementation : MethodImplementation
public T Data; public T Data;
} }
public override Guid MethodClassGuid => KnownInstanceGuids.MethodClasses.SelectFromInstanceSetMethod; public override Guid ClassGuid => KnownInstanceGuids.MethodClasses.SelectFromInstanceSetMethod;
protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method) protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method)
{ {
//! FIXME ! //! FIXME !

View File

@ -19,7 +19,7 @@ namespace Mocha.Core.MethodImplementations;
public class UpdateBySystemRoutineMethodImplementation : MethodImplementation public class UpdateBySystemRoutineMethodImplementation : MethodImplementation
{ {
public override Guid MethodClassGuid => KnownInstanceGuids.MethodClasses.UpdateBySystemRoutineMethod; public override Guid ClassGuid => KnownInstanceGuids.MethodClasses.UpdateBySystemRoutineMethod;
protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method) protected override InstanceHandle ExecuteInternal(Oms oms, OmsContext context, InstanceHandle method)
{ {
InstanceHandle irForClass = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Method__for__Class)); InstanceHandle irForClass = oms.GetRelatedInstance(method, oms.GetInstance(KnownRelationshipGuids.Method__for__Class));

View File

@ -55,7 +55,13 @@ public abstract class Oms
MethodImplementation[] methodImplementations = MBS.Core.Reflection.TypeLoader.GetAvailableTypes<MethodImplementation>(new System.Reflection.Assembly[] { Assembly.GetExecutingAssembly() }); MethodImplementation[] methodImplementations = MBS.Core.Reflection.TypeLoader.GetAvailableTypes<MethodImplementation>(new System.Reflection.Assembly[] { Assembly.GetExecutingAssembly() });
foreach (MethodImplementation impl in methodImplementations) foreach (MethodImplementation impl in methodImplementations)
{ {
RegisterMethodImplementation(impl.MethodClassGuid, impl); ClassImplementations.Register(impl.ClassGuid, impl);
}
AttributeImplementation[] attributeImplementations = MBS.Core.Reflection.TypeLoader.GetAvailableTypes<AttributeImplementation>(new System.Reflection.Assembly[] { Assembly.GetExecutingAssembly() });
foreach (AttributeImplementation impl in attributeImplementations)
{
ClassImplementations.Register(impl.ClassGuid, impl);
} }
} }
@ -902,7 +908,11 @@ public abstract class Oms
} }
} }
private void ValidateConstraintsForAttribute(InstanceHandle source, InstanceHandle attribute, object value) public void ValidateConstraintsForAttribute(InstanceHandle attribute, object value)
{
ValidateConstraintsForAttribute(InstanceHandle.Empty, attribute, value);
}
public void ValidateConstraintsForAttribute(InstanceHandle source, InstanceHandle attribute, object value)
{ {
if (!ValidateConstraints) if (!ValidateConstraints)
return; return;
@ -918,11 +928,10 @@ public abstract class Oms
InstanceHandle a_NumericAttribute = GetInstance(KnownInstanceGuids.Classes.NumericAttribute); InstanceHandle a_NumericAttribute = GetInstance(KnownInstanceGuids.Classes.NumericAttribute);
InstanceHandle a_DateAttribute = GetInstance(KnownInstanceGuids.Classes.DateAttribute); InstanceHandle a_DateAttribute = GetInstance(KnownInstanceGuids.Classes.DateAttribute);
InstanceHandle sourceParentClass = GetParentClass(source);
bool Verify_Classes_Contain_Attributes = false; bool Verify_Classes_Contain_Attributes = false;
if (Verify_Classes_Contain_Attributes) if (Verify_Classes_Contain_Attributes && source != InstanceHandle.Empty)
{ {
InstanceHandle sourceParentClass = GetParentClass(source);
if (!RecursiveClassHasAttribute(sourceParentClass, attribute)) if (!RecursiveClassHasAttribute(sourceParentClass, attribute))
{ {
string name = GetAttributeValue<string>(attribute, GetInstance(KnownAttributeGuids.Text.Name)); string name = GetAttributeValue<string>(attribute, GetInstance(KnownAttributeGuids.Text.Name));
@ -931,53 +940,14 @@ public abstract class Oms
} }
} }
if (IsInstanceOf(attribute, a_TextAttribute)) Guid parentClassGuid = GetGlobalIdentifier(GetParentClass(attribute));
IEnumerable<AttributeImplementation> attrs = ClassImplementations.GetAll<AttributeImplementation>();
foreach (AttributeImplementation impl in attrs)
{ {
if (!(value is string)) if (impl.ClassGuid == parentClassGuid)
{ {
throw new ArgumentException("value for TextAttribute must be System.String"); impl.Validate(this, attribute, value);
} // throw new ArgumentException(String.Format("value {0} cannot be converted to a `{1}`", value is string ? "\"" + value + "\"" : value, Oms.GetInstanceText(Oms.GetParentClass(parm))), nameof(value));
if (TryGetAttributeValue(attribute, GetInstance(KnownAttributeGuids.Numeric.MinimumLength), out decimal minimumLength))
{
if (((string)value).Length < minimumLength)
{
throw new ArgumentOutOfRangeException(String.Format("value for TextAttribute must be greater than {0} characters", minimumLength - 1));
}
}
if (TryGetAttributeValue(attribute, GetInstance(KnownAttributeGuids.Numeric.MaximumLength), out decimal maximumLength))
{
if (((string)value).Length > maximumLength)
{
throw new ArgumentOutOfRangeException(String.Format("value for TextAttribute must be less than {0} characters", maximumLength + 1));
}
}
}
else if (IsInstanceOf(attribute, a_BooleanAttribute))
{
if (!(value is bool))
{
throw new ArgumentException("value for BooleanAttribute must be System.Boolean");
}
}
else if (IsInstanceOf(attribute, a_NumericAttribute))
{
if (!(value is decimal))
{
throw new ArgumentException("value for NumericAttribute must be System.Decimal");
}
if (TryGetAttributeValue(attribute, GetInstance(KnownAttributeGuids.Numeric.MinimumValue), out decimal minimumValue))
{
if (((decimal)value) < minimumValue)
{
throw new ArgumentOutOfRangeException(String.Format("value for NumericAttribute must be greater than {0}", minimumValue - 1));
}
}
if (TryGetAttributeValue(attribute, GetInstance(KnownAttributeGuids.Numeric.MaximumValue), out decimal maximumValue))
{
if (((decimal)value) > maximumValue)
{
throw new ArgumentOutOfRangeException(String.Format("value for NumericAttribute must be greater than {0}", maximumValue - 1));
}
} }
} }
} }
@ -995,14 +965,14 @@ public abstract class Oms
IReadOnlyCollection<InstanceHandle> superclasses = GetRelatedInstances(sourceParentClass, GetInstance(KnownRelationshipGuids.Class__has_super__Class)); IReadOnlyCollection<InstanceHandle> superclasses = GetRelatedInstances(sourceParentClass, GetInstance(KnownRelationshipGuids.Class__has_super__Class));
if (superclasses != null) if (superclasses != null)
{ {
foreach (InstanceHandle ir in superclasses) foreach (InstanceHandle ir in superclasses)
{
if (RecursiveClassHasAttribute(ir, attribute))
{ {
return true; if (RecursiveClassHasAttribute(ir, attribute))
{
return true;
}
} }
} }
}
} }
return false; return false;
} }
@ -1213,11 +1183,7 @@ public abstract class Oms
return value; return value;
} }
private Dictionary<Guid, MethodImplementation> methodImplementations = new Dictionary<Guid, MethodImplementation>(); public ClassImplementationRegistry ClassImplementations { get; } = new ClassImplementationRegistry();
private void RegisterMethodImplementation(Guid methodClassId, MethodImplementation implementation)
{
methodImplementations[methodClassId] = implementation;
}
public InstanceHandle Execute(OmsContext context, MethodBinding methodBinding, IInstanceReference? targetInstance = null) public InstanceHandle Execute(OmsContext context, MethodBinding methodBinding, IInstanceReference? targetInstance = null)
{ {
@ -1303,32 +1269,7 @@ public abstract class Oms
*/ */
{ {
IEnumerable<InstanceHandle> parameterAssignments = GetRelatedInstances(methodOrMethodBinding, GetInstance(KnownRelationshipGuids.Method_Binding__has__Parameter_Assignment)); IEnumerable<InstanceHandle> parameterAssignments = GetRelatedInstances(methodOrMethodBinding, GetInstance(KnownRelationshipGuids.Method_Binding__has__Parameter_Assignment));
foreach (InstanceHandle parm in parameterAssignments) AssignParameters(context, parameterAssignments);
{
InstanceHandle assignsToParm = GetRelatedInstance(parm, GetInstance(KnownRelationshipGuids.Parameter_Assignment__assigns_to__Work_Data));
IInstanceReference assignsFromWorkData = GetRelatedInstance(parm, GetInstance(KnownRelationshipGuids.Parameter_Assignment__assigns_from__Executable_returning_Work_Data));
if (assignsFromWorkData == null)
{
Console.Error.WriteLine("oms: error: assigns from work data not set for parameter assignment '{0}'", parm.GlobalIdentifier);
continue;
}
if (IsInstanceOf(assignsFromWorkData, GetInstance(KnownInstanceGuids.Classes.Class)))
{
assignsFromWorkData = context.GetWorkData<IInstanceReference>(assignsFromWorkData);
}
if (IsInstanceOf(assignsFromWorkData, GetInstance(KnownInstanceGuids.Classes.WorkSet)))
{
bool evaluateWorkSet = GetAttributeValue<bool>(parm, GetInstance(KnownAttributeGuids.Boolean.EvaluateWorkSet));
if (evaluateWorkSet)
{
assignsFromWorkData = context.GetWorkData<InstanceHandle>(assignsFromWorkData);
}
}
context.SetWorkData(assignsToParm, assignsFromWorkData);
}
InstanceHandle relatedMethod = GetRelatedInstance(methodOrMethodBinding, GetInstance<Relationship>(KnownRelationshipGuids.Method_Binding__executes__Method)); InstanceHandle relatedMethod = GetRelatedInstance(methodOrMethodBinding, GetInstance<Relationship>(KnownRelationshipGuids.Method_Binding__executes__Method));
InstanceHandle relatedMethod_for_Class = GetRelatedInstance(relatedMethod, GetInstance<Relationship>(KnownRelationshipGuids.Method__for__Class)); InstanceHandle relatedMethod_for_Class = GetRelatedInstance(relatedMethod, GetInstance<Relationship>(KnownRelationshipGuids.Method__for__Class));
@ -1368,11 +1309,11 @@ public abstract class Oms
} }
else else
{ {
if (methodImplementations.ContainsKey(parentClassId)) if (ClassImplementations.TryGet<MethodImplementation>(parentClassId, out MethodImplementation? impl))
{ {
InstanceHandle forClass = GetRelatedInstance(methodOrMethodBinding, GetInstance(KnownRelationshipGuids.Method__for__Class));
if (targetInstance == null) if (targetInstance == null)
{ {
InstanceHandle forClass = GetRelatedInstance(methodOrMethodBinding, GetInstance(KnownRelationshipGuids.Method__for__Class));
if (forClass != InstanceHandle.Empty) if (forClass != InstanceHandle.Empty)
{ {
IInstanceReference? irTarget = context.GetWorkData<IInstanceReference?>(forClass); IInstanceReference? irTarget = context.GetWorkData<IInstanceReference?>(forClass);
@ -1389,6 +1330,29 @@ public abstract class Oms
//sthrow new NullReferenceException(String.Format("Attempt to call instance method `{0}` without an instance", methodOrMethodBinding)); //sthrow new NullReferenceException(String.Format("Attempt to call instance method `{0}` without an instance", methodOrMethodBinding));
} }
bool is_abstract = GetAttributeValue<bool>(methodOrMethodBinding, GetInstance(KnownAttributeGuids.Boolean.Abstract));
if (is_abstract)
{
InstanceHandle forClassInstance = context.GetWorkData<InstanceHandle>(forClass);
InstanceHandle parentClass2 = GetParentClass(forClassInstance);
string parentClassName = GetAttributeValue<string>(parentClass2, GetInstance(KnownAttributeGuids.Text.Name));
IEnumerable<InstanceHandle> methodsImplementingMethod = GetRelatedInstances(methodOrMethodBinding, GetInstance(KnownRelationshipGuids.Method__implemented_by__Method));
foreach (InstanceHandle ih in methodsImplementingMethod)
{
InstanceHandle forClassInstance2 = GetRelatedInstance(ih, GetInstance(KnownRelationshipGuids.Method__for__Class));
if (parentClass2 == forClassInstance2)
{
// call implementing method instead
retval = Execute(context, ih, targetInstance);
if (retval != InstanceHandle.Empty)
{
return retval.GetValueOrDefault();
}
}
}
throw new InvalidOperationException(String.Format("No method implementation for abstract method {0} on class {1} ({2})", GetInstanceKey(methodOrMethodBinding), parentClassName.Replace(' ', '_') + "--IS", GetInstanceKey(parentClass2)));
}
if (targetInstance == null) if (targetInstance == null)
{ {
@ -1423,15 +1387,14 @@ public abstract class Oms
InstanceHandle pclassInstance = GetParentClass(hh); InstanceHandle pclassInstance = GetParentClass(hh);
context.SetWorkData(pclassInstance, hh); context.SetWorkData(pclassInstance, hh);
} }
retval = methodImplementations[parentClassId].Execute(this, context, methodOrMethodBinding); retval = impl.Execute(this, context, methodOrMethodBinding);
}
else
{
throw new NotImplementedException(String.Format("method implementation not found for method class {0}", GetGlobalIdentifier(parentClass)));
} }
} }
if (retval == null) if (retval != null)
{
// return InstanceHandle.Empty;
throw new NotImplementedException(String.Format("method implementation not found for method class {0}", GetGlobalIdentifier(parentClass)));
}
else
{ {
// context.StackTrace.Pop(); // context.StackTrace.Pop();
IDictionary<InstanceHandle, object?> dict = context.GetAllWorkData(); IDictionary<InstanceHandle, object?> dict = context.GetAllWorkData();
@ -1443,6 +1406,62 @@ public abstract class Oms
} }
return retval.Value; return retval.Value;
} }
else
{
// return InstanceHandle.Empty;
throw new InvalidOperationException(String.Format("method did not return work data for method class {0}", GetGlobalIdentifier(parentClass)));
}
}
private void AssignParameters(OmsContext context, IEnumerable<InstanceHandle> parameterAssignments)
{
foreach (InstanceHandle parm in parameterAssignments)
{
InstanceHandle assignsToParm = GetRelatedInstance(parm, GetInstance(KnownRelationshipGuids.Parameter_Assignment__assigns_to__Work_Data));
IInstanceReference assignsFromWorkData = GetRelatedInstance(parm, GetInstance(KnownRelationshipGuids.Parameter_Assignment__assigns_from__Executable_returning_Work_Data));
if (assignsFromWorkData == null)
{
Console.Error.WriteLine("oms: error: assigns from work data not set for parameter assignment '{0}'", parm.GlobalIdentifier);
continue;
}
// there are several possibilities:
// `assigns to Parm` is a Class which is an Attribute. `assigns from Work Data` is an Attribute.
// in this case, we should set the work data to the value of the work data pointed to by `assigns from`
// `Token` := `User Name` -> `Token` = "testinguser"
//
// `assigns to Parm` is a Class. `assigns from Work Data` is a Class which is NOT an Attribute.
// just use the ref as-is
// `System User` := `User` -> `System User` = `User`
//
// `Worker who can Resign` := `Current Signed In Worker` -> `Worker who can Resign` = `Steve`
if (IsInstanceOf(assignsToParm, GetInstance(KnownInstanceGuids.Classes.Attribute)) && IsInstanceOf(assignsFromWorkData, GetInstance(KnownInstanceGuids.Classes.Attribute)))
{
// if `assigns to Parm` is a Class which inherits from Attribute, and `assigns from Work Data` is an Attribute, then assign the underlying work data
context.SetWorkData(assignsToParm, context.GetWorkData(assignsFromWorkData));
}
else
{
if (IsInstanceOf(assignsFromWorkData, GetInstance(KnownInstanceGuids.Classes.Class)))
{
assignsFromWorkData = context.GetWorkData<IInstanceReference>(assignsFromWorkData);
}
if (IsInstanceOf(assignsFromWorkData, GetInstance(KnownInstanceGuids.Classes.WorkSet)))
{
bool evaluateWorkSet = GetAttributeValue<bool>(parm, GetInstance(KnownAttributeGuids.Boolean.EvaluateWorkSet));
if (evaluateWorkSet)
{
assignsFromWorkData = context.GetWorkData<InstanceHandle>(assignsFromWorkData);
}
}
context.SetWorkData(assignsToParm, assignsFromWorkData);
}
}
} }
private InstanceHandle ExecuteMethodBinding(OmsContext context, InstanceHandle methodBinding, IInstanceReference? targetInstance = null) private InstanceHandle ExecuteMethodBinding(OmsContext context, InstanceHandle methodBinding, IInstanceReference? targetInstance = null)
@ -2768,4 +2787,18 @@ public abstract class Oms
} }
return InstanceHandle.Empty; return InstanceHandle.Empty;
} }
public AttributeImplementation GetAttributeImplementation(InstanceHandle att)
{
InstanceHandle parentClass = GetParentClass(att);
Guid classGuid = GetGlobalIdentifier(parentClass);
// find AttributeImplementation whose ClassGuid matches
return ClassImplementations.Get<AttributeImplementation>(classGuid);
}
public InstanceHandle GetInstance(object method__implements__Method)
{
throw new NotImplementedException();
}
} }

View File

@ -137,6 +137,60 @@ public class OmsContext
return defaultValue; return defaultValue;
} }
private void ValidateSubclassConstraints(InstanceHandle parm, System.Collections.IEnumerable en)
{
bool singular = false;
if (!Oms.TryGetAttributeValue<bool>(parm, Oms.GetInstance(KnownAttributeGuids.Boolean.Singular), out singular))
{
singular = false;
}
bool includeSubclasses = false;
if (!Oms.TryGetAttributeValue<bool>(parm, Oms.GetInstance(KnownAttributeGuids.Boolean.IncludeSubclasses), out includeSubclasses))
{
includeSubclasses = false;
}
int ct = 0;
foreach (object o in en)
{
ct++;
}
if (singular && ct > 1)
{
throw new InvalidOperationException("cannot assign multiple instances to a singular Work Set");
}
foreach (object o in en)
{
if (o is IInstanceReference ir)
{
IReadOnlyCollection<InstanceHandle> irs = Oms.GetRelatedInstances(parm, Oms.GetInstance(KnownRelationshipGuids.Work_Set__has_valid__Class));
if (irs.Count > 0)
{
if (includeSubclasses)
{
foreach (InstanceHandle possibleParentClass in irs)
{
if (!Oms.IsInstanceOf(ir, possibleParentClass))
{
throw new ArgumentException("instance reference must be an instance of appropriate class");
}
}
}
else
{
InstanceHandle parentClass = Oms.GetParentClass(ir);
if (!irs.Contains(parentClass))
{
throw new ArgumentException("instance reference must be an instance of appropriate class");
}
}
}
}
}
}
public void SetWorkData(IInstanceReference parm, object? value) public void SetWorkData(IInstanceReference parm, object? value)
{ {
SetWorkData(parm.GetHandle(), value); SetWorkData(parm.GetHandle(), value);
@ -147,75 +201,31 @@ public class OmsContext
{ {
if (Oms.IsInstanceOf(parm, Oms.GetInstance(KnownInstanceGuids.Classes.WorkSet))) if (Oms.IsInstanceOf(parm, Oms.GetInstance(KnownInstanceGuids.Classes.WorkSet)))
{ {
bool singular = false;
if (!Oms.TryGetAttributeValue<bool>(parm, Oms.GetInstance(KnownAttributeGuids.Boolean.Singular), out singular))
{
singular = false;
}
if (value is IInstanceReference) if (value is IInstanceReference)
{ {
IReadOnlyCollection<InstanceHandle> irs = Oms.GetRelatedInstances(parm, Oms.GetInstance(KnownRelationshipGuids.Work_Set__has_valid__Class)); ValidateSubclassConstraints(parm, new IInstanceReference[] { (IInstanceReference)value });
if (irs.Count > 0)
{
InstanceHandle ir = ((IInstanceReference)value).GetHandle();
InstanceHandle parentClass = Oms.GetParentClass(ir);
if (!irs.Contains(parentClass))
{
throw new ArgumentException("instance reference must be an instance of appropriate class");
}
}
} }
else if (value is IEnumerable<InstanceHandle>) else if (value is IEnumerable<InstanceHandle>)
{ {
IEnumerable<InstanceHandle> insts = (IEnumerable<InstanceHandle>)value; ValidateSubclassConstraints(parm, (IEnumerable<InstanceHandle>)value);
if (singular && insts.Count() > 1)
{
throw new InvalidOperationException("Singular Work Set must only contain a single InstanceReference or be an array of InstanceReference that contains exactly zero or one item.");
}
IEnumerable<InstanceHandle> irs = Oms.GetRelatedInstances(parm, Oms.GetInstance(KnownRelationshipGuids.Work_Set__has_valid__Class));
if (irs.Count() > 0)
{
foreach (InstanceHandle ir in insts)
{
InstanceHandle parentClass = Oms.GetParentClass(ir);
if (!irs.Contains(parentClass))
{
throw new ArgumentException("instance reference must be an instance of appropriate class");
}
}
}
// value = ((IEnumerable<InstanceHandle>)value).FirstOrDefault();
} }
else if (value is IEnumerable<InstanceWrapper>) else if (value is IEnumerable<InstanceWrapper>)
{ {
IEnumerable<InstanceWrapper> insts = (IEnumerable<InstanceWrapper>)value; ValidateSubclassConstraints(parm, (IEnumerable<InstanceWrapper>)value);
if (singular && insts.Count() > 1) }
{ else if (value is IEnumerable<IInstanceReference>)
throw new InvalidOperationException("Singular Work Set must only contain a single InstanceReference or be an array of InstanceReference that contains exactly zero or one item."); {
} ValidateSubclassConstraints(parm, (IEnumerable<IInstanceReference>)value);
IEnumerable<InstanceHandle> irs = Oms.GetRelatedInstances(parm, Oms.GetInstance(KnownRelationshipGuids.Work_Set__has_valid__Class));
if (irs != null)
{
if (irs.Count() > 0)
{
foreach (InstanceWrapper iw in insts)
{
InstanceHandle ir = iw.GetHandle();
InstanceHandle parentClass = Oms.GetParentClass(ir);
if (!irs.Contains(parentClass))
{
throw new ArgumentException("instance reference must be an instance of appropriate class");
}
}
}
}
} }
else else
{ {
throw new ArgumentException(String.Format("cannot assign literal data '{0}' to a Work Set", value)); throw new ArgumentException(String.Format("cannot assign literal data '{0}' to a Work Set", value));
} }
} }
else
{
Oms.ValidateConstraintsForAttribute(parm, value);
}
} }
_WorkData[parm] = value; _WorkData[parm] = value;
} }

View File

@ -25,7 +25,7 @@ namespace Mocha.Core;
public class OmsMethodBuilder public class OmsMethodBuilder
{ {
private InstanceHandle c_ReturnAttributeMethodBinding, c_ReturnInstanceSetMethodBinding, c_ReturnElementMethodBinding, c_BuildResponseMethodBinding; private InstanceHandle c_ReturnAttributeMethodBinding, c_ReturnInstanceSetMethodBinding, c_ReturnElementMethodBinding, c_BuildResponseMethodBinding, c_ExecuteUpdateMethodBinding, c_ProcessUpdatesMethodBinding;
public Oms Oms { get; } public Oms Oms { get; }
public OmsMethodBuilder(Oms oms) public OmsMethodBuilder(Oms oms)
@ -35,38 +35,68 @@ public class OmsMethodBuilder
c_ReturnAttributeMethodBinding = Oms.GetInstance(KnownInstanceGuids.Classes.ReturnAttributeMethodBinding); c_ReturnAttributeMethodBinding = Oms.GetInstance(KnownInstanceGuids.Classes.ReturnAttributeMethodBinding);
c_ReturnInstanceSetMethodBinding = Oms.GetInstance(KnownInstanceGuids.Classes.ReturnInstanceSetMethodBinding); c_ReturnInstanceSetMethodBinding = Oms.GetInstance(KnownInstanceGuids.Classes.ReturnInstanceSetMethodBinding);
c_ReturnElementMethodBinding = Oms.GetInstance(KnownInstanceGuids.Classes.ReturnElementMethodBinding); c_ReturnElementMethodBinding = Oms.GetInstance(KnownInstanceGuids.Classes.ReturnElementMethodBinding);
c_BuildResponseMethodBinding = Oms.GetInstance(KnownInstanceGuids.Classes.BuildResponseMethodBinding);
c_ExecuteUpdateMethodBinding = Oms.GetInstance(KnownInstanceGuids.Classes.ExecuteUpdateMethodBinding);
c_ProcessUpdatesMethodBinding = Oms.GetInstance(KnownInstanceGuids.Classes.ProcessUpdatesMethodBinding);
} }
public ReturnAttributeMethodBinding CreateReturnAttributeMethodBinding(MethodReturningAttribute method) private InstanceHandle CreateMethodBindingBase(InstanceHandle parentClass, Method method, IEnumerable<KeyValuePair<InstanceHandle, InstanceHandle>>? parameterAssignments)
{ {
InstanceHandle methodBinding = Oms.CreateInstanceOf(c_ReturnAttributeMethodBinding); InstanceHandle methodBinding = Oms.CreateInstanceOf(parentClass);
Oms.AssignRelationship(methodBinding, Oms.GetInstance(KnownRelationshipGuids.Method_Binding__executes__Method), method.GetHandle()); Oms.AssignRelationship(methodBinding, Oms.GetInstance(KnownRelationshipGuids.Method_Binding__executes__Method), method.GetHandle());
if (parameterAssignments != null)
{
CreateParameterAssignments(methodBinding, parameterAssignments);
}
return methodBinding;
}
private void CreateParameterAssignments(InstanceHandle methodBinding, IEnumerable<KeyValuePair<InstanceHandle, InstanceHandle>> parameterAssignments)
{
List<InstanceHandle> parmAssignments = new List<InstanceHandle>();
foreach (KeyValuePair<InstanceHandle, InstanceHandle> kvp in parameterAssignments)
{
InstanceHandle parmAssignment = Oms.CreateInstanceOf(Oms.GetInstance(KnownInstanceGuids.Classes.ParameterAssignment));
Oms.AssignRelationship(parmAssignment, Oms.GetInstance(KnownRelationshipGuids.Parameter_Assignment__assigns_to__Work_Data), kvp.Key);
Oms.AssignRelationship(parmAssignment, Oms.GetInstance(KnownRelationshipGuids.Parameter_Assignment__assigns_from__Executable_returning_Work_Data), kvp.Value);
parmAssignments.Add(parmAssignment);
}
Oms.AssignRelationship(methodBinding, Oms.GetInstance(KnownRelationshipGuids.Method_Binding__has__Parameter_Assignment), parmAssignments);
}
public ReturnAttributeMethodBinding CreateReturnAttributeMethodBinding(MethodReturningAttribute method, IEnumerable<KeyValuePair<InstanceHandle, InstanceHandle>>? parameterAssignments = null)
{
InstanceHandle methodBinding = CreateMethodBindingBase(c_ReturnAttributeMethodBinding, method, parameterAssignments);
return new ReturnAttributeMethodBinding(methodBinding); return new ReturnAttributeMethodBinding(methodBinding);
} }
public ReturnInstanceSetMethodBinding CreateReturnInstanceSetMethodBinding(MethodReturningInstanceSet method) public ReturnInstanceSetMethodBinding CreateReturnInstanceSetMethodBinding(MethodReturningInstanceSet method, IEnumerable<KeyValuePair<InstanceHandle, InstanceHandle>>? parameterAssignments = null)
{ {
InstanceHandle methodBinding = Oms.CreateInstanceOf(c_ReturnInstanceSetMethodBinding); InstanceHandle methodBinding = CreateMethodBindingBase(c_ReturnInstanceSetMethodBinding, method, parameterAssignments);
Oms.AssignRelationship(methodBinding, Oms.GetInstance(KnownRelationshipGuids.Method_Binding__executes__Method), method.GetHandle());
return new ReturnInstanceSetMethodBinding(methodBinding); return new ReturnInstanceSetMethodBinding(methodBinding);
} }
public ReturnElementMethodBinding CreateReturnElementMethodBinding(MethodReturningElement method) public ReturnElementMethodBinding CreateReturnElementMethodBinding(MethodReturningElement method, IEnumerable<KeyValuePair<InstanceHandle, InstanceHandle>>? parameterAssignments = null)
{ {
InstanceHandle methodBinding = Oms.CreateInstanceOf(c_ReturnElementMethodBinding); InstanceHandle methodBinding = CreateMethodBindingBase(c_ReturnElementMethodBinding, method, parameterAssignments);
Oms.AssignRelationship(methodBinding, Oms.GetInstance(KnownRelationshipGuids.Method_Binding__executes__Method), method.GetHandle());
return new ReturnElementMethodBinding(methodBinding); return new ReturnElementMethodBinding(methodBinding);
} }
public BuildResponseMethodBinding CreateBuildResponseMethodBinding(MethodBuildingResponse method) public BuildResponseMethodBinding CreateBuildResponseMethodBinding(MethodBuildingResponse method, IEnumerable<KeyValuePair<InstanceHandle, InstanceHandle>>? parameterAssignments = null)
{ {
if (c_BuildResponseMethodBinding == InstanceHandle.Empty) InstanceHandle methodBinding = CreateMethodBindingBase(c_BuildResponseMethodBinding, method, parameterAssignments);
{
c_BuildResponseMethodBinding = Oms.GetInstance(KnownInstanceGuids.Classes.BuildResponseMethodBinding);
}
InstanceHandle methodBinding = Oms.CreateInstanceOf(c_BuildResponseMethodBinding);
Oms.AssignRelationship(methodBinding, Oms.GetInstance(KnownRelationshipGuids.Method_Binding__executes__Method), method.GetHandle());
return new BuildResponseMethodBinding(methodBinding); return new BuildResponseMethodBinding(methodBinding);
} }
public ExecuteUpdateMethodBinding CreateExecuteUpdateMethodBinding(Method method, IEnumerable<KeyValuePair<InstanceHandle, InstanceHandle>>? parameterAssignments = null)
{
InstanceHandle methodBinding = CreateMethodBindingBase(c_ExecuteUpdateMethodBinding, method, parameterAssignments);
return new ExecuteUpdateMethodBinding(methodBinding);
}
public ExecuteUpdateMethodBinding CreateProcessUpdatesMethodBinding(Method method, IEnumerable<KeyValuePair<InstanceHandle, InstanceHandle>>? parameterAssignments = null)
{
InstanceHandle methodBinding = CreateMethodBindingBase(c_ProcessUpdatesMethodBinding, method, parameterAssignments);
return new ExecuteUpdateMethodBinding(methodBinding);
}
public GetAttributeMethod CreateGetAttributeMethod(IInstanceReference forClassInstance, string verb, string name, InstanceHandle attributeInstance) public GetAttributeMethod CreateGetAttributeMethod(IInstanceReference forClassInstance, string verb, string name, InstanceHandle attributeInstance)
{ {
return CreateGetAttributeMethod(forClassInstance, verb, name, null, false, attributeInstance); return CreateGetAttributeMethod(forClassInstance, verb, name, null, false, attributeInstance);
@ -458,4 +488,28 @@ public class OmsMethodBuilder
} }
return new InvokeWebServiceMethod(ih); return new InvokeWebServiceMethod(ih);
} }
public PUMProcess CreatePUMProcess(IEnumerable<ExecuteUpdateMethodBinding> executeUpdateMethodBindings)
{
InstanceHandle ih = Oms.CreateInstanceOf(Oms.GetInstance(KnownInstanceGuids.Classes.PUMProcess));
List<InstanceHandle> list = new List<InstanceHandle>();
foreach (ExecuteUpdateMethodBinding eumb in executeUpdateMethodBindings)
{
list.Add(eumb.GetHandle());
}
Oms.AssignRelationship(ih, Oms.GetInstance(KnownRelationshipGuids.PUM_Process__invokes__Execute_Update_Method_Binding), list);
return new PUMProcess(ih);
}
public ProcessUpdatesMethod CreateProcessUpdatesMethod(IInstanceReference forClassInstance, string verb, string name, AccessModifier accessModifier, bool isStatic, IEnumerable<ExecuteUpdateMethodBinding> executeUpdateMethodBindings)
{
PUMProcess pumProcess = CreatePUMProcess(executeUpdateMethodBindings);
return CreateProcessUpdatesMethod(forClassInstance, verb, name, accessModifier, isStatic, pumProcess);
}
public ProcessUpdatesMethod CreateProcessUpdatesMethod(IInstanceReference forClassInstance, string verb, string name, AccessModifier accessModifier, bool isStatic, PUMProcess pumProcess)
{
InstanceHandle ih = CreateMethodBase(Oms.GetInstance(KnownInstanceGuids.MethodClasses.ProcessUpdatesMethod), forClassInstance, verb, name, accessModifier, isStatic);
Oms.AssignRelationship(ih, Oms.GetInstance(KnownRelationshipGuids.Process_Updates_Method__has__PUM_Process), pumProcess);
return new ProcessUpdatesMethod(ih);
}
} }

View File

@ -42,3 +42,8 @@ public class BuildResponseMethodBinding : MethodBinding //, IExecutableBuildingR
public override Guid ClassId => KnownInstanceGuids.Classes.BuildResponseMethodBinding; public override Guid ClassId => KnownInstanceGuids.Classes.BuildResponseMethodBinding;
internal BuildResponseMethodBinding(InstanceHandle handle) : base(handle) { } internal BuildResponseMethodBinding(InstanceHandle handle) : base(handle) { }
} }
public class ExecuteUpdateMethodBinding : MethodBinding //, IExecutableBuildingResponse
{
public override Guid ClassId => KnownInstanceGuids.Classes.ExecuteUpdateMethodBinding;
internal ExecuteUpdateMethodBinding(InstanceHandle handle) : base(handle) { }
}

View File

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

View File

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

View File

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

View File

@ -22,9 +22,12 @@ public class CreateInstance : IMethodMember
public ObjectReference ObjectReference { get; set; } public ObjectReference ObjectReference { get; set; }
public List<object> ParameterValues { get; } = new List<object>(); public List<object> ParameterValues { get; } = new List<object>();
public CreateInstance(IEnumerable<string> objectNames, IEnumerable<object> parameterValues) public CreateInstance(ObjectReference createWhat, IEnumerable<object>? parameterValues = null)
{ {
ObjectReference = new ObjectReference(objectNames); ObjectReference = createWhat;
ParameterValues.AddRange(parameterValues); if (parameterValues != null)
{
ParameterValues.AddRange(parameterValues);
}
} }
} }

View File

@ -32,8 +32,7 @@ public class MethodCall : IMethodMember
{ {
foreach (object parmValue in parmValues) foreach (object parmValue in parmValues)
{ {
MethodParameter parm = new MethodParameter(); MethodParameter parm = new MethodParameter(parmValue);
parm.Value = parmValue;
Parameters.Add(parm); Parameters.Add(parm);
} }
} }

View File

@ -19,13 +19,17 @@ namespace Mocha.Modeling.CodeGeneration;
public class MethodParameter public class MethodParameter
{ {
public MethodParameter(string? name = null, ObjectReference? dataType = null) public MethodParameter(object value)
{
Value = value;
}
public MethodParameter(string name, ObjectReference dataType)
{ {
Name = name; Name = name;
DataType = dataType; DataType = dataType;
} }
public ObjectReference? DataType { get; set; } = null; public ObjectReference DataType { get; set; } = null;
public string? Name { get; set; } = null; public string Name { get; set; } = null;
public object? Value { get; set; } = null; public object? Value { get; set; } = null;
} }

View File

@ -15,14 +15,31 @@
// 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 Mocha.NET. If not, see <https://www.gnu.org/licenses/>. // along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
using System.Text;
namespace Mocha.Modeling.CodeGeneration; namespace Mocha.Modeling.CodeGeneration;
public class ObjectReference public class ObjectReference
{ {
public IEnumerable<string> ObjectNames { get; set; } = null; public IEnumerable<string> ObjectNames { get; set; } = null;
public IEnumerable<ObjectReference>? GenericArguments { get; set; } = null;
public ObjectReference(IEnumerable<string> objectNames) public ObjectReference(IEnumerable<string> objectNames, IEnumerable<ObjectReference>? genericArguments = null)
{ {
ObjectNames = objectNames; ObjectNames = objectNames;
GenericArguments = genericArguments;
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append(String.Join('.', ObjectNames));
if (GenericArguments != null && GenericArguments.Count() > 0)
{
sb.Append('<');
sb.Append(String.Join(',', GenericArguments));
sb.Append('>');
}
return sb.ToString();
} }
} }

View File

@ -0,0 +1,34 @@
// Copyright (C) 2025 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.Modeling.CodeGeneration;
public class Field : IClassMember
{
public Field(string name, ObjectReference returnType, object? value = null)
{
Name = name;
ReturnType = returnType;
Value = value;
}
public AccessModifier AccessModifier { get; set; } = AccessModifier.None;
public string Name { get; set; } = "";
public ObjectReference ReturnType { get; set; }
public object? Value { get; set; }
public bool ReadOnly { get; set; } = false;
}

View File

@ -47,7 +47,7 @@ public class CSharpCodeGenerator : DotNetCodeGenerator
if (item is Namespace ns) if (item is Namespace ns)
{ {
sb.Append("namespace "); sb.Append("namespace ");
sb.Append(BuildObjectReference(ns.Names)); sb.Append(BuildObjectReference(new ObjectReference(ns.Names)));
sb.Append(" { "); sb.Append(" { ");
foreach (ICodeItem subItem in ns.Items) foreach (ICodeItem subItem in ns.Items)
{ {
@ -63,7 +63,7 @@ public class CSharpCodeGenerator : DotNetCodeGenerator
if (c.InheritsClass != null) if (c.InheritsClass != null)
{ {
sb.Append(" : "); sb.Append(" : ");
sb.Append(BuildObjectReference(c.InheritsClass.ObjectNames)); sb.Append(BuildObjectReference(c.InheritsClass));
} }
sb.Append(" { "); sb.Append(" { ");
foreach (IClassMember subItem in c.Items) foreach (IClassMember subItem in c.Items)
@ -115,10 +115,35 @@ public class CSharpCodeGenerator : DotNetCodeGenerator
if (p.Value != null || (p.UseAutoProperty && p.ReadOnly)) if (p.Value != null || (p.UseAutoProperty && p.ReadOnly))
{ {
sb.Append("= "); sb.Append("= ");
sb.Append(ExpressionOrLiteral(p.Value)); if (p.Value != null)
{
sb.Append(ExpressionOrLiteral(p.Value));
}
else if (p.UseAutoProperty && p.GetMethod != null && p.GetMethod.Items.Count == 1 && p.GetMethod.Items[0] is Return r)
{
sb.Append(ExpressionOrLiteral(r.Value));
}
sb.Append(";"); sb.Append(";");
} }
} }
else if (item is Field f)
{
sb.Append(GenerateCode(f.AccessModifier));
sb.Append(' ');
if (f.ReadOnly)
{
sb.Append("readonly ");
}
sb.Append(GenerateCode(f.ReturnType));
sb.Append(' ');
sb.Append(f.Name);
if (f.Value != null)
{
sb.Append(" = ");
sb.Append(ExpressionOrLiteral(f.Value));
}
sb.Append(";");
}
else if (item is Method m) else if (item is Method m)
{ {
sb.Append(GenerateCode(m.AccessModifier)); sb.Append(GenerateCode(m.AccessModifier));
@ -144,7 +169,7 @@ public class CSharpCodeGenerator : DotNetCodeGenerator
for (int i = 0; i < m.Parameters.Count; i++) for (int i = 0; i < m.Parameters.Count; i++)
{ {
MethodParameter parm = m.Parameters[i]; MethodParameter parm = m.Parameters[i];
sb.Append(BuildObjectReference(parm.DataType.ObjectNames)); sb.Append(BuildObjectReference(parm.DataType));
sb.Append(' '); sb.Append(' ');
sb.Append(parm.Name); sb.Append(parm.Name);
if (i < m.Parameters.Count - 1) if (i < m.Parameters.Count - 1)
@ -165,7 +190,7 @@ public class CSharpCodeGenerator : DotNetCodeGenerator
else if (item is CreateInstance ci) else if (item is CreateInstance ci)
{ {
sb.Append("new "); sb.Append("new ");
sb.Append(BuildObjectReference(ci.ObjectReference.ObjectNames)); sb.Append(BuildObjectReference(ci.ObjectReference));
sb.Append("("); sb.Append("(");
sb.Append(BuildParameterList(ci.ParameterValues)); sb.Append(BuildParameterList(ci.ParameterValues));
sb.Append(")"); sb.Append(")");
@ -177,7 +202,7 @@ public class CSharpCodeGenerator : DotNetCodeGenerator
} }
else if (item is MethodCall mc) else if (item is MethodCall mc)
{ {
sb.Append(BuildObjectReference(mc.ObjectName.ObjectNames)); sb.Append(BuildObjectReference(mc.ObjectName));
sb.Append('.'); sb.Append('.');
sb.Append(mc.MethodName); sb.Append(mc.MethodName);
if (mc.GenericParameters != null) if (mc.GenericParameters != null)
@ -192,16 +217,9 @@ public class CSharpCodeGenerator : DotNetCodeGenerator
} }
else if (item is PropertyAssignment pa) else if (item is PropertyAssignment pa)
{ {
sb.Append(BuildObjectReference(pa.ObjectReference.ObjectNames)); sb.Append(BuildObjectReference(pa.ObjectReference));
sb.Append(" = "); sb.Append(" = ");
if (pa.Value != null) sb.Append(ExpressionOrLiteral(pa.Value));
{
sb.Append(pa.Value);
}
else
{
sb.Append("null");
}
} }
return sb.ToString(); return sb.ToString();
} }
@ -242,7 +260,7 @@ public class CSharpCodeGenerator : DotNetCodeGenerator
} }
else if (value is ObjectReference orr) else if (value is ObjectReference orr)
{ {
return BuildObjectReference(orr.ObjectNames); return BuildObjectReference(orr);
} }
return value.ToString() ?? ""; return value.ToString() ?? "";
} }
@ -251,20 +269,49 @@ public class CSharpCodeGenerator : DotNetCodeGenerator
protected ObjectReference ParseObjectReference(string value) protected ObjectReference ParseObjectReference(string value)
{ {
string[] parts = value.Split(new char[] { '.' }); string[]? genericArgs = null;
return new ObjectReference(parts); string typePart = value;
List<ObjectReference> genericArgList = new List<ObjectReference>();
if (value.Contains('<') && value.Contains('>'))
{
string genericPart = value.Substring(value.IndexOf('<') + 1, value.IndexOf('>') - value.IndexOf('<') - 1);
genericArgs = genericPart.Split(new char[] { ',' });
foreach (string genericArg in genericArgs)
{
genericArgList.Add(ParseObjectReference(genericArg));
}
typePart = value.Substring(0, value.IndexOf('<'));
}
string[] parts = typePart.Split(new char[] { '.' });
return new ObjectReference(parts, genericArgList);
} }
protected Property GenerateProperty(PropertyInfo pi) protected Property GenerateProperty(CodeGeneration.Class parentClass, PropertyInfo pi)
{ {
Property pp = new Property(pi.Name, ParseObjectReference(SafeTypeName(pi.PropertyType))); Property pp = new Property(pi.Name, ParseObjectReference(SafeTypeName(pi.PropertyType)));
pp.AccessModifier = AccessModifier.Public; pp.AccessModifier = AccessModifier.Public;
if (pi.PropertyType.IsSubclassOfGeneric(typeof(IList<>))) if (pi.PropertyType.IsSubclassOfGeneric(typeof(IList<>)))
{ {
pp.GetMethod = new Method(new IMethodMember[] Type[] genericArgs = pi.PropertyType.GetGenericArguments();
if (genericArgs.Length == 1 && genericArgs[0].GetInterfaces().Contains(typeof(IOmsClass)))
{ {
new Return(null) Field backingField = new Field("__backing_" + pi.Name, ParseObjectReference(SafeTypeName(pi.PropertyType)));
}); parentClass.Items.Add(backingField);
pp.GetMethod = new Method(new IMethodMember[]
{
new Return(new ObjectReference(new string[] { "__backing_" + pi.Name }))
});
pp.UseAutoProperty = false;
pp.ReadOnly = true;
}
else
{
pp.GetMethod = new Method(new IMethodMember[]
{
new Return(null)
});
}
if (pi.GetSetMethod() != null) if (pi.GetSetMethod() != null)
{ {
@ -281,7 +328,7 @@ public class CSharpCodeGenerator : DotNetCodeGenerator
new Return(new MethodCall(new string[] { "this", "Oms" }, "GetAttributeValue", new object[] new Return(new MethodCall(new string[] { "this", "Oms" }, "GetAttributeValue", new object[]
{ {
new MethodCall(new string[] { "this", "Oms" }, "GetInstance", new object[] { new ObjectReference(new string[] { "this", "GlobalIdentifier" })}), new MethodCall(new string[] { "this", "Oms" }, "GetInstance", new object[] { new ObjectReference(new string[] { "this", "GlobalIdentifier" })}),
new MethodCall(new string[] { "this", "Oms" }, "GetInstance", new object[] { new CreateInstance(new string[] { "System", "Guid" }, new object[] { "{9153A637-992E-4712-ADF2-B03F0D9EDEA6}" })}) new MethodCall(new string[] { "this", "Oms" }, "GetInstance", new object[] { new CreateInstance(new ObjectReference(new string[] { "System", "Guid" }), new object[] { "{9153A637-992E-4712-ADF2-B03F0D9EDEA6}" })})
}) { GenericParameters = [ new ObjectReference(["string"]) ]}) }) { GenericParameters = [ new ObjectReference(["string"]) ]})
}); });
// GetAttributeValue<T>(InstanceKey source, InstanceHandle attribute, T defaultValue = default(T), DateTime? effectiveDate = null) // GetAttributeValue<T>(InstanceKey source, InstanceHandle attribute, T defaultValue = default(T), DateTime? effectiveDate = null)
@ -298,7 +345,7 @@ public class CSharpCodeGenerator : DotNetCodeGenerator
new Return(new MethodCall(new string[] { "this", "Oms" }, "GetAttributeValue", new object[] new Return(new MethodCall(new string[] { "this", "Oms" }, "GetAttributeValue", new object[]
{ {
new MethodCall(new string[] { "this", "Oms" }, "GetInstance", new object[] { new ObjectReference(new string[] { "this", "GlobalIdentifier" })}), new MethodCall(new string[] { "this", "Oms" }, "GetInstance", new object[] { new ObjectReference(new string[] { "this", "GlobalIdentifier" })}),
new MethodCall(new string[] { "this", "Oms" }, "GetInstance", new object[] { new CreateInstance(new string[] { "System", "Guid" }, new object[] { "{9153A637-992E-4712-ADF2-B03F0D9EDEA6}" })}) new MethodCall(new string[] { "this", "Oms" }, "GetInstance", new object[] { new CreateInstance(new ObjectReference(new string[] { "System", "Guid" }), new object[] { "{9153A637-992E-4712-ADF2-B03F0D9EDEA6}" })})
}) { GenericParameters = [ new ObjectReference(["int"]) ]}) }) { GenericParameters = [ new ObjectReference(["int"]) ]})
}); });
// GetAttributeValue<T>(InstanceKey source, InstanceHandle attribute, T defaultValue = default(T), DateTime? effectiveDate = null) // GetAttributeValue<T>(InstanceKey source, InstanceHandle attribute, T defaultValue = default(T), DateTime? effectiveDate = null)
@ -315,7 +362,7 @@ public class CSharpCodeGenerator : DotNetCodeGenerator
new Return(new MethodCall(new string[] { "this", "Oms" }, "GetAttributeValue", new object[] new Return(new MethodCall(new string[] { "this", "Oms" }, "GetAttributeValue", new object[]
{ {
new MethodCall(new string[] { "this", "Oms" }, "GetInstance", new object[] { new ObjectReference(new string[] { "this", "GlobalIdentifier" })}), new MethodCall(new string[] { "this", "Oms" }, "GetInstance", new object[] { new ObjectReference(new string[] { "this", "GlobalIdentifier" })}),
new MethodCall(new string[] { "this", "Oms" }, "GetInstance", new object[] { new CreateInstance(new string[] { "System", "Guid" }, new object[] { "{9153A637-992E-4712-ADF2-B03F0D9EDEA6}" })}) new MethodCall(new string[] { "this", "Oms" }, "GetInstance", new object[] { new CreateInstance(new ObjectReference(new string[] { "System", "Guid" }), new object[] { "{9153A637-992E-4712-ADF2-B03F0D9EDEA6}" })})
}) { GenericParameters = [ new ObjectReference(["decimal"]) ]}) }) { GenericParameters = [ new ObjectReference(["decimal"]) ]})
}); });
// GetAttributeValue<T>(InstanceKey source, InstanceHandle attribute, T defaultValue = default(T), DateTime? effectiveDate = null) // GetAttributeValue<T>(InstanceKey source, InstanceHandle attribute, T defaultValue = default(T), DateTime? effectiveDate = null)
@ -332,7 +379,7 @@ public class CSharpCodeGenerator : DotNetCodeGenerator
new Return(new MethodCall(new string[] { "this", "Oms" }, "GetAttributeValue", new object[] new Return(new MethodCall(new string[] { "this", "Oms" }, "GetAttributeValue", new object[]
{ {
new MethodCall(new string[] { "this", "Oms" }, "GetInstance", new object[] { new ObjectReference(new string[] { "this", "GlobalIdentifier" })}), new MethodCall(new string[] { "this", "Oms" }, "GetInstance", new object[] { new ObjectReference(new string[] { "this", "GlobalIdentifier" })}),
new MethodCall(new string[] { "this", "Oms" }, "GetInstance", new object[] { new CreateInstance(new string[] { "System", "Guid" }, new object[] { "{9153A637-992E-4712-ADF2-B03F0D9EDEA6}" })}) new MethodCall(new string[] { "this", "Oms" }, "GetInstance", new object[] { new CreateInstance(new ObjectReference(new string[] { "System", "Guid" }), new object[] { "{9153A637-992E-4712-ADF2-B03F0D9EDEA6}" })})
}) { GenericParameters = [ new ObjectReference(["System.DateTime"]) ]}) }) { GenericParameters = [ new ObjectReference(["System.DateTime"]) ]})
}); });
// GetAttributeValue<T>(InstanceKey source, InstanceHandle attribute, T defaultValue = default(T), DateTime? effectiveDate = null) // GetAttributeValue<T>(InstanceKey source, InstanceHandle attribute, T defaultValue = default(T), DateTime? effectiveDate = null)

View File

@ -28,7 +28,7 @@ public abstract class DotNetCodeGenerator : CodeGenerator
{ {
public string GenerateCode(ObjectReference objectReference) public string GenerateCode(ObjectReference objectReference)
{ {
return BuildObjectReference(objectReference.ObjectNames); return BuildObjectReference(objectReference);
} }
protected string? SafeTypeName(Type type) protected string? SafeTypeName(Type type)
{ {
@ -92,22 +92,20 @@ public abstract class DotNetCodeGenerator : CodeGenerator
protected abstract string ExpressionOrLiteral(object? value); protected abstract string ExpressionOrLiteral(object? value);
protected virtual string BuildObjectReference(IEnumerable<string> objectNames) protected virtual string BuildObjectReference(ObjectReference objectReference)
{ {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
int i = 0; sb.Append(String.Join('.', objectReference.ObjectNames));
foreach (string objectName in objectNames) if (objectReference.GenericArguments != null && objectReference.GenericArguments.Count() > 0)
{ {
sb.Append(objectName); sb.Append('<');
if (i < objectNames.Count() - 1) sb.Append(String.Join(',', objectReference.GenericArguments));
{ sb.Append('>');
sb.Append('.');
}
i++;
} }
return sb.ToString(); return sb.ToString();
} }
protected Assembly CompileScript(SyntaxTree syntaxTree, IEnumerable<string>? additionalDLLs = null) protected Assembly CompileScript(SyntaxTree syntaxTree, IEnumerable<string>? additionalDLLs = null)
{ {
// thanks https://stackoverflow.com/questions/66672329 // thanks https://stackoverflow.com/questions/66672329

View File

@ -41,6 +41,17 @@ public class OmsObjectFactory<TOmsClass> : CSharpCodeGenerator where TOmsClass :
{ {
CreateType(oms, t2); CreateType(oms, t2);
} }
foreach (Type t2 in t.GetNestedTypes())
{
PropertyInfo[] pis = t2.GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (PropertyInfo pi in pis)
{
if (pi.PropertyType.IsSubclassOfGeneric(typeof(IList<>)) || pi.PropertyType.GetInterfaces().Contains(typeof(IOmsClass)))
{
CreateRelationship(oms, t2, pi);
}
}
}
Type?[] tis; Type?[] tis;
try try
@ -60,6 +71,58 @@ public class OmsObjectFactory<TOmsClass> : CSharpCodeGenerator where TOmsClass :
} }
throw new TypeInitializationException(typeof(TOmsClass).Name, null); throw new TypeInitializationException(typeof(TOmsClass).Name, null);
} }
private void CreateRelationship(Oms oms, Type parentClassType, PropertyInfo pi)
{
OmsRelationshipTypeAttribute? attrRelationshipType = pi.GetCustomAttribute<OmsRelationshipTypeAttribute>();
OmsGlobalIdentifierAttribute? attrGlobalIdentifier = pi.GetCustomAttribute<OmsGlobalIdentifierAttribute>();
if (attrGlobalIdentifier != null)
{
if (!oms.TryGetInstance(attrGlobalIdentifier.GlobalIdentifier, out InstanceHandle ih))
{
InstanceHandle ihRelationship = oms.CreateInstanceOf(oms.GetInstance(KnownInstanceGuids.Classes.Relationship), attrGlobalIdentifier.GlobalIdentifier);
InstanceHandle ihSourceClass = InstanceHandle.Empty;
InstanceHandle ihDestinationClass = InstanceHandle.Empty;
OmsGlobalIdentifierAttribute? attrParentClassGlobalIdentifier = parentClassType.GetCustomAttribute<OmsGlobalIdentifierAttribute>();
if (attrParentClassGlobalIdentifier != null)
{
ihSourceClass = oms.GetInstance(attrParentClassGlobalIdentifier.GlobalIdentifier);
}
bool singular = false;
if (pi.PropertyType.IsSubclassOfGeneric(typeof(IList<>)))
{
OmsGlobalIdentifierAttribute? attrTargetClassGlobalIdentifier = pi.PropertyType.GetGenericArguments()[0].GetCustomAttribute<OmsGlobalIdentifierAttribute>();
if (attrTargetClassGlobalIdentifier != null)
{
ihDestinationClass = oms.GetInstance(attrTargetClassGlobalIdentifier.GlobalIdentifier);
}
singular = false;
}
else if (pi.PropertyType.GetInterfaces().Contains(typeof(IOmsClass)))
{
OmsGlobalIdentifierAttribute? attrTargetClassGlobalIdentifier = pi.PropertyType.GetCustomAttribute<OmsGlobalIdentifierAttribute>();
if (attrTargetClassGlobalIdentifier != null)
{
ihDestinationClass = oms.GetInstance(attrTargetClassGlobalIdentifier.GlobalIdentifier);
}
singular = true;
}
oms.AssignRelationship(ihRelationship, oms.GetInstance(KnownRelationshipGuids.Relationship__has_source__Class), ihSourceClass);
oms.AssignRelationship(ihRelationship, oms.GetInstance(KnownRelationshipGuids.Relationship__has_destination__Class), ihDestinationClass);
if (attrRelationshipType != null)
{
oms.SetAttributeValue(ihRelationship, oms.GetInstance(KnownAttributeGuids.Text.RelationshipType), attrRelationshipType.Value);
}
oms.SetAttributeValue(ihRelationship, oms.GetInstance(KnownAttributeGuids.Boolean.Singular), singular);
}
}
}
public TOmsClass CreateInstance(Oms oms, Guid globalIdentifier) public TOmsClass CreateInstance(Oms oms, Guid globalIdentifier)
{ {
string script = BuildScript(globalIdentifier); string script = BuildScript(globalIdentifier);
@ -132,14 +195,29 @@ public class OmsObjectFactory<TOmsClass> : CSharpCodeGenerator where TOmsClass :
foreach (PropertyInfo pi in t.GetProperties(BindingFlags.Public | BindingFlags.Instance)) foreach (PropertyInfo pi in t.GetProperties(BindingFlags.Public | BindingFlags.Instance))
{ {
cl.Items.Add(GenerateProperty(pi)); cl.Items.Add(GenerateProperty(cl, pi));
} }
cl.Items.Add(new Property("Oms", new ObjectReference(new string[] { "Mocha", "Core", "Oms" }), null) { AccessModifier = CodeGeneration.AccessModifier.Public, UseAutoProperty = true, ReadOnly = false }); cl.Items.Add(new Property("Oms", new ObjectReference(new string[] { "Mocha", "Core", "Oms" }), null) { AccessModifier = CodeGeneration.AccessModifier.Public, UseAutoProperty = true, ReadOnly = false });
cl.Items.Add(new CodeGeneration.Method("Initialize", new MethodParameter[] { new MethodParameter("oms", new ObjectReference(["Mocha", "Core", "Oms"]))}, new IMethodMember[]
List<IMethodMember> list = new List<IMethodMember>();
list.Add(new PropertyAssignment(new ObjectReference(["this", "Oms"]), "oms"));
foreach (IClassMember item in cl.Items)
{ {
new PropertyAssignment(new ObjectReference(["this", "Oms"]), "oms") if (item is Field f)
}) { AccessModifier = CodeGeneration.AccessModifier.Public}); {
if (f.Name.StartsWith("__backing_"))
{
ObjectReference returnType = f.ReturnType;
if (f.ReturnType.ToString().StartsWith("System.Collections.Generic.IList<"))
{
returnType = new ObjectReference(["Mocha", "Core", "Modeling", "PropertyImplementations", "OmsNonsingularRelationshipProperty"], f.ReturnType.GenericArguments);
}
list.Add(new PropertyAssignment(new ObjectReference(["this", f.Name]), new CreateInstance(returnType, new object[] { new ObjectReference(["this", "Oms"]) })));
}
}
}
cl.Items.Add(new CodeGeneration.Method("Initialize", new MethodParameter[] { new MethodParameter("oms", new ObjectReference(["Mocha", "Core", "Oms"])) }, list) { AccessModifier = CodeGeneration.AccessModifier.Public });
return cl; return cl;
} }
@ -155,12 +233,12 @@ public class OmsObjectFactory<TOmsClass> : CSharpCodeGenerator where TOmsClass :
globalIdentifier = OmsDatabase.GetGlobalIdentifierForClass(t); globalIdentifier = OmsDatabase.GetGlobalIdentifierForClass(t);
} }
cl.Items.Add(new Property("GlobalIdentifier", new ObjectReference(new string[] { "System", "Guid" }), new CreateInstance(["System", "Guid"], [globalIdentifier.ToString()])) { AccessModifier = CodeGeneration.AccessModifier.Public }); cl.Items.Add(new Property("GlobalIdentifier", new ObjectReference(new string[] { "System", "Guid" }), new CreateInstance(new ObjectReference(["System", "Guid"]), [globalIdentifier.ToString()])) { AccessModifier = CodeGeneration.AccessModifier.Public });
cl.Items.Add(new Property("Oms", new ObjectReference(new string[] { "Mocha", "Core", "Oms" }), null) { AccessModifier = CodeGeneration.AccessModifier.Public, UseAutoProperty = true, ReadOnly = false }); cl.Items.Add(new Property("Oms", new ObjectReference(new string[] { "Mocha", "Core", "Oms" }), null) { AccessModifier = CodeGeneration.AccessModifier.Public, UseAutoProperty = true, ReadOnly = false });
foreach (PropertyInfo pi in t.GetProperties(BindingFlags.Public | BindingFlags.Instance)) foreach (PropertyInfo pi in t.GetProperties(BindingFlags.Public | BindingFlags.Instance))
{ {
cl.Items.Add(GenerateProperty(pi)); cl.Items.Add(GenerateProperty(cl, pi));
} }
return cl; return cl;
} }

View File

@ -0,0 +1,26 @@
// Copyright (C) 2025 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.Modeling;
public abstract class OmsPropertyImplementation
{
internal OmsPropertyImplementation(Oms oms)
{
}
}

View File

@ -15,8 +15,71 @@
// 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 Mocha.NET. If not, see <https://www.gnu.org/licenses/>. // along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
using System.Collections;
using Mocha.Modeling;
namespace Mocha.Core.Modeling.PropertyImplementations; namespace Mocha.Core.Modeling.PropertyImplementations;
public class OmsNonsingularRelationshipProperty : OmsRelationshipProperty public class OmsNonsingularRelationshipProperty<T> : OmsPropertyImplementation, IList<T> where T : IOmsClass
{ {
internal OmsNonsingularRelationshipProperty(Oms oms) : base(oms)
{
}
public T this[int index] { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public int Count => throw new NotImplementedException();
public bool IsReadOnly => throw new NotImplementedException();
public void Add(T item)
{
throw new NotImplementedException();
}
public void Clear()
{
throw new NotImplementedException();
}
public bool Contains(T item)
{
throw new NotImplementedException();
}
public void CopyTo(T[] array, int arrayIndex)
{
throw new NotImplementedException();
}
public IEnumerator<T> GetEnumerator()
{
throw new NotImplementedException();
}
public int IndexOf(T item)
{
throw new NotImplementedException();
}
public void Insert(int index, T item)
{
throw new NotImplementedException();
}
public bool Remove(T item)
{
throw new NotImplementedException();
}
public void RemoveAt(int index)
{
throw new NotImplementedException();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
} }

View File

@ -1,4 +1,4 @@
// Copyright (C) 2024 Michael Becker <alcexhim@gmail.com> // Copyright (C) 2025 Michael Becker <alcexhim@gmail.com>
// //
// This file is part of Mocha.NET. // This file is part of Mocha.NET.
// //
@ -15,9 +15,9 @@
// 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 Mocha.NET. If not, see <https://www.gnu.org/licenses/>. // along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
namespace Mocha.Core.Modeling.PropertyImplementations; namespace Mocha.Core.Modeling.PropertyImplementations;
public abstract class OmsRelationshipProperty public class OmsSingularRelationshipProperty
{ {
} }

View File

@ -15,6 +15,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 Mocha.NET. If not, see <https://www.gnu.org/licenses/>. // along with Mocha.NET. If not, see <https://www.gnu.org/licenses/>.
using Mocha.Core.Oop;
using Mocha.Core.Oop.Methods;
using Mocha.Testing; using Mocha.Testing;
namespace Mocha.Core.Tests; namespace Mocha.Core.Tests;
@ -51,4 +53,89 @@ public class InheritanceTests : OmsTestsBase
InstanceHandle ihParentClass = Oms.GetParentClass(ihTextAttribute); InstanceHandle ihParentClass = Oms.GetParentClass(ihTextAttribute);
Assert.That(ihParentClass, Is.EqualTo(ihClass)); Assert.That(ihParentClass, Is.EqualTo(ihClass));
} }
[Test]
public void Unimplemented_Abstract_Method_Call_throws_Exception()
{
// this is what we want to achieve:
// Abstract Base Class (e.g. Layout) defines attribute `Widget Name` which should be overridden by subclasses
// Abstract Base Class also defines a single Get Attribute method which returns `Widget Name`
// Concrete Subclass (e.g. Stylized Header Layout) overrides `Widget Name` attribute by re-defining it on the subclass
// Calling `Abstract Base Class@get Widget Name` with the subclass as `this` parm SHOULD return the overridden attribute value
// The Method should only be defined ONCE, and changes based on the overridden attributes of the subclasses
InstanceHandle c_TestClass = Oms.GetInstance(TEST_CLASS_GUID);
// `Test Class@get Widget Name(BA)` which is Abstract
BuildAttributeMethod m_TestMethod = Oms.MethodBuilder.CreateBuildAttributeMethod(c_TestClass, "get", "Widget Name", Core.Oop.AccessModifier.Public, false, Oms.GetInstance(KnownAttributeGuids.Text.Name), "DO_NOT_USE");
Oms.SetAttributeValue(m_TestMethod, Oms.GetInstance(KnownAttributeGuids.Boolean.Abstract), true);
ReturnAttributeMethodBinding ramb = m_TestMethod.CreateMethodBinding(Oms);
InstanceHandle c_TestClass2 = Oms.GetInstance(TEST_CLASS2_GUID);
Oms.AddSuperClass(c_TestClass2, c_TestClass);
// i_TestClass1 is an instance of c_TestClass2, which by inheritance includes c_TestClass
InstanceHandle i_TestClass1 = Oms.CreateInstanceOf(c_TestClass2);
OmsContext context = Oms.CreateContext();
Assert.That(delegate ()
{
// set the c_TestClass to i_TestClass1
// this call SHOULD succeed given that c_TestClass is a superclass of c_TestClass2, but I don't think this is enforced (yet)
context.SetWorkData(c_TestClass, i_TestClass1);
// this should throw an exception since c_TestClass2 does not yet implement the m_TestMethod defined as abstract on c_TestClass
string nom = Oms.ExecuteReturningAttributeValue<string>(context, ramb);
}, Throws.InvalidOperationException);
}
[Test]
public void Overridden_Abstract_Method_Call_does_not_throw_Exception()
{
// this is what we want to achieve:
// Abstract Base Class (e.g. Layout) defines attribute `Widget Name` which should be overridden by subclasses
// Abstract Base Class also defines a single Get Attribute method which returns `Widget Name`
// Concrete Subclass (e.g. Stylized Header Layout) overrides `Widget Name` attribute by re-defining it on the subclass
// Calling `Abstract Base Class@get Widget Name` with the subclass as `this` parm SHOULD return the overridden attribute value
// The Method should only be defined ONCE, and changes based on the overridden attributes of the subclasses
InstanceHandle c_TestClass = Oms.GetInstance(TEST_CLASS_GUID);
// `Test Class@get Widget Name(BA)` which is Abstract
BuildAttributeMethod m_TestMethod = Oms.MethodBuilder.CreateBuildAttributeMethod(c_TestClass, "get", "Widget Name", Core.Oop.AccessModifier.Public, false, Oms.GetInstance(KnownAttributeGuids.Text.Name), "DO_NOT_USE");
Oms.SetAttributeValue(m_TestMethod, Oms.GetInstance(KnownAttributeGuids.Boolean.Abstract), true);
ReturnAttributeMethodBinding ramb = m_TestMethod.CreateMethodBinding(Oms);
InstanceHandle c_TestClass2 = Oms.GetInstance(TEST_CLASS2_GUID);
Oms.AddSuperClass(c_TestClass2, c_TestClass);
// `Test Class 2@get Widget Name(BA)` which is overriding the Abstract defined above
string NOM_TEST_VALUE = "Hello World Test Class";
BuildAttributeMethod m_TestMethod2 = Oms.MethodBuilder.CreateBuildAttributeMethod(c_TestClass2, "get", "Widget Name", Core.Oop.AccessModifier.Public, false, Oms.GetInstance(KnownAttributeGuids.Text.Name), NOM_TEST_VALUE);
ReturnAttributeMethodBinding ramb2 = m_TestMethod2.CreateMethodBinding(Oms);
Oms.AssignRelationship(m_TestMethod2, Oms.GetInstance(KnownRelationshipGuids.Method__implements__Method), m_TestMethod);
// i_TestClass1 is an instance of c_TestClass2, which by inheritance includes c_TestClass
InstanceHandle i_TestClass1 = Oms.CreateInstanceOf(c_TestClass2);
OmsContext context = Oms.CreateContext();
string nom = "";
Assert.That(delegate ()
{
// set the c_TestClass to i_TestClass1
// this call SHOULD succeed given that c_TestClass is a superclass of c_TestClass2, but I don't think this is enforced (yet)
context.SetWorkData(c_TestClass, i_TestClass1);
// this should throw an exception since c_TestClass2 does not yet implement the m_TestMethod defined as abstract on c_TestClass
nom = Oms.ExecuteReturningAttributeValue<string>(context, ramb);
}, Throws.Nothing);
Assert.That(nom, Is.EqualTo(NOM_TEST_VALUE));
}
} }

View File

@ -33,17 +33,17 @@ public class MethodBindingTests : MethodTestsBase
[Test] [Test]
public void REMBInheritsFromMethodBinding() public void REMBInheritsFromMethodBinding()
{ {
/*
OmsMethodBuilder mb = new OmsMethodBuilder(Oms); OmsMethodBuilder mb = new OmsMethodBuilder(Oms);
InstanceHandle c_MethodBinding = Oms.GetInstance(KnownInstanceGuids.Classes.MethodBinding); InstanceHandle c_MethodBinding = Oms.GetInstance(KnownInstanceGuids.Classes.MethodBinding);
InstanceHandle a_Text = Oms.GetInstance(KnownAttributeGuids.Text.Value); InstanceHandle a_Text = Oms.GetInstance(KnownAttributeGuids.Text.Value);
MethodReturningAttribute dummy = mb.CreateGetAttributeMethod(c_TestClass, "get", "Test Attribute", a_Text); InstanceHandle hasBemProcess = Oms.CreateInstanceOf(Oms.GetInstance(KnownInstanceGuids.Classes.BEMProcess));
InstanceHandle elem = Oms.CreateInstanceOf(Oms.GetInstance(KnownInstanceGuids.Classes.Element));
InstanceHandle handle = mb.CreateReturnAttributeMethodBinding(dummy).Handle; MethodReturningElement dummy = mb.CreateBuildElementMethod(c_TestClass, "get", "Test Element", AccessModifier.Public, true, hasBemProcess, elem);
InstanceHandle handle = mb.CreateReturnElementMethodBinding(dummy).GetHandle();
Assert.That(Oms.IsInstanceOf(handle, c_MethodBinding)); Assert.That(Oms.IsInstanceOf(handle, c_MethodBinding));
*/
Assert.Ignore();
} }
[Test] [Test]
public void BRMBInheritsFromMethodBinding() public void BRMBInheritsFromMethodBinding()
@ -75,32 +75,28 @@ public class MethodBindingTests : MethodTestsBase
[Test] [Test]
public void PUMBInheritsFromMethodBinding() public void PUMBInheritsFromMethodBinding()
{ {
/*
OmsMethodBuilder mb = new OmsMethodBuilder(Oms); OmsMethodBuilder mb = new OmsMethodBuilder(Oms);
InstanceHandle c_MethodBinding = Oms.GetInstance(KnownInstanceGuids.Classes.MethodBinding); InstanceHandle c_MethodBinding = Oms.GetInstance(KnownInstanceGuids.Classes.MethodBinding);
InstanceHandle a_Text = Oms.GetInstance(KnownAttributeGuids.Text.Value); InstanceHandle a_Text = Oms.GetInstance(KnownAttributeGuids.Text.Value);
MethodReturningAttribute dummy = mb.CreateGetAttributeMethod(c_TestClass, "get", "Test Attribute", a_Text); List<ExecuteUpdateMethodBinding> eumbs = new List<ExecuteUpdateMethodBinding>();
ProcessUpdatesMethod dummy = mb.CreateProcessUpdatesMethod(c_TestClass, "process", "Test Attribute", AccessModifier.Public, true, eumbs);
InstanceHandle handle = mb.CreateReturnAttributeMethodBinding(dummy).Handle; InstanceHandle handle = mb.CreateProcessUpdatesMethodBinding(dummy).GetHandle();
Assert.That(Oms.IsInstanceOf(handle, c_MethodBinding)); Assert.That(Oms.IsInstanceOf(handle, c_MethodBinding));
*/
Assert.Ignore();
} }
[Test] [Test]
public void EUMBInheritsFromMethodBinding() public void EUMBInheritsFromMethodBinding()
{ {
/*
OmsMethodBuilder mb = new OmsMethodBuilder(Oms); OmsMethodBuilder mb = new OmsMethodBuilder(Oms);
InstanceHandle c_MethodBinding = Oms.GetInstance(KnownInstanceGuids.Classes.MethodBinding); InstanceHandle c_MethodBinding = Oms.GetInstance(KnownInstanceGuids.Classes.MethodBinding);
InstanceHandle a_Text = Oms.GetInstance(KnownAttributeGuids.Text.Value); InstanceHandle a_Text = Oms.GetInstance(KnownAttributeGuids.Text.Value);
InstanceHandle a_Token = Oms.GetInstance(KnownAttributeGuids.Text.Token);
MethodReturningAttribute dummy = mb.CreateGetAttributeMethod(c_TestClass, "get", "Test Attribute", a_Text); AssignAttributeMethod dummy = mb.CreateAssignAttributeMethod(c_TestClass, "set", "Test Attribute", AccessModifier.Public, true, a_Token, a_Text);
InstanceHandle handle = mb.CreateReturnAttributeMethodBinding(dummy).Handle; InstanceHandle handle = mb.CreateExecuteUpdateMethodBinding(dummy).GetHandle();
Assert.That(Oms.IsInstanceOf(handle, c_MethodBinding)); Assert.That(Oms.IsInstanceOf(handle, c_MethodBinding));
*/
Assert.Ignore();
} }
[Test] [Test]

View File

@ -53,22 +53,63 @@ public class SystemRoutineTests : MethodTestsBase
OmsMethodBuilder methodBuilder = new OmsMethodBuilder(Oms); OmsMethodBuilder methodBuilder = new OmsMethodBuilder(Oms);
OmsSystemRoutineBuilder systemRoutineBuilder = new OmsSystemRoutineBuilder(Oms); OmsSystemRoutineBuilder systemRoutineBuilder = new OmsSystemRoutineBuilder(Oms);
// create a System Attribute Routine to return a test value
SystemAttributeRoutine<string> testSystemAttributeRoutine = systemRoutineBuilder.CreateSystemAttributeRoutine(TEST_SYSTEM_ATTRIBUTE_ROUTINE_GUID, delegate (Oms oms, OmsContext context) SystemAttributeRoutine<string> testSystemAttributeRoutine = systemRoutineBuilder.CreateSystemAttributeRoutine(TEST_SYSTEM_ATTRIBUTE_ROUTINE_GUID, delegate (Oms oms, OmsContext context)
{ {
string value = context.GetWorkData<string>(oms.GetInstance(KnownAttributeGuids.Text.Token)); string value = context.GetWorkData<string>(oms.GetInstance(KnownAttributeGuids.Text.Token));
return TEST_SYSTEM_ATTRIBUTE_ROUTINE_VALUE + value; return TEST_SYSTEM_ATTRIBUTE_ROUTINE_VALUE + value;
}); });
// create a GAS - Get Attribute by System Routine method which returns the attribute via the above system routine
GetAttributeBySystemRoutineMethod gasMethod = methodBuilder.CreateGetAttributeBySystemRoutineMethod(irTestClass, "get", "Test System Routine Text Attribute", AccessModifier.Public, true, Oms.GetInstance(KnownAttributeGuids.Text.Value), testSystemAttributeRoutine); GetAttributeBySystemRoutineMethod gasMethod = methodBuilder.CreateGetAttributeBySystemRoutineMethod(irTestClass, "get", "Test System Routine Text Attribute", AccessModifier.Public, true, Oms.GetInstance(KnownAttributeGuids.Text.Value), testSystemAttributeRoutine);
ReturnAttributeMethodBinding gasMethodRamb = methodBuilder.CreateReturnAttributeMethodBinding(gasMethod); ReturnAttributeMethodBinding gasMethodRamb = methodBuilder.CreateReturnAttributeMethodBinding(gasMethod);
OmsContext context = Oms.CreateContext(); OmsContext context = Oms.CreateContext();
// execute the above RAMB, passing in the `Token` parameter with an expected hardcoded string
string value = Oms.ExecuteReturningAttributeValue<string>(context, gasMethodRamb, null, new KeyValuePair<InstanceHandle, object>[] string value = Oms.ExecuteReturningAttributeValue<string>(context, gasMethodRamb, null, new KeyValuePair<InstanceHandle, object>[]
{ {
// !!! WARNING: do not use 'Value' here as it is the return type attribute of the GAS method and WILL be overwritten after execution !!! // !!! WARNING: do not use 'Value' here as it is the return type attribute of the GAS method and WILL be overwritten after execution !!!
new KeyValuePair<InstanceHandle, object>(Oms.GetInstance(KnownAttributeGuids.Text.Token), "pqdms") new KeyValuePair<InstanceHandle, object>(Oms.GetInstance(KnownAttributeGuids.Text.Token), "pqdms")
}); });
// check to ensure that the result is the above executed System Routine which combines the test value with the passed in parameter
Assert.That(value, Is.EqualTo(TEST_SYSTEM_ATTRIBUTE_ROUTINE_VALUE + "pqdms"));
}
[Test]
public void PassParmViaSystemRoutineTest_AssignedViaRAMB()
{
InstanceHandle irTestClass = Oms.GetInstance(TEST_CLASS_GUID);
OmsMethodBuilder methodBuilder = new OmsMethodBuilder(Oms);
OmsSystemRoutineBuilder systemRoutineBuilder = new OmsSystemRoutineBuilder(Oms);
// create a System Attribute Routine to return a test value
SystemAttributeRoutine<string> testSystemAttributeRoutine = systemRoutineBuilder.CreateSystemAttributeRoutine(TEST_SYSTEM_ATTRIBUTE_ROUTINE_GUID, delegate (Oms oms, OmsContext context)
{
string value = context.GetWorkData<string>(oms.GetInstance(KnownAttributeGuids.Text.Token));
return TEST_SYSTEM_ATTRIBUTE_ROUTINE_VALUE + value;
});
// create a GAS - Get Attribute by System Routine method which returns the attribute via the above system routine
GetAttributeBySystemRoutineMethod gasMethod = methodBuilder.CreateGetAttributeBySystemRoutineMethod(irTestClass, "get", "Test System Routine Text Attribute", AccessModifier.Public, true, Oms.GetInstance(KnownAttributeGuids.Text.Value), testSystemAttributeRoutine);
ReturnAttributeMethodBinding gasMethodRamb = methodBuilder.CreateReturnAttributeMethodBinding(gasMethod, new KeyValuePair<InstanceHandle, InstanceHandle>[]
{
// assign from work data: `User Name` to parm: `Token`
new KeyValuePair<InstanceHandle, InstanceHandle>(Oms.GetInstance(KnownAttributeGuids.Text.Token), Oms.GetInstance(KnownAttributeGuids.Text.UserName))
});
OmsContext context = Oms.CreateContext();
// execute the above RAMB, passing in the `Token` parameter with an expected hardcoded string
// here we specify `User Name` attribute instead of `Token`; the RAMB is set to assign `Token` =
string value = Oms.ExecuteReturningAttributeValue<string>(context, gasMethodRamb, null, new KeyValuePair<InstanceHandle, object>[]
{
// !!! WARNING: do not use 'Value' here as it is the return type attribute of the GAS method and WILL be overwritten after execution !!!
new KeyValuePair<InstanceHandle, object>(Oms.GetInstance(KnownAttributeGuids.Text.UserName), "pqdms")
});
// check to ensure that the result is the above executed System Routine which combines the test value with the passed in parameter
Assert.That(value, Is.EqualTo(TEST_SYSTEM_ATTRIBUTE_ROUTINE_VALUE + "pqdms")); Assert.That(value, Is.EqualTo(TEST_SYSTEM_ATTRIBUTE_ROUTINE_VALUE + "pqdms"));
} }

View File

@ -59,6 +59,28 @@ public class WorkSetTests : OmsTestsBase
}, Throws.ArgumentException); }, Throws.ArgumentException);
} }
[Test]
public void SingleValidClassConstraintWithInheritance()
{
// we should be able to put a `Text Attribute` instance into this Work Set if its valid class is `Attribute`
InstanceHandle c_Attribute = Oms.GetInstance(KnownInstanceGuids.Classes.Attribute);
InstanceHandle c_TextAttribute = Oms.GetInstance(KnownInstanceGuids.Classes.TextAttribute);
WorkSet workSet = Oms.CreateWorkSet("Dummy Work Set", true, new InstanceHandle[]
{
c_Attribute
});
Oms.SetAttributeValue(workSet, Oms.GetInstance(KnownAttributeGuids.Boolean.IncludeSubclasses), true);
InstanceHandle a_Name = Oms.GetInstance(KnownAttributeGuids.Text.Name);
OmsContext context = Oms.CreateContext();
Assert.That(delegate ()
{
context.SetWorkData(workSet, a_Name);
}, Throws.Nothing);
}
[Test] [Test]
public void MultipleValidClassConstraintSingular() public void MultipleValidClassConstraintSingular()
{ {
@ -151,4 +173,64 @@ public class WorkSetTests : OmsTestsBase
context.SetWorkData(workSet, true); context.SetWorkData(workSet, true);
}, Throws.ArgumentException); }, Throws.ArgumentException);
} }
[Test]
public void TextAttributeWorkData()
{
OmsContext context = Oms.CreateContext();
Assert.That(delegate ()
{
// cannot assign boolean to Text Attribute
InstanceHandle a_Name = Oms.GetInstance(KnownAttributeGuids.Text.Name);
context.SetWorkData(a_Name, true);
}, Throws.ArgumentException);
Assert.That(delegate ()
{
// cannot assign DateTime to Text Attribute
InstanceHandle a_Name = Oms.GetInstance(KnownAttributeGuids.Text.Name);
context.SetWorkData(a_Name, DateTime.Now);
}, Throws.ArgumentException);
Assert.That(delegate ()
{
// cannot assign decimal to Text Attribute
InstanceHandle a_Name = Oms.GetInstance(KnownAttributeGuids.Text.Name);
context.SetWorkData(a_Name, 5.3M);
}, Throws.ArgumentException);
Assert.That(delegate ()
{
// can assign string to Text Attribute
InstanceHandle a_Name = Oms.GetInstance(KnownAttributeGuids.Text.Name);
context.SetWorkData(a_Name, "hello world");
}, Throws.Nothing);
}
[Test]
public void DateAttributeWorkData()
{
OmsContext context = Oms.CreateContext();
Assert.That(delegate ()
{
// cannot assign boolean to Date Attribute
InstanceHandle a_Name = Oms.GetInstance(KnownAttributeGuids.Date.DateAndTime);
context.SetWorkData(a_Name, true);
}, Throws.ArgumentException);
Assert.That(delegate ()
{
// cannot assign decimal to Date Attribute
InstanceHandle a_Name = Oms.GetInstance(KnownAttributeGuids.Date.DateAndTime);
context.SetWorkData(a_Name, 5.3M);
}, Throws.ArgumentException);
Assert.That(delegate ()
{
// cannot assign string to Date Attribute
InstanceHandle a_Name = Oms.GetInstance(KnownAttributeGuids.Date.DateAndTime);
context.SetWorkData(a_Name, "hello world");
}, Throws.ArgumentException);
Assert.That(delegate ()
{
// can assign DateTime to Date Attribute
InstanceHandle a_Name = Oms.GetInstance(KnownAttributeGuids.Date.DateAndTime);
context.SetWorkData(a_Name, DateTime.Now);
}, Throws.Nothing);
}
} }