Exemple #1
0
        /// <summary>
        /// Updates the event types in cache with the most recent info fetched from the AE server.
        /// </summary>
        public void UpdateCache(ServerSystemContext context, ushort namespaceIndex)
        {
            // clear the existing nodes.
            EventTypeNodes = new NodeIdDictionary<BaseObjectTypeState>();
            Attributes = new Dictionary<int,int[]>();
            TypeTable typeTable = context.TypeTable as TypeTable;

            // rebuild from the recently fetched list.
            for (int ii = 0; ii < EventTypes.Count; ii++)
            {
                // save the attributes for use when creating filters.
                if (EventTypes[ii].EventTypeMapping != EventTypeMapping.ConditionClassType && !Attributes.ContainsKey(EventTypes[ii].CategoryId))
                {
                    EventType eventType = EventTypes[ii];

                    int[] attributeIds = new int[eventType.Attributes.Count];

                    for (int jj = 0; jj < attributeIds.Length; jj++)
                    {
                        attributeIds[jj] = eventType.Attributes[jj].Id;
                    }

                    Attributes.Add(EventTypes[ii].CategoryId, attributeIds);
                }

                AeEventTypeState node = new AeEventTypeState(EventTypes[ii], namespaceIndex);

                BaseObjectTypeState mappingNode = null;

                if (!EventTypeNodes.TryGetValue(node.SuperTypeId, out mappingNode))
                {
                    mappingNode = new AeEventTypeMappingState(node.EventType.EventTypeMapping, namespaceIndex);
                    EventTypeNodes.Add(mappingNode.NodeId, mappingNode);

                    // ensure the mapping node is in the type table.
                    if (typeTable != null)
                    {
                        if (!typeTable.IsKnown(mappingNode.NodeId))
                        {
                            typeTable.AddSubtype(mappingNode.NodeId, mappingNode.SuperTypeId);
                        }
                    }
                }

                EventTypeNodes.Add(node.NodeId, node);

                // ensure the type node is in the type table.
                if (typeTable != null)
                {
                    if (!typeTable.IsKnown(node.NodeId))
                    {
                        typeTable.AddSubtype(node.NodeId, mappingNode.NodeId);
                    }
                }
            }
        }
        /// <summary>
        /// Indexes the well known subtypes.
        /// </summary>
        private void IndexWellKnownTypes()
        {
            SystemContext context = new SystemContext();

            context.EncodeableFactory = m_session.MessageContext.Factory;
            context.NamespaceUris     = m_session.NamespaceUris;
            context.ServerUris        = m_session.ServerUris;

            NodeStateCollection predefinedNodes = new NodeStateCollection();

            predefinedNodes.LoadFromBinaryResource(context, "Opc.Ua.Stack.Generated.Opc.Ua.PredefinedNodes.uanodes", typeof(NodeState).Assembly, true);

            NodeIdDictionary <BaseTypeState> types = new NodeIdDictionary <BaseTypeState>();

            // collect the instance declarations for all types.
            for (int ii = 0; ii < predefinedNodes.Count; ii++)
            {
                BaseTypeState type = predefinedNodes[ii] as BaseTypeState;

                if (type != null)
                {
                    types.Add(type.NodeId, type);
                }
            }

            // index only those types which are subtypes of BaseEventType.
            foreach (BaseTypeState type in types.Values)
            {
                BaseTypeState subType   = type;
                BaseTypeState superType = null;

                int eventType = 0;

                while (subType != null)
                {
                    if (subType.NodeId == Opc.Ua.ObjectTypeIds.ConditionType || subType.SuperTypeId == Opc.Ua.ObjectTypeIds.ConditionType)
                    {
                        eventType = OpcRcw.Ae.Constants.CONDITION_EVENT;
                    }

                    else if (subType.NodeId == Opc.Ua.ObjectTypeIds.AuditEventType || subType.SuperTypeId == Opc.Ua.ObjectTypeIds.AuditEventType)
                    {
                        eventType = OpcRcw.Ae.Constants.TRACKING_EVENT;
                    }

                    else if (subType.NodeId == Opc.Ua.ObjectTypeIds.BaseEventType || subType.SuperTypeId == Opc.Ua.ObjectTypeIds.BaseEventType)
                    {
                        eventType = OpcRcw.Ae.Constants.SIMPLE_EVENT;
                    }

                    // found an event, collect the attribute and index it.
                    if (eventType != 0)
                    {
                        List <AeEventAttribute> declarations      = new List <AeEventAttribute>();
                        Dictionary <string, AeEventAttribute> map = new Dictionary <string, AeEventAttribute>();

                        ComAeUtils.CollectInstanceDeclarations(
                            m_session,
                            this,
                            type,
                            null,
                            declarations,
                            map);

                        AeEventCategory declaration = new AeEventCategory();
                        declaration.TypeId               = type.NodeId;
                        declaration.SuperTypeId          = type.SuperTypeId;
                        declaration.EventType            = eventType;
                        declaration.Description          = (LocalizedText.IsNullOrEmpty(type.DisplayName))?type.BrowseName.Name:type.DisplayName.Text;
                        declaration.Attributes           = declarations;
                        m_eventTypes[declaration.TypeId] = declaration;
                        break;
                    }

                    // follow the tree to the parent.
                    if (!types.TryGetValue(subType.SuperTypeId, out superType))
                    {
                        break;
                    }

                    subType = superType;
                }
            }

            // hide the built in attributes.
            AeEventCategory category = GetCategory(Opc.Ua.ObjectTypeIds.BaseEventType);

            if (category != null)
            {
                for (int ii = 0; ii < category.Attributes.Count; ii++)
                {
                    switch (category.Attributes[ii].BrowsePathDisplayText)
                    {
                    case Opc.Ua.BrowseNames.Message:
                    case Opc.Ua.BrowseNames.Severity:
                    case Opc.Ua.BrowseNames.SourceName:
                    case Opc.Ua.BrowseNames.Time:
                    case Opc.Ua.BrowseNames.ReceiveTime:
                    case Opc.Ua.BrowseNames.LocalTime:
                    {
                        category.Attributes[ii].Hidden = true;
                        break;
                    }
                    }
                }
            }
        }
        /// <summary cref="IDictionary.Remove" />
        public bool Remove(IReference key)
        {
            // validate key.
            if (!ValidateReference(key, false))
            {
                return(false);
            }

            m_version++;

            // look up the reference type.
            ReferenceTypeEntry entry = null;

            if (!m_references.TryGetValue(key.ReferenceTypeId, out entry))
            {
                return(false);
            }

            // handle reference to external targets.
            if (key.TargetId.IsAbsolute)
            {
                Dictionary <ExpandedNodeId, LinkedListNode <KeyValuePair <IReference, T> > > targets = null;

                if (key.IsInverse)
                {
                    targets = entry.InverseExternalTargets;
                }
                else
                {
                    targets = entry.ForwardExternalTargets;
                }

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

                LinkedListNode <KeyValuePair <IReference, T> > node;

                if (!targets.TryGetValue(key.TargetId, out node))
                {
                    return(false);
                }

                m_list.Remove(node);
                targets.Remove(key.TargetId);
            }

            // handle reference to internal target.
            else
            {
                NodeIdDictionary <LinkedListNode <KeyValuePair <IReference, T> > > targets = null;

                if (key.IsInverse)
                {
                    targets = entry.InverseTargets;
                }
                else
                {
                    targets = entry.ForwardTargets;
                }

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

                LinkedListNode <KeyValuePair <IReference, T> > node;

                if (!targets.TryGetValue((NodeId)key.TargetId, out node))
                {
                    return(false);
                }

                m_list.Remove(node);
                targets.Remove((NodeId)key.TargetId);
            }

            // remove empty reference.
            if (entry.IsEmpty)
            {
                m_references.Remove(key.ReferenceTypeId);
            }

            return(true);
        }
        /// <summary>
        /// Adds or replaces a reference.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        /// <param name="replace">if set to <c>true</c> reference is replaced.</param>
        private void Add(IReference key, T value, bool replace)
        {
            // validate key.
            ValidateReference(key, true);

            m_version++;

            // look up the reference type.
            ReferenceTypeEntry entry = null;

            if (!m_references.TryGetValue(key.ReferenceTypeId, out entry))
            {
                entry = new ReferenceTypeEntry();
                m_references.Add(key.ReferenceTypeId, entry);
            }

            // handle reference to external targets.
            if (key.TargetId.IsAbsolute)
            {
                Dictionary <ExpandedNodeId, LinkedListNode <KeyValuePair <IReference, T> > > targets = null;

                if (key.IsInverse)
                {
                    if (entry.InverseExternalTargets == null)
                    {
                        entry.InverseExternalTargets = new Dictionary <ExpandedNodeId, LinkedListNode <KeyValuePair <IReference, T> > >();
                    }

                    targets = entry.InverseExternalTargets;
                }
                else
                {
                    if (entry.ForwardExternalTargets == null)
                    {
                        entry.ForwardExternalTargets = new Dictionary <ExpandedNodeId, LinkedListNode <KeyValuePair <IReference, T> > >();
                    }

                    targets = entry.ForwardExternalTargets;
                }

                // create a new target.
                LinkedListNode <KeyValuePair <IReference, T> > node = new LinkedListNode <KeyValuePair <IReference, T> >(new KeyValuePair <IReference, T>(key, value));

                // check if target already exists.
                LinkedListNode <KeyValuePair <IReference, T> > existingNode = null;

                if (!targets.TryGetValue(key.TargetId, out existingNode))
                {
                    existingNode = node;
                    m_list.AddLast(node);
                }

                // need to replace reference in linked linked as well as the target list.
                else
                {
                    if (!replace)
                    {
                        throw new ArgumentException("Key already exists in dictionary.", "key");
                    }

                    m_list.AddAfter(existingNode, node);
                    m_list.Remove(existingNode);
                }

                targets[key.TargetId] = node;
            }

            // handle reference to internal target.
            else
            {
                NodeIdDictionary <LinkedListNode <KeyValuePair <IReference, T> > > targets = null;

                if (key.IsInverse)
                {
                    if (entry.InverseTargets == null)
                    {
                        entry.InverseTargets = new NodeIdDictionary <LinkedListNode <KeyValuePair <IReference, T> > >();
                    }

                    targets = entry.InverseTargets;
                }
                else
                {
                    if (entry.ForwardTargets == null)
                    {
                        entry.ForwardTargets = new NodeIdDictionary <LinkedListNode <KeyValuePair <IReference, T> > >();
                    }

                    targets = entry.ForwardTargets;
                }

                NodeId targetId = (NodeId)key.TargetId;

                // create a new target.
                LinkedListNode <KeyValuePair <IReference, T> > node = new LinkedListNode <KeyValuePair <IReference, T> >(new KeyValuePair <IReference, T>(key, value));

                // check if target already exists.
                LinkedListNode <KeyValuePair <IReference, T> > existingNode = null;

                if (!targets.TryGetValue(targetId, out existingNode))
                {
                    existingNode = node;
                    m_list.AddLast(node);
                }

                // need to replace reference in linked linked as well as the target list.
                else
                {
                    if (!replace)
                    {
                        throw new ArgumentException("Key already exists in dictionary.", "key");
                    }

                    m_list.AddAfter(existingNode, node);
                    m_list.Remove(existingNode);
                }

                targets[targetId] = node;
            }
        }
        /// <summary>
        /// Returns the target entry associated with the reference.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        /// <returns>The target entry associated with the reference.</returns>
        private bool TryGetEntry(IReference key, out KeyValuePair <IReference, T> value)
        {
            value = new KeyValuePair <IReference, T>();

            // validate key.
            if (!ValidateReference(key, false))
            {
                return(false);
            }

            // look up the reference type.
            ReferenceTypeEntry entry = null;

            if (!m_references.TryGetValue(key.ReferenceTypeId, out entry))
            {
                return(false);
            }

            // handle reference to external targets.
            if (key.TargetId.IsAbsolute)
            {
                Dictionary <ExpandedNodeId, LinkedListNode <KeyValuePair <IReference, T> > > targets = null;

                if (key.IsInverse)
                {
                    targets = entry.InverseExternalTargets;
                }
                else
                {
                    targets = entry.ForwardExternalTargets;
                }

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

                LinkedListNode <KeyValuePair <IReference, T> > node;

                if (targets.TryGetValue(key.TargetId, out node))
                {
                    value = node.Value;
                    return(true);
                }
            }

            // handle reference to internal target.
            else
            {
                NodeIdDictionary <LinkedListNode <KeyValuePair <IReference, T> > > targets = null;

                if (key.IsInverse)
                {
                    targets = entry.InverseTargets;
                }
                else
                {
                    targets = entry.ForwardTargets;
                }

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

                LinkedListNode <KeyValuePair <IReference, T> > node;

                if (targets.TryGetValue((NodeId)key.TargetId, out node))
                {
                    value = node.Value;
                    return(true);
                }
            }

            return(false);
        }
        /// <summary>
        /// Indexes the well known subtypes.
        /// </summary>
        private void IndexWellKnownTypes()
        {
            SystemContext context = new SystemContext();
            context.EncodeableFactory = m_session.MessageContext.Factory;
            context.NamespaceUris = m_session.NamespaceUris;
            context.ServerUris = m_session.ServerUris;

            NodeStateCollection predefinedNodes = new NodeStateCollection();
            predefinedNodes.LoadFromBinaryResource(context, "Opc.Ua.Stack.Generated.Opc.Ua.PredefinedNodes.uanodes", typeof(NodeState).Assembly, true);
            
            NodeIdDictionary<BaseTypeState> types = new NodeIdDictionary<BaseTypeState>();

            // collect the instance declarations for all types.
            for (int ii = 0; ii < predefinedNodes.Count; ii++)
            {
                BaseTypeState type = predefinedNodes[ii] as BaseTypeState;

                if (type != null)
                {
                    types.Add(type.NodeId, type);
                }
            }

            // index only those types which are subtypes of BaseEventType.
            foreach (BaseTypeState type in types.Values)
            {
                BaseTypeState subType = type;
                BaseTypeState superType = null;

                int eventType = 0;

                while (subType != null)
                {
                    if (subType.NodeId == Opc.Ua.ObjectTypeIds.ConditionType || subType.SuperTypeId == Opc.Ua.ObjectTypeIds.ConditionType)
                    {
                        eventType = OpcRcw.Ae.Constants.CONDITION_EVENT;
                    }

                    else if (subType.NodeId == Opc.Ua.ObjectTypeIds.AuditEventType || subType.SuperTypeId == Opc.Ua.ObjectTypeIds.AuditEventType)
                    {
                        eventType = OpcRcw.Ae.Constants.TRACKING_EVENT;
                    }

                    else if (subType.NodeId == Opc.Ua.ObjectTypeIds.BaseEventType || subType.SuperTypeId == Opc.Ua.ObjectTypeIds.BaseEventType)
                    {
                        eventType = OpcRcw.Ae.Constants.SIMPLE_EVENT;
                    }

                    // found an event, collect the attribute and index it.
                    if (eventType != 0)
                    {
                        List<AeEventAttribute> declarations = new List<AeEventAttribute>();
                        Dictionary<string, AeEventAttribute> map = new Dictionary<string, AeEventAttribute>();

                        ComAeUtils.CollectInstanceDeclarations(
                            m_session,
                            this,
                            type,
                            null,
                            declarations,
                            map);

                        AeEventCategory declaration = new AeEventCategory();
                        declaration.TypeId = type.NodeId;
                        declaration.SuperTypeId = type.SuperTypeId;
                        declaration.EventType = eventType;
                        declaration.Description = (LocalizedText.IsNullOrEmpty(type.DisplayName))?type.BrowseName.Name:type.DisplayName.Text;
                        declaration.Attributes = declarations;
                        m_eventTypes[declaration.TypeId] = declaration;
                        break;
                    }

                    // follow the tree to the parent.
                    if (!types.TryGetValue(subType.SuperTypeId, out superType))
                    {
                        break;
                    }

                    subType = superType;
                }
            }

            // hide the built in attributes.
            AeEventCategory category = GetCategory(Opc.Ua.ObjectTypeIds.BaseEventType);

            if (category != null)
            {
                for (int ii = 0; ii < category.Attributes.Count; ii++)
                {
                    switch (category.Attributes[ii].BrowsePathDisplayText)
                    {
                        case Opc.Ua.BrowseNames.Message:
                        case Opc.Ua.BrowseNames.Severity:
                        case Opc.Ua.BrowseNames.SourceName:
                        case Opc.Ua.BrowseNames.Time:
                        case Opc.Ua.BrowseNames.ReceiveTime:
                        case Opc.Ua.BrowseNames.LocalTime:
                        {
                            category.Attributes[ii].Hidden = true;
                            break;
                        }
                    }
                }
            }
        }