diff --git a/mocha-dotnet/src/lib/Mocha.Core/LibraryPlugin.cs b/mocha-dotnet/src/lib/Mocha.Core/LibraryPlugin.cs index 50be1c4..0b04289 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/LibraryPlugin.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/LibraryPlugin.cs @@ -22,6 +22,14 @@ namespace Mocha.Core; public abstract class LibraryPlugin : Plugin { + protected virtual void LoadInternal(Stream stream, Library library) + { + throw new NotSupportedException(); + } + public void Load(Stream stream, Library library) + { + LoadInternal(stream, library); + } protected abstract void LoadInternal(string filename, Library library); public void Load(string filename, Library library) { diff --git a/mocha-dotnet/src/lib/Mocha.Core/Oms.cs b/mocha-dotnet/src/lib/Mocha.Core/Oms.cs index f832f1d..5808136 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/Oms.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/Oms.cs @@ -1060,6 +1060,61 @@ public abstract class Oms return LibraryHandle.Empty; } + /// + /// Loads the specified library file into memory. To add it to the tenant, + /// first the desired tenant, and then call + /// . + /// + /// + /// + public LibraryHandle LoadLibrary(Stream stream) + { + // some examples: + // .mcl compiled binary library file (fastest?) + // /path/to/directory containing a bunch of XML / JSON / YAML files + // .mcz ZIP archive of XML / JSON / YAML files (slowest?) + LibraryHandle lh = LibraryHandle.Create(); + + Library lib = new Library(); + // _libraries[name] = lh; + + // get a list of all library loaders we have implemented + LibraryPlugin[] plugins = Plugin.Get(); + foreach (LibraryPlugin plugin in plugins) + { + Console.WriteLine("found plugin: {0}", plugin.GetType().FullName); + + try + { + // if passed a directory, will enumerate all the + // .xml / .json / .yaml files in the directory and + // subdirectories + plugin.Load(stream, lib); + break; + } + catch (NotSupportedException ex) + { + } + } + + // if the files have not already been compiled, we need to do two passes. + // - the first pass loads all instances into our tenant + // - the second pass applies the attributes and relationships, which depend on the + // presence of the instances + + // compiling to .mcl binary library format does this all ahead of time and should + // be faster. + // let's be lazy and just look at the file extension to determine how to parse + + // once all the instances have been loaded, tell the in-memory library manager + // to do its second pass "linking" the objects + lib.Link(); + + InitializeLibraryInternal(lh, lib); + + return lh; + } + /// /// Loads the specified library file into memory. To add it to the tenant, /// first the desired tenant, and then call diff --git a/mocha-dotnet/src/lib/Mocha.Core/OmsImplementations/Mini/MiniOms.cs b/mocha-dotnet/src/lib/Mocha.Core/OmsImplementations/Mini/HardcodedMiniOms.cs similarity index 99% rename from mocha-dotnet/src/lib/Mocha.Core/OmsImplementations/Mini/MiniOms.cs rename to mocha-dotnet/src/lib/Mocha.Core/OmsImplementations/Mini/HardcodedMiniOms.cs index ca39589..a49d464 100644 --- a/mocha-dotnet/src/lib/Mocha.Core/OmsImplementations/Mini/MiniOms.cs +++ b/mocha-dotnet/src/lib/Mocha.Core/OmsImplementations/Mini/HardcodedMiniOms.cs @@ -24,9 +24,9 @@ using MBS.Core; /// Implements completely in-memory with a bare minimum schema definition which /// includes Class, Attribute and subclasses, Relationship, and File for attachments. /// -public class MiniOms : MemoryOms +public class HardcodedMiniOms : MemoryOms { - private MiniOms() + private HardcodedMiniOms() { } @@ -42,7 +42,7 @@ public class MiniOms : MemoryOms public List Modules { get; } = new List(); - private MiniOms(MiniOmsModule[] modules = null) + private HardcodedMiniOms(MiniOmsModule[] modules = null) { if (modules == null) { diff --git a/mocha-dotnet/src/plugins/Mocha.Plugins.Libraries.McxMini/McxMiniPlugin.cs b/mocha-dotnet/src/plugins/Mocha.Plugins.Libraries.McxMini/McxMiniPlugin.cs index 788b672..a353cdd 100644 --- a/mocha-dotnet/src/plugins/Mocha.Plugins.Libraries.McxMini/McxMiniPlugin.cs +++ b/mocha-dotnet/src/plugins/Mocha.Plugins.Libraries.McxMini/McxMiniPlugin.cs @@ -34,10 +34,11 @@ public class McxMiniLibraryPlugin : LibraryPlugin return ext.Equals(".mcx") || ext.Equals(".mcl"); } - protected override void LoadInternal(string filename, Library library) + protected override void LoadInternal(Stream stream, Library library) { - FileStream fs = File.Open(filename, FileMode.Open); - BinaryReader r = new BinaryReader(fs); + base.LoadInternal(stream, library); + + BinaryReader r = new BinaryReader(stream); string signature = r.ReadFixedString(4); if (!signature.Equals("MCX!")) @@ -170,4 +171,10 @@ public class McxMiniLibraryPlugin : LibraryPlugin } } + + protected override void LoadInternal(string filename, Library library) + { + FileStream fs = File.Open(filename, FileMode.Open); + LoadInternal(fs, library); + } } diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/BasicTests.cs b/mocha-dotnet/tests/Mocha.Core.Tests/BasicTests.cs index 6e15455..6e56d1a 100644 --- a/mocha-dotnet/tests/Mocha.Core.Tests/BasicTests.cs +++ b/mocha-dotnet/tests/Mocha.Core.Tests/BasicTests.cs @@ -1,20 +1,20 @@ -// 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 . - +// 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 System.Runtime.CompilerServices; using Mocha.Core.OmsImplementations.Mini; @@ -24,11 +24,6 @@ namespace Mocha.Core.Tests; [TestFixture] public class BasicTests : OmsTestsBase { - protected override Oms CreateOms() - { - return new MiniOms(); - } - [Test] public void PrerequisitesDefined() diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/EmbeddedMiniOms.cs b/mocha-dotnet/tests/Mocha.Core.Tests/EmbeddedMiniOms.cs new file mode 100644 index 0000000..f5b0688 --- /dev/null +++ b/mocha-dotnet/tests/Mocha.Core.Tests/EmbeddedMiniOms.cs @@ -0,0 +1,26 @@ +using Mocha.Core.OmsImplementations; + +namespace Mocha.Core.Tests; + +public class EmbeddedMiniOms : MemoryOms +{ + protected override void InitializeInternal() + { + base.InitializeInternal(); + + TenantHandle th = CreateTenant("super"); + SelectTenant(th); + + System.Reflection.Assembly asm = System.Reflection.Assembly.GetExecutingAssembly(); + Stream? stream = asm.GetManifestResourceStream("Mocha.Core.Tests.Resources.net.alcetech.Mocha.System.mcl"); + if (stream != null) + { + LibraryHandle lh = LoadLibrary(stream); + this.AddLibraryReference(lh); + } + else + { + throw new InvalidOperationException("Manifest resource stream not found!"); + } + } +} \ No newline at end of file diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/OmsTestsBase.cs b/mocha-dotnet/tests/Mocha.Core.Tests/OmsTestsBase.cs index 98a9190..89a880b 100644 --- a/mocha-dotnet/tests/Mocha.Core.Tests/OmsTestsBase.cs +++ b/mocha-dotnet/tests/Mocha.Core.Tests/OmsTestsBase.cs @@ -23,7 +23,12 @@ public abstract class OmsTestsBase { public Oms Oms { get; private set; } - protected virtual Oms CreateOms() { return new MiniOms(); } + protected Oms CreateOms() + { + EmbeddedMiniOms oms = new EmbeddedMiniOms(); + oms.Initialize(); + return oms; + } protected readonly Guid TEST_CLASS_GUID = new Guid("{5821fc28-6411-4339-a7d2-56dc05591501}"); protected readonly Guid TEST_CLASS2_GUID = new Guid("{6351ecb7-da5d-4029-ba3a-196a6dc980e9}"); diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/RelationshipTests.cs b/mocha-dotnet/tests/Mocha.Core.Tests/RelationshipTests.cs index 11daf71..3d50318 100644 --- a/mocha-dotnet/tests/Mocha.Core.Tests/RelationshipTests.cs +++ b/mocha-dotnet/tests/Mocha.Core.Tests/RelationshipTests.cs @@ -22,11 +22,6 @@ namespace Mocha.Core.Tests; public class RelationshipTests : OmsTestsBase { - protected override Oms CreateOms() - { - return new MiniOms(); - } - protected readonly Guid TEST_REL3_GUID = new Guid("{e1cacab7-c8a9-480d-b2b6-5b25c6c549e0}"); protected readonly Guid TEST_REL4_GUID = new Guid("{82b8f531-fe32-4c36-ad3a-9e0f79bc95b4}"); protected readonly Guid TEST_REL5_GUID = new Guid("{b80995cf-6a2d-44c2-9c93-ebb80c9be802}"); diff --git a/mocha-dotnet/tests/Mocha.Core.Tests/WorkSetTests.cs b/mocha-dotnet/tests/Mocha.Core.Tests/WorkSetTests.cs index e272870..03c673b 100644 --- a/mocha-dotnet/tests/Mocha.Core.Tests/WorkSetTests.cs +++ b/mocha-dotnet/tests/Mocha.Core.Tests/WorkSetTests.cs @@ -25,11 +25,6 @@ namespace Mocha.Core.Tests; public class WorkSetTests : OmsTestsBase { - protected override Oms CreateOms() - { - return new MiniOms(); - } - [Test] public void NoValidClassConstraints() {