Skip to content

Commit

Permalink
[Refactor] ExternalReferenceResolver to support reading known xmi; fixes
Browse files Browse the repository at this point in the history
 #73

[Add] PrimitiveTypes.xmi, StandardProfile.xmi and UML.xmi as embedded resources to the uml4net.xmi project.

[Add] ResourceLoader to support reading known Resources
  • Loading branch information
samatstariongroup committed Jan 5, 2025
1 parent 75ff1b1 commit 390c8ab
Show file tree
Hide file tree
Showing 26 changed files with 18,796 additions and 79 deletions.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -233,10 +233,10 @@
</ItemGroup>

<ItemGroup>
<Content Include="..\resources\UML\PrimitiveTypes.xmi.xml" Link="TestData\PrimitiveTypes.xmi">
<Content Include="..\resources\UML\PrimitiveTypes.xmi" Link="TestData\PrimitiveTypes.xmi">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="..\resources\UML\UML.xmi.xml" Link="TestData\UML.xmi">
<Content Include="..\resources\UML\UML.xmi" Link="TestData\UML.xmi">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Expected\AutoGenXmiReaders\LiteralUnlimitedNaturalReader.cs">
Expand Down
4 changes: 2 additions & 2 deletions uml4net.Extensions.Tests/uml4net.Extensions.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@
</ItemGroup>

<ItemGroup>
<Content Include="..\resources\UML\PrimitiveTypes.xmi.xml" Link="TestData\PrimitiveTypes.xmi">
<Content Include="..\resources\UML\PrimitiveTypes.xmi" Link="TestData\PrimitiveTypes.xmi">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="..\resources\UML\UML.xmi.xml" Link="TestData\UML.xmi">
<Content Include="..\resources\UML\UML.xmi" Link="TestData\UML.xmi">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="..\resources\SySML2\SysML.uml" Link="TestData\SysML.uml">
Expand Down
4 changes: 2 additions & 2 deletions uml4net.HandleBars.Tests/uml4net.HandleBars.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@
</ItemGroup>

<ItemGroup>
<Content Include="..\resources\UML\PrimitiveTypes.xmi.xml" Link="TestData\PrimitiveTypes.xmi">
<Content Include="..\resources\UML\PrimitiveTypes.xmi" Link="TestData\PrimitiveTypes.xmi">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="..\resources\UML\UML.xmi.xml" Link="TestData\UML.xmi">
<Content Include="..\resources\UML\UML.xmi" Link="TestData\UML.xmi">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="..\resources\SySML2\SysML.uml" Link="TestData\SysML.uml">
Expand Down
4 changes: 2 additions & 2 deletions uml4net.Reporting.Tests/uml4net.Reporting.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@
</ItemGroup>

<ItemGroup>
<Content Include="..\resources\UML\PrimitiveTypes.xmi.xml" Link="TestData\PrimitiveTypes.xmi">
<Content Include="..\resources\UML\PrimitiveTypes.xmi" Link="TestData\PrimitiveTypes.xmi">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="..\resources\UML\UML.xmi.xml" Link="TestData\UML.xmi">
<Content Include="..\resources\UML\UML.xmi" Link="TestData\UML.xmi">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="..\resources\SySML2\SysML.uml" Link="TestData\SysML.uml">
Expand Down
4 changes: 2 additions & 2 deletions uml4net.Tools.Tests/uml4net.Tools.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@
</ItemGroup>

<ItemGroup>
<Content Include="..\resources\UML\PrimitiveTypes.xmi.xml" Link="TestData\PrimitiveTypes.xmi">
<Content Include="..\resources\UML\PrimitiveTypes.xmi" Link="TestData\PrimitiveTypes.xmi">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="..\resources\UML\UML.xmi.xml" Link="TestData\UML.xmi">
<Content Include="..\resources\UML\UML.xmi" Link="TestData\UML.xmi">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<None Include="..\resources\SySML2\SysML.uml" Link="TestData\SysML.uml">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public void Verify_that_DMN_XMI_can_be_read()
.WithLogger(this.loggerFactory)
.Build();

var xmiReaderResult = reader.Read(Path.Combine(TestContext.CurrentContext.TestDirectory, "TestData", "dtc-23-02-13.xmi.xml"));
var xmiReaderResult = reader.Read(Path.Combine(TestContext.CurrentContext.TestDirectory, "TestData", "dtc-23-02-13.xmi"));

Assert.That(xmiReaderResult.Packages.Count, Is.EqualTo(2));

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
// -------------------------------------------------------------------------------------------------
// <copyright file="ExternalReferenceResolverTestFixture.cs" company="Starion Group S.A.">
//
// Copyright 2019-2025 Starion Group S.A.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// </copyright>
// ------------------------------------------------------------------------------------------------

namespace uml4net.xmi.Tests.ReferenceResolver
{
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Classification;
using Microsoft.Extensions.Logging;
using Moq;
using NUnit.Framework;
using Resources;
using Serilog;
using Settings;
using uml4net.xmi.ReferenceResolver;

[TestFixture]
public class ExternalReferenceResolverTestFixture
{
private ILoggerFactory loggerFactory;

private ExternalReferenceResolver referenceResolver;

private ResourceLoader resourceLoader;

private XmiElementCache xmiElementCache;

private IXmiReaderSettings settings;

[OneTimeSetUp]
public void OneTimeSetUp()
{
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.Console()
.CreateLogger();

loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddSerilog();
});
}

[SetUp]
public void SetUp()
{
this.resourceLoader = new ResourceLoader();

this.xmiElementCache = new XmiElementCache();

this.settings = new Settings.DefaultSettings();

this.referenceResolver = new ExternalReferenceResolver(this.resourceLoader,
this.xmiElementCache, settings, this.loggerFactory.CreateLogger<ExternalReferenceResolver>());
}

[Test]
public void Verify_that_resolving_external_resources_that_are_known_returns_expected_result()
{
var property_1 = new Property
{
XmiId = "property_1",
Name = "IsValid",
DocumentName = "test",
};
property_1.SingleValueReferencePropertyIdentifiers.Add("type", "http://www.omg.org/spec/UML/20131001/PrimitiveTypes.xmi#Boolean");
property_1.MultiValueReferencePropertyIdentifiers.Add("subsettedProperty", ["https://www.omg.org/spec/UML/20131001/PrimitiveTypes.xmi#Boolean"]);

var property_2 = new Property
{
XmiId = "property_2",
Name = "IsComposite",
DocumentName = "test",
};
property_2.SingleValueReferencePropertyIdentifiers.Add("type", "PrimitiveTypes.xmi#Boolean");
property_2.MultiValueReferencePropertyIdentifiers.Add("subsettedProperty", ["PrimitiveTypes#Boolean"]);

this.xmiElementCache.TryAdd(property_1);
this.xmiElementCache.TryAdd(property_2);

var resolvedKnowReferences = this.referenceResolver.TryResolve("test");

Assert.That(resolvedKnowReferences.Count, Is.EqualTo(4));

Assert.That(resolvedKnowReferences[0].Context, Is.EqualTo("http://www.omg.org/spec/UML/20131001/PrimitiveTypes.xmi"));
Assert.That(resolvedKnowReferences[1].Context, Is.EqualTo("PrimitiveTypes.xmi"));
Assert.That(resolvedKnowReferences[2].Context, Is.EqualTo("https://www.omg.org/spec/UML/20131001/PrimitiveTypes.xmi"));
Assert.That(resolvedKnowReferences[3].Context, Is.EqualTo("PrimitiveTypes"));
}

[Test]
public void Verify_that_duplicate_use_of_known_resource_returns_only_once()
{
var property_1 = new Property
{
XmiId = "property_1",
Name = "IsValid",
DocumentName = "test",
};
property_1.SingleValueReferencePropertyIdentifiers.Add("type", "https://www.omg.org/spec/UML/20131001/PrimitiveTypes.xmi#Boolean");
property_1.MultiValueReferencePropertyIdentifiers.Add("subsettedProperty", ["https://www.omg.org/spec/UML/20131001/PrimitiveTypes.xmi#Integer"]);

this.xmiElementCache.TryAdd(property_1);

var resolvedKnowReferences = this.referenceResolver.TryResolve("test");

Assert.That(resolvedKnowReferences.Count, Is.EqualTo(1));

Assert.That(resolvedKnowReferences[0].Context, Is.EqualTo("https://www.omg.org/spec/UML/20131001/PrimitiveTypes.xmi"));
}

[Test]
public void verify_that_http_or_https_resolve_to_local_file()
{
var rootPath = Path.Combine(TestContext.CurrentContext.TestDirectory, "TestData");

this.settings.LocalReferenceBasePath = rootPath;

var property_1 = new Property
{
XmiId = "property_1",
Name = "IsValid",
DocumentName = "test",
};
property_1.SingleValueReferencePropertyIdentifiers.Add("type", "https://www.omg.org/spec/UML/PrimitiveTypes.xmi#Boolean");
property_1.SingleValueReferencePropertyIdentifiers.Add("count", "http://www.omg.org/spec/UML/PrimitiveTypes.xmi#Integer");
property_1.SingleValueReferencePropertyIdentifiers.Add("unlimitedCount", "ftp://www.omg.org/spec/UML/PrimitiveTypes.xmi#LiteralUnlimitedNatural");

this.xmiElementCache.TryAdd(property_1);

var resolvedKnowReferences = this.referenceResolver.TryResolve("test");

Assert.That(resolvedKnowReferences.Count, Is.EqualTo(3));

Assert.That(resolvedKnowReferences[0].Context, Is.EqualTo("https://www.omg.org/spec/UML/PrimitiveTypes.xmi"));
Assert.That(resolvedKnowReferences[1].Context, Is.EqualTo("http://www.omg.org/spec/UML/PrimitiveTypes.xmi"));
Assert.That(resolvedKnowReferences[2].Context, Is.EqualTo("ftp://www.omg.org/spec/UML/PrimitiveTypes.xmi"));
}

[Test]
public void Verity_that_file_references_can_be_processed()
{
var rootPath = Path.Combine(TestContext.CurrentContext.TestDirectory, "TestData");

var fileSchemePath = $"file://{rootPath}//PrimitiveTypes.xmi#Boolean";
var resoureceName = $"file://{rootPath}//PrimitiveTypes.xmi";

var property_1 = new Property
{
XmiId = "property_1",
Name = "IsValid",
DocumentName = "test",
};
property_1.SingleValueReferencePropertyIdentifiers.Add("type", fileSchemePath);

this.xmiElementCache.TryAdd(property_1);

var resolvedKnowReferences = this.referenceResolver.TryResolve("test");

Assert.That(resolvedKnowReferences.Count, Is.EqualTo(1));

Assert.That(resolvedKnowReferences[0].Context, Is.EqualTo(resoureceName));
}

[Test]
public void Verify_that_non_external_references_are_not_processed()
{
var property_1 = new Property
{
XmiId = "property_1",
Name = "IsValid",
DocumentName = "test",
};
property_1.SingleValueReferencePropertyIdentifiers.Add("type", "Boolean");

this.xmiElementCache.TryAdd(property_1);

var resolvedKnowReferences = this.referenceResolver.TryResolve("test");

Assert.That(resolvedKnowReferences.Count, Is.EqualTo(0));
}
}
}
2 changes: 1 addition & 1 deletion uml4net.xmi.Tests/StandardProfileReaderTestFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public void Verify_that_StandardProfile_XMI_can_be_read()
.WithLogger(this.loggerFactory)
.Build();

var xmiReaderResult = reader.Read(Path.Combine(TestContext.CurrentContext.TestDirectory, "TestData", "StandardProfile.xmi.xml"));
var xmiReaderResult = reader.Read(Path.Combine(TestContext.CurrentContext.TestDirectory, "TestData", "StandardProfile.xmi"));

Assert.That(xmiReaderResult.Packages.Count, Is.EqualTo(3));

Expand Down
23 changes: 23 additions & 0 deletions uml4net.xmi.Tests/TestData/doc1.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8" ?>
<xmi:XMI xmlns:uml="http://www.omg.org/spec/UML/20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001">
<documentation>
<shortDescription>demo for crossreferencing between doc1 and doc2</shortDescription>
</documentation>
<uml:Package xmi:type="uml:Package" xmi:id="doc1" name="doc1">
<uml:packagedElement xmi:id="class01" xmi:type="uml:Class">
<uml:ownedOperation xmi:id="idO1" xmi:type="uml:Operation" xmi:label="op1" >
<ownedRule xmi:id="idC1" xmi:type="uml:Constraint" xmi:label="co1" >
<specification xmi:type="uml:OpaqueExpression">
<body>First Constraint definition</body>
</specification>
<constrainedElement xmi:idref="idO1"/>
</ownedRule>
</uml:ownedOperation>
</uml:packagedElement>
<uml:packagedElement xmi:id="class02" xmi:type="uml:Class" >
<ownedAttribute xmi:type="uml:Property" xmi:id="class02-prop1" name="prop1">
<type href="doc2.xml#class01"/>
</ownedAttribute>
</uml:packagedElement>
</uml:Package>
</xmi:XMI>
16 changes: 16 additions & 0 deletions uml4net.xmi.Tests/TestData/doc2.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8" ?>
<xmi:XMI xmlns:uml="http://www.omg.org/spec/UML/20131001" xmlns:xmi="http://www.omg.org/spec/XMI/20131001">
<documentation>
<shortDescription>demo for crossreferencing between doc1 and doc2</shortDescription>
</documentation>
<uml:Package xmi:type="uml:Package" xmi:id="doc2" name="doc2">
<uml:packagedElement xmi:id="class01" xmi:type="uml:Class">
<uml:ownedRule xmi:id="idC4" xmi:type="uml:Constraint" xmi:label="co4" xmi:uuid="DCE:mnop">
<specification xmi:type="uml:OpaqueExpression">
<body>Fourth Constraint definition</body>
</specification>
<constrainedElement href="doc1.xml#idO1"/>
</uml:ownedRule>
</uml:packagedElement>
</uml:Package>
</xmi:XMI>
Loading

0 comments on commit 390c8ab

Please sign in to comment.