Skip to content

Commit 4d03cf6

Browse files
53 unused UaNodeNamespaceUri (#60)
* Remove Unused attributes for NodeIds * Remove Test designed to be more of an investigation report * Resolve Issue 53 - Remove UaNodeNamespaceUri
1 parent ca3dfb6 commit 4d03cf6

File tree

3 files changed

+166
-41
lines changed

3 files changed

+166
-41
lines changed

NodeSetToAML.cs

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@ public class NodeSetToAML
109109
private Dictionary<string, Dictionary<string,string>> LookupNames = new Dictionary<string, Dictionary<string, string>>();
110110
private HashSet<string> ExtensionObjectExclusions = null;
111111

112+
private Dictionary<string, Dictionary<string, DataTypeField>> ReferenceAttributeMap =
113+
new Dictionary<string, Dictionary<string, DataTypeField>>();
114+
private readonly string[] NodeId_IdAttributeNames = { "NumericId", "StringId", "GuidId", "OpaqueId" };
115+
112116
private List<string> PreventInfiniteRecursionList = new List<string>();
113117
private const int ua2xslookup_count = 18;
114118
private const int ua2xslookup_uaname = 0;
@@ -820,6 +824,8 @@ private AttributeType AddModifyAttribute(AttributeSequence seq, string name, str
820824
}
821825
a.DefaultValue = null;
822826
a.Value = null;
827+
828+
MinimizeExplicitNodeId( rootNodeId );
823829
}
824830

825831
if ( expandedNodeId != null )
@@ -947,16 +953,63 @@ private AttributeType AddModifyAttribute(AttributeSequence seq, string name, str
947953
{
948954
// this is specifically the variant case
949955
NodeId dataTypeFromBase = new NodeId( (uint)val.TypeInfo.BuiltInType );
950-
string sdfsd = GetAttributeDataType( dataTypeFromBase );
951-
a.AttributeDataType = sdfsd;
956+
string variantDataType = GetAttributeDataType( dataTypeFromBase );
957+
a.AttributeDataType = variantDataType;
952958
}
953959
}
954960
}
955961

956962
return a;
957963
}
958964

959-
private Dictionary<string, Dictionary<string, DataTypeField>> ReferenceAttributeMap = new Dictionary<string, Dictionary<string, DataTypeField>>();
965+
private bool MinimizeExplicitNodeId( AttributeType explicitNodeIdAttribute )
966+
{
967+
bool minimized = false;
968+
969+
if( explicitNodeIdAttribute != null )
970+
{
971+
string path = ATLPrefix + MetaModelName + "/ExplicitNodeId";
972+
if( explicitNodeIdAttribute.RefAttributeType.Equals( path ) )
973+
{
974+
// If NamespaceUri is empty, don't do anything, for nothing is set, and cannot minimize
975+
AttributeType namespaceUri = explicitNodeIdAttribute.Attribute[ "NamespaceUri" ];
976+
if( namespaceUri != null && namespaceUri.Value.Length > 0 )
977+
{
978+
string keepAttributeName = string.Empty;
979+
foreach( string idAttributeName in NodeId_IdAttributeNames )
980+
{
981+
AttributeType nodeIdTypeAttribute = explicitNodeIdAttribute.Attribute[ idAttributeName ];
982+
if( nodeIdTypeAttribute != null &&
983+
nodeIdTypeAttribute.Value != null &&
984+
nodeIdTypeAttribute.Value.Length > 0 )
985+
{
986+
keepAttributeName = idAttributeName;
987+
minimized = true;
988+
break;
989+
}
990+
}
991+
992+
if( keepAttributeName != string.Empty )
993+
{
994+
foreach( string idAttributeName in NodeId_IdAttributeNames )
995+
{
996+
if( !idAttributeName.Equals( keepAttributeName ) )
997+
{
998+
AttributeType nodeIdTypeAttribute = explicitNodeIdAttribute.Attribute[ idAttributeName ];
999+
if( nodeIdTypeAttribute != null )
1000+
{
1001+
explicitNodeIdAttribute.Attribute.RemoveElement( nodeIdTypeAttribute );
1002+
}
1003+
}
1004+
}
1005+
}
1006+
}
1007+
}
1008+
}
1009+
1010+
return minimized;
1011+
}
1012+
9601013

9611014
private Dictionary<string, DataTypeField> CreateFieldReferenceTypes( AttributeType attribute, NodeId typeNodeId )
9621015
{
@@ -2757,11 +2810,6 @@ InternalElementType RecursiveAddModifyInstance<T>(ref T parent, UANode toAdd) wh
27572810
ie.Name = toAdd.DecodedBrowseName.Name;
27582811
AddBaseNodeClassAttributes(ie.Attribute, toAdd);
27592812

2760-
AttributeType a = ie.Attribute.Append("UaNodeNamespaceUri"); //bucket for the namespace URI of the node when present on an instance node
2761-
a.AttributeDataType = "xs:anyURI";
2762-
2763-
ie.Attribute["UaNodeNamespaceUri"].Value = m_modelManager.FindModelUri(toAdd.DecodedNodeId);
2764-
27652813
parent.Insert(ie);
27662814

27672815
}

SystemTest/NodeSetFiles/TestAml.xml

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2423,8 +2423,8 @@
24232423
</uax:ExpandedNodeId>
24242424
</Value>
24252425
</UAVariable>
2426-
<UAVariable DataType="ExpandedNodeId" NodeId="ns=1;g=0EB66E95-DCED-415F-B8EC-43ED3F0C759B" BrowseName="1:GuidNodeIdWithAcutalGuidId" ParentNodeId="ns=1;i=5020" UserAccessLevel="3" AccessLevel="3">
2427-
<DisplayName>GuidNodeIdWithAcutalGuidId</DisplayName>
2426+
<UAVariable DataType="ExpandedNodeId" NodeId="ns=1;g=0EB66E95-DCED-415F-B8EC-43ED3F0C759B" BrowseName="1:GuidNodeIdWithActualGuidId" ParentNodeId="ns=1;i=5020" UserAccessLevel="3" AccessLevel="3">
2427+
<DisplayName>GuidNodeIdWithActualGuidId</DisplayName>
24282428
<References>
24292429
<Reference ReferenceType="Organizes" IsForward="false">ns=1;i=5020</Reference>
24302430
<Reference ReferenceType="HasTypeDefinition">i=63</Reference>
@@ -2436,6 +2436,13 @@
24362436
</uax:ExpandedNodeId>
24372437
</Value>
24382438
</UAVariable>
2439+
<UAVariable DataType="ExpandedNodeId" NodeId="ns=1;s=ThereIsNoValue" BrowseName="1:ThereIsNoValue" ParentNodeId="ns=1;i=5020" UserAccessLevel="3" AccessLevel="3">
2440+
<DisplayName>ThereIsNoValue</DisplayName>
2441+
<References>
2442+
<Reference ReferenceType="Organizes" IsForward="false">ns=1;i=5020</Reference>
2443+
<Reference ReferenceType="HasTypeDefinition">i=63</Reference>
2444+
</References>
2445+
</UAVariable>
24392446
<UAVariable DataType="ExpandedNodeId" NodeId="ns=1;i=6184" BrowseName="1:OpaqueNodeId" ParentNodeId="ns=1;i=5020" UserAccessLevel="3" AccessLevel="3">
24402447
<DisplayName>OpaqueNodeId</DisplayName>
24412448
<References>

SystemTest/TestNodeIds.cs

Lines changed: 101 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -22,57 +22,128 @@ public class TestNodeIds
2222

2323
#region Tests
2424
[TestMethod]
25-
[DataRow("GuidNodeIdWithAcutalGuidId", "0EB66E95-DCED-415F-B8EC-43ED3F0C759B", IdType.Guid)]
26-
[DataRow("NumericNodeIdWithActualNumericId", "12345", IdType.Numeric)]
27-
[DataRow("OpaqueNodeIdWithActualOpaqueId", "T3BhcXVlTm9kZUlk", IdType.Opaque)]
28-
[DataRow("StringNodeIdWithActualStringId", "StringNodeId", IdType.String)]
29-
public void TestNodeIdentifierTypes(string internelElemantName, string nodeId, IdType idType)
25+
[DataRow( "GuidNodeIdWithActualGuidId", "0EB66E95-DCED-415F-B8EC-43ED3F0C759B", IdType.Guid )]
26+
[DataRow( "NumericNodeIdWithActualNumericId", "12345", IdType.Numeric )]
27+
[DataRow( "OpaqueNodeIdWithActualOpaqueId", "T3BhcXVlTm9kZUlk", IdType.Opaque )]
28+
[DataRow( "StringNodeIdWithActualStringId", "StringNodeId", IdType.String )]
29+
[DataRow( "ThereIsNoValue", "ThereIsNoValue", IdType.String, false )]
30+
public void TestNodeIdentifierTypes( string internalElementName, string nodeId, IdType idType, bool hasValue = true )
3031
{
31-
InternalElementType testInternalElement = findInternalElementByName(internelElemantName);
32-
Assert.IsNotNull(testInternalElement, "Could not find test object");
33-
var nodeIdAttribute = testInternalElement.Attribute.FirstOrDefault(childElement => childElement.Name == "NodeId");
34-
Assert.IsNotNull(nodeIdAttribute, "Unable to find nodeId attribute");
35-
var rootNodeIdAttribute = nodeIdAttribute.Attribute.FirstOrDefault(childElement => childElement.Name == "RootNodeId");
36-
Assert.IsNotNull(rootNodeIdAttribute, "Unable to find rootNodeId attribute");
37-
switch (idType)
32+
InternalElementType testInternalElement = findInternalElementByName( internalElementName );
33+
Assert.IsNotNull( testInternalElement, "Could not find test object" );
34+
35+
var nodeIdAttribute = testInternalElement.Attribute.FirstOrDefault( childElement => childElement.Name == "NodeId" );
36+
Assert.IsNotNull( nodeIdAttribute, "Unable to find nodeId attribute" );
37+
var rootNodeIdAttribute = nodeIdAttribute.Attribute.FirstOrDefault( childElement => childElement.Name == "RootNodeId" );
38+
Assert.IsNotNull( rootNodeIdAttribute, "Unable to find rootNodeId attribute" );
39+
40+
string idName = Enum.GetName( typeof( IdType ), idType ) + "Id";
41+
42+
AttributeType specificAttribute = rootNodeIdAttribute.Attribute.FirstOrDefault(
43+
childElement => childElement.Name == idName );
44+
Assert.IsNotNull( specificAttribute, "Unable to find " + idName + " attribute" );
45+
Assert.AreEqual( nodeId, specificAttribute.Value.ToString(), true );
46+
ValidateNodeId( rootNodeIdAttribute, idType );
47+
48+
AttributeType valueAttribute = testInternalElement.Attribute[ "Value" ];
49+
Assert.IsNotNull( valueAttribute, "Could not find test value object" );
50+
AttributeType valueRootNodeId = valueAttribute.Attribute[ "RootNodeId" ];
51+
Assert.IsNotNull( valueRootNodeId, "Could not find test value object" );
52+
53+
AttributeType specificValueAttribute = valueRootNodeId.Attribute.FirstOrDefault(
54+
childElement => childElement.Name == idName );
55+
Assert.IsNotNull( specificValueAttribute, "Unable to find " + idName + " value attribute" );
56+
if( hasValue )
3857
{
39-
case IdType.Opaque:
40-
var opaqueNodeIdAttribute = rootNodeIdAttribute.Attribute.FirstOrDefault(childElement => childElement.Name == "OpaqueId");
41-
Assert.IsNotNull(opaqueNodeIdAttribute, "Unable to find opaqueNodeId attribute");
42-
Assert.AreEqual(nodeId, opaqueNodeIdAttribute.Value.ToString(), true);
58+
Assert.AreEqual( nodeId, specificValueAttribute.Value.ToString(), true );
59+
ValidateNodeId( valueRootNodeId, idType );
60+
}
61+
else
62+
{
63+
ValidNoNode( valueRootNodeId );
64+
}
65+
}
66+
67+
private void ValidateNodeId( AttributeType rootNodeId, IdType idType )
68+
{
69+
AttributeType namespaceUri = rootNodeId.Attribute[ "NamespaceUri" ];
70+
Assert.IsNotNull( namespaceUri );
71+
Assert.IsNotNull( namespaceUri.Value );
72+
Assert.AreNotEqual( 0, namespaceUri.Value.Length );
73+
74+
AttributeType numericId = rootNodeId.Attribute[ "NumericId" ];
75+
AttributeType stringId = rootNodeId.Attribute[ "StringId" ];
76+
AttributeType guidId = rootNodeId.Attribute[ "GuidId" ];
77+
AttributeType opaqueId = rootNodeId.Attribute[ "OpaqueId" ];
78+
79+
switch( idType )
80+
{
81+
case IdType.Numeric:
82+
Assert.IsNotNull( numericId );
83+
Assert.IsNotNull( numericId.Value );
84+
Assert.AreNotEqual( 0, numericId.Value.Length );
85+
Assert.IsNull( stringId );
86+
Assert.IsNull( guidId );
87+
Assert.IsNull( opaqueId );
4388
break;
4489

4590
case IdType.String:
46-
var stringNodeIdAttribute = rootNodeIdAttribute.Attribute.FirstOrDefault(childElement => childElement.Name == "StringId");
47-
Assert.IsNotNull(stringNodeIdAttribute, "Unable to find stringNodeId attribute");
48-
Assert.AreEqual(nodeId, stringNodeIdAttribute.Value.ToString());
91+
Assert.IsNull( numericId );
92+
Assert.IsNotNull( stringId );
93+
Assert.IsNotNull( stringId.Value );
94+
Assert.AreNotEqual( 0, stringId.Value.Length );
95+
Assert.IsNull( guidId );
96+
Assert.IsNull( opaqueId );
4997
break;
5098

5199
case IdType.Guid:
52-
var guidNodeIdAttribute = rootNodeIdAttribute.Attribute.FirstOrDefault(childElement => childElement.Name == "GuidId");
53-
Assert.IsNotNull(guidNodeIdAttribute, "Unable to find guidNodeId attribute");
54-
Assert.AreEqual(nodeId, guidNodeIdAttribute.Value.ToString(), true);
100+
Assert.IsNull( numericId );
101+
Assert.IsNull( stringId );
102+
Assert.IsNotNull( guidId );
103+
Assert.IsNotNull( guidId.Value );
104+
Assert.AreNotEqual( 0, guidId.Value.Length );
105+
Assert.IsNull( opaqueId );
55106
break;
56107

57-
case IdType.Numeric:
58-
var numericNodeIdAttribute = rootNodeIdAttribute.Attribute.FirstOrDefault(childElement => childElement.Name == "NumericId");
59-
Assert.IsNotNull(numericNodeIdAttribute, "Unable to find numericNodeId attribute");
60-
Assert.AreEqual(nodeId, numericNodeIdAttribute.Value.ToString());
108+
case IdType.Opaque:
109+
Assert.IsNull( numericId );
110+
Assert.IsNull( stringId );
111+
Assert.IsNull( guidId );
112+
Assert.IsNotNull( opaqueId );
113+
Assert.IsNotNull( opaqueId.Value );
114+
Assert.AreNotEqual( 0, opaqueId.Value.Length );
61115
break;
62116
}
63117
}
118+
119+
private void ValidNoNode( AttributeType rootNodeId )
120+
{
121+
ValidateAttributeEmpty( rootNodeId, "NamespaceUri" );
122+
ValidateAttributeEmpty( rootNodeId, "NumericId" );
123+
ValidateAttributeEmpty( rootNodeId, "StringId" );
124+
ValidateAttributeEmpty( rootNodeId, "GuidId" );
125+
ValidateAttributeEmpty( rootNodeId, "OpaqueId" );
126+
}
127+
128+
private void ValidateAttributeEmpty( AttributeType source, string attributeName )
129+
{
130+
AttributeType attribute = source.Attribute[ attributeName ];
131+
Assert.IsNotNull( attribute );
132+
Assert.IsNull( attribute.Value );
133+
}
134+
64135
#endregion
65136

66137
#region Helpers
67138

68-
public InternalElementType? findInternalElementByName(string internelElemantName)
139+
public InternalElementType? findInternalElementByName( string internelElemantName )
69140
{
70-
foreach (var instanceHierarchy in GetDocument().CAEXFile.InstanceHierarchy)
141+
foreach( var instanceHierarchy in GetDocument().CAEXFile.InstanceHierarchy )
71142
{
72143
// browse all InternalElements deep and find element with name "FxRoot"
73-
foreach (var internalElement in instanceHierarchy.Descendants<InternalElementType>())
144+
foreach( var internalElement in instanceHierarchy.Descendants<InternalElementType>() )
74145
{
75-
if (internalElement.Name.Equals(internelElemantName)) return internalElement;
146+
if( internalElement.Name.Equals( internelElemantName ) ) return internalElement;
76147
}
77148
}
78149

@@ -90,7 +161,6 @@ private CAEXDocument GetDocument()
90161
return m_document;
91162
}
92163

93-
94164
#endregion
95165
}
96166
}

0 commit comments

Comments
 (0)