Skip to content

Commit

Permalink
UAReferenceContext - causes circular references #558
Browse files Browse the repository at this point in the history
- working on inheritance chain to replace the ReferenceKindEnum
- UT 👍
  • Loading branch information
mpostol committed Mar 28, 2021
1 parent a0219cc commit 55ff1c9
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,11 @@ public Parameter ExportArgument(Argument argument)
throw new NotImplementedException();
}

public void GetBaseTypes(IUANodeContext rootNode, List<IUANodeContext> inheritanceChain)
{
throw new NotImplementedException();
}

#endregion IAddressSpaceBuildContext

#region private instrumentation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,11 +208,50 @@ public void ChildConnector()
Assert.AreEqual<ReferenceKindEnum>(ReferenceKindEnum.HasComponent, instance2Test.ReferenceKind);
}

[TestMethod]
public void IsSubtypeOfReferenceTypeTest()
{
XML.Reference reference = new XML.Reference() { IsForward = true, ReferenceType = ReferenceTypeIds.HasOrderedComponent.ToString(), Value = "ns=1;i=11" };
reference.RecalculateNodeIds(x => NodeId.Parse(x));

Mock<IUANodeContext> sourceMock = new Mock<IUANodeContext>();
Mock<IAddressSpaceBuildContext> asMock = new Mock<IAddressSpaceBuildContext>();
asMock.Setup(x => x.GetOrCreateNodeContext(It.Is<NodeId>(z => z == ReferenceTypeIds.HasOrderedComponent), It.IsAny<Func<NodeId, IUANodeContext>>()));
asMock.Setup(x => x.GetOrCreateNodeContext(It.Is<NodeId>(z => z == NodeId.Parse(reference.Value)), It.IsAny<Func<NodeId, IUANodeContext>>()));
asMock.Setup(x => x.GetBaseTypes(It.IsAny<IUANodeContext>(), It.Is<List<IUANodeContext>>(z => ListOTypesFixture(z))));

UAReferenceContext instance2Test = new UAReferenceContext(reference, asMock.Object, sourceMock.Object);

asMock.Verify(x => x.GetOrCreateNodeContext(It.Is<NodeId>(z => z == ReferenceTypeIds.HasOrderedComponent), It.IsAny<Func<NodeId, IUANodeContext>>()), Times.Once);
asMock.Verify(x => x.GetOrCreateNodeContext(It.Is<NodeId>(z => z == NodeId.Parse(reference.Value)), It.IsAny<Func<NodeId, IUANodeContext>>()), Times.Once);

Assert.IsTrue(instance2Test.IsSubtypeOf(NodeId.Parse("i=123")));
}

private bool ListOTypesFixture(List<IUANodeContext> references)
{
Assert.AreEqual<int>(0, references.Count);
Mock<IUANodeContext> node1 = new Mock<IUANodeContext>();
references.Add(node1.Object);
references.Add(node1.Object);
references.Add(node1.Object);
Mock<IUANodeContext> node2 = new Mock<IUANodeContext>();
node2.Setup(x => x.NodeIdContext).Returns(NodeId.Parse("i=123"));
references.Add(node2.Object);
Mock<IUANodeContext> node3 = new Mock<IUANodeContext>();
references.Add(node3.Object);
references.Add(node3.Object);
references.Add(node3.Object);
references.Add(node1.Object);
references.Add(node1.Object);
return true;
}

private bool CreatePathFixture(List<string> z)
{
z.Add("2P8ZkTA2Ccahvs");
z.Add("bLAsL6DSp1Ow5d");
return z.Count == 2;
return true;
}
}
}
34 changes: 18 additions & 16 deletions SemanticData/UANodeSetValidation/AddressSpaceContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,23 @@ public Parameter ExportArgument(DataSerialization.Argument argument)
return ExportArgument(argument, _dataType);
}

public void GetBaseTypes(IUANodeContext rootNode, List<IUANodeContext> inheritanceChain)
{
if (rootNode == null)
throw new ArgumentNullException("rootNode");
if (rootNode.InRecursionChain)
throw new ArgumentOutOfRangeException("Circular reference");
rootNode.InRecursionChain = true;
IEnumerable<IUANodeContext> _derived = m_References.Values.Where<UAReferenceContext>(x => (x.TypeNode.NodeIdContext == ReferenceTypeIds.HasSubtype) && (x.TargetNode == rootNode)).
Select<UAReferenceContext, IUANodeContext>(x => x.SourceNode);
inheritanceChain.AddRange(_derived);
if (_derived.Count<IUANodeContext>() > 1)
throw new ArgumentOutOfRangeException("To many subtypes");
else if (_derived.Count<IUANodeContext>() == 1)
GetBaseTypes(_derived.First<IUANodeContext>(), inheritanceChain);
rootNode.InRecursionChain = false;
}

#endregion IAddressSpaceBuildContext

#region IAddressSpaceValidationContext
Expand Down Expand Up @@ -326,22 +343,7 @@ private IUANodeContext TryGetUANodeContext(NodeId nodeId)
return _ret;
}

private void GetBaseTypes(IUANodeContext rootNode, List<IUANodeContext> inheritanceChain)
{
if (rootNode == null)
throw new ArgumentNullException("rootNode");
if (rootNode.InRecursionChain)
throw new ArgumentOutOfRangeException("Circular reference");
rootNode.InRecursionChain = true;
IEnumerable<IUANodeContext> _derived = m_References.Values.Where<UAReferenceContext>(x => (x.TypeNode.NodeIdContext == ReferenceTypeIds.HasSubtype) && (x.TargetNode == rootNode)).
Select<UAReferenceContext, IUANodeContext>(x => x.SourceNode);
inheritanceChain.AddRange(_derived);
if (_derived.Count<IUANodeContext>() > 1)
throw new ArgumentOutOfRangeException("To many subtypes");
else if (_derived.Count<IUANodeContext>() == 1)
GetBaseTypes(_derived.First<IUANodeContext>(), inheritanceChain);
rootNode.InRecursionChain = false;
}


private void ValidateAndExportModel(int nameSpaceIndex)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
//___________________________________________________________________________________

using System;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using UAOOI.SemanticData.InformationModelFactory;
Expand Down Expand Up @@ -76,5 +75,7 @@ internal interface IAddressSpaceBuildContext
/// <param name="argument">The argument.</param>
/// <returns>An instance encapsulating <see cref="Parameter"/>.</returns>
Parameter ExportArgument(Argument argument);

void GetBaseTypes(IUANodeContext rootNode, List<IUANodeContext> inheritanceChain);
}
}
9 changes: 9 additions & 0 deletions SemanticData/UANodeSetValidation/UAReferenceContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using UAOOI.SemanticData.UANodeSetValidation.DataSerialization;
using UAOOI.SemanticData.UANodeSetValidation.UAInformationModel;
using UAOOI.SemanticData.UANodeSetValidation.XML;
using System.Linq;

namespace UAOOI.SemanticData.UANodeSetValidation
{
Expand Down Expand Up @@ -45,6 +46,14 @@ internal UAReferenceContext(Reference reference, IAddressSpaceBuildContext addre

#region semantics

//TODO UAReferenceContext - causes circular references #558
internal bool IsSubtypeOf(NodeId referenceType)
{
List<IUANodeContext> inheritanceChain = new List<IUANodeContext>();
m_AddressSpace.GetBaseTypes(TypeNode, inheritanceChain);
return inheritanceChain.Where<IUANodeContext>(x => x.NodeIdContext == referenceType).Any<IUANodeContext>();
}

/// <summary>
/// Gets the kind of the reference.
/// </summary>
Expand Down

0 comments on commit 55ff1c9

Please sign in to comment.