示例#1
0
        /// <summary>
        /// Creates the appropriate NodeState object from a NodeId.
        /// </summary>
        public static NodeState CreateHandleFromNodeId(
            ISystemContext context,
            NodeId nodeId,
            IDictionary <NodeId, NodeState> cache)
        {
            // get the system to use.
            FileSystemMonitor system = context.SystemHandle as FileSystemMonitor;

            if (system == null)
            {
                return(null);
            }

            // check for valid node id.
            if (nodeId == null || nodeId.NamespaceIndex != system.m_namespaceIndex || nodeId.IdType != IdType.String)
            {
                return(null);
            }

            // lookup in cache.
            NodeState state = null;

            if (cache != null)
            {
                if (cache.TryGetValue(nodeId, out state))
                {
                    return(state);
                }
            }

            string path     = (string)nodeId.Identifier;
            uint   baseline = (uint)Convert.ToUInt32('0');

            // parse the object type id.
            uint objectTypeId = 0;
            int  start        = 0;

            for (int ii = 0; ii < path.Length; ii++)
            {
                if (path[ii] == ':')
                {
                    start = ii + 1;
                    break;
                }

                if (!Char.IsDigit(path[ii]))
                {
                    return(null);
                }

                objectTypeId *= 10;
                objectTypeId += (uint)Convert.ToUInt32(path[ii]) - baseline;
            }

            string parentPath = path;
            NodeId parentId   = nodeId;

            // check if referencing a child of the object.
            int end = -1;

            if (start < path.Length)
            {
                end = path.IndexOf(':', start);

                if (end >= start)
                {
                    parentPath = path.Substring(0, end);
                    parentId   = new NodeId(parentPath, system.NamespaceIndex);
                }
            }

            // return cached value if available.
            if (cache != null)
            {
                if (!cache.TryGetValue(parentId, out state))
                {
                    state = null;
                }
            }

            // create the object instance.
            if (state == null)
            {
                switch (objectTypeId)
                {
                case ObjectTypes.AreaType:
                {
                    string directoryPath = system.ExtractPathFromNodeId(nodeId);
                    state = new AreaState(context, new DirectoryInfo(directoryPath));
                    break;
                }

                case ObjectTypes.ControllerType:
                {
                    string filePath = system.ExtractPathFromNodeId(nodeId);
                    filePath += ".csv";
                    state     = new ControllerState(context, new FileInfo(filePath));
                    break;
                }

                default:
                {
                    return(null);
                }
                }

                // update cache if provided.
                if (cache != null)
                {
                    cache[parentId] = state;
                }
            }

            // nothing more to do if referencing the root.
            if (end < 0)
            {
                return(state);
            }

            // create the child identified by the name in the node id.
            string childPath = path.Substring(end + 1);

            // extract path of children.
            List <string> childNames = new List <string>();

            int index = childPath.IndexOf(':');

            while (index > 0)
            {
                childNames.Add(childPath.Substring(0, index));
                childPath = childPath.Substring(index + 1);
                index     = childPath.IndexOf(':');
            }

            childNames.Add(childPath);

            NodeState         parent = state;
            BaseInstanceState child  = null;

            for (int ii = 0; ii < childNames.Count; ii++)
            {
                child = parent.CreateChild(
                    context,
                    new QualifiedName(childNames[ii], 0));

                if (child == null)
                {
                    return(null);
                }

                parent = child;

                if (ii == childNames.Count - 1)
                {
                    child.NodeId = nodeId;

                    if (state.ValidationRequired)
                    {
                        child.OnValidate = system.ValidateChild;
                    }

                    if (cache != null)
                    {
                        cache[nodeId] = child;
                    }
                }
            }

            return(child);
        }