コード例 #1
0
ファイル: DataSource.cs プロジェクト: neobox3000/UA-.NET
        /// <summary>
        /// Imports a ExpandedNodeId
        /// </summary>
        private Opc.Ua.ExpandedNodeId ImportExpandedNodeId(string source, NamespaceTable namespaceUris, StringTable serverUris)
        {
            if (String.IsNullOrEmpty(source))
            {
                return(Opc.Ua.ExpandedNodeId.Null);
            }

            // parse the node.
            Opc.Ua.ExpandedNodeId nodeId = Opc.Ua.ExpandedNodeId.Parse(source);

            if (nodeId.ServerIndex <= 0 && nodeId.NamespaceIndex <= 0 && String.IsNullOrEmpty(nodeId.NamespaceUri))
            {
                return(nodeId);
            }

            uint   serverIndex    = ImportServerIndex(nodeId.ServerIndex, serverUris);
            ushort namespaceIndex = ImportNamespaceIndex(nodeId.NamespaceIndex, namespaceUris);

            if (serverIndex > 0)
            {
                string namespaceUri = nodeId.NamespaceUri;

                if (String.IsNullOrEmpty(nodeId.NamespaceUri))
                {
                    namespaceUri = namespaceUris.GetString(namespaceIndex);
                }

                nodeId = new Opc.Ua.ExpandedNodeId(nodeId.Identifier, 0, namespaceUri, serverIndex);
                return(nodeId);
            }


            nodeId = new Opc.Ua.ExpandedNodeId(nodeId.Identifier, namespaceIndex, null, 0);
            return(nodeId);
        }
コード例 #2
0
        /// <summary cref="ITypeTable.FindSuperType(ExpandedNodeId)" />
        public NodeId FindSuperType(ExpandedNodeId typeId)
        {
            if (NodeId.IsNull(typeId) || typeId.ServerIndex != 0)
            {
                return NodeId.Null;
            }
            
            NodeId localId = ExpandedNodeId.ToNodeId(typeId, m_namespaceUris);
            
            if (localId == null)
            {
                return NodeId.Null;
            }

            lock (m_lock)
            {
                TypeInfo typeInfo = null;

                if (!m_nodes.TryGetValue(localId, out typeInfo))
                {
                    return NodeId.Null;
                }

                if (typeInfo.SuperType != null)
                {
                    return typeInfo.SuperType.NodeId;
                }

                return NodeId.Null;
            }
        }
コード例 #3
0
ファイル: NodeId.cs プロジェクト: yuriik83/UA-.NET
 /// <summary>
 /// Initializes the node id with an identifier.
 /// </summary>
 public NodeId(ExpandedNodeId nodeId)
 {
     if (!NodeId.IsNull(nodeId))
     {
         Identifier = nodeId.Identifier;
     }
 }
コード例 #4
0
        /// <summary>
        /// Displays the dialog.
        /// </summary>
        public ExpandedNodeId ShowDialog(Session session, ExpandedNodeId value)
        {
            if (session == null) throw new ArgumentNullException("session");

            m_browser = new Browser(session);
            m_rootId = Objects.RootFolder;
            Identifier = ExpandedNodeId.ToNodeId(value, session.NamespaceUris);

            Popup myPopup = new Popup();
            myPopup.Child = this;
            myPopup.IsOpen = true;

            return this.Identifier;
        }
コード例 #5
0
        /// <summary cref="ITypeTable.IsKnown(ExpandedNodeId)" />
        public bool IsKnown(ExpandedNodeId typeId)
        {            
            if (NodeId.IsNull(typeId) || typeId.ServerIndex != 0)
            {
                return false;
            }

            NodeId localId = ExpandedNodeId.ToNodeId(typeId, m_namespaceUris);
            
            if (localId == null)
            {
                return false;
            }

            lock (m_lock)
            {
                return m_nodes.ContainsKey(localId);
            }
        }
コード例 #6
0
ファイル: ExtensionObject.cs プロジェクト: yuriik83/UA-.NET
        /// <summary>
        /// Serializes the value using XML and stores it in the extension object.
        /// </summary>
        public ExtensionObject(ExpandedNodeId typeId, object value)
        {
            TypeId = typeId;

            StringBuilder buffer = new StringBuilder();

            using (XmlWriter writer = XmlWriter.Create(buffer))
            {
                DataContractSerializer serializer = new DataContractSerializer(value.GetType());
                serializer.WriteObject(writer, value);
            }

            XmlDocument document = new XmlDocument();
            document.InnerXml = buffer.ToString();

            ExtensionObjectBody body = new ExtensionObjectBody();
            body.Nodes = new XmlNode[] { document.DocumentElement };
            Body = body;
        }
コード例 #7
0
 /// <summary>
 /// Constructs a reference to an external target.
 /// </summary>
 public NodeStateReference(NodeId referenceTypeId, bool isInverse, ExpandedNodeId targetId)
 {
     m_referenceTypeId = referenceTypeId;
     m_isInverse = isInverse;
     m_targetId = targetId;
     m_target = null;
 }
コード例 #8
0
ファイル: DataSource.cs プロジェクト: OPCFoundation/UA-.NET
        /// <summary>
        /// Imports a ExpandedNodeId
        /// </summary>
        private Opc.Ua.ExpandedNodeId ImportExpandedNodeId(string source, NamespaceTable namespaceUris, StringTable serverUris)
        {
            if (String.IsNullOrEmpty(source))
            {
                return Opc.Ua.ExpandedNodeId.Null;
            }

            // parse the node.
            Opc.Ua.ExpandedNodeId nodeId = Opc.Ua.ExpandedNodeId.Parse(source);

            if (nodeId.ServerIndex <= 0 && nodeId.NamespaceIndex <= 0 && String.IsNullOrEmpty(nodeId.NamespaceUri))
            {
                return nodeId;
            }

            uint serverIndex = ImportServerIndex(nodeId.ServerIndex, serverUris);
            ushort namespaceIndex = ImportNamespaceIndex(nodeId.NamespaceIndex, namespaceUris);

            if (serverIndex > 0)
            {
                string namespaceUri = nodeId.NamespaceUri;

                if (String.IsNullOrEmpty(nodeId.NamespaceUri))
                {
                    namespaceUri = namespaceUris.GetString(namespaceIndex);
                }

                nodeId = new Opc.Ua.ExpandedNodeId(nodeId.Identifier, 0, namespaceUri, serverIndex);
                return nodeId;
            }


            nodeId = new Opc.Ua.ExpandedNodeId(nodeId.Identifier, namespaceIndex, null, 0);
            return nodeId;
        }
コード例 #9
0
ファイル: Node.cs プロジェクト: yuriik83/UA-.NET
 /// <summary>
 /// Initializes the reference.
 /// </summary>
 /// <param name="referenceTypeId">The reference type id.</param>
 /// <param name="isInverse">if set to <c>true</c> [is inverse].</param>
 /// <param name="targetId">The target id.</param>
 public ReferenceNode(NodeId referenceTypeId, bool isInverse, ExpandedNodeId targetId)
 {
     m_referenceTypeId = referenceTypeId;
     m_isInverse       = isInverse;
     m_targetId        = targetId;
 }
コード例 #10
0
ファイル: MonitoringFilter.cs プロジェクト: yuriik83/UA-.NET
 /// <summary>
 /// Creates an operand that references a component/property of a type.
 /// </summary>
 public SimpleAttributeOperand(
     FilterContext  context, 
     ExpandedNodeId typeDefinitionId,
     string         browsePath,
     uint           attributeId,
     string         indexRange)
 {
     m_typeDefinitionId = ExpandedNodeId.ToNodeId(typeDefinitionId, context.NamespaceUris);
     m_browsePath       = Parse(browsePath);
     m_attributeId      = attributeId;
     m_indexRange       = indexRange;                
 }
コード例 #11
0
        /// <summary>
        /// Recursively collects the nodes within a type hierarchy.
        /// </summary>
        private void GetInstanceHierarchyForType(
            HierarchyBrowsePath parent,
            ExpandedNodeId instanceId,
            InstanceDeclarationHierarchy hierarchy)
        {
            // the instance must be local to the address space.
            ILocalNode instance = m_nodes.Find(instanceId) as ILocalNode;

            if (instance == null)
            {
                return;
            }

            // must be an object, variable or method.
            if ((instance.NodeClass & (NodeClass.Object | NodeClass.Variable | NodeClass.Method)) == 0)
            {
                return;
            }

            // get the naming rule.
            NamingRule namingRule = GetNamingRule(instance.ModellingRule);

            // only include instances with unique browse names in the hierarchy.
            if (namingRule != NamingRule.Unique && namingRule != NamingRule.UniqueOptional)
            {
                return;
            }

            // construct the browse path that identifies the node.
            string browsePath = null;

            if (parent.BrowsePath == "/")
            {
                browsePath = Utils.Format("/{0}", instance.BrowseName);
            }
            else
            {
                browsePath = Utils.Format("{0}/{1}", parent.BrowsePath, instance.BrowseName);
            }

            // check if the browse path already exists in the hierarchy.
            HierarchyBrowsePath child = null;

            if (!hierarchy.BrowsePaths.TryGetValue(browsePath, out child))
            {
                child = new HierarchyBrowsePath();

                child.BrowsePath    = browsePath;
                child.DeclarationId = instance.NodeId;
                child.InstanceId    = null;
                child.IsModelParent = false;
                child.IsOptional    = namingRule != NamingRule.Unique;

                // add new browse path to hierarchy.
                hierarchy.BrowsePaths.Add(browsePath, child);
            }

            // override any declaration specified in a supertype.
            child.DeclarationId = instance.NodeId;

            // check if node has been processed via another path.
            HierarchyBrowsePath alternatePath = null;

            if (hierarchy.Declarations.TryGetValue(instance.NodeId, out alternatePath))
            {
                // keep the model parent path as the primary path.
                if (!alternatePath.IsModelParent && child.IsModelParent)
                {
                    hierarchy.Declarations[instance.NodeId] = child;
                }

                // nothing more to do since node has been processed once.
                return;
            }

            // save child.
            hierarchy.Declarations.Add(instance.NodeId, child);



            // follow children.
            foreach (IReference reference in instance.References.Find(ReferenceTypeIds.HierarchicalReferences, false, true, m_nodes.TypeTree))
            {
                GetInstanceHierarchyForType(child, reference.TargetId, hierarchy);
            }
        }
コード例 #12
0
        /// <summary>
        /// Recursively builds the full inhierited type hierarchy starting with the top-level type.
        /// </summary>
        private void GetInstanceHierarchyForType(ExpandedNodeId typeId, InstanceDeclarationHierarchy hierarchy)
        {
            // the type must be local to the address space.
            ILocalNode type = m_nodes.Find(typeId) as ILocalNode;

            if (type == null)
            {
                throw ServiceResultException.Create(
                          StatusCodes.BadNodeIdUnknown,
                          "The type is not in the local address space.\r\nNodeId = {0}",
                          typeId);
            }

            // must be an object or variable type.
            if ((type.NodeClass & (NodeClass.ObjectType | NodeClass.VariableType)) == 0)
            {
                throw ServiceResultException.Create(
                          StatusCodes.BadNodeClassInvalid,
                          "The type node is not an ObjectType or VariableType.\r\nNodeId = {0}\r\nNodeClass = {1}",
                          typeId,
                          type.NodeClass);
            }

            // find hierarchy in supertypes first.
            foreach (IReference reference in type.References.Find(ReferenceTypeIds.HasSubtype, true, false, null))
            {
                GetInstanceHierarchyForType(reference.TargetId, hierarchy);
            }

            string browsePath = "/";

            // check if the browse path already exists in the hierarchy.
            HierarchyBrowsePath parent = null;

            if (!hierarchy.BrowsePaths.TryGetValue(browsePath, out parent))
            {
                parent = new HierarchyBrowsePath();

                parent.BrowsePath    = browsePath;
                parent.DeclarationId = type.NodeId;
                parent.InstanceId    = null;
                parent.IsModelParent = true;
                parent.IsOptional    = false;

                // add new browse path to hierarchy.
                hierarchy.BrowsePaths.Add(browsePath, parent);
            }

            // override any declaration specified in a supertype.
            parent.DeclarationId = type.NodeId;
            hierarchy.Declarations[type.NodeId] = parent;

            // follow hierarchial references to nodes with a naming rule of unique or unique optional.
            foreach (IReference reference in type.References.Find(ReferenceTypeIds.HierarchicalReferences, false, true, m_nodes.TypeTree))
            {
                GetInstanceHierarchyForType(parent, reference.TargetId, hierarchy);
            }

            // update references defined in the type.
            foreach (HierarchyBrowsePath declaration in hierarchy.Declarations.Values)
            {
                // the declaration must be local to the address space.
                ILocalNode declarationNode = m_nodes.Find(declaration.DeclarationId) as ILocalNode;

                if (declarationNode == null)
                {
                    continue;
                }

                // process all references.
                foreach (IReference reference in declarationNode.References)
                {
                    UpdateReferenceDeclaration(declaration, reference, hierarchy);
                }
            }
        }
コード例 #13
0
ファイル: ContentFilter.cs プロジェクト: yuriik83/UA-.NET
 /// <summary>
 /// Creates an operand that references a component/property of a type.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="typeDefinitionId">The type definition identifier.</param>
 /// <param name="browsePath">The browse path.</param>
 /// <param name="attributeId">The attribute identifier.</param>
 /// <param name="indexRange">The index range.</param>
 public AttributeOperand(
     FilterContext  context, 
     ExpandedNodeId typeDefinitionId,
     string         browsePath,
     uint           attributeId,
     string         indexRange)
 {
     m_nodeId      = ExpandedNodeId.ToNodeId(typeDefinitionId, context.NamespaceUris);
     m_browsePath  = RelativePath.Parse(browsePath, context.TypeTree);
     m_attributeId = attributeId;
     m_indexRange  = indexRange;
     m_alias       = null;                        
 }
コード例 #14
0
ファイル: ExtensionObject.cs プロジェクト: mcooper87/UA-.NET
 /// <summary>
 /// Initializes the object with a <paramref name="typeId"/>.
 /// </summary>
 /// <param name="typeId">The type to copy and create an instance from</param>
 public ExtensionObject(ExpandedNodeId typeId)
 {
     TypeId = typeId;
     Body   = null;
 }
コード例 #15
0
        /// <summary>
        /// Updates the nodeset string tables and returns a NodeId that references those tables.
        /// </summary>
        /// <param name="nodeId">The node identifier.</param>
        /// <param name="targetNamespaceUris">The target namespace URIs.</param>
        /// <param name="targetServerUris">The target server URIs.</param>
        /// <param name="sourceNamespaceUris">The source namespace URIs.</param>
        /// <param name="sourceServerUris">The source server URIs.</param>
        /// <returns>A NodeId that references those tables.</returns>
        private static ExpandedNodeId Translate(
            ExpandedNodeId nodeId,
            NamespaceTable targetNamespaceUris,
            StringTable targetServerUris,
            NamespaceTable sourceNamespaceUris,
            StringTable sourceServerUris)
        {
            if (targetNamespaceUris == null)
            {
                throw new ArgumentNullException("targetNamespaceUris");
            }
            if (sourceNamespaceUris == null)
            {
                throw new ArgumentNullException("sourceNamespaceUris");
            }

            if (nodeId.ServerIndex > 0)
            {
                if (targetServerUris == null)
                {
                    throw new ArgumentNullException("targetServerUris");
                }
                if (sourceServerUris == null)
                {
                    throw new ArgumentNullException("sourceServerUris");
                }
            }

            if (NodeId.IsNull(nodeId))
            {
                return(nodeId);
            }

            if (!nodeId.IsAbsolute)
            {
                return(Translate((NodeId)nodeId, targetNamespaceUris, sourceNamespaceUris));
            }

            string namespaceUri = nodeId.NamespaceUri;

            if (nodeId.ServerIndex > 0)
            {
                if (String.IsNullOrEmpty(namespaceUri))
                {
                    namespaceUri = sourceNamespaceUris.GetString(nodeId.NamespaceIndex);
                }

                string serverUri = sourceServerUris.GetString(nodeId.ServerIndex);

                int index = targetServerUris.GetIndex(serverUri);

                if (index == -1)
                {
                    index = targetServerUris.Append(serverUri);
                }

                return(new ExpandedNodeId(new NodeId(nodeId.Identifier, 0), namespaceUri, (uint)index));
            }

            ushort namespaceIndex = 0;

            if (!String.IsNullOrEmpty(namespaceUri))
            {
                int index = targetNamespaceUris.GetIndex(namespaceUri);

                if (index == -1)
                {
                    index = targetNamespaceUris.Append(namespaceUri);
                }

                namespaceIndex = (ushort)index;
            }

            return(new NodeId(nodeId.Identifier, namespaceIndex));
        }
コード例 #16
0
 /// <summary>
 /// Updates the specified string tables and returns a NodeId that references those tables.
 /// </summary>
 /// <param name="nodeId">The node identifier.</param>
 /// <param name="namespaceUris">The namespace URIs.</param>
 /// <param name="serverUris">The server URIs.</param>
 /// <returns>A NodeId that references those tables.</returns>
 public ExpandedNodeId Import(ExpandedNodeId nodeId, NamespaceTable namespaceUris, StringTable serverUris)
 {
     return(Translate(nodeId, namespaceUris, serverUris, m_namespaceUris, m_serverUris));
 }
コード例 #17
0
        /// <summary>
        /// Adds a node to the type table if it is a type and does not already exist. If it exists references are updated.
        /// </summary>
        /// <param name="node">The node.</param>
        public void Add(ILocalNode node)
        {
            // ignore null.
            if (node == null || NodeId.IsNull(node.NodeId))
            {
                return;
            }

            // ignore non-types.
            if ((node.NodeClass & (NodeClass.ObjectType | NodeClass.VariableType | NodeClass.ReferenceType | NodeClass.DataType)) == 0)
            {
                return;
            }

            NodeId localsuperTypeId = null;

            // find the supertype.
            ExpandedNodeId superTypeId = node.References.FindTarget(ReferenceTypeIds.HasSubtype, true, false, null, 0);

            if (superTypeId != null)
            {
                localsuperTypeId = ExpandedNodeId.ToNodeId(superTypeId, m_namespaceUris);

                if (localsuperTypeId == null)
                {
                    throw ServiceResultException.Create(StatusCodes.BadNodeIdInvalid, "A valid supertype identifier is required.");
                }
            }

            lock (m_lock)
            {
                // lookup the supertype.
                TypeInfo superTypeInfo = null;

                if (localsuperTypeId != null)
                {
                    if (!m_nodes.TryGetValue(localsuperTypeId, out superTypeInfo))
                    {
                        throw ServiceResultException.Create(StatusCodes.BadNodeIdInvalid, "A valid supertype identifier is required.");
                    }
                }

                // create the type info.
                TypeInfo typeInfo = null;

                if (!m_nodes.TryGetValue(node.NodeId, out typeInfo))
                {
                    typeInfo = new TypeInfo();
                    m_nodes.Add(node.NodeId, typeInfo);
                }

                // update the info.
                typeInfo.NodeId    = node.NodeId;
                typeInfo.SuperType = superTypeInfo;
                typeInfo.Deleted   = false;

                // add to supertype.
                if (superTypeInfo != null)
                {
                    superTypeInfo.AddSubType(typeInfo);
                }

                // remove the encodings.
                if (typeInfo.Encodings != null)
                {
                    foreach (NodeId encoding in typeInfo.Encodings)
                    {
                        m_encodings.Remove(encoding);
                    }
                }

                // any new encodings.
                IList <IReference> encodings = node.References.Find(ReferenceTypeIds.HasEncoding, false, false, null);

                if (encodings.Count > 0)
                {
                    typeInfo.Encodings = new NodeId[encodings.Count];

                    for (int ii = 0; ii < encodings.Count; ii++)
                    {
                        typeInfo.Encodings[ii] = ExpandedNodeId.ToNodeId(encodings[ii].TargetId, m_namespaceUris);
                        m_encodings[typeInfo.Encodings[ii]] = typeInfo;
                    }
                }

                // add reference type.
                if ((node.NodeClass & NodeClass.ReferenceType) != 0)
                {
                    if (!QualifiedName.IsNull(typeInfo.BrowseName))
                    {
                        m_referenceTypes.Remove(typeInfo.BrowseName);
                    }

                    typeInfo.BrowseName = node.BrowseName;

                    m_referenceTypes[node.BrowseName] = typeInfo;
                }
            }
        }
コード例 #18
0
        /// <summary>
        /// Adds a set of nodes to the table.
        /// </summary>
        /// <param name="nodeSet">The node set.</param>
        /// <param name="externalReferences">The external references.</param>
        /// <returns></returns>
        public List <Node> Import(NodeSet nodeSet, IDictionary <NodeId, IList <IReference> > externalReferences)
        {
            List <Node> importedNodes = new List <Node>();

            if (nodeSet == null)
            {
                return(importedNodes);
            }

            // add the nodes.
            foreach (Node nodeToImport in nodeSet.Nodes)
            {
                // ignore empty nodes.
                if (nodeToImport == null || NodeId.IsNull(nodeToImport.NodeId))
                {
                    continue;
                }

                Node node = nodeSet.Copy(nodeToImport, m_namespaceUris, m_serverUris);

                // assign a browse name.
                if (QualifiedName.IsNull(node.BrowseName))
                {
                    node.BrowseName = new QualifiedName(node.NodeId.ToString(), 1);
                }

                // assign a display name.
                if (LocalizedText.IsNullOrEmpty(node.DisplayName))
                {
                    node.DisplayName = new LocalizedText(node.BrowseName.Name);
                }

                // index references (the node ids in the references were translated by the Copy() call above).
                foreach (ReferenceNode reference in node.References)
                {
                    // ignore invalid references.
                    if (NodeId.IsNull(reference.ReferenceTypeId) || NodeId.IsNull(reference.TargetId))
                    {
                        continue;
                    }

                    // ignore missing targets.
                    ExpandedNodeId targetId = reference.TargetId;

                    if (NodeId.IsNull(targetId))
                    {
                        continue;
                    }

                    // index reference.
                    node.ReferenceTable.Add(reference.ReferenceTypeId, reference.IsInverse, targetId);

                    // see if a remote node needs to be created.
                    if (targetId.ServerIndex != 0)
                    {
                        RemoteNode remoteNode = Find(targetId) as RemoteNode;

                        if (remoteNode == null)
                        {
                            remoteNode = new RemoteNode(this, targetId);
                            InternalAdd(remoteNode);
                        }

                        remoteNode.AddRef();
                    }
                }

                // clear imported references.
                node.References.Clear();

                // add the node.
                InternalAdd(node);
                importedNodes.Add(node);
            }

            // import the nodes.
            foreach (Node node in importedNodes)
            {
                // ignore invalid nodes.
                if (node == null || NodeId.IsNull(node.NodeId))
                {
                    continue;
                }

                // add reverse references.
                foreach (IReference reference in node.ReferenceTable)
                {
                    Node targetNode = Find(reference.TargetId) as Node;

                    if (targetNode == null)
                    {
                        if (reference.TargetId.ServerIndex != 0)
                        {
                            continue;
                        }

                        // return the reverse reference to a node outside the table.
                        if (externalReferences != null)
                        {
                            NodeId targetId = ExpandedNodeId.ToNodeId(reference.TargetId, m_namespaceUris);

                            if (targetId == null)
                            {
                                continue;
                            }

                            IList <IReference> referenceList = null;

                            if (!externalReferences.TryGetValue(targetId, out referenceList))
                            {
                                externalReferences[targetId] = referenceList = new List <IReference>();
                            }

                            ReferenceNode reverseReference = new ReferenceNode();

                            reverseReference.ReferenceTypeId = reference.ReferenceTypeId;
                            reverseReference.IsInverse       = !reference.IsInverse;
                            reverseReference.TargetId        = node.NodeId;

                            referenceList.Add(reverseReference);
                        }

                        continue;
                    }

                    // type definition and modelling rule references are one way.
                    if (reference.ReferenceTypeId != ReferenceTypeIds.HasTypeDefinition && reference.ReferenceTypeId != ReferenceTypeIds.HasModellingRule)
                    {
                        targetNode.ReferenceTable.Add(reference.ReferenceTypeId, !reference.IsInverse, node.NodeId);
                    }
                }

                // see if it is a type.
                if (m_typeTree != null)
                {
                    m_typeTree.Add(node);
                }
            }

            return(importedNodes);
        }
コード例 #19
0
 /// <summary>
 /// Returns a list of references to the specified target.
 /// </summary>
 /// <param name="targetId">The target identifier.</param>
 /// <returns>A list of references to the specified target.</returns>
 public IList <IReference> FindReferencesToTarget(ExpandedNodeId targetId)
 {
     return(m_references.FindReferencesToTarget(targetId));
 }
コード例 #20
0
ファイル: NodeId.cs プロジェクト: yuriik83/UA-.NET
        /// <summary>
        /// Checks if the node id is null.
        /// </summary>
        public static bool IsNull(ExpandedNodeId nodeId)
        {
            if (nodeId == null || String.IsNullOrEmpty(nodeId.Identifier))
            {
                return true;
            }

            return false;
        }
コード例 #21
0
 /// <summary>
 /// Removes the reference from the node.
 /// </summary>
 /// <param name="referenceTypeId">The reference type identifier.</param>
 /// <param name="isInverse">if set to <c>true</c> this is inverse reference.</param>
 /// <param name="targetId">The target identifier.</param>
 /// <returns>The result of removal.</returns>
 public bool Remove(NodeId referenceTypeId, bool isInverse, ExpandedNodeId targetId)
 {
     return(m_references.Remove(new ReferenceNode(referenceTypeId, isInverse, targetId)));
 }
コード例 #22
0
ファイル: ExtensionObject.cs プロジェクト: mcooper87/UA-.NET
 /// <summary>
 /// Initializes the object with an encodeable object.
 /// </summary>
 /// <param name="typeId">The type describing the body</param>
 /// <param name="body">The underlying data/body to wrap</param>
 /// <remarks>
 /// Initializes the object with an encodeable object.
 /// </remarks>
 public ExtensionObject(ExpandedNodeId typeId, object body)
 {
     TypeId = typeId;
     Body   = body;
 }
コード例 #23
0
        /// <summary>
        /// Converts a value to a ExpandedNodeId
        /// </summary>
        private static object ToExpandedNodeId(object value, BuiltInType sourceType)
        {            
            // check for array conversions.
            Array array = value as Array;

            if (array != null)
            {
                ExpandedNodeId[] output = new ExpandedNodeId[array.Length];

                for (int ii = 0; ii < array.Length; ii++)
                {
                    output[ii] = (ExpandedNodeId)Cast(array.GetValue(ii), BuiltInType.ExpandedNodeId);
                }

                return output;
            }
            
            // handle for supported conversions.
            switch (sourceType)
            {
                case BuiltInType.ExpandedNodeId:
                {
                    return (ExpandedNodeId)value; 
                }

                case BuiltInType.NodeId:
                {
                    return (ExpandedNodeId)(NodeId)value; 
                }

                case BuiltInType.String:
                {
                    return ExpandedNodeId.Parse((string)value);
                }
            }
            
            // conversion not supported.
            return null;
        }
コード例 #24
0
 /// <summary>
 /// Returns true if the node is in the table.
 /// </summary>
 /// <param name="nodeId">The node identifier.</param>
 /// <returns></returns>
 public bool Exists(ExpandedNodeId nodeId)
 {
     return(InternalFind(nodeId) != null);
 }
コード例 #25
0
        /// <summary>
        /// Removes a subtype.
        /// </summary>
        /// <param name="typeId">The type identifier.</param>
        public void Remove(ExpandedNodeId typeId)
        {
            if (NodeId.IsNull(typeId) || typeId.ServerIndex != 0)
            {
                return;
            }
            
            NodeId localId = ExpandedNodeId.ToNodeId(typeId, m_namespaceUris);

            if (localId == null)
            {
                return;
            }

            lock (m_lock)
            {
                // remove type.
                TypeInfo typeInfo = null;

                if (!m_nodes.TryGetValue(localId, out typeInfo))
                {
                    return;               
                }

                m_nodes.Remove(localId);

                // setting the flag to deleted ensures references from subtypes are not broken.
                typeInfo.Deleted = true;

                // remove from subtype list.
                if (typeInfo.SuperType != null)
                {
                    typeInfo.SuperType.RemoveSubType(localId);
                }

                // remove encodings.
                if (typeInfo.Encodings != null)
                {
                    for (int ii = 0; ii < typeInfo.Encodings.Length; ii++)
                    {
                        m_encodings.Remove(typeInfo.Encodings[ii]);
                    }
                }
                        
                // remove reference type.
                if (!QualifiedName.IsNull(typeInfo.BrowseName))
                {
                    m_referenceTypes.Remove(typeInfo.BrowseName);
                }
            }
        }
コード例 #26
0
 /// <summary>
 /// Finds a node in the node set.
 /// </summary>
 /// <param name="nodeId">The node identifier.</param>
 /// <returns>Returns null if the node does not exist.</returns>
 public INode Find(ExpandedNodeId nodeId)
 {
     return(InternalFind(nodeId));
 }
コード例 #27
0
ファイル: MonitoringFilter.cs プロジェクト: yuriik83/UA-.NET
 /// <summary>
 /// Creates an operand that references a component/property of a type.
 /// </summary>
 public SimpleAttributeOperand(
     FilterContext        context, 
     ExpandedNodeId       typeId,
     IList<QualifiedName> browsePath)
 {
     m_typeDefinitionId = ExpandedNodeId.ToNodeId(typeId, context.NamespaceUris);
     m_browsePath       = new QualifiedNameCollection(browsePath);
     m_attributeId      = Attributes.Value;
     m_indexRange       = null;
 }
コード例 #28
0
        /// <summary>
        /// Compares the current instance to the object.
        /// </summary>
        /// <remarks>
        /// Compares the current instance to the object.
        /// </remarks>
        public int CompareTo(object obj)
        {
            // check for null.
            if (Object.ReferenceEquals(obj, null))
            {
                return(-1);
            }

            // check for reference comparisons.
            if (Object.ReferenceEquals(this, obj))
            {
                return(0);
            }

            // just compare node ids.
            if (!this.IsAbsolute)
            {
                if (this.m_nodeId != null)
                {
                    return(this.m_nodeId.CompareTo(obj));
                }
            }

            NodeId nodeId = obj as NodeId;

            // check for expanded node ids.
            ExpandedNodeId expandedId = obj as ExpandedNodeId;

            if (expandedId != null)
            {
                if (this.IsNull && expandedId.IsNull)
                {
                    return(0);
                }

                if (this.ServerIndex != expandedId.ServerIndex)
                {
                    return(this.ServerIndex.CompareTo(expandedId.ServerIndex));
                }

                if (this.NamespaceUri != expandedId.NamespaceUri)
                {
                    if (this.NamespaceUri != null)
                    {
                        return(String.CompareOrdinal(NamespaceUri, expandedId.NamespaceUri));
                    }

                    return(-1);
                }

                nodeId = expandedId.m_nodeId;
            }

            // check for null.
            if (this.m_nodeId != null)
            {
                return(this.m_nodeId.CompareTo(nodeId));
            }

            // compare node ids.
            return((nodeId == null) ? 0 : -1);
        }
コード例 #29
0
ファイル: Node.cs プロジェクト: yuriik83/UA-.NET
 /// <summary>
 /// Returns true if the reference exist.
 /// </summary>
 /// <param name="referenceTypeId">The reference type id.</param>
 /// <param name="isInverse">if set to <c>true</c> [is inverse].</param>
 /// <param name="targetId">The target id.</param>
 /// <returns>True if the reference exist.</returns>
 public bool ReferenceExists(
     NodeId         referenceTypeId, 
     bool           isInverse, 
     ExpandedNodeId targetId)
 {
     return ReferenceTable.Exists(referenceTypeId, isInverse, targetId, false, null);
 }
コード例 #30
0
        public bool WriteUDT(List <string> opcNodes, List <object> values, out List <bool> status)
        {
            bool ret = false;

            try
            {
                if (opcNodes.Count != values.Count)
                {
                    throw new Exception("opcNodes.Count != values.Count");
                }

                int count = opcNodes.Count;

                status = new List <bool>(count);
                List <Type>   types   = new List <Type>(count);
                List <NodeId> nodeIds = new List <NodeId>(count);

                DiagnosticInfoCollection diags;
                StatusCodeCollection     statusCodes;

                WriteValueCollection writeValues = new WriteValueCollection(count);

                for (int i = 0; i < count; i++)
                {
                    //Variant variant = new Variant(values[i]);


                    Opc.Ua.ExpandedNodeId  expNodeId = new Opc.Ua.ExpandedNodeId(opcNodes[i]);
                    Opc.Ua.ExtensionObject extObj    = new Opc.Ua.ExtensionObject(expNodeId, values[i]);

                    DataValue dataVal = new DataValue(extObj);

                    WriteValue writeVal = new WriteValue();
                    //writeVal.
                    writeVal.Value       = dataVal;
                    writeVal.NodeId      = new NodeId(opcNodes[i]);
                    writeVal.AttributeId = Attributes.Value;

                    writeValues.Add(writeVal);
                }

                ResponseHeader rh = session.Write(null, writeValues, out statusCodes, out diags);



                ret = StatusCode.IsGood(rh.ServiceResult.Code);

                for (int i = 0; i < count; i++)
                {
                    //status[i] = StatusCode.IsGood(statusCodes[i]);
                    status.Add(StatusCode.IsGood(statusCodes[i]));
                    ret = ret & status[i];
                }
            }
            catch (Exception ex)
            {
                ret    = false;
                status = null;
                System.Diagnostics.Debug.WriteLine("Exception OpcUaClient::WriteValues " + ex.Message);
            }

            return(ret);
        }
コード例 #31
0
ファイル: JsonEncoder.cs プロジェクト: OPCFoundation/UA-.NET
        /// <summary>
        /// Writes an ExpandedNodeId to the stream.
        /// </summary>
        public void WriteExpandedNodeId(string fieldName, ExpandedNodeId value)
        {
            if (NodeId.IsNull(value))
            {
                WriteSimpleField(fieldName, null, false);
                return;
            }

            PushStructure(fieldName);

            if (UseReversibleEncoding)
            {
                WriteSimpleField("Id", new NodeId(value.Identifier, value.NamespaceIndex).ToString(), true);

                if (!String.IsNullOrEmpty(value.NamespaceUri))
                {
                    WriteSimpleField("Uri", value.NamespaceUri, true);
                }

                if (value.ServerIndex > 0)
                {
                    WriteSimpleField("ServerIndex", value.ServerIndex.ToString(), false);
                }
            }
            else
            {
                WriteSimpleField("Id", new NodeId(value.Identifier, 0).ToString(), true);
                WriteNamespaceIndex(value.NamespaceIndex);
                WriteServerIndex(value.ServerIndex);
            }

            PopStructure();
        }
コード例 #32
0
        private ServiceResult OnUserScalarValue2(
            ISystemContext context,
            MethodState method,
            NodeId objectId,
            DateTime dateTimeIn,
            Uuid guidIn,
            byte[] byteStringIn,
            XmlElement xmlElementIn,
            NodeId nodeIdIn,
            ExpandedNodeId expandedNodeIdIn,
            QualifiedName qualifiedNameIn,
            LocalizedText localizedTextIn,
            StatusCode statusCodeIn,
            object variantIn,
            ref DateTime dateTimeOut,
            ref Uuid guidOut,
            ref byte[] byteStringOut,
            ref XmlElement xmlElementOut,
            ref NodeId nodeIdOut,
            ref ExpandedNodeId expandedNodeIdOut,
            ref QualifiedName qualifiedNameOut,
            ref LocalizedText localizedTextOut,
            ref StatusCode statusCodeOut,
            ref object variantOut)
        {
            dateTimeOut = dateTimeIn;
            guidOut = guidIn;
            byteStringOut = byteStringIn;
            xmlElementOut = xmlElementIn;
            nodeIdOut = nodeIdIn;
            expandedNodeIdOut = expandedNodeIdIn;
            qualifiedNameOut = qualifiedNameIn;
            localizedTextOut = localizedTextIn;
            statusCodeOut = statusCodeIn;
            variantOut = variantIn;

            return ServiceResult.Good;
        }
コード例 #33
0
 /// <summary>
 /// Adds a reference to target identified by its node id.
 /// </summary>
 public virtual void Add(NodeId referenceTypeId, bool isInverse, ExpandedNodeId targetId)
 {
     lock (DataLock)
     {
         m_references.Add(new NodeStateReference(referenceTypeId, isInverse, targetId));
     }
 }
コード例 #34
0
 /// <summary>
 /// Adds a reference to target identified by its node id.
 /// </summary>
 public virtual void Add(NodeId referenceTypeId, bool isInverse, ExpandedNodeId targetId)
 {
     lock (DataLock) {
         m_references.Add(new NodeStateReference(referenceTypeId, isInverse, targetId));
     }
 }
コード例 #35
0
        /// <summary>
        /// This method is used to delete bi-directional references to nodes from other node managers.
        /// </summary>
        public virtual ServiceResult DeleteReference(
            object         sourceHandle, 
            NodeId         referenceTypeId, 
            bool           isInverse, 
            ExpandedNodeId targetId, 
            bool           deleteBiDirectional)
        {
            lock (Lock)
            {
                // get the handle.
                NodeHandle source = IsHandleInNamespace(sourceHandle);

                if (source == null)
                {
                    return StatusCodes.BadNodeIdUnknown;
                }

                // only support external references to nodes that are stored in memory.
                if (!source.Validated || source.Node == null)
                {
                    return StatusCodes.BadNotSupported;
                }
                
                // only support references to Source Areas.
                source.Node.RemoveReference(referenceTypeId, isInverse, targetId);

                if (deleteBiDirectional)
                {
                    // check if the target is also managed by this node manager.
                    if (!targetId.IsAbsolute)
                    {
                        NodeHandle target = GetManagerHandle(m_systemContext, (NodeId)targetId, null);

                        if (target != null && target.Validated && target.Node != null)
                        {
                            target.Node.RemoveReference(referenceTypeId, !isInverse, source.NodeId);
                        }
                    }
                }

                return ServiceResult.Good;
            }
        }
コード例 #36
0
ファイル: XmlDecoder.cs プロジェクト: yuriik83/UA-.NET
        /// <summary>
        /// Reads the body extension object from the stream.
        /// </summary>
        public object ReadExtensionObjectBody(ExpandedNodeId typeId)
        {            
            m_reader.MoveToContent();
                                    
            // check for binary encoded body.
            if (m_reader.LocalName == "ByteString" && m_reader.NamespaceURI == Namespaces.OpcUaXsd)
            {
                PushNamespace(Namespaces.OpcUaXsd);
                byte[] bytes = ReadByteString("ByteString");       
                PopNamespace();
                
                return bytes;
            }

            // check for empty body.
            XmlDocument document = new XmlDocument();

            if (m_reader.IsEmptyElement)
            {        
                document.InnerXml = m_reader.ReadOuterXml();                        
                return document.DocumentElement;
            }

            // lookup type.
            IEncodeable encodeable = null;

            Type systemType = m_context.Factory.GetSystemType(typeId);

            // decode known type.
            if (systemType != null)
            {                      
                PushNamespace(m_reader.NamespaceURI);
                encodeable = ReadEncodeable(m_reader.LocalName, systemType);
                PopNamespace();
                                
                return encodeable;
            }
            
            // return undecoded xml body.                 
            document.InnerXml = m_reader.ReadOuterXml();                        
            return document.DocumentElement;
        }
コード例 #37
0
        /// <summary cref="ITypeTable.FindSubTypes(ExpandedNodeId)" />
        public IList<NodeId> FindSubTypes(ExpandedNodeId typeId)
        {
            List<NodeId> subtypes = new List<NodeId>();

            if (typeId == null)
            {
                return subtypes;
            }

            NodeId localId = ExpandedNodeId.ToNodeId(typeId, m_namespaceUris);

            if (localId == null)
            {
                return subtypes;
            }

            lock (m_lock)
            {
                TypeInfo typeInfo = null;

                if (m_nodes.TryGetValue(localId, out typeInfo))
                {
                    typeInfo.GetSubtypes(subtypes);
                }

                return subtypes;
            }
        }
コード例 #38
0
 /// <summary>
 /// Adds the reference to the node.
 /// </summary>
 /// <param name="referenceTypeId">The reference type identifier.</param>
 /// <param name="isInverse">if set to <c>true</c> this is inverse reference.</param>
 /// <param name="targetId">The target identifier.</param>
 public void Add(NodeId referenceTypeId, bool isInverse, ExpandedNodeId targetId)
 {
     m_references[new ReferenceNode(referenceTypeId, isInverse, targetId)] = null;
 }
コード例 #39
0
        private ServiceResult OnUserArrayValue2(
            ISystemContext context,
            MethodState method,
            NodeId objectId,
            DateTime[] dateTimeIn,
            Uuid[] guidIn,
            byte[][] byteStringIn,
            XmlElement[] xmlElementIn,
            NodeId[] nodeIdIn,
            ExpandedNodeId[] expandedNodeIdIn,
            QualifiedName[] qualifiedNameIn,
            LocalizedText[] localizedTextIn,
            StatusCode[] statusCodeIn,
            Variant[] variantIn,
            ref DateTime[] dateTimeOut,
            ref Uuid[] guidOut,
            ref byte[][] byteStringOut,
            ref XmlElement[] xmlElementOut,
            ref NodeId[] nodeIdOut,
            ref ExpandedNodeId[] expandedNodeIdOut,
            ref QualifiedName[] qualifiedNameOut,
            ref LocalizedText[] localizedTextOut,
            ref StatusCode[] statusCodeOut,
            ref Variant[] variantOut)
        {
            dateTimeOut = dateTimeIn;
            guidOut = guidIn;
            byteStringOut = byteStringIn;
            xmlElementOut = xmlElementIn;
            nodeIdOut = nodeIdIn;
            expandedNodeIdOut = expandedNodeIdIn;
            qualifiedNameOut = qualifiedNameIn;
            localizedTextOut = localizedTextIn;
            statusCodeOut = statusCodeIn;
            variantOut = variantIn;

            return ServiceResult.Good;
        }
コード例 #40
0
        /// <summary cref="ITypeTable.IsTypeOf(ExpandedNodeId, ExpandedNodeId)" />
        public bool IsTypeOf(ExpandedNodeId subTypeId, ExpandedNodeId superTypeId)
        {
            if (NodeId.IsNull(subTypeId) || subTypeId.ServerIndex != 0)
            {
                return false;
            }
            
            if (NodeId.IsNull(superTypeId) || superTypeId.ServerIndex != 0)
            {
                return false;
            }

            // check for exact match.
            if (subTypeId == superTypeId)
            {
                return true;
            }

            NodeId startId = ExpandedNodeId.ToNodeId(subTypeId, m_namespaceUris);
            
            if (startId == null)
            {
                return false;
            }

            NodeId targetId = ExpandedNodeId.ToNodeId(superTypeId, m_namespaceUris);
            
            if (targetId == null)
            {
                return false;
            }

            lock (m_lock)
            {
                TypeInfo typeInfo = null;

                if (!m_nodes.TryGetValue(startId, out typeInfo))
                {
                    return false;
                }

                return typeInfo.IsTypeOf(targetId);
            }
        }
コード例 #41
0
ファイル: XmlDecoder.cs プロジェクト: yuriik83/UA-.NET
        /// <summary>
        /// Reads an ExpandedNodeId from the stream.
        /// </summary>
        public ExpandedNodeId ReadExpandedNodeId(string fieldName)
        {
            ExpandedNodeId value = new ExpandedNodeId();

            if (BeginField(fieldName, true))
            {                
                PushNamespace(Namespaces.OpcUaXsd);
                value.IdentifierText = ReadString("Identifier");
                PopNamespace();
                
                EndField(fieldName);
            }

            if (m_namespaceMappings != null && m_namespaceMappings.Length > value.NamespaceIndex)
            {
                value.SetNamespaceIndex(m_namespaceMappings[value.NamespaceIndex]);
            }

            if (m_serverMappings != null && m_serverMappings.Length > value.ServerIndex)
            {
                value.SetServerIndex(m_serverMappings[value.NamespaceIndex]);
            }

            return value;
        }
コード例 #42
0
        /// <summary cref="ITypeTable.IsEncodingOf(ExpandedNodeId, ExpandedNodeId)" />
        public bool IsEncodingOf(ExpandedNodeId encodingId, ExpandedNodeId datatypeId)
        {
            // check for invalid ids.
            if (NodeId.IsNull(encodingId) || NodeId.IsNull(datatypeId))
            {
                return false;
            }
            
            NodeId localId = ExpandedNodeId.ToNodeId(encodingId, m_namespaceUris);

            if (localId == null)
            {
                return false;
            }

            NodeId localTypeId = ExpandedNodeId.ToNodeId(datatypeId, m_namespaceUris);
            
            if (localTypeId == null)
            {
                return false;
            }

            lock (m_lock)
            {
                // lookup the immediate basetype of the subtype.
                TypeInfo typeInfo = null;

                if (!m_encodings.TryGetValue(localId, out typeInfo))
                {
                    return false;
                }

                // the encoding is a representation of the expected datatype id.
                if (localTypeId == typeInfo.NodeId)
                {
                    return true;
                }

                // check if the encoding is a representation of a subtype of the expected datatype id.
                TypeInfo superTypeInfo = typeInfo.SuperType;

                while (superTypeInfo != null)
                {
                    if (!superTypeInfo.Deleted && superTypeInfo.NodeId == localTypeId)
                    {
                        return true;
                    }

                    superTypeInfo = superTypeInfo.SuperType;
                }

                // no match.
                return false;
            }
        }
コード例 #43
0
ファイル: ContentFilter.cs プロジェクト: yuriik83/UA-.NET
 /// <summary>
 /// Creates an operand that references a component/property of a type.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="nodeId">The node identifier.</param>
 /// <param name="relativePath">The relative path.</param>
 public AttributeOperand(
     FilterContext  context, 
     ExpandedNodeId nodeId,
     RelativePath   relativePath)
 {
     m_nodeId      = ExpandedNodeId.ToNodeId(nodeId, context.NamespaceUris);
     m_browsePath  = relativePath;
     m_attributeId = Attributes.Value;
     m_indexRange  = null;
     m_alias       = null;
 }
コード例 #44
0
        /// <summary cref="ITypeTable.FindDataTypeId(ExpandedNodeId)" />
        public NodeId FindDataTypeId(ExpandedNodeId encodingId)            
        {            
            NodeId localId = ExpandedNodeId.ToNodeId(encodingId, m_namespaceUris);

            if (localId == null)
            {
                return NodeId.Null;
            }

            lock (m_lock)
            {
                TypeInfo typeInfo = null;

                if (!m_encodings.TryGetValue(localId, out typeInfo))
                {
                    return NodeId.Null;
                }

                return typeInfo.NodeId;
            }
        }
コード例 #45
0
        /// <summary>
        /// Writes an ExpandedNodeId to the stream.
        /// </summary>
        public void WriteExpandedNodeId(string fieldName, ExpandedNodeId value)
        {
            if (BeginField(fieldName, value == null, true))
            {
                PushNamespace(Namespaces.OpcUaXsd);

                if (value != null)
                {
                    ushort namespaceIndex = value.NamespaceIndex;

                    if (m_namespaceMappings != null && m_namespaceMappings.Length > namespaceIndex)
                    {
                        namespaceIndex = m_namespaceMappings[namespaceIndex];
                    }

                    uint serverIndex = value.ServerIndex;

                    if (m_serverMappings != null && m_serverMappings.Length > serverIndex)
                    {
                        serverIndex = m_serverMappings[serverIndex];
                    }

                    StringBuilder buffer = new StringBuilder();
                    ExpandedNodeId.Format(buffer, value.Identifier, value.IdType, namespaceIndex, value.NamespaceUri, serverIndex);
                    WriteString("Identifier", buffer.ToString());
                }

                PopNamespace();

                EndField(fieldName);
            }
        }
コード例 #46
0
        /// <summary>
        /// Adds an encoding for an existing data type.
        /// </summary>
        public bool AddEncoding(NodeId dataTypeId, ExpandedNodeId encodingId)
        {
            NodeId localId = ExpandedNodeId.ToNodeId(encodingId, m_namespaceUris);

            if (localId == null)
            {
                return false;
            }

            lock (m_lock)
            {
                TypeInfo typeInfo = null;
                
                if (!m_nodes.TryGetValue(dataTypeId, out typeInfo))
                {
                    return false;
                }

                if (typeInfo.Encodings == null)
                {
                    typeInfo.Encodings = new NodeId[] { localId };
                }
                else
                {
                    NodeId[] encodings = new NodeId[typeInfo.Encodings.Length + 1];
                    System.Array.Copy(typeInfo.Encodings, encodings, typeInfo.Encodings.Length);
                    encodings[encodings.Length - 1] = localId;
                    typeInfo.Encodings = encodings;
                }

                m_encodings[localId] = typeInfo;
                return true;
            }
        }
コード例 #47
0
        /// <summary>
        /// Finds the service identified by the request type.
        /// </summary>
        protected ServiceDefinition FindService(ExpandedNodeId requestTypeId)
        {
            ServiceDefinition service = null;

            if (!SupportedServices.TryGetValue(requestTypeId, out service))
            {
                throw ServiceResultException.Create(
                    StatusCodes.BadServiceUnsupported, 
                    "'{0}' is an unrecognized service identifier.",
                    requestTypeId);
            }

            return service;
        }
コード例 #48
0
        /// <summary>
        /// Recursively collects the nodes within a type hierarchy.
        /// </summary>
        private void UpdateInstanceHierarchyWithInstance(
            HierarchyBrowsePath parent,
            ExpandedNodeId instanceId,
            InstanceDeclarationHierarchy hierarchy)
        {
            INode instance = m_nodes.Find(instanceId) as INode;

            // ignore instances not in the address space.
            if (instance == null)
            {
                return;
            }

            // must be an object, variable or method.
            if ((instance.NodeClass & (NodeClass.Object | NodeClass.Variable | NodeClass.Method)) == 0)
            {
                return;
            }

            // construct the browse path that identifies the node.
            string browsePath = null;

            if (parent.BrowsePath == "/")
            {
                browsePath = Utils.Format("/{0}", instance.BrowseName);
            }
            else
            {
                browsePath = Utils.Format("{0}/{1}", parent.BrowsePath, instance.BrowseName);
            }

            // check if the browse path exists in the hierarchy.
            HierarchyBrowsePath child = null;

            if (!hierarchy.BrowsePaths.TryGetValue(browsePath, out child))
            {
                return;
            }

            // update the instance.
            child.InstanceId = instance.NodeId;

            // check if already followed.
            if (hierarchy.Instances.ContainsKey((NodeId)instance.NodeId))
            {
                return;
            }

            // save child.
            hierarchy.Instances.Add((NodeId)instance.NodeId, instance);

            // check for local node.
            ILocalNode localInstance = instance as ILocalNode;

            if (localInstance == null)
            {
                return;
            }

            // follow children.
            foreach (IReference reference in localInstance.References.Find(ReferenceTypeIds.HierarchicalReferences, false, true, m_nodes.TypeTree))
            {
                UpdateInstanceHierarchyWithInstance(child, reference.TargetId, hierarchy);
            }
        }