예제 #1
0
 private static bool IsNeedNullableMember(ElementAccessor element)
 {
     if (element.Mapping is ArrayMapping)
     {
         ArrayMapping arrayMapping = (ArrayMapping)element.Mapping;
         if (arrayMapping.Elements != null && arrayMapping.Elements.Length == 1)
         {
             return(IsNeedNullableMember(arrayMapping.Elements[0]));
         }
         return(false);
     }
     else
     {
         return(element.IsNullable && element.Mapping.TypeDesc.IsValueType);
     }
 }
예제 #2
0
        internal ElementAccessor Clone()
        {
            ElementAccessor newAccessor = new ElementAccessor();

            newAccessor._nullable          = _nullable;
            newAccessor.IsTopLevelInSchema = this.IsTopLevelInSchema;
            newAccessor.Form      = this.Form;
            newAccessor._isSoap   = _isSoap;
            newAccessor.Name      = this.Name;
            newAccessor.Default   = this.Default;
            newAccessor.Namespace = this.Namespace;
            newAccessor.Mapping   = this.Mapping;
            newAccessor.Any       = this.Any;

            return(newAccessor);
        }
예제 #3
0
        /// <include file='doc\SoapReflectionImporter.uex' path='docs/doc[@for="SoapReflectionImporter.ImportMembersMapping3"]/*' />
        /// <devdoc>
        ///    <para>[To be supplied.]</para>
        /// </devdoc>
        public XmlMembersMapping ImportMembersMapping(string elementName, string ns, XmlReflectionMember[] members, bool hasWrapperElement, bool writeAccessors, bool validate, XmlMappingAccess access)
        {
            ElementAccessor element = new ElementAccessor();

            element.IsSoap = true;
            element.Name   = elementName == null || elementName.Length == 0 ? elementName : XmlConvert.EncodeLocalName(elementName);

            element.Mapping          = ImportMembersMapping(members, ns, hasWrapperElement, writeAccessors, validate, new RecursionLimiter());
            element.Mapping.TypeName = elementName;
            element.Namespace        = element.Mapping.Namespace == null ? ns : element.Mapping.Namespace;
            element.Form             = XmlSchemaForm.Qualified;
            XmlMembersMapping xmlMapping = new XmlMembersMapping(_typeScope, element, access);

            xmlMapping.IsSoap             = true;
            xmlMapping.GenerateSerializer = true;
            return(xmlMapping);
        }
예제 #4
0
        /// <include file='doc\SoapSchemaImporter.uex' path='docs/doc[@for="SoapSchemaImporter.ImportMembersMapping3"]/*' />
        /// <devdoc>
        ///    <para>[To be supplied.]</para>
        /// </devdoc>
        public XmlMembersMapping ImportMembersMapping(string name, string ns, SoapSchemaMember[] members, bool hasWrapperElement, Type baseType, bool baseTypeCanBeIndirect)
        {
            XmlSchemaComplexType type = new XmlSchemaComplexType();
            XmlSchemaSequence    seq  = new XmlSchemaSequence();

            type.Particle = seq;
            foreach (SoapSchemaMember member in members)
            {
                XmlSchemaElement element = new XmlSchemaElement();
                element.Name           = member.MemberName;
                element.SchemaTypeName = member.MemberType;
                seq.Items.Add(element);
            }

            CodeIdentifiers identifiers = new CodeIdentifiers();

            identifiers.UseCamelCasing = true;
            MembersMapping mapping = new MembersMapping();

            mapping.TypeDesc          = Scope.GetTypeDesc(typeof(object[]));
            mapping.Members           = ImportTypeMembers(type, ns, identifiers);
            mapping.HasWrapperElement = hasWrapperElement;

            if (baseType != null)
            {
                for (int i = 0; i < mapping.Members.Length; i++)
                {
                    MemberMapping member = mapping.Members[i];
                    if (member.Accessor.Mapping is StructMapping)
                    {
                        MakeDerived((StructMapping)member.Accessor.Mapping, baseType, baseTypeCanBeIndirect);
                    }
                }
            }
            ElementAccessor accessor = new ElementAccessor();

            accessor.IsSoap     = true;
            accessor.Name       = name;
            accessor.Namespace  = ns;
            accessor.Mapping    = mapping;
            accessor.IsNullable = false;
            accessor.Form       = XmlSchemaForm.Qualified;

            return(new XmlMembersMapping(Scope, accessor, XmlMappingAccess.Read | XmlMappingAccess.Write));
        }
예제 #5
0
        internal XmlMembersMapping(TypeScope scope, ElementAccessor accessor, XmlMappingAccess access) : base(scope, accessor, access)
        {
            MembersMapping mapping = (MembersMapping)accessor.Mapping;
            StringBuilder  key     = new StringBuilder();

            key.Append(":");
            _mappings = new XmlMemberMapping[mapping.Members.Length];
            for (int i = 0; i < _mappings.Length; i++)
            {
                if (mapping.Members[i].TypeDesc.Type != null)
                {
                    key.Append(GenerateKey(mapping.Members[i].TypeDesc.Type, null, null));
                    key.Append(":");
                }
                _mappings[i] = new XmlMemberMapping(mapping.Members[i]);
            }
            SetKeyInternal(key.ToString());
        }
예제 #6
0
        private static XmlTypeMapping GetKnownMapping(Type type, string ns)
        {
            if (ns != null && ns != string.Empty)
            {
                return(null);
            }
            TypeDesc typeDesc = (TypeDesc)TypeScope.PrimtiveTypes[type];

            if (typeDesc == null)
            {
                return(null);
            }
            ElementAccessor element = new ElementAccessor();

            element.Name = typeDesc.DataType.Name;
            XmlTypeMapping mapping = new XmlTypeMapping(null, element);

            mapping.SetKeyInternal(XmlMapping.GenerateKey(type, null, null));
            return(mapping);
        }
예제 #7
0
 private void ExportArrayElements(CodeAttributeDeclarationCollection metadata, ArrayMapping array, string ns, TypeDesc elementTypeDesc, int nestingLevel)
 {
     for (int i = 0; i < array.Elements.Length; i++)
     {
         ElementAccessor arrayElement    = array.Elements[i];
         TypeMapping     elementMapping  = arrayElement.Mapping;
         string          elementName     = Accessor.UnescapeName(arrayElement.Name);
         bool            sameName        = arrayElement.Mapping.TypeDesc.IsArray ? false : elementName == arrayElement.Mapping.TypeName;
         bool            sameElementType = elementMapping.TypeDesc == elementTypeDesc;
         bool            sameElementNs   = arrayElement.Form == XmlSchemaForm.Unqualified || arrayElement.Namespace == ns;
         bool            sameNullable    = arrayElement.IsNullable == elementMapping.TypeDesc.IsNullable;
         bool            defaultForm     = arrayElement.Form != XmlSchemaForm.Unqualified;
         if (!sameName || !sameElementType || !sameElementNs || !sameNullable || !defaultForm || nestingLevel > 0)
         {
             ExportArrayItem(metadata, sameName ? null : elementName, sameElementNs ? null : arrayElement.Namespace, sameElementType ? null : elementMapping.TypeDesc, elementMapping.TypeDesc, arrayElement.IsNullable, defaultForm ? XmlSchemaForm.None : arrayElement.Form, nestingLevel);
         }
         if (elementMapping is ArrayMapping)
         {
             ExportArrayElements(metadata, (ArrayMapping)elementMapping, ns, elementTypeDesc.ArrayElementTypeDesc, nestingLevel + 1);
         }
     }
 }
예제 #8
0
        /// <include file='doc\SoapSchemaImporter.uex' path='docs/doc[@for="SoapSchemaImporter.ImportDerivedTypeMapping"]/*' />
        /// <devdoc>
        ///    <para>[To be supplied.]</para>
        /// </devdoc>
        public XmlTypeMapping ImportDerivedTypeMapping(XmlQualifiedName name, Type baseType, bool baseTypeCanBeIndirect)
        {
            TypeMapping mapping = ImportType(name, false);

            if (mapping is StructMapping)
            {
                MakeDerived((StructMapping)mapping, baseType, baseTypeCanBeIndirect);
            }
            else if (baseType != null)
            {
                throw new InvalidOperationException(string.Format(ResXml.XmlPrimitiveBaseType, name.Name, name.Namespace, baseType.FullName));
            }
            ElementAccessor accessor = new ElementAccessor();

            accessor.IsSoap     = true;
            accessor.Name       = name.Name;
            accessor.Namespace  = name.Namespace;
            accessor.Mapping    = mapping;
            accessor.IsNullable = true;
            accessor.Form       = XmlSchemaForm.Qualified;

            return(new XmlTypeMapping(Scope, accessor));
        }
예제 #9
0
        private ElementAccessor ImportElement(XmlSchemaElement element, string ns)
        {
            if (!element.RefName.IsEmpty)
            {
                throw new InvalidOperationException(string.Format(ResXml.RefSyntaxNotSupportedForElements0, element.RefName.Name, element.RefName.Namespace));
            }

            if (element.Name.Length == 0)
            {
                XmlQualifiedName parentType = XmlSchemas.GetParentName(element);
                throw new InvalidOperationException(string.Format(ResXml.XmlElementHasNoName, parentType.Name, parentType.Namespace));
            }
            TypeMapping     mapping  = ImportElementType(element, ns);
            ElementAccessor accessor = new ElementAccessor();

            accessor.IsSoap     = true;
            accessor.Name       = element.Name;
            accessor.Namespace  = ns;
            accessor.Mapping    = mapping;
            accessor.IsNullable = element.IsNillable;
            accessor.Form       = XmlSchemaForm.None;

            return(accessor);
        }
예제 #10
0
        private void AddMemberMetadata(CodeMemberField field, CodeAttributeDeclarationCollection metadata, MemberMapping member, string ns, bool forceUseMemberName, CodeCommentStatementCollection comments, CodeConstructor ctor)
        {
            if (member.Xmlns != null)
            {
                CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(typeof(XmlNamespaceDeclarationsAttribute).FullName);
                metadata.Add(attribute);
            }
            else if (member.Attribute != null)
            {
                AttributeAccessor attribute = member.Attribute;
                if (attribute.Any)
                {
                    ExportAnyAttribute(metadata);
                }
                else
                {
                    TypeMapping mapping  = (TypeMapping)attribute.Mapping;
                    string      attrName = Accessor.UnescapeName(attribute.Name);
                    bool        sameType = mapping.TypeDesc == member.TypeDesc ||
                                           (member.TypeDesc.IsArrayLike && mapping.TypeDesc == member.TypeDesc.ArrayElementTypeDesc);
                    bool sameName    = attrName == member.Name && !forceUseMemberName;
                    bool sameNs      = attribute.Namespace == ns;
                    bool defaultForm = attribute.Form != XmlSchemaForm.Qualified;
                    ExportAttribute(metadata,
                                    sameName ? null : attrName,
                                    sameNs || defaultForm ? null : attribute.Namespace,
                                    sameType ? null : mapping.TypeDesc,
                                    mapping.TypeDesc,
                                    defaultForm ? XmlSchemaForm.None : attribute.Form);

                    AddDefaultValueAttribute(field, metadata, attribute.Default, mapping, comments, member.TypeDesc, attribute, ctor);
                }
            }
            else
            {
                if (member.Text != null)
                {
                    TypeMapping mapping  = (TypeMapping)member.Text.Mapping;
                    bool        sameType = mapping.TypeDesc == member.TypeDesc ||
                                           (member.TypeDesc.IsArrayLike && mapping.TypeDesc == member.TypeDesc.ArrayElementTypeDesc);
                    ExportText(metadata, sameType ? null : mapping.TypeDesc, mapping.TypeDesc.IsAmbiguousDataType ? mapping.TypeDesc.DataType.Name : null);
                }
                if (member.Elements.Length == 1)
                {
                    ElementAccessor element     = member.Elements[0];
                    TypeMapping     mapping     = (TypeMapping)element.Mapping;
                    string          elemName    = Accessor.UnescapeName(element.Name);
                    bool            sameName    = ((elemName == member.Name) && !forceUseMemberName);
                    bool            isArray     = mapping is ArrayMapping;
                    bool            sameNs      = element.Namespace == ns;
                    bool            defaultForm = element.Form != XmlSchemaForm.Unqualified;

                    if (element.Any)
                    {
                        ExportAnyElement(metadata, elemName, element.Namespace, member.SequenceId);
                    }
                    else if (isArray)
                    {
                        bool         sameType = mapping.TypeDesc == member.TypeDesc;
                        ArrayMapping array    = (ArrayMapping)mapping;
                        if (!sameName || !sameNs || element.IsNullable || !defaultForm || member.SequenceId != -1)
                        {
                            ExportArray(metadata, sameName ? null : elemName, sameNs ? null : element.Namespace, element.IsNullable, defaultForm ? XmlSchemaForm.None : element.Form, member.SequenceId);
                        }
                        else if (mapping.TypeDesc.ArrayElementTypeDesc == new TypeScope().GetTypeDesc(typeof(byte)))
                        {
                            // special case for byte[]. It can be a primitive (base64Binary or hexBinary), or it can
                            // be an array of bytes. Our default is primitive; specify [XmlArray] to get array behavior.
                            ExportArray(metadata, null, null, false, XmlSchemaForm.None, member.SequenceId);
                        }
                        ExportArrayElements(metadata, array, element.Namespace, member.TypeDesc.ArrayElementTypeDesc, 0);
                    }
                    else
                    {
                        bool sameType = mapping.TypeDesc == member.TypeDesc ||
                                        (member.TypeDesc.IsArrayLike && mapping.TypeDesc == member.TypeDesc.ArrayElementTypeDesc);
                        if (member.TypeDesc.IsArrayLike)
                        {
                            sameName = false;
                        }
                        ExportElement(metadata, sameName ? null : elemName, sameNs ? null : element.Namespace, sameType ? null : mapping.TypeDesc, mapping.TypeDesc, element.IsNullable, defaultForm ? XmlSchemaForm.None : element.Form, member.SequenceId);
                    }
                    AddDefaultValueAttribute(field, metadata, element.Default, mapping, comments, member.TypeDesc, element, ctor);
                }
                else
                {
                    for (int i = 0; i < member.Elements.Length; i++)
                    {
                        ElementAccessor element  = member.Elements[i];
                        string          elemName = Accessor.UnescapeName(element.Name);
                        bool            sameNs   = element.Namespace == ns;
                        if (element.Any)
                        {
                            ExportAnyElement(metadata, elemName, element.Namespace, member.SequenceId);
                        }
                        else
                        {
                            bool defaultForm = element.Form != XmlSchemaForm.Unqualified;
                            ExportElement(metadata, elemName, sameNs ? null : element.Namespace, ((TypeMapping)element.Mapping).TypeDesc, ((TypeMapping)element.Mapping).TypeDesc, element.IsNullable, defaultForm ? XmlSchemaForm.None : element.Form, member.SequenceId);
                        }
                    }
                }
                if (member.ChoiceIdentifier != null)
                {
                    CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(typeof(XmlChoiceIdentifierAttribute).FullName);
                    attribute.Arguments.Add(new CodeAttributeArgument(new CodePrimitiveExpression(member.ChoiceIdentifier.MemberName)));
                    metadata.Add(attribute);
                }
                if (member.Ignore)
                {
                    CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(typeof(XmlIgnoreAttribute).FullName);
                    metadata.Add(attribute);
                }
            }
        }
예제 #11
0
        private ArrayMapping ImportArrayMapping(XmlSchemaType type, string ns)
        {
            ArrayMapping arrayMapping;

            if (type.Name == Soap.Array && ns == Soap.Encoding)
            {
                arrayMapping = new ArrayMapping();
                TypeMapping     mapping      = GetRootMapping();
                ElementAccessor itemAccessor = new ElementAccessor();
                itemAccessor.IsSoap     = true;
                itemAccessor.Name       = Soap.UrType;
                itemAccessor.Namespace  = ns;
                itemAccessor.Mapping    = mapping;
                itemAccessor.IsNullable = true;
                itemAccessor.Form       = XmlSchemaForm.None;

                arrayMapping.Elements = new ElementAccessor[] { itemAccessor };
                arrayMapping.TypeDesc = itemAccessor.Mapping.TypeDesc.CreateArrayTypeDesc();
                arrayMapping.TypeName = "ArrayOf" + CodeIdentifier.MakePascal(itemAccessor.Mapping.TypeName);
                return(arrayMapping);
            }
            if (!(type.DerivedFrom.Name == Soap.Array && type.DerivedFrom.Namespace == Soap.Encoding))
            {
                return(null);
            }

            // the type should be a XmlSchemaComplexType
            XmlSchemaContentModel model = ((XmlSchemaComplexType)type).ContentModel;

            // the Content  should be an restriction
            if (!(model.Content is XmlSchemaComplexContentRestriction))
            {
                return(null);
            }

            arrayMapping = new ArrayMapping();

            XmlSchemaComplexContentRestriction restriction = (XmlSchemaComplexContentRestriction)model.Content;

            for (int i = 0; i < restriction.Attributes.Count; i++)
            {
                XmlSchemaAttribute attribute = restriction.Attributes[i] as XmlSchemaAttribute;
                if (attribute != null && attribute.RefName.Name == Soap.ArrayType && attribute.RefName.Namespace == Soap.Encoding)
                {
                    // read the value of the wsdl:arrayType attribute
                    string arrayType = null;

                    if (attribute.UnhandledAttributes != null)
                    {
                        foreach (XmlAttribute a in attribute.UnhandledAttributes)
                        {
                            if (a.LocalName == Wsdl.ArrayType && a.NamespaceURI == Wsdl.Namespace)
                            {
                                arrayType = a.Value;
                                break;
                            }
                        }
                    }
                    if (arrayType != null)
                    {
                        string           dims;
                        XmlQualifiedName typeName = TypeScope.ParseWsdlArrayType(arrayType, out dims, attribute);

                        TypeMapping mapping;
                        TypeDesc    td = Scope.GetTypeDesc(typeName.Name, typeName.Namespace);
                        if (td != null && td.IsPrimitive)
                        {
                            mapping          = new PrimitiveMapping();
                            mapping.TypeDesc = td;
                            mapping.TypeName = td.DataType.Name;
                        }
                        else
                        {
                            mapping = ImportType(typeName, false);
                        }
                        ElementAccessor itemAccessor = new ElementAccessor();
                        itemAccessor.IsSoap     = true;
                        itemAccessor.Name       = typeName.Name;
                        itemAccessor.Namespace  = ns;
                        itemAccessor.Mapping    = mapping;
                        itemAccessor.IsNullable = true;
                        itemAccessor.Form       = XmlSchemaForm.None;

                        arrayMapping.Elements = new ElementAccessor[] { itemAccessor };
                        arrayMapping.TypeDesc = itemAccessor.Mapping.TypeDesc.CreateArrayTypeDesc();
                        arrayMapping.TypeName = "ArrayOf" + CodeIdentifier.MakePascal(itemAccessor.Mapping.TypeName);

                        return(arrayMapping);
                    }
                }
            }

            XmlSchemaParticle particle = restriction.Particle;

            if (particle is XmlSchemaAll || particle is XmlSchemaSequence)
            {
                XmlSchemaGroupBase group = (XmlSchemaGroupBase)particle;
                if (group.Items.Count != 1 || !(group.Items[0] is XmlSchemaElement))
                {
                    return(null);
                }
                XmlSchemaElement itemElement = (XmlSchemaElement)group.Items[0];
                if (!itemElement.IsMultipleOccurrence)
                {
                    return(null);
                }
                ElementAccessor itemAccessor = ImportElement(itemElement, ns);
                arrayMapping.Elements = new ElementAccessor[] { itemAccessor };
                arrayMapping.TypeDesc = ((TypeMapping)itemAccessor.Mapping).TypeDesc.CreateArrayTypeDesc();
            }
            else
            {
                return(null);
            }
            return(arrayMapping);
        }
예제 #12
0
 internal XmlMapping(TypeScope scope, ElementAccessor accessor) : this(scope, accessor, XmlMappingAccess.Read | XmlMappingAccess.Write)
 {
 }
예제 #13
0
 private void ExportElement(ElementAccessor element)
 {
     ExportType(element.Mapping);
 }
예제 #14
0
 internal XmlTypeMapping(TypeScope scope, ElementAccessor accessor) : base(scope, accessor)
 {
 }
예제 #15
0
 private void ExportElement(ElementAccessor element)
 {
     ExportType(element.Mapping, Accessor.UnescapeName(element.Name), element.Namespace, element, true);
 }
예제 #16
0
        private void ExportType(TypeMapping mapping, string name, string ns, ElementAccessor rootElement, bool checkReference)
        {
            if (mapping.IsReference && mapping.Namespace != Soap.Encoding)
            {
                return;
            }

            if (mapping is StructMapping && checkReference && ((StructMapping)mapping).ReferencedByTopLevelElement && rootElement == null)
            {
                return;
            }

            if (mapping is ArrayMapping && rootElement != null && rootElement.IsTopLevelInSchema && ((ArrayMapping)mapping).TopLevelMapping != null)
            {
                mapping = ((ArrayMapping)mapping).TopLevelMapping;
            }

            CodeTypeDeclaration codeClass = null;

            if (ExportedMappings[mapping] == null)
            {
                ExportedMappings.Add(mapping, mapping);
                if (mapping.TypeDesc.IsMappedType)
                {
                    codeClass = mapping.TypeDesc.ExtendedType.ExportTypeDefinition(CodeNamespace, CodeCompileUnit);
                }
                else if (mapping is EnumMapping)
                {
                    codeClass = ExportEnum((EnumMapping)mapping, typeof(XmlEnumAttribute));
                }
                else if (mapping is StructMapping)
                {
                    codeClass = ExportStruct((StructMapping)mapping);
                }
                else if (mapping is ArrayMapping)
                {
                    EnsureTypesExported(((ArrayMapping)mapping).Elements, ns);
                }
                if (codeClass != null)
                {
                    if (!mapping.TypeDesc.IsMappedType)
                    {
                        // Add [GeneratedCodeAttribute(Tool=.., Version=..)]
                        codeClass.CustomAttributes.Add(GeneratedCodeAttribute);

                        if (!codeClass.IsEnum)
                        {
                            // Add [DebuggerStepThrough]
                            codeClass.CustomAttributes.Add(new CodeAttributeDeclaration(typeof(DebuggerStepThroughAttribute).FullName));
                            // Add [DesignerCategory("code")]
                        }
                        AddTypeMetadata(codeClass.CustomAttributes, typeof(XmlTypeAttribute), mapping.TypeDesc.Name, Accessor.UnescapeName(mapping.TypeName), mapping.Namespace, mapping.IncludeInSchema);
                    }
                    else if (FindAttributeDeclaration(typeof(GeneratedCodeAttribute), codeClass.CustomAttributes) == null)
                    {
                        // Add [GeneratedCodeAttribute(Tool=.., Version=..)]
                        codeClass.CustomAttributes.Add(GeneratedCodeAttribute);
                    }
                    ExportedClasses.Add(mapping, codeClass);
                }
            }
            else
            {
                codeClass = (CodeTypeDeclaration)ExportedClasses[mapping];
            }

            if (codeClass != null && rootElement != null)
            {
                AddRootMetadata(codeClass.CustomAttributes, mapping, name, ns, rootElement);
            }
        }
예제 #17
0
        private void AddRootMetadata(CodeAttributeDeclarationCollection metadata, TypeMapping typeMapping, string name, string ns, ElementAccessor rootElement)
        {
            string rootAttrName = typeof(XmlRootAttribute).FullName;

            // check that we haven't already added a root attribute since we can only add one
            foreach (CodeAttributeDeclaration attr in metadata)
            {
                if (attr.Name == rootAttrName)
                {
                    return;
                }
            }

            CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(rootAttrName);

            if (typeMapping.TypeDesc.Name != name)
            {
                attribute.Arguments.Add(new CodeAttributeArgument(new CodePrimitiveExpression(name)));
            }
            if (ns != null)
            {
                attribute.Arguments.Add(new CodeAttributeArgument("Namespace", new CodePrimitiveExpression(ns)));
            }
            if (typeMapping.TypeDesc != null && typeMapping.TypeDesc.IsAmbiguousDataType)
            {
                attribute.Arguments.Add(new CodeAttributeArgument("DataType", new CodePrimitiveExpression(typeMapping.TypeDesc.DataType.Name)));
            }
            if ((object)(rootElement.IsNullable) != null)
            {
                attribute.Arguments.Add(new CodeAttributeArgument("IsNullable", new CodePrimitiveExpression((bool)rootElement.IsNullable)));
            }
            metadata.Add(attribute);
        }