/// <summary>
 /// Add an enum type defined in a binary schema dictionary.
 /// </summary>
 private void AddEnumTypes(
     IComplexTypeBuilder complexTypeBuilder,
     IList <Opc.Ua.Schema.Binary.TypeDescription> enumList,
     IList <INode> enumerationTypes
     )
 {
     foreach (var item in enumList)
     {
         Type         newType  = null;
         DataTypeNode enumType = enumerationTypes.Where(node =>
                                                        node.BrowseName.Name == item.Name &&
                                                        (node.NodeId.NamespaceIndex == complexTypeBuilder.TargetNamespaceIndex ||
                                                         complexTypeBuilder.TargetNamespaceIndex == -1)).FirstOrDefault()
                                 as DataTypeNode;
         if (enumType != null)
         {
             // try dictionary enum definition
             var enumeratedObject = item as Schema.Binary.EnumeratedType;
             if (enumeratedObject != null)
             {
                 // 1. use Dictionary entry
                 newType = complexTypeBuilder.AddEnumType(enumeratedObject);
             }
             if (newType == null)
             {
                 var dataType = m_session.NodeCache.Find(enumType.NodeId) as DataTypeNode;
                 if (dataType != null)
                 {
                     if (dataType.DataTypeDefinition != null)
                     {
                         // 2. use DataTypeDefinition
                         newType = complexTypeBuilder.AddEnumType(enumType.BrowseName.Name, dataType.DataTypeDefinition);
                     }
                     else
                     {
                         // browse for EnumFields or EnumStrings property
                         var property  = BrowseForSingleProperty(enumType.NodeId);
                         var enumArray = m_session.ReadValue(
                             ExpandedNodeId.ToNodeId(property.NodeId, m_session.NamespaceUris));
                         if (enumArray.Value is ExtensionObject[])
                         {
                             // 3. use EnumValues
                             newType = complexTypeBuilder.AddEnumType(enumType.BrowseName.Name, (ExtensionObject[])enumArray.Value);
                         }
                         else if (enumArray.Value is LocalizedText[])
                         {
                             // 4. use EnumStrings
                             newType = complexTypeBuilder.AddEnumType(enumType.BrowseName.Name, (LocalizedText[])enumArray.Value);
                         }
                     }
                 }
             }
             if (newType != null)
             {
                 // match namespace and add to type factory
                 AddEncodeableType(enumType.NodeId, newType);
             }
         }
     }
 }
Exemplo n.º 2
0
        // PUBLIC METHODS ///////////////////////////////////////////////////
        #region Extension Methods
        public static IAttributeInfoBuilder Attribute <TComplex, TProperty>(this IComplexTypeBuilder <TComplex> complexTypeBuilder, Expression <Func <TComplex, TProperty> > clrPropertySelector)
        {
            Contract.Requires(complexTypeBuilder != null);
            Contract.Requires(clrPropertySelector != null);

            var clrPropertyType = typeof(TProperty);
            var clrPropertyName = StaticReflection.GetMemberName(clrPropertySelector);

            return(complexTypeBuilder.Attribute(clrPropertyName, clrPropertyType));
        }
        private static void AttributePropertyDiscovered(IComplexTypeBuilder complexTypeConfiguration, PropertyInfo attributeProperty)
        {
            Contract.Requires(complexTypeConfiguration != null);
            Contract.Requires(attributeProperty != null);

            var clrPropertyName = attributeProperty.Name;
            var clrPropertyType = attributeProperty.PropertyType;

            complexTypeConfiguration.Attribute(clrPropertyName, clrPropertyType);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Load all custom types with DataTypeDefinition into the type factory.
        /// </summary>
        /// <returns>true if all types were loaded, false otherwise</returns>
        private IList<INode> LoadBaseEnumDataTypes(
            IList<INode> serverEnumTypes
            )
        {
            // strip known types
            serverEnumTypes = RemoveKnownTypes(serverEnumTypes);

            // add new enum Types for all namespaces
            var enumTypesToDoList = new List<INode>();
            int namespaceCount = m_session.NamespaceUris.Count;

            // create enumeration types for all namespaces
            for (uint i = 0; i < namespaceCount; i++)
            {
                IComplexTypeBuilder complexTypeBuilder = null;
                var enumTypes = serverEnumTypes.Where(node => node.NodeId.NamespaceIndex == i).ToList();
                if (enumTypes.Count != 0)
                {
                    if (complexTypeBuilder == null)
                    {
                        string targetNamespace = m_session.NamespaceUris.GetString(i);
                        complexTypeBuilder = m_complexTypeBuilderFactory.Create(
                            targetNamespace,
                            (int)i);
                    }
                    foreach (var enumType in enumTypes)
                    {
                        var newType = AddEnumType(complexTypeBuilder, enumType as DataTypeNode);
                        if (newType != null)
                        {
                            // match namespace and add to type factory
                            AddEncodeableType(enumType.NodeId, newType);
                        }
                        else
                        {
                            enumTypesToDoList.Add(enumType);
                        }
                    }
                }
            }

            // all types loaded, return remaining
            return enumTypesToDoList;
        }
        /// <summary>
        /// Add structured type to assembly with StructureDefinition.
        /// </summary>
        private Type AddStructuredType(
            IComplexTypeBuilder complexTypeBuilder,
            StructureDefinition structureDefinition,
            string typeName,
            ExpandedNodeId complexTypeId,
            ExpandedNodeId binaryEncodingId,
            ExpandedNodeId xmlEncodingId = null
            )
        {
            // check all types
            var typeList = new List <Type>();

            foreach (StructureField field in structureDefinition.Fields)
            {
                var newType = GetFieldType(field);
                if (newType == null)
                {
                    // missing that type
                    return(null);
                }
                typeList.Add(newType);
            }

            var fieldBuilder = complexTypeBuilder.AddStructuredType(
                typeName,
                structureDefinition
                );

            fieldBuilder.AddTypeIdAttribute(complexTypeId, binaryEncodingId, xmlEncodingId);

            int order = 1;
            var typeListEnumerator = typeList.GetEnumerator();

            foreach (StructureField field in structureDefinition.Fields)
            {
                typeListEnumerator.MoveNext();
                fieldBuilder.AddField(field, typeListEnumerator.Current, order);
                order += 1;
            }

            return(fieldBuilder.CreateType());
        }
        // PUBLIC METHODS ///////////////////////////////////////////////////
        #region IComplexTypeConvention Implementation
        public IComplexTypeBuilder Apply(IComplexTypeBuilder complexTypeConfiguration)
        {
            Contract.Requires(complexTypeConfiguration != null);

            // Use reflection, get all the directly declard, public, and instance-based type of properties for the given resource type.
            var clrComplexType = complexTypeConfiguration.ClrType;
            var clrProperties  = clrComplexType
                                 .GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance)
                                 .ToList();

            // Remaining properties are attributes.
            var attributeProperties = DiscoverAttributeProperties(clrProperties);

            foreach (var attributeProperty in attributeProperties)
            {
                AttributePropertyDiscovered(complexTypeConfiguration, attributeProperty);
            }

            return(complexTypeConfiguration);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Add an enum type defined in a DataType node.
        /// </summary>
        private Type AddEnumType(
            IComplexTypeBuilder complexTypeBuilder,
            DataTypeNode enumTypeNode
            )
        {
            Type newType = null;

            if (enumTypeNode != null)
            {
                string name = enumTypeNode.BrowseName.Name;
                if (enumTypeNode.DataTypeDefinition != null)
                {
                    // 1. use DataTypeDefinition
                    newType = complexTypeBuilder.AddEnumType(name, enumTypeNode.DataTypeDefinition);
                }
                else
                {
                    // browse for EnumFields or EnumStrings property
                    var property = BrowseForSingleProperty(enumTypeNode.NodeId);
                    if (property != null)
                    {
                        var enumArray = m_session.ReadValue(
                            ExpandedNodeId.ToNodeId(property.NodeId,
                                                    m_session.NamespaceUris));
                        if (enumArray.Value is ExtensionObject[])
                        {
                            // 2. use EnumValues
                            newType = complexTypeBuilder.AddEnumType(name, (ExtensionObject[])enumArray.Value);
                        }
                        else if (enumArray.Value is LocalizedText[])
                        {
                            // 3. use EnumStrings
                            newType = complexTypeBuilder.AddEnumType(name, (LocalizedText[])enumArray.Value);
                        }
                    }
                }
            }
            return(newType);
        }
Exemplo n.º 8
0
        /// <summary>
        /// Load all structure custom types with DataTypeDefinition into the type factory.
        /// </summary>
        /// <returns>true if all types were loaded, false otherwise</returns>
        private IList<INode> LoadBaseStructureDataTypes(
            IList<INode> serverStructTypes
            )
        {
            // strip known types
            serverStructTypes = RemoveKnownTypes(serverStructTypes);

            // add new enum Types for all namespaces
            int namespaceCount = m_session.NamespaceUris.Count;

            bool retryAddStructType;
            var structTypesToDoList = new List<INode>();
            var structTypesWorkList = serverStructTypes;

            // create structured types for all namespaces
            do
            {
                retryAddStructType = false;
                for (uint i = 0; i < namespaceCount; i++)
                {
                    IComplexTypeBuilder complexTypeBuilder = null;
                    var structTypes = structTypesWorkList.Where(node => node.NodeId.NamespaceIndex == i).ToList();
                    if (structTypes.Count != 0)
                    {
                        if (complexTypeBuilder == null)
                        {
                            string targetNamespace = m_session.NamespaceUris.GetString(i);
                            complexTypeBuilder = m_complexTypeBuilderFactory.Create(
                                targetNamespace,
                                (int)i);
                        }
                        foreach (INode structType in structTypes)
                        {
                            Type newType = null;
                            if (!(structType is DataTypeNode dataTypeNode))
                            {
                                continue;
                            }
                            var structureDefinition = GetStructureDefinition(dataTypeNode);
                            if (structureDefinition != null)
                            {
                                var encodingIds = BrowseForEncodings(structType.NodeId, m_supportedEncodings,
                                    out ExpandedNodeId binaryEncodingId, out ExpandedNodeId xmlEncodingId);
                                try
                                {
                                    newType = AddStructuredType(
                                        complexTypeBuilder,
                                        structureDefinition,
                                        dataTypeNode.BrowseName.Name,
                                        structType.NodeId,
                                        binaryEncodingId,
                                        xmlEncodingId
                                        );
                                }
                                catch (DataTypeNotFoundException dtnfex)
                                {
                                    var typeMatch = structTypesWorkList.Where(n => n.NodeId == dtnfex.nodeId).FirstOrDefault();
                                    if (typeMatch == null)
                                    {
                                        throw dtnfex;
                                    }
                                    else
                                    {   // known missing type, retry on next round
                                        retryAddStructType = true;
                                    }
                                }
                                catch
                                {
                                    // creating the new type failed, likely a missing dependency, retry later
                                    retryAddStructType = true;
                                }
                                if (newType != null)
                                {
                                    foreach (var encodingId in encodingIds)
                                    {
                                        AddEncodeableType(encodingId, newType);
                                    }
                                    AddEncodeableType(structType.NodeId, newType);
                                }
                            }
                            if (newType == null)
                            {
                                structTypesToDoList.Add(structType);
                            }
                        }
                    }
                }
                // due to type dependencies, retry missing types until there is no more progress
                if (retryAddStructType &&
                    structTypesWorkList.Count != structTypesToDoList.Count)
                {
                    structTypesWorkList = structTypesToDoList;
                    structTypesToDoList = new List<INode>();
                }
            } while (retryAddStructType);

            // all types loaded
            return structTypesToDoList;
        }
        /// <summary>
        /// Load all custom types with DataTypeDefinition into the type factory.
        /// </summary>
        private bool LoadBaseDataTypes(
            IList <INode> serverEnumTypes,
            IList <INode> serverStructTypes
            )
        {
            // strip known types
            serverEnumTypes   = RemoveKnownTypes(serverEnumTypes);
            serverStructTypes = RemoveKnownTypes(serverStructTypes);

            // add new enum Types for all namespaces
            var enumTypesToDoList = new List <INode>();
            int namespaceCount    = m_session.NamespaceUris.Count;

            // create enumeration types for all namespaces
            for (uint i = 0; i < namespaceCount; i++)
            {
                IComplexTypeBuilder complexTypeBuilder = null;
                var enumTypes = serverEnumTypes.Where(node => node.NodeId.NamespaceIndex == i).ToList();
                if (enumTypes.Count != 0)
                {
                    if (complexTypeBuilder == null)
                    {
                        string targetNamespace = m_session.NamespaceUris.GetString(i);
                        complexTypeBuilder = m_complexTypeBuilderFactory.Create(
                            targetNamespace,
                            (int)i);
                    }
                    foreach (var enumType in enumTypes)
                    {
                        var newType = AddEnumType(complexTypeBuilder, enumType as DataTypeNode);
                        if (newType != null)
                        {
                            // match namespace and add to type factory
                            AddEncodeableType(enumType.NodeId, newType);
                        }
                        else
                        {
                            enumTypesToDoList.Add(enumType);
                        }
                    }
                }
            }

            bool retryAddStructType;
            var  structTypesToDoList = new List <INode>();
            var  structTypesWorkList = serverStructTypes;

            // create structured types for all namespaces
            do
            {
                retryAddStructType = false;
                for (uint i = 0; i < namespaceCount; i++)
                {
                    IComplexTypeBuilder complexTypeBuilder = null;
                    var structTypes = structTypesWorkList.Where(node => node.NodeId.NamespaceIndex == i).ToList();
                    if (structTypes.Count != 0)
                    {
                        if (complexTypeBuilder == null)
                        {
                            string targetNamespace = m_session.NamespaceUris.GetString(i);
                            complexTypeBuilder = m_complexTypeBuilderFactory.Create(
                                targetNamespace,
                                (int)i);
                        }
                        foreach (INode structType in structTypes)
                        {
                            Type newType      = null;
                            var  dataTypeNode = structType as DataTypeNode;
                            if (dataTypeNode == null)
                            {
                                continue;
                            }
                            var structureDefinition = dataTypeNode.DataTypeDefinition?.Body as StructureDefinition;
                            if (structureDefinition != null)
                            {
                                try
                                {
                                    newType = AddStructuredType(
                                        complexTypeBuilder,
                                        structureDefinition,
                                        dataTypeNode.BrowseName.Name,
                                        structType.NodeId,
                                        structureDefinition.DefaultEncodingId
                                        );
                                }
                                catch
                                {
                                    // creating the new type failed, likely a missing dependency, retry later
                                    retryAddStructType = true;
                                }
                                if (newType != null)
                                {
                                    // match namespace and add new type to type factory
                                    AddEncodeableType(structureDefinition.DefaultEncodingId, newType);
                                    AddEncodeableType(structType.NodeId, newType);
                                }
                            }
                            if (newType == null)
                            {
                                structTypesToDoList.Add(structType);
                            }
                        }
                    }
                }
                // due to type dependencies, retry missing types until there is no more progress
                if (retryAddStructType &&
                    structTypesWorkList.Count != structTypesToDoList.Count)
                {
                    structTypesWorkList = structTypesToDoList;
                    structTypesToDoList = new List <INode>();
                }
            } while (retryAddStructType);

            return(structTypesToDoList.Count == 0);
        }