示例#1
0
        private static bool ShouldInclude(ArrayMapping arrayMapping)
        {
            if (arrayMapping.ReferencedByElement)
            {
                return(false);
            }
            if (arrayMapping.Next != null)
            {
                return(false);
            }
            if (arrayMapping.Elements.Length == 1)
            {
                TypeKind kind = arrayMapping.Elements[0].Mapping.TypeDesc.Kind;
                if (kind == TypeKind.Node)
                {
                    return(false);
                }
            }

            for (int i = 0; i < arrayMapping.Elements.Length; i++)
            {
                if (arrayMapping.Elements[i].Name != arrayMapping.Elements[i].Mapping.DefaultElementName)
                {
                    // in the case we need custom attributes to serialize an array instance, we cannot include arrau mapping without explicit reference.
                    return(false);
                }
            }
            return(true);
        }
示例#2
0
        internal void ExportRoot(StructMapping mapping, Type includeType)
        {
            if (!_rootExported)
            {
                _rootExported = true;
                ExportDerivedStructs(mapping);

                for (StructMapping derived = mapping.DerivedMappings; derived != null; derived = derived.NextDerivedMapping)
                {
                    if (!derived.ReferencedByElement && derived.IncludeInSchema && !derived.IsAnonymousType)
                    {
                        CodeAttributeDeclaration include = new CodeAttributeDeclaration(includeType.FullName);
                        include.Arguments.Add(new CodeAttributeArgument(new CodeTypeOfExpression(derived.TypeDesc.FullName)));
                        _includeMetadata.Add(include);
                    }
                }
                Hashtable typesIncluded = new Hashtable();
                foreach (TypeMapping m in Scope.TypeMappings)
                {
                    if (m is ArrayMapping)
                    {
                        ArrayMapping arrayMapping = (ArrayMapping)m;
                        if (ShouldInclude(arrayMapping) && !typesIncluded.Contains(arrayMapping.TypeDesc.FullName))
                        {
                            CodeAttributeDeclaration include = new CodeAttributeDeclaration(includeType.FullName);
                            include.Arguments.Add(new CodeAttributeArgument(new CodeTypeOfExpression(arrayMapping.TypeDesc.FullName)));
                            _includeMetadata.Add(include);
                            typesIncluded.Add(arrayMapping.TypeDesc.FullName, string.Empty);
                            EnsureTypesExported(arrayMapping.Elements, arrayMapping.Namespace);
                        }
                    }
                }
            }
        }
示例#3
0
        private XmlQualifiedName ExportArrayMapping(ArrayMapping mapping, string ns)
        {
            // for the Rpc ArrayMapping  different mappings could have the same schema type
            // we link all mappings corresponding to the same type together
            // loop through all mapping that will map to the same complexType, and export only one,
            // the obvious choice is the last one.
            while (mapping.Next != null)
            {
                mapping = mapping.Next;
            }

            XmlSchemaComplexType type = (XmlSchemaComplexType)_types[mapping];

            if (type == null)
            {
                CheckForDuplicateType(mapping.TypeName, mapping.Namespace);
                type      = new XmlSchemaComplexType();
                type.Name = mapping.TypeName;
                _types.Add(mapping, type);

                // we need to add the type first, to make sure that the schema get created
                AddSchemaItem(type, mapping.Namespace, ns);
                AddSchemaImport(Soap.Encoding, mapping.Namespace);
                AddSchemaImport(Wsdl.Namespace, mapping.Namespace);

                XmlSchemaComplexContentRestriction restriction = new XmlSchemaComplexContentRestriction();
                XmlQualifiedName qname = ExportTypeMapping(mapping.Elements[0].Mapping, mapping.Namespace);

                if (qname.IsEmpty)
                {
                    // this is a root mapping
                    qname = new XmlQualifiedName(Soap.UrType, XmlSchema.Namespace);
                }
                //<attribute ref="soapenc:arrayType" wsdl:arrayType="xsd:float[]"/>
                XmlSchemaAttribute attr = new XmlSchemaAttribute();
                attr.RefName = s_arrayTypeQName;
                XmlAttribute attribute = new XmlAttribute("wsdl", Wsdl.ArrayType, Wsdl.Namespace, Document);
                attribute.Value = qname.Namespace + ":" + qname.Name + "[]";

                attr.UnhandledAttributes = new XmlAttribute[] { attribute };
                restriction.Attributes.Add(attr);
                restriction.BaseTypeName = s_arrayQName;
                XmlSchemaComplexContent model = new XmlSchemaComplexContent();
                model.Content     = restriction;
                type.ContentModel = model;
                if (qname.Namespace != XmlSchema.Namespace)
                {
                    AddSchemaImport(qname.Namespace, mapping.Namespace);
                }
            }
            else
            {
                AddSchemaImport(mapping.Namespace, ns);
            }
            return(new XmlQualifiedName(mapping.TypeName, mapping.Namespace));
        }
示例#4
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);
     }
 }
        private ArrayMapping ImportArrayLikeMapping(ArrayModel model, RecursionLimiter limiter)
        {
            ArrayMapping mapping = new ArrayMapping();

            mapping.IsSoap = true;
            TypeMapping itemTypeMapping = ImportTypeMapping(model.Element, limiter);

            if (itemTypeMapping.TypeDesc.IsValueType && !itemTypeMapping.TypeDesc.IsPrimitive && !itemTypeMapping.TypeDesc.IsEnum)
            {
                throw new NotSupportedException(string.Format(ResXml.XmlRpcArrayOfValueTypes, model.TypeDesc.FullName));
            }

            mapping.TypeDesc = model.TypeDesc;
            mapping.Elements = new ElementAccessor[] {
                CreateElementAccessor(itemTypeMapping, mapping.Namespace)
            };
            SetArrayMappingType(mapping);

            // in the case of an ArrayMapping we can have more that one mapping correspond to a type
            // examples of that are ArrayList and object[] both will map tp ArrayOfur-type
            // so we create a link list for all mappings of the same XSD type
            ArrayMapping existingMapping = (ArrayMapping)_types[mapping.TypeName, mapping.Namespace];

            if (existingMapping != null)
            {
                ArrayMapping first = existingMapping;
                while (existingMapping != null)
                {
                    if (existingMapping.TypeDesc == model.TypeDesc)
                    {
                        return(existingMapping);
                    }
                    existingMapping = existingMapping.Next;
                }
                mapping.Next = first;
                _types[mapping.TypeName, mapping.Namespace] = mapping;
                return(mapping);
            }
            _typeScope.AddTypeMapping(mapping);
            _types.Add(mapping.TypeName, mapping.Namespace, mapping);
            IncludeTypes(model.Type);
            return(mapping);
        }
示例#6
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);
        }
        // UNDONE Nullable
        private void SetArrayMappingType(ArrayMapping mapping)
        {
            bool useDefaultNs = false;

            string itemTypeName;
            string itemTypeNamespace;

            TypeMapping itemTypeMapping;

            if (mapping.Elements.Length == 1)
            {
                itemTypeMapping = mapping.Elements[0].Mapping;
            }
            else
            {
                itemTypeMapping = null;
            }

            if (itemTypeMapping is EnumMapping)
            {
                itemTypeNamespace = itemTypeMapping.Namespace;
                itemTypeName      = itemTypeMapping.TypeName;
            }
            else if (itemTypeMapping is PrimitiveMapping)
            {
                itemTypeNamespace = itemTypeMapping.TypeDesc.IsXsdType ? XmlSchema.Namespace : UrtTypes.Namespace;
                itemTypeName      = itemTypeMapping.TypeDesc.DataType.Name;
                useDefaultNs      = true;
            }
            else if (itemTypeMapping is StructMapping)
            {
                if (itemTypeMapping.TypeDesc.IsRoot)
                {
                    itemTypeNamespace = XmlSchema.Namespace;
                    itemTypeName      = Soap.UrType;
                    useDefaultNs      = true;
                }
                else
                {
                    itemTypeNamespace = itemTypeMapping.Namespace;
                    itemTypeName      = itemTypeMapping.TypeName;
                }
            }
            else if (itemTypeMapping is ArrayMapping)
            {
                itemTypeNamespace = itemTypeMapping.Namespace;
                itemTypeName      = itemTypeMapping.TypeName;
            }
            else
            {
                throw new InvalidOperationException(string.Format(ResXml.XmlInvalidSoapArray, mapping.TypeDesc.FullName));
            }

            itemTypeName = CodeIdentifier.MakePascal(itemTypeName);
            string      uniqueName      = "ArrayOf" + itemTypeName;
            string      ns              = useDefaultNs ? _defaultNs : itemTypeNamespace;
            int         i               = 1;
            TypeMapping existingMapping = (TypeMapping)_types[uniqueName, ns];

            while (existingMapping != null)
            {
                if (existingMapping is ArrayMapping)
                {
                    ArrayMapping arrayMapping = (ArrayMapping)existingMapping;
                    if (AccessorMapping.ElementsMatch(arrayMapping.Elements, mapping.Elements))
                    {
                        break;
                    }
                }
                // need to re-name the mapping
                uniqueName      = itemTypeName + i.ToString();
                existingMapping = (TypeMapping)_types[uniqueName, ns];
                i++;
            }
            mapping.Namespace = ns;
            mapping.TypeName  = uniqueName;
        }
示例#8
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);
                }
            }
        }
示例#9
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);
         }
     }
 }