/// <summary> /// Constructs a NodeId from the ItemId for a DA branch. /// </summary> /// <param name="itemId">The item id.</param> /// <param name="propertyId">The property id.</param> /// <param name="namespaceIndex">Index of the namespace.</param> /// <returns>The node id.</returns> public static NodeId ConstructIdForDaElement(string itemId, int propertyId, ushort namespaceIndex) { DaParsedNodeId parsedNodeId = new DaParsedNodeId(); parsedNodeId.RootId = itemId; parsedNodeId.NamespaceIndex = namespaceIndex; parsedNodeId.RootType = DaElement; if (propertyId >= 0) { parsedNodeId.PropertyId = propertyId; parsedNodeId.RootType = DaProperty; } return parsedNodeId.Construct(); }
/// <summary> /// Returns a unique handle for the node. /// </summary> protected override NodeHandle GetManagerHandle(ServerSystemContext context, NodeId nodeId, IDictionary <NodeId, NodeState> cache) { lock (Lock) { // quickly exclude nodes that are not in the namespace. if (!IsNodeIdInNamespace(nodeId)) { return(null); } // check for predefined nodes. if (PredefinedNodes != null) { NodeState node = null; if (PredefinedNodes.TryGetValue(nodeId, out node)) { NodeHandle handle = new NodeHandle(); handle.NodeId = nodeId; handle.Validated = true; handle.Node = node; return(handle); } } // parse the identifier. DaParsedNodeId parsedNodeId = DaParsedNodeId.Parse(nodeId); if (parsedNodeId != null) { NodeHandle handle = new NodeHandle(); handle.NodeId = nodeId; handle.Validated = false; handle.Node = null; handle.ParsedNodeId = parsedNodeId; return(handle); } return(null); } }
/// <summary> /// Verifies that the specified node exists. /// </summary> protected override NodeState ValidateNode( ServerSystemContext context, NodeHandle handle, IDictionary <NodeId, NodeState> cache) { // not valid if no root. if (handle == null) { return(null); } // check if previously validated. if (handle.Validated) { return(handle.Node); } NodeState target = null; // check if already in the cache. if (cache != null) { if (cache.TryGetValue(handle.NodeId, out target)) { // nulls mean a NodeId which was previously found to be invalid has been referenced again. if (target == null) { return(null); } handle.Node = target; handle.Validated = true; return(handle.Node); } target = null; } try { // check if the node id has been parsed. DaParsedNodeId parsedNodeId = handle.ParsedNodeId as DaParsedNodeId; if (parsedNodeId == null) { return(null); } NodeState root = null; DaElement element = null; ComDaClient client = m_system.SelectClient(context, false); // validate a branch or item. if (parsedNodeId.RootType == DaModelUtils.DaElement) { element = client.FindElement(parsedNodeId.RootId); // branch does not exist. if (element == null) { return(null); } // create a temporary object to use for the operation. root = DaModelUtils.ConstructElement(context, element, NamespaceIndex); root.Handle = element; AddAdditionalElementReferences(SystemContext, root); } // validate an property. else if (parsedNodeId.RootType == DaModelUtils.DaProperty) { element = client.FindElement(parsedNodeId.RootId); // branch does not exist. if (element == null) { return(null); } // validate the property. DaProperty property = client.FindProperty(parsedNodeId.RootId, parsedNodeId.PropertyId); // property does not exist. if (property == null) { return(null); } // create a temporary object to use for the operation. root = DaModelUtils.ConstructProperty(context, element.ItemId, property, NamespaceIndex); root.Handle = property; AddAdditionalElementReferences(SystemContext, root); } // unknown root type. else { return(null); } // all done if no components to validate. if (String.IsNullOrEmpty(parsedNodeId.ComponentPath)) { handle.Validated = true; handle.Node = target = root; return(handle.Node); } // validate component. NodeState component = root.FindChildBySymbolicName(context, parsedNodeId.ComponentPath); // component does not exist. if (component == null) { return(null); } // found a valid component. handle.Validated = true; handle.Node = target = component; return(handle.Node); } finally { // store the node in the cache to optimize subsequent lookups. if (cache != null) { cache.Add(handle.NodeId, target); } } }
/// <summary> /// Parses the specified node identifier. /// </summary> /// <param name="nodeId">The node identifier.</param> /// <returns>The parsed node identifier. Null if the identifier cannot be parsed.</returns> public static new DaParsedNodeId Parse(NodeId nodeId) { // can only parse non-null string node identifiers. if (NodeId.IsNull(nodeId)) { return(null); } string identifier = nodeId.Identifier as string; if (String.IsNullOrEmpty(identifier)) { return(null); } DaParsedNodeId parsedNodeId = new DaParsedNodeId(); parsedNodeId.NamespaceIndex = nodeId.NamespaceIndex; // extract the type of identifier. parsedNodeId.RootType = 0; int start = 0; for (int ii = 0; ii < identifier.Length; ii++) { if (!Char.IsDigit(identifier[ii])) { start = ii; break; } parsedNodeId.RootType *= 10; parsedNodeId.RootType += (byte)(identifier[ii] - '0'); } if (start >= identifier.Length || identifier[start] != ':') { return(null); } // extract any component path. StringBuilder buffer = new StringBuilder(); int index = start + 1; int end = identifier.Length; bool escaped = false; while (index < end) { char ch = identifier[index++]; // skip any escape character but keep the one after it. if (ch == '&') { escaped = true; continue; } if (!escaped && ch == '?') { end = index; break; } buffer.Append(ch); escaped = false; } // extract any component. parsedNodeId.RootId = buffer.ToString(); parsedNodeId.ComponentPath = null; if (parsedNodeId.RootType == DaModelUtils.DaProperty) { // must have the property id. if (end >= identifier.Length) { return(null); } // extract the property id. for (int ii = end; ii < identifier.Length; ii++) { end++; if (!Char.IsDigit(identifier[ii])) { // check for terminator. if (identifier[ii] != ':') { return(null); } break; } parsedNodeId.PropertyId *= 10; parsedNodeId.PropertyId += (byte)(identifier[ii] - '0'); } } // extract the component path. if (end < identifier.Length) { parsedNodeId.ComponentPath = identifier.Substring(end); } return(parsedNodeId); }
/// <summary> /// Parses the specified node identifier. /// </summary> /// <param name="nodeId">The node identifier.</param> /// <returns>The parsed node identifier. Null if the identifier cannot be parsed.</returns> public static new DaParsedNodeId Parse(NodeId nodeId) { // can only parse non-null string node identifiers. if (NodeId.IsNull(nodeId)) { return null; } string identifier = nodeId.Identifier as string; if (String.IsNullOrEmpty(identifier)) { return null; } DaParsedNodeId parsedNodeId = new DaParsedNodeId(); parsedNodeId.NamespaceIndex = nodeId.NamespaceIndex; // extract the type of identifier. parsedNodeId.RootType = 0; int start = 0; for (int ii = 0; ii < identifier.Length; ii++) { if (!Char.IsDigit(identifier[ii])) { start = ii; break; } parsedNodeId.RootType *= 10; parsedNodeId.RootType += (byte)(identifier[ii] - '0'); } if (start >= identifier.Length || identifier[start] != ':') { return null; } // extract any component path. StringBuilder buffer = new StringBuilder(); int index = start+1; int end = identifier.Length; bool escaped = false; while (index < end) { char ch = identifier[index++]; // skip any escape character but keep the one after it. if (ch == '&') { escaped = true; continue; } if (!escaped && ch == '?') { end = index; break; } buffer.Append(ch); escaped = false; } // extract any component. parsedNodeId.RootId = buffer.ToString(); parsedNodeId.ComponentPath = null; if (parsedNodeId.RootType == DaModelUtils.DaProperty) { // must have the property id. if (end >= identifier.Length) { return null; } // extract the property id. for (int ii = end; ii < identifier.Length; ii++) { end++; if (!Char.IsDigit(identifier[ii])) { // check for terminator. if (identifier[ii] != ':') { return null; } break; } parsedNodeId.PropertyId *= 10; parsedNodeId.PropertyId += (byte)(identifier[ii] - '0'); } } // extract the component path. if (end < identifier.Length) { parsedNodeId.ComponentPath = identifier.Substring(end); } return parsedNodeId; }