/// <summary>
        /// Gets the integer mapping for a remote node id.
        /// </summary>
        /// <param name="mappingType">Type of the mapping.</param>
        /// <param name="remoteId">The remote node id.</param>
        /// <returns>The mapping; 0 if not found.</returns>
        public uint GetLocalIntegerIdMapping(string mappingType, NodeId remoteId)
        {
            lock (m_lock)
            {
                // check if no mappings defined.
                if (m_mappingSets == null)
                {
                    return(0);
                }

                if (mappingType == null)
                {
                    mappingType = String.Empty;
                }

                // check for an existing mapping.
                NodeIdMappingSet mappingSet = null;

                if (!m_mappingSets.TryGetValue(mappingType, out mappingSet))
                {
                    return(0);
                }

                // search for a existing integer id.
                NodeId localId = GetLocalNodeId(remoteId);

                if (mappingSet.Mappings != null)
                {
                    for (int ii = 0; ii < mappingSet.Mappings.Count; ii++)
                    {
                        NodeIdMapping mapping = mappingSet.Mappings[ii];

                        if (localId == mapping.NodeId)
                        {
                            return(mapping.IntegerId);
                        }
                    }
                }

                // not found.
                return(0);
            }
        }
        /// <summary>
        /// Updates an integer id mapping set.
        /// </summary>
        public void UpdateMappingSet(NodeIdMappingSet mappingSet)
        {
            lock (m_lock)
            {
                if (m_mappingSets == null)
                {
                    m_mappingSets = new Dictionary <string, NodeIdMappingSet>();
                }

                string mappingType = mappingSet.MappingType;

                if (mappingType == null)
                {
                    mappingType = String.Empty;
                }

                m_mappingSets[mappingType] = mappingSet;
            }
        }
        /// <summary>
        /// Replaces the mapping set. Adds it if it does not exist.
        /// </summary>
        public void ReplaceMappingSet(NodeIdMappingSet mappingSet)
        {
            if (this.MappingSets != null)
            {
                for (int ii = 0; ii < this.MappingSets.Count; ii++)
                {
                    if (this.MappingSets[ii].MappingType == mappingSet.MappingType)
                    {
                        this.MappingSets[ii] = mappingSet;
                        return;
                    }
                }
            }

            if (this.MappingSets == null)
            {
                this.MappingSets = new NodeIdMappingSetCollection();
            }

            this.MappingSets.Add(mappingSet);
        }
        /// <summary>
        /// Returns the mapping set. Creates an empty one if it does not exist.
        /// </summary>
        public NodeIdMappingSet GetMappingSet(string mappingType)
        {
            NodeIdMappingSet mappingSet = new NodeIdMappingSet();

            mappingSet.MappingType = mappingType;

            if (this.MappingSets != null)
            {
                for (int ii = 0; ii < this.MappingSets.Count; ii++)
                {
                    if (this.MappingSets[ii].MappingType == mappingType)
                    {
                        mappingSet.Mappings = this.MappingSets[ii].Mappings;
                        return(mappingSet);
                    }
                }
            }

            mappingSet.Mappings = new NodeIdMappingCollection();
            return(mappingSet);
        }
예제 #5
0
        /// <summary>
        /// Initializes the mapper.
        /// </summary>
        public void Initialize(Session session, ComAe2ProxyConfiguration configuration)
        {
            base.Initialize(session, configuration);

            m_session = session;

            // discard the table.
            m_eventTypes = new NodeIdDictionary <AeEventCategory>();
            m_categories = new Dictionary <uint, AeEventCategory>();
            m_attributes = new Dictionary <uint, AeEventAttribute>();

            // load the well known types from an embedded resource.
            IndexWellKnownTypes();

            // browse the server for additional types.
            if (!configuration.UseOnlyBuiltInTypes)
            {
                IndexTypesFromServer(Opc.Ua.ObjectTypeIds.BaseEventType, OpcRcw.Ae.Constants.SIMPLE_EVENT);
            }

            // check for existing category mapping.
            NodeIdMappingSet mappingSet = configuration.GetMappingSet("EventCategories");

            // update mappings.
            UpdateEventTypeMappings(mappingSet);

            // update configuration.
            configuration.ReplaceMappingSet(mappingSet);

            // check for existing attribute mapping.
            mappingSet = configuration.GetMappingSet("EventAttributes");

            // update mappings.
            UpdateEventAttributeMappings(mappingSet);

            // update configuration.
            configuration.ReplaceMappingSet(mappingSet);
        }
예제 #6
0
        /// <summary>
        /// Assigns a locally unique numeric id to each event type.
        /// </summary>
        private void UpdateEventAttributeMappings(NodeIdMappingSet mappingSet)
        {
            NodeIdMappingCollection mappingsToKeep = new NodeIdMappingCollection();

            // collect all unique declarations.
            List <AeEventAttribute> list = new List <AeEventAttribute>();

            foreach (AeEventCategory type in m_eventTypes.Values)
            {
                for (int ii = 0; ii < type.Attributes.Count; ii++)
                {
                    AeEventAttribute declaration = type.Attributes[ii];

                    // only variables can be attributes.
                    if (declaration.NodeClass != NodeClass.Variable)
                    {
                        continue;
                    }

                    // need to link attributes to any attributes that they override.
                    AeEventCategory subType   = type;
                    AeEventCategory superType = null;

                    while (subType != null)
                    {
                        if (NodeId.IsNull(subType.SuperTypeId) || subType.TypeId == subType.SuperTypeId || subType.SuperTypeId == Opc.Ua.ObjectTypeIds.BaseObjectType)
                        {
                            list.Add(declaration);
                            break;
                        }

                        if (!m_eventTypes.TryGetValue(subType.SuperTypeId, out superType))
                        {
                            break;
                        }

                        for (int jj = 0; jj < superType.Attributes.Count; jj++)
                        {
                            if (superType.Attributes[jj].BrowsePathDisplayText == declaration.BrowsePathDisplayText)
                            {
                                declaration.OverriddenDeclaration = superType.Attributes[jj];
                                declaration = declaration.OverriddenDeclaration;
                                break;
                            }
                        }

                        subType = superType;
                    }
                }
            }

            // look up ids for all attributes in master list.
            Dictionary <uint, AeEventAttribute> attributes = new Dictionary <uint, AeEventAttribute>();

            for (int ii = 0; ii < list.Count; ii++)
            {
                AeEventAttribute declaration = list[ii];

                for (int jj = 0; jj < mappingSet.Mappings.Count; jj++)
                {
                    NodeIdMapping mapping = mappingSet.Mappings[jj];

                    try
                    {
                        // browse display paths always use local namespa indexes.
                        if (declaration.BrowsePathDisplayText != mapping.BrowePath)
                        {
                            continue;
                        }

                        // need to convert the cached type id to a remote id.
                        NodeId localId  = NodeId.Parse(mapping.NodeId);
                        NodeId remoteId = this.GetRemoteNodeId(localId);

                        if (declaration.RootTypeId != remoteId)
                        {
                            continue;
                        }

                        // must update the saved integer id.
                        if (!attributes.ContainsKey(mapping.IntegerId))
                        {
                            declaration.LocalId             = mapping.IntegerId;
                            attributes[declaration.LocalId] = declaration;
                            mappingsToKeep.Add(mapping);
                        }

                        // must assign a new one if a duplicate found.
                        else
                        {
                            declaration.LocalId = 0;
                        }
                    }
                    catch (Exception)
                    {
                        // ignore invalid mappings.
                    }
                }
            }

            // assign new ids.
            uint nextId = 1;

            for (int ii = 0; ii < list.Count; ii++)
            {
                AeEventAttribute declaration = list[ii];

                if (declaration.LocalId == 0)
                {
                    // find a unique id.
                    while (attributes.ContainsKey(nextId))
                    {
                        nextId++;
                    }

                    // assign the id.
                    declaration.LocalId             = nextId;
                    attributes[declaration.LocalId] = declaration;

                    // save the mapping.
                    NodeIdMapping mapping = new NodeIdMapping();
                    mapping.IntegerId = nextId;
                    mapping.NodeId    = this.GetLocalNodeId(declaration.RootTypeId).ToString();
                    mapping.BrowePath = declaration.BrowsePathDisplayText;

                    mappingsToKeep.Add(mapping);
                }
            }

            // update mapping set.
            mappingSet.Mappings = mappingsToKeep;
            m_attributes        = attributes;
        }
예제 #7
0
        /// <summary>
        /// Assigns a locally unique numeric id to each event type.
        /// </summary>
        private void UpdateEventTypeMappings(NodeIdMappingSet mappingSet)
        {
            NodeIdMappingCollection            mappingsToKeep = new NodeIdMappingCollection();
            Dictionary <uint, AeEventCategory> categories     = new Dictionary <uint, AeEventCategory>();

            for (int ii = 0; ii < mappingSet.Mappings.Count; ii++)
            {
                NodeIdMapping mapping = mappingSet.Mappings[ii];

                try
                {
                    // need to convert the cached type id to a remote id.
                    NodeId localId  = NodeId.Parse(mapping.NodeId);
                    NodeId remoteId = this.GetRemoteNodeId(localId);

                    AeEventCategory eventType = null;

                    if (m_eventTypes.TryGetValue(remoteId, out eventType))
                    {
                        // check if the event already has an id.
                        if (eventType.LocalId == 0)
                        {
                            // must update the saved integer id.
                            if (!categories.ContainsKey(mapping.IntegerId))
                            {
                                eventType.LocalId             = mapping.IntegerId;
                                categories[eventType.LocalId] = eventType;
                                mappingsToKeep.Add(mapping);
                            }

                            // must assign a new one if a duplicate found.
                            else
                            {
                                eventType.LocalId = 0;
                            }
                        }
                    }
                }
                catch (Exception)
                {
                    // discard invalid mappings.
                }
            }

            // assign ids to any types which do not have mappings.
            uint nextId = 1;

            foreach (AeEventCategory eventType in m_eventTypes.Values)
            {
                if (eventType.LocalId == 0)
                {
                    // find a unique id.
                    while (categories.ContainsKey(nextId))
                    {
                        nextId++;
                    }

                    // assign the id.
                    eventType.LocalId             = nextId;
                    categories[eventType.LocalId] = eventType;

                    // save the mapping.
                    NodeIdMapping mapping = new NodeIdMapping();
                    mapping.IntegerId = nextId;
                    mapping.NodeId    = this.GetLocalNodeId(eventType.TypeId).ToString();

                    mappingsToKeep.Add(mapping);
                }
            }

            // update mappings.
            mappingSet.Mappings = mappingsToKeep;
            m_categories        = categories;
        }