Compare commits

...

3 Commits

9 changed files with 94 additions and 25 deletions

@ -1 +1 @@
Subproject commit 4581cd44fa4c70c8b596cc50d056152b7498a6d9 Subproject commit 899d60cd1b22dec2fe010c6fe4ed49e006cd173c

View File

@ -123,6 +123,10 @@ public class Program : WebApplication
Log.WriteLine("path not found: " + path); Log.WriteLine("path not found: " + path);
return; return;
} }
else
{
Log.WriteLine("base path for MCLs: " + path);
}
string[] requiredLibraries = new string[] string[] requiredLibraries = new string[]
{ {

View File

@ -48,6 +48,7 @@ public class ElementCommand : InstanceCommand
JsonObject obj2 = new JsonObject(); JsonObject obj2 = new JsonObject();
obj2.Add("result", "failure"); obj2.Add("result", "failure");
obj2.Add("message", "no CT associated with element"); obj2.Add("message", "no CT associated with element");
obj2.Add("element", oms.GetInstanceKey(ProcessingInstance).ToString());
RespondWithJson(oms, sw, e.Context, 400, "Bad Request", obj2); RespondWithJson(oms, sw, e.Context, 400, "Bad Request", obj2);
return; return;
} }

View File

@ -40,6 +40,11 @@ public abstract class AttributeImplementation : ClassImplementation
protected virtual IEnumerable<Type> ConvertibleDataTypes { get; } = []; protected virtual IEnumerable<Type> ConvertibleDataTypes { get; } = [];
protected abstract object? ConvertFromInternal(Oms oms, object? value); protected abstract object? ConvertFromInternal(Oms oms, object? value);
protected virtual object AutoCast(object value)
{
return value;
}
public object? ReadDerivedData(BinaryReader br) public object? ReadDerivedData(BinaryReader br)
{ {
return ReadDerivedDataInternal(br); return ReadDerivedDataInternal(br);
@ -63,6 +68,7 @@ public abstract class AttributeImplementation : ClassImplementation
} }
public void Validate(Oms oms, InstanceHandle attributeInstance, object value) public void Validate(Oms oms, InstanceHandle attributeInstance, object value)
{ {
value = AutoCast(value);
if (ValidDataTypes != null) if (ValidDataTypes != null)
{ {
if (value != null && !ValidDataTypes.Contains(value.GetType())) if (value != null && !ValidDataTypes.Contains(value.GetType()))
@ -78,7 +84,8 @@ public abstract class AttributeImplementation : ClassImplementation
{ {
id = oms.GetGlobalIdentifier(ih).ToString("b"); id = oms.GetGlobalIdentifier(ih).ToString("b");
} }
throw new ArgumentException(String.Format("value {0} cannot be converted to attribute type `{1}` [{2}]", value is string ? "\"" + value.ToString() + "\"" : id, oms.GetInstanceText(attributeInstance), oms.GetInstanceKey(attributeInstance))); // throw new ArgumentException(String.Format("value {0} cannot be converted to attribute type `{1}` [{2}]", value is string ? "\"" + value.ToString() + "\"" : id, oms.GetInstanceText(attributeInstance), oms.GetInstanceKey(attributeInstance)));
throw new ArgumentException(String.Format("value {0} cannot be converted to attribute type `{1}`", value is string ? "\"" + value.ToString() + "\"" : value, oms.GetInstanceKey(attributeInstance)));
} }
} }
} }

View File

@ -26,6 +26,15 @@ public class BooleanAttributeImplementation : AttributeImplementation<bool>
public override Guid ClassGuid => KnownInstanceGuids.Classes.BooleanAttribute; public override Guid ClassGuid => KnownInstanceGuids.Classes.BooleanAttribute;
protected override IEnumerable<Type> ConvertibleDataTypes => [ typeof(string) ]; protected override IEnumerable<Type> ConvertibleDataTypes => [ typeof(string) ];
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) protected override object? ConvertFromInternal(Oms oms, object? value)
{ {
if (value is string) if (value is string)

View File

@ -0,0 +1,31 @@
// Copyright (C) 2025 Michael Becker <alcexhim@gmail.com>
//
// 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 <https://www.gnu.org/licenses/>.
/// <summary>
/// Debug toggle switches for internal Mocha Core use only.
/// </summary>
public static class DebugToggleSwitches
{
/// <summary>
/// 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.
/// </summary>
/// <value></value>
public static bool Validate_Constraints_for_Attributes_on_set_Work_Data { get; } = false;
}

View File

@ -917,7 +917,7 @@ public abstract class Oms
if (!ValidateConstraints) if (!ValidateConstraints)
return; 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` // all we can do really is verify if it's supposed to be `Not Empty`
return; return;
@ -1426,8 +1426,10 @@ public abstract class Oms
continue; continue;
} }
object? assignsFromWorkDataValue = assignsFromWorkData;
// there are several possibilities: // there are several possibilities:
// `assigns to Parm` is a Class which is an Attribute. `assigns from Work Data` is an Attribute. // `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` // 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" // `Token` := `User Name` -> `Token` = "testinguser"
@ -1471,8 +1473,10 @@ public abstract class Oms
assignsFromWorkData = context.GetWorkData<InstanceHandle>(assignsFromWorkData); assignsFromWorkData = context.GetWorkData<InstanceHandle>(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);
} }
} }
@ -2484,29 +2488,27 @@ public abstract class Oms
public bool EvaluateConditions(OmsContext context, IEnumerable<InstanceHandle> trueConditions, IEnumerable<InstanceHandle> falseConditions, bool useAnyCondition) public bool EvaluateConditions(OmsContext context, IEnumerable<InstanceHandle> trueConditions, IEnumerable<InstanceHandle> falseConditions, bool useAnyCondition)
{ {
bool value = false; 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); value = true;
if (retval is bool && ((bool)retval)) 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); value = true;
object? retval = context.GetWorkData(ret); break;
if (retval is bool && (!(bool)retval))
{
value = true;
break;
}
} }
} }
return value; return value;

View File

@ -74,11 +74,17 @@ public class OmsContext
// !fixme! move all this hardcoded $@#! into configurable OMS AttributeImplementations // !fixme! move all this hardcoded $@#! into configurable OMS AttributeImplementations
if (Oms.IsInstanceOf(parm, Oms.GetInstance(KnownInstanceGuids.Classes.BooleanAttribute))) 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))) 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; return value;
@ -224,7 +230,12 @@ public class OmsContext
} }
else 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; _WorkData[parm] = value;

View File

@ -40,6 +40,10 @@ public class Element : Widget
// if we hae `Show Subelements Vertically`, we are a vbox // if we hae `Show Subelements Vertically`, we are a vbox
if (displayOptions.Contains(doShowSubelementsVertically)) if (displayOptions.Contains(doShowSubelementsVertically))
{ {
if (displayOptions.Contains(doSingular))
{
return "fieldSet"; // hack
}
return "vbox"; return "vbox";
} }
else else