diff --git a/mocha-dotnet/src/app/Mocha.Oms.Server/Program.cs b/mocha-dotnet/src/app/Mocha.Oms.Server/Program.cs index 07a1004..1636ba5 100644 --- a/mocha-dotnet/src/app/Mocha.Oms.Server/Program.cs +++ b/mocha-dotnet/src/app/Mocha.Oms.Server/Program.cs @@ -123,6 +123,10 @@ public class Program : WebApplication Log.WriteLine("path not found: " + path); return; } + else + { + Log.WriteLine("base path for MCLs: " + path); + } string[] requiredLibraries = new string[] { diff --git a/mocha-dotnet/src/lib/Mocha.Core.UI.Server/Commands/ElementCommand.cs b/mocha-dotnet/src/lib/Mocha.Core.UI.Server/Commands/ElementCommand.cs index da22f66..8289413 100644 --- a/mocha-dotnet/src/lib/Mocha.Core.UI.Server/Commands/ElementCommand.cs +++ b/mocha-dotnet/src/lib/Mocha.Core.UI.Server/Commands/ElementCommand.cs @@ -48,6 +48,7 @@ public class ElementCommand : InstanceCommand JsonObject obj2 = new JsonObject(); obj2.Add("result", "failure"); obj2.Add("message", "no CT associated with element"); + obj2.Add("element", oms.GetInstanceKey(ProcessingInstance).ToString()); RespondWithJson(oms, sw, e.Context, 400, "Bad Request", obj2); return; } diff --git a/mocha-dotnet/src/lib/Mocha.Core/AttributeImplementation.cs b/mocha-dotnet/src/lib/Mocha.Core/AttributeImplementation.cs index 00bd958..3b1a8b9 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/AttributeImplementation.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/AttributeImplementation.cs @@ -39,6 +39,11 @@ public abstract class AttributeImplementation : ClassImplementation protected virtual IEnumerable? ValidDataTypes { get; } protected abstract object? ConvertFromInternal(Oms oms, object? value); + protected virtual object AutoCast(object value) + { + return value; + } + public object? ReadDerivedData(BinaryReader br) { return ReadDerivedDataInternal(br); @@ -62,11 +67,12 @@ public abstract class AttributeImplementation : ClassImplementation } public void Validate(Oms oms, InstanceHandle attributeInstance, object value) { + value = AutoCast(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))); + throw new ArgumentException(String.Format("value {0} cannot be converted to attribute type `{1}`", value is string ? "\"" + value.ToString() + "\"" : value, oms.GetInstanceKey(attributeInstance))); } } ValidateInternal(oms, attributeInstance, value); diff --git a/mocha-dotnet/src/lib/Mocha.Core/AttributeImplementations/BooleanAttributeImplementation.cs b/mocha-dotnet/src/lib/Mocha.Core/AttributeImplementations/BooleanAttributeImplementation.cs index 8e6c83d..a922778 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/AttributeImplementations/BooleanAttributeImplementation.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/AttributeImplementations/BooleanAttributeImplementation.cs @@ -25,6 +25,15 @@ public class BooleanAttributeImplementation : AttributeImplementation { public override Guid ClassGuid => KnownInstanceGuids.Classes.BooleanAttribute; + protected override object AutoCast(object value) + { + if (value is string) + { + return Boolean.Parse((string)value); + } + return value; + } + protected override object? ConvertFromInternal(Oms oms, object? value) { if (value is string) diff --git a/mocha-dotnet/src/lib/Mocha.Core/DebugToggleSwitches.cs b/mocha-dotnet/src/lib/Mocha.Core/DebugToggleSwitches.cs new file mode 100644 index 0000000..d670a25 --- /dev/null +++ b/mocha-dotnet/src/lib/Mocha.Core/DebugToggleSwitches.cs @@ -0,0 +1,31 @@ +// Copyright (C) 2025 Michael Becker +// +// This file is part of mocha-docker. +// +// mocha-docker 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-docker 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-docker. If not, see . + +/// +/// Debug toggle switches for internal Mocha Core use only. +/// +public static class DebugToggleSwitches +{ + /// + /// Temporary toggle to fix latent bugs which surfaced when we started validating attributes on Work Data. + /// (See OmsContext.cs) + /// + /// Toggle on when testing to uncover the underlying issues in the MCL/YAML; toggle off if you want a usable PHP/docker frontend to work. + /// + /// + public static bool Validate_Constraints_for_Attributes_on_set_Work_Data { get; } = false; +} \ No newline at end of file diff --git a/mocha-dotnet/src/lib/Mocha.Core/InstanceHandle.cs b/mocha-dotnet/src/lib/Mocha.Core/InstanceHandle.cs index 3c743c8..0cc8cce 100755 --- a/mocha-dotnet/src/lib/Mocha.Core/InstanceHandle.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/InstanceHandle.cs @@ -109,7 +109,7 @@ namespace Mocha.Core if (Oms.DebugOms != null) { - return Oms.DebugOms.GetInstanceText(this); + //return Oms.DebugOms.GetInstanceText(this); } return _ID.ToString(); } diff --git a/mocha-dotnet/src/lib/Mocha.Core/Oms.cs b/mocha-dotnet/src/lib/Mocha.Core/Oms.cs index 57cd478..c9cdd92 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/Oms.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/Oms.cs @@ -917,7 +917,7 @@ public abstract class Oms if (!ValidateConstraints) return; - if (value == null || value == "") + if (value == null || (value is string && (string)value == "")) { // all we can do really is verify if it's supposed to be `Not Empty` return; @@ -1426,8 +1426,10 @@ public abstract class Oms continue; } + object? assignsFromWorkDataValue = assignsFromWorkData; + // 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" @@ -1442,7 +1444,11 @@ public abstract class Oms 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)); + assignsFromWorkDataValue = context.GetWorkData(assignsFromWorkData); + } + else if (IsInstanceOf(assignsToParm, GetInstance(KnownInstanceGuids.Classes.Attribute)) && IsInstanceOf(assignsFromWorkData, GetInstance(KnownInstanceGuids.Classes.ReturnAttributeMethodBinding))) + { + assignsFromWorkDataValue = Execute(context, assignsFromWorkData.GetHandle()); } else { @@ -1459,8 +1465,10 @@ public abstract class Oms assignsFromWorkData = context.GetWorkData(assignsFromWorkData); } } - context.SetWorkData(assignsToParm, assignsFromWorkData); + assignsFromWorkDataValue = assignsFromWorkData; } + // Console.Error.WriteLine("assign to parm: {0}, assign from WD: {1} ('{2}')", GetInstanceKey(assignsToParm), GetInstanceKey(assignsFromWorkData), assignsFromWorkDataValue); + context.SetWorkData(assignsToParm, assignsFromWorkData); } } @@ -2472,29 +2480,27 @@ public abstract class Oms public bool EvaluateConditions(OmsContext context, IEnumerable trueConditions, IEnumerable falseConditions, bool useAnyCondition) { bool value = false; - if (trueConditions != null) + if (trueConditions.Count() == 0 && falseConditions.Count() == 0) { - foreach (InstanceHandle trueCondition in trueConditions) + return true; + } + foreach (InstanceHandle trueCondition in trueConditions) + { + object? retval = Evaluate(context, trueCondition, InstanceHandle.Empty); + if (retval is bool && ((bool)retval)) { - object? retval = Evaluate(context, trueCondition, InstanceHandle.Empty); - if (retval is bool && ((bool)retval)) - { - value = true; - break; - } + value = true; + break; } } - if (falseConditions != null) + foreach (InstanceHandle falseCondition in falseConditions) { - foreach (InstanceHandle falseCondition in falseConditions) + InstanceHandle ret = Execute(context, falseCondition); + object? retval = context.GetWorkData(ret); + if (retval is bool && (!(bool)retval)) { - InstanceHandle ret = Execute(context, falseCondition); - object? retval = context.GetWorkData(ret); - if (retval is bool && (!(bool)retval)) - { - value = true; - break; - } + value = true; + break; } } return value; diff --git a/mocha-dotnet/src/lib/Mocha.Core/OmsContext.cs b/mocha-dotnet/src/lib/Mocha.Core/OmsContext.cs index 971474a..166381f 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/OmsContext.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/OmsContext.cs @@ -74,11 +74,17 @@ public class OmsContext // !fixme! move all this hardcoded $@#! into configurable OMS AttributeImplementations if (Oms.IsInstanceOf(parm, Oms.GetInstance(KnownInstanceGuids.Classes.BooleanAttribute))) { - value = Boolean.Parse(sz); + if (Boolean.TryParse(sz, out bool val)) + { + value = val; + } } else if (Oms.IsInstanceOf(parm, Oms.GetInstance(KnownInstanceGuids.Classes.DateAttribute))) { - value = DateTime.Parse(sz); + if (DateTime.TryParse(sz, out DateTime val)) + { + value = val; + } } } return value; @@ -224,7 +230,12 @@ public class OmsContext } else { - Oms.ValidateConstraintsForAttribute(parm, value); + // FIXME: this bugs out for some reason when running the whole frontend PHP application + // perhaps we've been doing something wrong this whole time? + if (DebugToggleSwitches.Validate_Constraints_for_Attributes_on_set_Work_Data) + { + Oms.ValidateConstraintsForAttribute(parm, value); + } } } _WorkData[parm] = value; diff --git a/mocha-dotnet/src/lib/Mocha.Core/UI/Widgets/Element.cs b/mocha-dotnet/src/lib/Mocha.Core/UI/Widgets/Element.cs index 2c92216..395de72 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/UI/Widgets/Element.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/UI/Widgets/Element.cs @@ -40,6 +40,10 @@ public class Element : Widget // if we hae `Show Subelements Vertically`, we are a vbox if (displayOptions.Contains(doShowSubelementsVertically)) { + if (displayOptions.Contains(doSingular)) + { + return "fieldSet"; // hack + } return "vbox"; } else