/// <summary> /// Assigns node ids to the children based on the parent node id. /// </summary> public void AssignChildNodeIds(ISystemContext context, NodeState parent) { NodeId parentId = parent.NodeId; // check for valid node id. if (parentId == null || parentId.IdType != IdType.String) { return; } List <BaseInstanceState> children = new List <BaseInstanceState>(); parent.GetChildren(context, children); for (int ii = 0; ii < children.Count; ii++) { BaseInstanceState child = children[ii]; if (child.SymbolicName == null) { continue; } StringBuilder builder = new StringBuilder(); builder.Append(parentId.Identifier); builder.Append(':'); builder.Append(child.SymbolicName); child.NodeId = new NodeId(builder.ToString(), parentId.NamespaceIndex); AssignChildNodeIds(context, child); } }
/// <summary> /// Removes the hierachy of nodes from the cache. /// </summary> private void RemoveNodeHierarchyFromCache(ISystemContext context, NodeState root) { m_cache.Remove(root.NodeId); List <BaseInstanceState> children = new List <BaseInstanceState>(); root.GetChildren(context, children); for (int ii = 0; ii < children.Count; ii++) { RemoveNodeHierarchyFromCache(context, children[ii]); } }
/// <summary> /// Adds the hierachy of nodes to the cache. /// </summary> private void AddNodeHierarchyToCache(ISystemContext context, NodeState root) { m_cache.Add(root.NodeId, root); List <BaseInstanceState> children = new List <BaseInstanceState>(); root.GetChildren(context, children); for (int ii = 0; ii < children.Count; ii++) { AddNodeHierarchyToCache(context, children[ii]); } }
/// <summary> /// Recursively populates the data view. /// </summary> private void PopulateDataView( ISystemContext context, NodeState parent, string parentPath) { List <BaseInstanceState> children = new List <BaseInstanceState>(); parent.GetChildren(context, children); for (int ii = 0; ii < children.Count; ii++) { BaseInstanceState child = children[ii]; StringBuilder childPath = new StringBuilder(); if (!String.IsNullOrEmpty(parentPath)) { childPath.Append(parentPath); childPath.Append("/"); } childPath.Append(child.GetDisplayText()); if (child.NodeClass == NodeClass.Variable) { BaseVariableState variable = (BaseVariableState)child; if (StatusCode.IsGood(variable.StatusCode)) { string dataType = m_session.NodeCache.GetDisplayText(variable.DataType); if (variable.ValueRank >= 0) { dataType += "[]"; } DataRow row = m_dataset.Tables[0].NewRow(); row[0] = m_dataset.Tables[0].Rows.Count; row[1] = childPath.ToString(); row[2] = dataType; row[3] = variable.WrappedValue; m_dataset.Tables[0].Rows.Add(row); } } PopulateDataView(context, child, childPath.ToString()); } }
/// <summary> /// Recursively collects the variables in a NodeState and returns a collection of BrowsePaths. /// </summary> public void GetBrowsePathFromNodeState( ISystemContext context, NodeId rootId, NodeState parent, RelativePath parentPath, BrowsePathCollection browsePaths) { List <BaseInstanceState> children = new List <BaseInstanceState>(); parent.GetChildren(context, children); for (int ii = 0; ii < children.Count; ii++) { BaseInstanceState child = children[ii]; BrowsePath browsePath = new BrowsePath(); browsePath.StartingNode = rootId; browsePath.Handle = child; if (parentPath != null) { browsePath.RelativePath.Elements.AddRange(parentPath.Elements); } RelativePathElement element = new RelativePathElement(); element.ReferenceTypeId = child.ReferenceTypeId; element.IsInverse = false; element.IncludeSubtypes = false; element.TargetName = child.BrowseName; browsePath.RelativePath.Elements.Add(element); if (child.NodeClass == NodeClass.Variable) { browsePaths.Add(browsePath); } GetBrowsePathFromNodeState(context, rootId, child, browsePath.RelativePath, browsePaths); } }
/// <summary> /// Recursively indexes the node and its children. /// </summary> protected virtual void RemovePredefinedNode( ISystemContext context, NodeState node, List<LocalReference> referencesToRemove) { m_predefinedNodes.Remove(node.NodeId); node.UpdateChangeMasks(NodeStateChangeMasks.Deleted); node.ClearChangeMasks(context, false); OnNodeRemoved(node); // remove from the parent. BaseInstanceState instance = node as BaseInstanceState; if (instance != null && instance.Parent != null) { instance.Parent.RemoveChild(instance); } // remove children. List<BaseInstanceState> children = new List<BaseInstanceState>(); node.GetChildren(context, children); for (int ii = 0; ii < children.Count; ii++) { node.RemoveChild(children[ii]); } for (int ii = 0; ii < children.Count; ii++) { RemovePredefinedNode(context, children[ii], referencesToRemove); } // remove from type table. BaseTypeState type = node as BaseTypeState; if (type != null) { m_server.TypeTree.Remove(type.NodeId); } // remove inverse references. List<IReference> references = new List<IReference>(); node.GetReferences(context, references); for (int ii = 0; ii < references.Count; ii++) { IReference reference = references[ii]; if (reference.TargetId.IsAbsolute) { continue; } LocalReference referenceToRemove = new LocalReference( (NodeId)reference.TargetId, reference.ReferenceTypeId, reference.IsInverse, node.NodeId); referencesToRemove.Add(referenceToRemove); } }
/// <summary> /// Adds a node to the set. /// </summary> public void Export(ISystemContext context, NodeState node, bool outputRedundantNames = true) { if (node == null) { throw new ArgumentNullException(nameof(node)); } if (Opc.Ua.NodeId.IsNull(node.NodeId)) { throw new ArgumentException("A non-null NodeId must be specified."); } UANode exportedNode = null; switch (node.NodeClass) { case NodeClass.Object: { BaseObjectState o = (BaseObjectState)node; UAObject value = new UAObject(); value.EventNotifier = o.EventNotifier; if (o.Parent != null) { value.ParentNodeId = ExportAlias(o.Parent.NodeId, context.NamespaceUris); } exportedNode = value; break; } case NodeClass.Variable: { BaseVariableState o = (BaseVariableState)node; UAVariable value = new UAVariable(); value.DataType = ExportAlias(o.DataType, context.NamespaceUris); value.ValueRank = o.ValueRank; value.ArrayDimensions = Export(o.ArrayDimensions); value.AccessLevel = o.AccessLevelEx; value.MinimumSamplingInterval = o.MinimumSamplingInterval; value.Historizing = o.Historizing; if (o.Parent != null) { value.ParentNodeId = ExportAlias(o.Parent.NodeId, context.NamespaceUris); } if (o.Value != null) { XmlEncoder encoder = CreateEncoder(context); Variant variant = new Variant(o.Value); encoder.WriteVariantContents(variant.Value, variant.TypeInfo); XmlDocument document = new XmlDocument(); document.InnerXml = encoder.Close(); value.Value = document.DocumentElement; } exportedNode = value; break; } case NodeClass.Method: { MethodState o = (MethodState)node; UAMethod value = new UAMethod(); value.Executable = o.Executable; if (o.TypeDefinitionId != null && !o.TypeDefinitionId.IsNullNodeId && o.TypeDefinitionId != o.NodeId) { value.MethodDeclarationId = Export(o.TypeDefinitionId, context.NamespaceUris); } if (o.Parent != null) { value.ParentNodeId = ExportAlias(o.Parent.NodeId, context.NamespaceUris); } exportedNode = value; break; } case NodeClass.View: { ViewState o = (ViewState)node; UAView value = new UAView(); value.ContainsNoLoops = o.ContainsNoLoops; exportedNode = value; break; } case NodeClass.ObjectType: { BaseObjectTypeState o = (BaseObjectTypeState)node; UAObjectType value = new UAObjectType(); value.IsAbstract = o.IsAbstract; exportedNode = value; break; } case NodeClass.VariableType: { BaseVariableTypeState o = (BaseVariableTypeState)node; UAVariableType value = new UAVariableType(); value.IsAbstract = o.IsAbstract; value.DataType = ExportAlias(o.DataType, context.NamespaceUris); value.ValueRank = o.ValueRank; value.ArrayDimensions = Export(o.ArrayDimensions); if (o.Value != null) { XmlEncoder encoder = CreateEncoder(context); Variant variant = new Variant(o.Value); encoder.WriteVariantContents(variant.Value, variant.TypeInfo); XmlDocument document = new XmlDocument(); document.InnerXml = encoder.Close(); value.Value = document.DocumentElement; } exportedNode = value; break; } case NodeClass.DataType: { DataTypeState o = (DataTypeState)node; UADataType value = new UADataType(); value.IsAbstract = o.IsAbstract; value.Definition = Export(o, o.DataTypeDefinition, context.NamespaceUris, outputRedundantNames); value.Purpose = o.Purpose; exportedNode = value; break; } case NodeClass.ReferenceType: { ReferenceTypeState o = (ReferenceTypeState)node; UAReferenceType value = new UAReferenceType(); value.IsAbstract = o.IsAbstract; if (!Opc.Ua.LocalizedText.IsNullOrEmpty(o.InverseName)) { value.InverseName = Export(new Opc.Ua.LocalizedText[] { o.InverseName }); } value.Symmetric = o.Symmetric; exportedNode = value; break; } } exportedNode.NodeId = Export(node.NodeId, context.NamespaceUris); exportedNode.BrowseName = Export(node.BrowseName, context.NamespaceUris); if (outputRedundantNames || node.DisplayName.Text != node.BrowseName.Name) { exportedNode.DisplayName = Export(new Opc.Ua.LocalizedText[] { node.DisplayName }); } else { exportedNode.DisplayName = null; } if (node.Description != null && !String.IsNullOrEmpty(node.Description.Text)) { exportedNode.Description = Export(new Opc.Ua.LocalizedText[] { node.Description }); } else { exportedNode.Description = new LocalizedText[0]; } exportedNode.Category = (node.Categories != null && node.Categories.Count > 0) ? new List <string>(node.Categories).ToArray() : null; exportedNode.ReleaseStatus = node.ReleaseStatus; exportedNode.WriteMask = (uint)node.WriteMask; exportedNode.UserWriteMask = (uint)node.UserWriteMask; exportedNode.Extensions = node.Extensions; if (!String.IsNullOrEmpty(node.SymbolicName) && node.SymbolicName != node.BrowseName.Name) { exportedNode.SymbolicName = node.SymbolicName; } // export references. INodeBrowser browser = node.CreateBrowser(context, null, null, true, BrowseDirection.Both, null, null, true); List <Reference> exportedReferences = new List <Reference>(); IReference reference = browser.Next(); while (reference != null) { if (node.NodeClass == NodeClass.Method) { if (!reference.IsInverse && reference.ReferenceTypeId == ReferenceTypeIds.HasTypeDefinition) { reference = browser.Next(); continue; } } Reference exportedReference = new Reference(); exportedReference.ReferenceType = ExportAlias(reference.ReferenceTypeId, context.NamespaceUris); exportedReference.IsForward = !reference.IsInverse; exportedReference.Value = Export(reference.TargetId, context.NamespaceUris, context.ServerUris); exportedReferences.Add(exportedReference); reference = browser.Next(); } exportedNode.References = exportedReferences.ToArray(); // add node to list. UANode[] nodes = null; int count = 1; if (this.Items == null) { nodes = new UANode[count]; } else { count += this.Items.Length; nodes = new UANode[count]; Array.Copy(this.Items, nodes, this.Items.Length); } nodes[count - 1] = exportedNode; this.Items = nodes; // recusively process children. List <BaseInstanceState> children = new List <BaseInstanceState>(); node.GetChildren(context, children); for (int ii = 0; ii < children.Count; ii++) { Export(context, children[ii], outputRedundantNames); } }
/// <summary> /// Removes the hierachy of nodes from the cache. /// </summary> private void RemoveNodeHierarchyFromCache(ISystemContext context, NodeState root) { m_cache.Remove(root.NodeId); List<BaseInstanceState> children = new List<BaseInstanceState>(); root.GetChildren(context, children); for (int ii = 0; ii < children.Count; ii++) { RemoveNodeHierarchyFromCache(context, children[ii]); } }
/// <summary> /// Adds the hierachy of nodes to the cache. /// </summary> private void AddNodeHierarchyToCache(ISystemContext context, NodeState root) { m_cache.Add(root.NodeId, root); List<BaseInstanceState> children = new List<BaseInstanceState>(); root.GetChildren(context, children); for (int ii = 0; ii < children.Count; ii++) { AddNodeHierarchyToCache(context, children[ii]); } }
/// <summary> /// Convert to service object /// </summary> /// <param name="state"></param> /// <param name="context"></param> /// <param name="parent"></param> /// <returns></returns> public static BaseNodeModel ToNodeModel(this NodeState state, ISystemContext context, BaseNodeModel parent = null) { BaseNodeModel nodeModel; switch (state) { case ViewState viewState: nodeModel = new ViewNodeModel { ContainsNoLoops = viewState.ContainsNoLoops.ToNullable(false), EventNotifier = viewState.EventNotifier.ToNullable(EventNotifiers.None), }; break; case BaseTypeState typeState: switch (typeState) { case BaseVariableTypeState variableType: switch (variableType) { case BaseDataVariableTypeState data: nodeModel = new DataVariableTypeNodeModel(); break; case PropertyTypeState property: nodeModel = new PropertyTypeNodeModel(); break; default: return(null); } var baseVariableTypeState = nodeModel as VariableTypeNodeModel; baseVariableTypeState.ArrayDimensions = variableType.ArrayDimensions?.ToArray(); baseVariableTypeState.DataType = variableType.DataType; baseVariableTypeState.ValueRank = variableType.ValueRank.ToNullable(ValueRanks.Scalar); baseVariableTypeState.Value = variableType.WrappedValue; break; case BaseObjectTypeState objectType: nodeModel = new ObjectTypeNodeModel(); break; case ReferenceTypeState referenceType: nodeModel = new ReferenceTypeNodeModel { Symmetric = referenceType.Symmetric.ToNullable(false), InverseName = referenceType.InverseName }; break; case DataTypeState dataType: nodeModel = new DataTypeNodeModel { // Definition = dataType.Definition.ToDataTypeDefinition(), Purpose = Schema.DataTypePurpose.Normal }; break; default: return(null); } var baseTypeState = nodeModel as TypeNodeModel; baseTypeState.IsAbstract = typeState.IsAbstract.ToNullable(false); break; case BaseInstanceState instanceState: switch (instanceState) { case BaseVariableState variable: switch (variable) { case BaseDataVariableState data: nodeModel = new DataVariableNodeModel(parent); break; case PropertyState property: nodeModel = new PropertyNodeModel(parent); break; default: return(null); } var baseVariableState = nodeModel as VariableNodeModel; baseVariableState.ArrayDimensions = variable.ArrayDimensions.ToArray(); baseVariableState.DataType = variable.DataType; baseVariableState.ValueRank = variable.ValueRank.ToNullable(ValueRanks.Scalar); baseVariableState.Value = variable.WrappedValue; baseVariableState.AccessLevel = variable.AccessLevel.ToNullable(AccessLevels.CurrentRead); baseVariableState.UserAccessLevel = variable.UserAccessLevel.ToNullable(AccessLevels.CurrentRead); baseVariableState.IsValueType = variable.IsValueType; baseVariableState.Historizing = variable.Historizing.ToNullable(false); baseVariableState.MinimumSamplingInterval = variable.MinimumSamplingInterval.ToNullable(0.0); baseVariableState.ModellingRuleId = variable.ModellingRuleId; baseVariableState.NumericId = variable.NumericId; baseVariableState.ReferenceTypeId = variable.ReferenceTypeId; baseVariableState.StatusCode = variable.StatusCode.ToNullable(StatusCodes.Good); baseVariableState.Timestamp = variable.Timestamp.ToNullable(DateTime.MinValue); baseVariableState.TypeDefinitionId = variable.TypeDefinitionId; break; case BaseObjectState obj: nodeModel = new ObjectNodeModel(parent) { EventNotifier = obj.EventNotifier.ToNullable(EventNotifiers.None) }; break; case MethodState method: nodeModel = new MethodNodeModel(parent) { UserExecutable = method.UserExecutable, Executable = method.Executable, MethodDeclarationId = method.MethodDeclarationId, }; break; default: return(null); } break; default: return(null); } nodeModel.BrowseName = state.BrowseName; nodeModel.Description = state.Description; nodeModel.DisplayName = state.DisplayName; nodeModel.Handle = state.Handle; nodeModel.NodeId = state.NodeId; nodeModel.SymbolicName = state.SymbolicName; nodeModel.WriteMask = state.WriteMask.ToNullable(AttributeWriteMask.None); nodeModel.UserWriteMask = state.UserWriteMask.ToNullable(AttributeWriteMask.None); var children = new List <BaseInstanceState>(); state.GetChildren(context, children); foreach (var child in children) { nodeModel.AddChild(child.ToNodeModel(context, nodeModel) as InstanceNodeModel); } var references = new List <IReference>(); state.GetReferences(context, references); foreach (var reference in references) { nodeModel.AddReference(reference.ReferenceTypeId, reference.IsInverse, reference.TargetId); } return(nodeModel); }
/// <summary> /// Collects instance declarations nodes from with a type. /// </summary> public static void CollectInstanceDeclarations( Session session, ComNamespaceMapper mapper, NodeState node, AeEventAttribute parent, List<AeEventAttribute> instances, IDictionary<string, AeEventAttribute> map) { List<BaseInstanceState> children = new List<BaseInstanceState>(); node.GetChildren(session.SystemContext, children); if (children.Count == 0) { return; } // process the children. for (int ii = 0; ii < children.Count; ii++) { BaseInstanceState instance = children[ii]; // only interested in objects and variables. if (instance.NodeClass != NodeClass.Object && instance.NodeClass != NodeClass.Variable) { return; } // ignore instances without a modelling rule. if (NodeId.IsNull(instance.ModellingRuleId)) { return; } // create a new declaration. AeEventAttribute declaration = new AeEventAttribute(); declaration.RootTypeId = (parent != null)?parent.RootTypeId:node.NodeId; declaration.NodeId = (NodeId)instance.NodeId; declaration.BrowseName = instance.BrowseName; declaration.NodeClass = instance.NodeClass; declaration.Description = (instance.Description != null)?instance.Description.ToString():null; // get data type information. BaseVariableState variable = instance as BaseVariableState; if (variable != null) { declaration.DataType = variable.DataType; declaration.ValueRank = variable.ValueRank; if (!NodeId.IsNull(variable.DataType)) { declaration.BuiltInType = DataTypes.GetBuiltInType(declaration.DataType, session.TypeTree); } } if (!LocalizedText.IsNullOrEmpty(instance.DisplayName)) { declaration.DisplayName = instance.DisplayName.Text; } else { declaration.DisplayName = instance.BrowseName.Name; } if (parent != null) { declaration.BrowsePath = new QualifiedNameCollection(parent.BrowsePath); declaration.BrowsePathDisplayText = Utils.Format("{0}/{1}", parent.BrowsePathDisplayText, mapper.GetLocalBrowseName(instance.BrowseName)); declaration.DisplayPath = Utils.Format("{0}/{1}", parent.DisplayPath, instance.DisplayName); } else { declaration.BrowsePath = new QualifiedNameCollection(); declaration.BrowsePathDisplayText = Utils.Format("{0}", instance.BrowseName); declaration.DisplayPath = Utils.Format("{0}", instance.DisplayName); } declaration.BrowsePath.Add(instance.BrowseName); // check if reading an overridden declaration. AeEventAttribute overriden = null; if (map.TryGetValue(declaration.BrowsePathDisplayText, out overriden)) { declaration.OverriddenDeclaration = overriden; } map[declaration.BrowsePathDisplayText] = declaration; // only interested in variables. if (instance.NodeClass == NodeClass.Variable) { instances.Add(declaration); } // recusively build tree. CollectInstanceDeclarations(session, mapper, instance, declaration, instances, map); } }
/// <summary> /// Recursively populates the data view. /// </summary> private void PopulateDataView( ISystemContext context, NodeState parent, string parentPath) { List<BaseInstanceState> children = new List<BaseInstanceState>(); parent.GetChildren(context, children); for (int ii = 0; ii < children.Count; ii++) { BaseInstanceState child = children[ii]; StringBuilder childPath = new StringBuilder(); if (!String.IsNullOrEmpty(parentPath)) { childPath.Append(parentPath); childPath.Append("/"); } childPath.Append(child.GetDisplayText()); if (child.NodeClass == NodeClass.Variable) { BaseVariableState variable = (BaseVariableState)child; if (StatusCode.IsGood(variable.StatusCode)) { string dataType = m_session.NodeCache.GetDisplayText(variable.DataType); if (variable.ValueRank >= 0) { dataType += "[]"; } DataRow row = m_dataset.Tables[0].NewRow(); row[0] = m_dataset.Tables[0].Rows.Count; row[1] = childPath.ToString(); row[2] = dataType; row[3] = variable.WrappedValue; m_dataset.Tables[0].Rows.Add(row); } } PopulateDataView(context, child, childPath.ToString()); } }
/// <summary> /// Collects instance declarations nodes from with a type. /// </summary> public static void CollectInstanceDeclarations( Session session, ComNamespaceMapper mapper, NodeState node, AeEventAttribute parent, List <AeEventAttribute> instances, IDictionary <string, AeEventAttribute> map) { List <BaseInstanceState> children = new List <BaseInstanceState>(); node.GetChildren(session.SystemContext, children); if (children.Count == 0) { return; } // process the children. for (int ii = 0; ii < children.Count; ii++) { BaseInstanceState instance = children[ii]; // only interested in objects and variables. if (instance.NodeClass != NodeClass.Object && instance.NodeClass != NodeClass.Variable) { return; } // ignore instances without a modelling rule. if (NodeId.IsNull(instance.ModellingRuleId)) { return; } // create a new declaration. AeEventAttribute declaration = new AeEventAttribute(); declaration.RootTypeId = (parent != null)?parent.RootTypeId:node.NodeId; declaration.NodeId = (NodeId)instance.NodeId; declaration.BrowseName = instance.BrowseName; declaration.NodeClass = instance.NodeClass; declaration.Description = (instance.Description != null)?instance.Description.ToString():null; // get data type information. BaseVariableState variable = instance as BaseVariableState; if (variable != null) { declaration.DataType = variable.DataType; declaration.ValueRank = variable.ValueRank; if (!NodeId.IsNull(variable.DataType)) { declaration.BuiltInType = DataTypes.GetBuiltInType(declaration.DataType, session.TypeTree); } } if (!LocalizedText.IsNullOrEmpty(instance.DisplayName)) { declaration.DisplayName = instance.DisplayName.Text; } else { declaration.DisplayName = instance.BrowseName.Name; } if (parent != null) { declaration.BrowsePath = new QualifiedNameCollection(parent.BrowsePath); declaration.BrowsePathDisplayText = Utils.Format("{0}/{1}", parent.BrowsePathDisplayText, mapper.GetLocalBrowseName(instance.BrowseName)); declaration.DisplayPath = Utils.Format("{0}/{1}", parent.DisplayPath, instance.DisplayName); } else { declaration.BrowsePath = new QualifiedNameCollection(); declaration.BrowsePathDisplayText = Utils.Format("{0}", instance.BrowseName); declaration.DisplayPath = Utils.Format("{0}", instance.DisplayName); } declaration.BrowsePath.Add(instance.BrowseName); // check if reading an overridden declaration. AeEventAttribute overriden = null; if (map.TryGetValue(declaration.BrowsePathDisplayText, out overriden)) { declaration.OverriddenDeclaration = overriden; } map[declaration.BrowsePathDisplayText] = declaration; // only interested in variables. if (instance.NodeClass == NodeClass.Variable) { instances.Add(declaration); } // recusively build tree. CollectInstanceDeclarations(session, mapper, instance, declaration, instances, map); } }
/// <summary> /// Recursively collects the variables in a NodeState and returns a collection of BrowsePaths. /// </summary> public void GetBrowsePathFromNodeState( ISystemContext context, NodeId rootId, NodeState parent, RelativePath parentPath, BrowsePathCollection browsePaths) { List<BaseInstanceState> children = new List<BaseInstanceState>(); parent.GetChildren(context, children); for (int ii = 0; ii < children.Count; ii++) { BaseInstanceState child = children[ii]; BrowsePath browsePath = new BrowsePath(); browsePath.StartingNode = rootId; browsePath.Handle = child; if (parentPath != null) { browsePath.RelativePath.Elements.AddRange(parentPath.Elements); } RelativePathElement element = new RelativePathElement(); element.ReferenceTypeId = child.ReferenceTypeId; element.IsInverse = false; element.IncludeSubtypes = false; element.TargetName = child.BrowseName; browsePath.RelativePath.Elements.Add(element); if (child.NodeClass == NodeClass.Variable) { browsePaths.Add(browsePath); } GetBrowsePathFromNodeState(context, rootId, child, browsePath.RelativePath, browsePaths); } }
/// <summary> /// Adds a node to the set. /// </summary> public void Export(ISystemContext context, NodeState node) { if (node == null) throw new ArgumentNullException("node"); if (Opc.Ua.NodeId.IsNull(node.NodeId)) { throw new ArgumentException("A non-null NodeId must be specified."); } UANode exportedNode = null; switch (node.NodeClass) { case NodeClass.Object: { BaseObjectState o = (BaseObjectState)node; UAObject value = new UAObject(); value.EventNotifier = o.EventNotifier; if (o.Parent != null) { value.ParentNodeId = ExportAlias(o.Parent.NodeId, context.NamespaceUris); } exportedNode = value; break; } case NodeClass.Variable: { BaseVariableState o = (BaseVariableState)node; UAVariable value = new UAVariable(); value.DataType = ExportAlias(o.DataType, context.NamespaceUris); value.ValueRank = o.ValueRank; value.ArrayDimensions = Export(o.ArrayDimensions); value.AccessLevel = o.AccessLevel; value.UserAccessLevel = o.UserAccessLevel; value.MinimumSamplingInterval = o.MinimumSamplingInterval; value.Historizing = o.Historizing; if (o.Parent != null) { value.ParentNodeId = ExportAlias(o.Parent.NodeId, context.NamespaceUris); } if (o.Value != null) { XmlEncoder encoder = CreateEncoder(context); Variant variant = new Variant(o.Value); encoder.WriteVariantContents(variant.Value, variant.TypeInfo); XmlDocument document = new XmlDocument(); document.InnerXml = encoder.Close(); value.Value = document.DocumentElement; } exportedNode = value; break; } case NodeClass.Method: { MethodState o = (MethodState)node; UAMethod value = new UAMethod(); value.Executable = o.Executable; value.UserExecutable = o.UserExecutable; if (o.Parent != null) { value.ParentNodeId = ExportAlias(o.Parent.NodeId, context.NamespaceUris); } exportedNode = value; break; } case NodeClass.View: { ViewState o = (ViewState)node; UAView value = new UAView(); value.ContainsNoLoops = o.ContainsNoLoops; exportedNode = value; break; } case NodeClass.ObjectType: { BaseObjectTypeState o = (BaseObjectTypeState)node; UAObjectType value = new UAObjectType(); value.IsAbstract = o.IsAbstract; exportedNode = value; break; } case NodeClass.VariableType: { BaseVariableTypeState o = (BaseVariableTypeState)node; UAVariableType value = new UAVariableType(); value.IsAbstract = o.IsAbstract; value.DataType = ExportAlias(o.DataType, context.NamespaceUris); value.ValueRank = o.ValueRank; value.ArrayDimensions = Export(o.ArrayDimensions); if (o.Value != null) { XmlEncoder encoder = CreateEncoder(context); Variant variant = new Variant(o.Value); encoder.WriteVariantContents(variant.Value, variant.TypeInfo); XmlDocument document = new XmlDocument(); document.InnerXml = encoder.Close(); value.Value = document.DocumentElement; } exportedNode = value; break; } case NodeClass.DataType: { DataTypeState o = (DataTypeState)node; UADataType value = new UADataType(); value.IsAbstract = o.IsAbstract; value.Definition = Export(o.Definition, context.NamespaceUris); exportedNode = value; break; } case NodeClass.ReferenceType: { ReferenceTypeState o = (ReferenceTypeState)node; UAReferenceType value = new UAReferenceType(); value.IsAbstract = o.IsAbstract; value.InverseName = Export(new Opc.Ua.LocalizedText[] { o.InverseName }); value.Symmetric = o.Symmetric; exportedNode = value; break; } } exportedNode.NodeId = Export(node.NodeId, context.NamespaceUris); exportedNode.BrowseName = Export(node.BrowseName, context.NamespaceUris); exportedNode.DisplayName = Export(new Opc.Ua.LocalizedText[] { node.DisplayName }); exportedNode.Description = Export(new Opc.Ua.LocalizedText[] { node.Description }); exportedNode.WriteMask = (uint)node.WriteMask; exportedNode.UserWriteMask = (uint)node.UserWriteMask; if (!String.IsNullOrEmpty(node.SymbolicName) && node.SymbolicName != node.BrowseName.Name) { exportedNode.SymbolicName = node.SymbolicName; } // export references. INodeBrowser browser = node.CreateBrowser(context, null, null, true, BrowseDirection.Both, null, null, true); List<Reference> exportedReferences = new List<Reference>(); IReference reference = browser.Next(); while (reference != null) { Reference exportedReference = new Reference(); exportedReference.ReferenceType = ExportAlias(reference.ReferenceTypeId, context.NamespaceUris); exportedReference.IsForward = !reference.IsInverse; exportedReference.Value = Export(reference.TargetId, context.NamespaceUris, context.ServerUris); exportedReferences.Add(exportedReference); reference = browser.Next(); } exportedNode.References = exportedReferences.ToArray(); // add node to list. UANode[] nodes = null; int count = 1; if (this.Items == null) { nodes = new UANode[count]; } else { count += this.Items.Length; nodes = new UANode[count]; Array.Copy(this.Items, nodes, this.Items.Length); } nodes[count-1] = exportedNode; this.Items = nodes; // recusively process children. List<BaseInstanceState> children = new List<BaseInstanceState>(); node.GetChildren(context, children); for (int ii = 0; ii < children.Count; ii++) { Export(context, children[ii]); } }
/// <summary> /// Assigns node ids to the children based on the parent node id. /// </summary> public void AssignChildNodeIds(ISystemContext context, NodeState parent) { NodeId parentId = parent.NodeId; // check for valid node id. if (parentId == null || parentId.IdType != IdType.String) { return; } List<BaseInstanceState> children = new List<BaseInstanceState>(); parent.GetChildren(context, children); for (int ii = 0; ii < children.Count; ii++) { BaseInstanceState child = children[ii]; if (child.SymbolicName == null) { continue; } StringBuilder builder = new StringBuilder(); builder.Append(parentId.Identifier); builder.Append(':'); builder.Append(child.SymbolicName); child.NodeId = new NodeId(builder.ToString(), parentId.NamespaceIndex); AssignChildNodeIds(context, child); } }