From 675dddbc0a84b63fa5398daf3b7ed6b39465b766 Mon Sep 17 00:00:00 2001 From: Michael Becker Date: Sun, 13 Oct 2024 18:39:59 -0400 Subject: [PATCH] still trying to figure things out... --- .../src/lib/Mocha.Core/InstanceHandle.cs | 2 + .../src/lib/Mocha.Core/InstanceReference.cs | 47 +++++ mocha-dotnet/src/lib/Mocha.Core/Oms.cs | 10 +- .../OmsImplementations/EmbeddedMiniOms.cs | 38 ++++ .../OmsImplementations/MemoryOms.cs | 170 +++++++++--------- .../Mini/HardcodedMiniOms.cs | 2 +- .../tests/Mocha.Core.Tests/EmbeddedMiniOms.cs | 10 +- .../Mocha.Core.Tests/LibraryLoaderTests.cs | 11 +- 8 files changed, 194 insertions(+), 96 deletions(-) create mode 100644 mocha-dotnet/src/lib/Mocha.Core/InstanceReference.cs create mode 100644 mocha-dotnet/src/lib/Mocha.Core/OmsImplementations/EmbeddedMiniOms.cs diff --git a/mocha-dotnet/src/lib/Mocha.Core/InstanceHandle.cs b/mocha-dotnet/src/lib/Mocha.Core/InstanceHandle.cs index d665118..a803187 100755 --- a/mocha-dotnet/src/lib/Mocha.Core/InstanceHandle.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/InstanceHandle.cs @@ -49,6 +49,8 @@ namespace Mocha.Core private NanoId _ID; private bool isNotEmpty; + public Guid GlobalIdentifier; + public InstanceHandle GetHandle() { return this; } public static InstanceHandle Create() diff --git a/mocha-dotnet/src/lib/Mocha.Core/InstanceReference.cs b/mocha-dotnet/src/lib/Mocha.Core/InstanceReference.cs new file mode 100644 index 0000000..d625429 --- /dev/null +++ b/mocha-dotnet/src/lib/Mocha.Core/InstanceReference.cs @@ -0,0 +1,47 @@ +// Copyright (C) 2024 Michael Becker +// +// 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 . + +public class InstanceReference +{ + public InstanceReference(Guid globalIdentifier) + { + GlobalIdentifier = globalIdentifier; + } + public Guid GlobalIdentifier { get; } + + public static bool operator==(InstanceReference left, InstanceReference right) + { + return left.Equals(right); + } + public static bool operator!=(InstanceReference left, InstanceReference right) + { + return !left.Equals(right); + } + + public override bool Equals(object? obj) + { + if (obj is InstanceReference) + { + return ((InstanceReference)obj).GlobalIdentifier.Equals(this.GlobalIdentifier); + } + return false; + } + public override int GetHashCode() + { + return GlobalIdentifier.GetHashCode(); + } +} \ No newline at end of file diff --git a/mocha-dotnet/src/lib/Mocha.Core/Oms.cs b/mocha-dotnet/src/lib/Mocha.Core/Oms.cs index 7eba1ca..f405314 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/Oms.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/Oms.cs @@ -266,6 +266,7 @@ public abstract class Oms { if (TryGetInstance(globalIdentifier, out InstanceHandle ih)) { + ih.GlobalIdentifier = globalIdentifier; return ih; } throw new KeyNotFoundException(String.Format("inst not found: {0}", globalIdentifier)); @@ -1212,7 +1213,7 @@ public abstract class Oms // to do its second pass "linking" the objects lib.Link(); - InitializeLibraryInternal(lh, lib); + InitializeLibrary(lh, lib); return lh; } @@ -1270,7 +1271,7 @@ public abstract class Oms // to do its second pass "linking" the objects lib.Link(); - InitializeLibraryInternal(lh, lib); + InitializeLibrary(lh, lib); return lh; } @@ -1284,12 +1285,17 @@ public abstract class Oms { LibraryHandle lh = LoadLibrary(st); _libraryFileNames[lh] = manifestResourceStreamName; + _libraries[manifestResourceStreamName] = lh; return lh; } throw new KeyNotFoundException(String.Format("manifest resource stream named '{0}' not found", manifestResourceStreamName)); } protected abstract void InitializeLibraryInternal(LibraryHandle lh, Library lib); + private void InitializeLibrary(LibraryHandle lh, Library lib) + { + InitializeLibraryInternal(lh, lib); + } public string? GetTenantName(TenantHandle tenant) { diff --git a/mocha-dotnet/src/lib/Mocha.Core/OmsImplementations/EmbeddedMiniOms.cs b/mocha-dotnet/src/lib/Mocha.Core/OmsImplementations/EmbeddedMiniOms.cs new file mode 100644 index 0000000..fb8f423 --- /dev/null +++ b/mocha-dotnet/src/lib/Mocha.Core/OmsImplementations/EmbeddedMiniOms.cs @@ -0,0 +1,38 @@ +// Copyright (C) 2024 Michael Becker +// +// 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 . + +using Mocha.Core.OmsImplementations; + +namespace Mocha.Core.OmsImplementations; + +public class EmbeddedMiniOms : MemoryOms +{ + public string SystemLibraryResourceName { get; set; } = "Mocha.Core.Tests.Resources.net.alcetech.Mocha.System.mcl"; + + protected override void InitializeInternal() + { + base.InitializeInternal(); + + TenantHandle th = CreateTenant("super"); + SelectTenant(th); + if (SystemLibraryResourceName != null) + { + LibraryHandle lh = LoadLibrary(typeof(EmbeddedMiniOms), SystemLibraryResourceName); + AddLibraryReference(lh); + } + } +} \ No newline at end of file diff --git a/mocha-dotnet/src/lib/Mocha.Core/OmsImplementations/MemoryOms.cs b/mocha-dotnet/src/lib/Mocha.Core/OmsImplementations/MemoryOms.cs index 81547ca..ae6b17c 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/OmsImplementations/MemoryOms.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/OmsImplementations/MemoryOms.cs @@ -25,6 +25,12 @@ public class MemoryOms : Oms { private class _Tenant { + private MemoryOms oms; + public _Tenant(MemoryOms oms) + { + this.oms = oms; + } + private Dictionary _instancesByGuid = new Dictionary(); private Dictionary _guidsByInstance = new Dictionary(); @@ -43,6 +49,12 @@ public class MemoryOms : Oms { return _guidsByInstance[instance]; } + foreach (LibraryHandle lh in _libraryReferences) + { + Guid gid = oms._libraries[lh].GetGlobalIdentifier(instance); + if (gid != Guid.Empty) + return gid; + } return Guid.Empty; } public InstanceKey GetInstanceKey(InstanceHandle instance) @@ -61,6 +73,20 @@ public class MemoryOms : Oms ih = _instancesByGuid[globalIdentifier]; return true; } + foreach (LibraryHandle lh in _libraryReferences) + { + if (oms._libraries.ContainsKey(lh)) + { + if (oms._libraries[lh].TryGetInstance(globalIdentifier, out ih)) + { + // LibraryInst_g g = new LibraryInst_g() { InstanceHandle = ih, SourceLibrary = lh, GlobalIdentifier = globalIdentifier }; + // _libraries[lh]._libraryInst_gs[globalIdentifier] = g; + // _libraries[lh]._libraryInst_is[ih] = g; + return true; + } + } + } + ih = InstanceHandle.Empty; return false; } @@ -84,6 +110,8 @@ public class MemoryOms : Oms public InstanceHandle CreateInstance(Guid guid) { InstanceHandle ir = InstanceHandle.Create(); + ir.GlobalIdentifier = guid; + _instancesByGuid[guid] = ir; _guidsByInstance[ir] = guid; return ir; @@ -139,6 +167,18 @@ public class MemoryOms : Oms return list2.ToArray(); } } + + foreach (LibraryHandle lh in _libraryReferences) + { + if (oms._libraries.ContainsKey(lh)) + { + IReadOnlyCollection insts2 = oms._libraries[lh].GetRelatedInstances(source, relationship, effectiveDate); + if (insts2.Count > 0) + { + return insts2; + } + } + } return new InstanceHandle[0]; } @@ -161,7 +201,7 @@ public class MemoryOms : Oms return false; } - public object GetAttributeValue(InstanceHandle source, InstanceHandle attribute, DateTime effectiveDate) + public object? GetAttributeValue(InstanceHandle source, InstanceHandle attribute, DateTime effectiveDate) { if (_Attributes.ContainsKey(source)) { @@ -182,6 +222,18 @@ public class MemoryOms : Oms } } } + + foreach (LibraryHandle lh in _libraryReferences) + { + if (oms._libraries.ContainsKey(lh)) + { + object? value = oms._libraries[lh].GetAttributeValue(source, attribute, effectiveDate); + if (value != null) + { + return value; + } + } + } return null; } public void SetAttributeValue(InstanceHandle source, InstanceHandle attribute, object value, DateTime effectiveDate) @@ -203,7 +255,23 @@ public class MemoryOms : Oms } list.Add(new AttributeValue(effectiveDate, value)); } - } + + private List _libraryReferences = new List(); + + public void AddLibraryReference(LibraryHandle library) + { + if (!_libraryReferences.Contains(library)) + { + // please don't reference the same library multiple times + _libraryReferences.Add(library); + } + } + public void RemoveLibraryReference(LibraryHandle library) + { + if (_libraryReferences.Contains(library)) + _libraryReferences.Remove(library); + } + } private Dictionary _tenantData = new Dictionary(); @@ -215,7 +283,7 @@ public class MemoryOms : Oms protected override TenantHandle CreateTenantInternal(string tenantName) { TenantHandle th = TenantHandle.Create(); - _tenantData[th] = new _Tenant(); + _tenantData[th] = new _Tenant(this); return th; } protected override bool SelectTenantInternal(TenantHandle tenant) @@ -229,53 +297,32 @@ public class MemoryOms : Oms _CurrentTenantData = null; } - private Dictionary> _libraryReferences = new Dictionary>(); - protected override void AddLibraryReferenceInternal(LibraryHandle library) { - if (!_libraryReferences.ContainsKey(_CurrentTenant)) + if (_CurrentTenantData != null) { - _libraryReferences[_CurrentTenant] = new List(); - } - if (!_libraryReferences[_CurrentTenant].Contains(library)) - { - // please don't reference the same library multiple times - _libraryReferences[_CurrentTenant].Add(library); + _CurrentTenantData.AddLibraryReference(library); } } protected override void RemoveLibraryReferenceInternal(LibraryHandle library) { - if (_libraryReferences.ContainsKey(_CurrentTenant)) + if (_CurrentTenantData != null) { - if (_libraryReferences[_CurrentTenant].Contains(library)) - { - _libraryReferences[_CurrentTenant].Remove(library); - } + _CurrentTenantData.RemoveLibraryReference(library); } } + public void __Test_AddLibraryReference_1(LibraryHandle lhWeb, LibraryHandle lhSystem) + { + _libraries[lhWeb].AddLibraryReference(lhSystem); + } + protected override Guid GetGlobalIdentifierInternal(InstanceHandle instance) { if (_CurrentTenantData == null) throw new InvalidOperationException("Please select a tenant first."); Guid gid = _CurrentTenantData.GetGlobalIdentifier(instance); - if (gid == Guid.Empty) - { - if (_libraryReferences.ContainsKey(_CurrentTenant)) - { - foreach (LibraryHandle lh in _libraryReferences[_CurrentTenant]) - { - gid = _libraries[lh].GetGlobalIdentifier(instance); - if (gid != Guid.Empty) - return gid; - } - } - // if (_libraryInst_is.ContainsKey(instance)) - // { - // gid = _libraryInst_is[instance].GlobalIdentifier; - // } - } return gid; } protected override InstanceKey GetInstanceKeyInternal(InstanceHandle instance) @@ -315,7 +362,7 @@ public class MemoryOms : Oms protected override void InitializeLibraryInternal(LibraryHandle lh, Library data) { - _Tenant lib = new _Tenant(); + _Tenant lib = new _Tenant(this); foreach (LibraryInstance inst in data.Instances) { InstanceHandle ih = lib.CreateInstance(inst.InstanceGuid); @@ -357,33 +404,6 @@ public class MemoryOms : Oms throw new InvalidOperationException("Please select a tenant first."); bool v = _CurrentTenantData.TryGetInstance(globalIdentifier, out ih); - if (!v) - { - // if (_libraryInst_gs.ContainsKey(globalIdentifier)) - // { - // ih = _libraryInst_gs[globalIdentifier].InstanceHandle; - // return true; - // } - // else - // { - if (_libraryReferences.ContainsKey(_CurrentTenant)) - { - foreach (LibraryHandle lh in _libraryReferences[_CurrentTenant]) - { - if (_libraries.ContainsKey(lh)) - { - if (_libraries[lh].TryGetInstance(globalIdentifier, out ih)) - { - // LibraryInst_g g = new LibraryInst_g() { InstanceHandle = ih, SourceLibrary = lh, GlobalIdentifier = globalIdentifier }; - // _libraries[lh]._libraryInst_gs[globalIdentifier] = g; - // _libraries[lh]._libraryInst_is[ih] = g; - return true; - } - } - } - } - // } - } return v; } protected override bool TryGetInstanceInternal(InstanceKey ik, out InstanceHandle ih) @@ -432,20 +452,6 @@ public class MemoryOms : Oms throw new InvalidOperationException("Please select a tenant first."); IReadOnlyCollection insts = _CurrentTenantData.GetRelatedInstances(source, relationship, effectiveDate); - if (insts.Count == 0) - { - foreach (LibraryHandle lh in _libraryReferences[_CurrentTenant]) - { - if (_libraries.ContainsKey(lh)) - { - IReadOnlyCollection insts2 = _libraries[lh].GetRelatedInstances(source, relationship, effectiveDate); - if (insts2.Count > 0) - { - return insts2; - } - } - } - } return insts; } @@ -462,20 +468,6 @@ public class MemoryOms : Oms throw new InvalidOperationException("Please select a tenant first."); object value = _CurrentTenantData.GetAttributeValue(source, attribute, effectiveDate); - if (value == null) - { - foreach (LibraryHandle lh in _libraryReferences[_CurrentTenant]) - { - if (_libraries.ContainsKey(lh)) - { - value = _libraries[lh].GetAttributeValue(source, attribute, effectiveDate); - if (value != null) - { - return value; - } - } - } - } return value; } protected override void SetAttributeValueInternal(InstanceHandle source, InstanceHandle attribute, object value, DateTime effectiveDate) diff --git a/mocha-dotnet/src/lib/Mocha.Core/OmsImplementations/Mini/HardcodedMiniOms.cs b/mocha-dotnet/src/lib/Mocha.Core/OmsImplementations/Mini/HardcodedMiniOms.cs index a49d464..7f44c71 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/OmsImplementations/Mini/HardcodedMiniOms.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/OmsImplementations/Mini/HardcodedMiniOms.cs @@ -26,7 +26,7 @@ using MBS.Core; /// public class HardcodedMiniOms : MemoryOms { - private HardcodedMiniOms() + public HardcodedMiniOms() { } diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/EmbeddedMiniOms.cs b/mocha-dotnet/tests/Mocha.Core.Tests/EmbeddedMiniOms.cs index be70bf5..a53d050 100644 --- a/mocha-dotnet/tests/Mocha.Core.Tests/EmbeddedMiniOms.cs +++ b/mocha-dotnet/tests/Mocha.Core.Tests/EmbeddedMiniOms.cs @@ -4,14 +4,18 @@ namespace Mocha.Core.Tests; public class EmbeddedMiniOms : MemoryOms { + public string? SystemLibraryResourceName { get; set; } = "Mocha.Core.Tests.Resources.net.alcetech.Mocha.System.mcl"; + protected override void InitializeInternal() { base.InitializeInternal(); - LibraryHandle lh = LoadLibrary(typeof(EmbeddedMiniOms), "Mocha.Core.Tests.Resources.net.alcetech.Mocha.System.mcl"); - TenantHandle th = CreateTenant("super"); SelectTenant(th); - AddLibraryReference(lh); + if (SystemLibraryResourceName != null) + { + LibraryHandle lh = LoadLibrary(typeof(EmbeddedMiniOms), SystemLibraryResourceName); + AddLibraryReference(lh); + } } } \ No newline at end of file diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/LibraryLoaderTests.cs b/mocha-dotnet/tests/Mocha.Core.Tests/LibraryLoaderTests.cs index 3a601e8..bca0249 100644 --- a/mocha-dotnet/tests/Mocha.Core.Tests/LibraryLoaderTests.cs +++ b/mocha-dotnet/tests/Mocha.Core.Tests/LibraryLoaderTests.cs @@ -16,7 +16,7 @@ // along with Mocha.NET. If not, see . using System.Runtime.CompilerServices; - +using Mocha.Core.OmsImplementations; using Mocha.Core.OmsImplementations.Mini; namespace Mocha.Core.Tests; @@ -31,8 +31,12 @@ public class LibraryLoaderTests : OmsTestsBase base.AfterSetup(); // add a reference to the other library + LibraryHandle lhSystem = Oms.GetLibrary("Mocha.Core.Tests.Resources.net.alcetech.Mocha.System.mcl"); + lhWeb = Oms.LoadLibrary(typeof(LibraryLoaderTests), "Mocha.Core.Tests.Resources.net.alcetech.Mocha.Web.mcl"); Oms.AddLibraryReference(lhWeb); + + ((MemoryOms)Oms).__Test_AddLibraryReference_1(lhWeb, lhSystem); } [Test] @@ -67,6 +71,11 @@ public class LibraryLoaderTests : OmsTestsBase [Test] public void Parent_Class_referenced_from_One_library_Accessible_from_Another() { + //! THIS WON'T WORK BECAUSE... + //! Parent Class referenced from another library requires a LibraryReference to the other library on the current library + //! BUT... there is no way right now to represent that in _Tenant + //! FIXME: add LibraryReferences to _Tenant and fix GetRelatedInstances etc. so that libraries can reference other libraries + // First we make sure that Class (defined in Mocha.System, which we are known to have) loads InstanceHandle ihClass = Oms.GetInstance(KnownInstanceGuids.Classes.Class); Assert.That(ihClass, Is.Not.EqualTo(InstanceHandle.Empty));