From 55ff1c913e6309d02e2abbd7e1b420b15c972503 Mon Sep 17 00:00:00 2001 From: mpostol Date: Sun, 28 Mar 2021 13:06:09 +0200 Subject: [PATCH] UAReferenceContext - causes circular references #558 - working on inheritance chain to replace the ReferenceKindEnum - UT :+1: --- .../UANodeContextUnitTest.cs | 5 +++ .../UAReferenceContextTestClass.cs | 41 ++++++++++++++++++- .../AddressSpaceContext.cs | 34 +++++++-------- .../IAddressSpaceBuildContext.cs | 3 +- .../UANodeSetValidation/UAReferenceContext.cs | 9 ++++ 5 files changed, 74 insertions(+), 18 deletions(-) diff --git a/SemanticData/Tests/USNodeSetValidationUnitTestProject/UANodeContextUnitTest.cs b/SemanticData/Tests/USNodeSetValidationUnitTestProject/UANodeContextUnitTest.cs index b71826bc..ed266b6a 100644 --- a/SemanticData/Tests/USNodeSetValidationUnitTestProject/UANodeContextUnitTest.cs +++ b/SemanticData/Tests/USNodeSetValidationUnitTestProject/UANodeContextUnitTest.cs @@ -453,6 +453,11 @@ public Parameter ExportArgument(Argument argument) throw new NotImplementedException(); } + public void GetBaseTypes(IUANodeContext rootNode, List inheritanceChain) + { + throw new NotImplementedException(); + } + #endregion IAddressSpaceBuildContext #region private instrumentation diff --git a/SemanticData/Tests/USNodeSetValidationUnitTestProject/UAReferenceContextTestClass.cs b/SemanticData/Tests/USNodeSetValidationUnitTestProject/UAReferenceContextTestClass.cs index f111cd1d..8de50352 100644 --- a/SemanticData/Tests/USNodeSetValidationUnitTestProject/UAReferenceContextTestClass.cs +++ b/SemanticData/Tests/USNodeSetValidationUnitTestProject/UAReferenceContextTestClass.cs @@ -208,11 +208,50 @@ public void ChildConnector() Assert.AreEqual(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 sourceMock = new Mock(); + Mock asMock = new Mock(); + asMock.Setup(x => x.GetOrCreateNodeContext(It.Is(z => z == ReferenceTypeIds.HasOrderedComponent), It.IsAny>())); + asMock.Setup(x => x.GetOrCreateNodeContext(It.Is(z => z == NodeId.Parse(reference.Value)), It.IsAny>())); + asMock.Setup(x => x.GetBaseTypes(It.IsAny(), It.Is>(z => ListOTypesFixture(z)))); + + UAReferenceContext instance2Test = new UAReferenceContext(reference, asMock.Object, sourceMock.Object); + + asMock.Verify(x => x.GetOrCreateNodeContext(It.Is(z => z == ReferenceTypeIds.HasOrderedComponent), It.IsAny>()), Times.Once); + asMock.Verify(x => x.GetOrCreateNodeContext(It.Is(z => z == NodeId.Parse(reference.Value)), It.IsAny>()), Times.Once); + + Assert.IsTrue(instance2Test.IsSubtypeOf(NodeId.Parse("i=123"))); + } + + private bool ListOTypesFixture(List references) + { + Assert.AreEqual(0, references.Count); + Mock node1 = new Mock(); + references.Add(node1.Object); + references.Add(node1.Object); + references.Add(node1.Object); + Mock node2 = new Mock(); + node2.Setup(x => x.NodeIdContext).Returns(NodeId.Parse("i=123")); + references.Add(node2.Object); + Mock node3 = new Mock(); + 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 z) { z.Add("2P8ZkTA2Ccahvs"); z.Add("bLAsL6DSp1Ow5d"); - return z.Count == 2; + return true; } } } \ No newline at end of file diff --git a/SemanticData/UANodeSetValidation/AddressSpaceContext.cs b/SemanticData/UANodeSetValidation/AddressSpaceContext.cs index 336175d7..76723266 100644 --- a/SemanticData/UANodeSetValidation/AddressSpaceContext.cs +++ b/SemanticData/UANodeSetValidation/AddressSpaceContext.cs @@ -224,6 +224,23 @@ public Parameter ExportArgument(DataSerialization.Argument argument) return ExportArgument(argument, _dataType); } + public void GetBaseTypes(IUANodeContext rootNode, List inheritanceChain) + { + if (rootNode == null) + throw new ArgumentNullException("rootNode"); + if (rootNode.InRecursionChain) + throw new ArgumentOutOfRangeException("Circular reference"); + rootNode.InRecursionChain = true; + IEnumerable _derived = m_References.Values.Where(x => (x.TypeNode.NodeIdContext == ReferenceTypeIds.HasSubtype) && (x.TargetNode == rootNode)). + Select(x => x.SourceNode); + inheritanceChain.AddRange(_derived); + if (_derived.Count() > 1) + throw new ArgumentOutOfRangeException("To many subtypes"); + else if (_derived.Count() == 1) + GetBaseTypes(_derived.First(), inheritanceChain); + rootNode.InRecursionChain = false; + } + #endregion IAddressSpaceBuildContext #region IAddressSpaceValidationContext @@ -326,22 +343,7 @@ private IUANodeContext TryGetUANodeContext(NodeId nodeId) return _ret; } - private void GetBaseTypes(IUANodeContext rootNode, List inheritanceChain) - { - if (rootNode == null) - throw new ArgumentNullException("rootNode"); - if (rootNode.InRecursionChain) - throw new ArgumentOutOfRangeException("Circular reference"); - rootNode.InRecursionChain = true; - IEnumerable _derived = m_References.Values.Where(x => (x.TypeNode.NodeIdContext == ReferenceTypeIds.HasSubtype) && (x.TargetNode == rootNode)). - Select(x => x.SourceNode); - inheritanceChain.AddRange(_derived); - if (_derived.Count() > 1) - throw new ArgumentOutOfRangeException("To many subtypes"); - else if (_derived.Count() == 1) - GetBaseTypes(_derived.First(), inheritanceChain); - rootNode.InRecursionChain = false; - } + private void ValidateAndExportModel(int nameSpaceIndex) { diff --git a/SemanticData/UANodeSetValidation/IAddressSpaceBuildContext.cs b/SemanticData/UANodeSetValidation/IAddressSpaceBuildContext.cs index 29afed4b..a90ab87b 100644 --- a/SemanticData/UANodeSetValidation/IAddressSpaceBuildContext.cs +++ b/SemanticData/UANodeSetValidation/IAddressSpaceBuildContext.cs @@ -6,7 +6,6 @@ //___________________________________________________________________________________ using System; -using System.Collections; using System.Collections.Generic; using System.Xml; using UAOOI.SemanticData.InformationModelFactory; @@ -76,5 +75,7 @@ internal interface IAddressSpaceBuildContext /// The argument. /// An instance encapsulating . Parameter ExportArgument(Argument argument); + + void GetBaseTypes(IUANodeContext rootNode, List inheritanceChain); } } \ No newline at end of file diff --git a/SemanticData/UANodeSetValidation/UAReferenceContext.cs b/SemanticData/UANodeSetValidation/UAReferenceContext.cs index fb2ee71b..155e4211 100644 --- a/SemanticData/UANodeSetValidation/UAReferenceContext.cs +++ b/SemanticData/UANodeSetValidation/UAReferenceContext.cs @@ -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 { @@ -45,6 +46,14 @@ internal UAReferenceContext(Reference reference, IAddressSpaceBuildContext addre #region semantics + //TODO UAReferenceContext - causes circular references #558 + internal bool IsSubtypeOf(NodeId referenceType) + { + List inheritanceChain = new List(); + m_AddressSpace.GetBaseTypes(TypeNode, inheritanceChain); + return inheritanceChain.Where(x => x.NodeIdContext == referenceType).Any(); + } + /// /// Gets the kind of the reference. ///