SoapSchemaExporter.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ FXUpdate3074 / FXUpdate3074 / 1.1 / untmp / whidbey / QFE / ndp / fx / src / Xml / System / Xml / Serialization / SoapSchemaExporter.cs / 2 / SoapSchemaExporter.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
//-----------------------------------------------------------------------------
 
namespace System.Xml.Serialization { 

    using System; 
    using System.Collections;
    using System.Xml.Schema;
    using System.Xml;
    using System.ComponentModel; 
    using System.Diagnostics;
 
    ///  
    /// 
    public class SoapSchemaExporter { 
        internal const XmlSchemaForm elementFormDefault = XmlSchemaForm.Qualified;
        XmlSchemas schemas;
        Hashtable types = new Hashtable();      // StructMapping/EnumMapping -> XmlSchemaComplexType/XmlSchemaSimpleType
        bool exportedRoot; 
        TypeScope scope;
        XmlDocument document; 
 
        static XmlQualifiedName ArrayQName = new XmlQualifiedName(Soap.Array, Soap.Encoding);
        static XmlQualifiedName ArrayTypeQName = new XmlQualifiedName(Soap.ArrayType, Soap.Encoding); 

        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        public SoapSchemaExporter(XmlSchemas schemas) { 
            this.schemas = schemas; 
        }
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        public void ExportTypeMapping(XmlTypeMapping xmlTypeMapping) {
            CheckScope(xmlTypeMapping.Scope); 
            ExportTypeMapping(xmlTypeMapping.Mapping, null); 
        }
 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        public void ExportMembersMapping(XmlMembersMapping xmlMembersMapping) {
            ExportMembersMapping(xmlMembersMapping, false); 
        } 

        ///  
        /// 
        ///    [To be supplied.]
        /// 
        public void ExportMembersMapping(XmlMembersMapping xmlMembersMapping, bool exportEnclosingType) { 
            CheckScope(xmlMembersMapping.Scope);
            MembersMapping membersMapping = (MembersMapping)xmlMembersMapping.Accessor.Mapping; 
            if (exportEnclosingType) { 
                ExportTypeMapping(membersMapping, null);
            } 
            else {
                foreach (MemberMapping memberMapping in membersMapping.Members) {
                    if (memberMapping.Elements.Length > 0)
                        ExportTypeMapping(memberMapping.Elements[0].Mapping, null); 
                }
            } 
        } 

        void CheckScope(TypeScope scope) { 
            if (this.scope == null) {
                this.scope = scope;
            }
            else if (this.scope != scope) { 
                throw new InvalidOperationException(Res.GetString(Res.XmlMappingsScopeMismatch));
            } 
        } 

        internal XmlDocument Document { 
            get {
                if (document == null) document = new XmlDocument();
                return document;
            } 
        }
 
        void CheckForDuplicateType(string newTypeName, string newNamespace){ 
            XmlSchema schema = schemas[newNamespace];
            if (schema != null){ 
                foreach (XmlSchemaObject o in schema.Items) {
                    XmlSchemaType type = o as XmlSchemaType;
                    if ( type != null && type.Name == newTypeName)
                        throw new InvalidOperationException(Res.GetString(Res.XmlDuplicateTypeName, newTypeName, newNamespace)); 

                } 
            } 
        }
 
        void AddSchemaItem(XmlSchemaObject item, string ns, string referencingNs) {
            if (!SchemaContainsItem(item, ns)) {
                XmlSchema schema = schemas[ns];
                if (schema == null) { 
                    schema = new XmlSchema();
                    schema.TargetNamespace = ns == null || ns.Length == 0 ? null : ns; 
 
#pragma warning disable 429   // unreachable code detected:  elementFormDefault is const so it will never be Unqualified
                    schema.ElementFormDefault = elementFormDefault == XmlSchemaForm.Unqualified ? XmlSchemaForm.None : elementFormDefault; 
#pragma warning restore 429
                    schemas.Add(schema);
                }
                schema.Items.Add(item); 
            }
            if (referencingNs != null) 
                AddSchemaImport(ns, referencingNs); 
        }
 
        void AddSchemaImport(string ns, string referencingNs) {
            if (referencingNs == null || ns == null) return;
            if (ns == referencingNs) return;
            XmlSchema schema = schemas[referencingNs]; 
            if (schema == null) throw new InvalidOperationException(Res.GetString(Res.XmlMissingSchema, referencingNs));
            if (ns != null && ns.Length > 0 && FindImport(schema, ns) == null) { 
                XmlSchemaImport import = new XmlSchemaImport(); 
                import.Namespace = ns;
                schema.Includes.Add(import); 
            }
        }

        bool SchemaContainsItem(XmlSchemaObject item, string ns) { 
            XmlSchema schema = schemas[ns];
            if (schema != null) { 
                return schema.Items.Contains(item); 
            }
            return false; 
        }

        XmlSchemaImport FindImport(XmlSchema schema, string ns) {
            foreach (object item in schema.Includes) { 
                if (item is XmlSchemaImport) {
                    XmlSchemaImport import = (XmlSchemaImport)item; 
                    if (import.Namespace == ns) { 
                        return import;
                    } 
                }
            }
            return null;
        } 

        XmlQualifiedName ExportTypeMapping(TypeMapping mapping, string ns) { 
            if (mapping is ArrayMapping) 
                 return ExportArrayMapping((ArrayMapping)mapping, ns);
            else if (mapping is EnumMapping) 
                return ExportEnumMapping((EnumMapping)mapping, ns);
            else if (mapping is PrimitiveMapping) {
                PrimitiveMapping pm = (PrimitiveMapping)mapping;
                if (pm.TypeDesc.IsXsdType) { 
                    return ExportPrimitiveMapping(pm);
                } 
                else { 
                    return ExportNonXsdPrimitiveMapping(pm, ns);
                } 
            }
            else if (mapping is StructMapping)
                return ExportStructMapping((StructMapping)mapping, ns);
            else if (mapping is NullableMapping) 
                return ExportTypeMapping(((NullableMapping)mapping).BaseMapping, ns);
            else if (mapping is MembersMapping) 
                return ExportMembersMapping((MembersMapping)mapping, ns); 
            else
                throw new ArgumentException(Res.GetString(Res.XmlInternalError), "mapping"); 
        }

        XmlQualifiedName ExportNonXsdPrimitiveMapping(PrimitiveMapping mapping, string ns) {
            XmlSchemaType type = mapping.TypeDesc.DataType; 
            if (!SchemaContainsItem(type, UrtTypes.Namespace)) {
                AddSchemaItem(type, UrtTypes.Namespace, ns); 
            } 
            else {
                AddSchemaImport(UrtTypes.Namespace, ns); 
            }
            return new XmlQualifiedName(mapping.TypeDesc.DataType.Name, UrtTypes.Namespace);
        }
 
        XmlQualifiedName ExportPrimitiveMapping(PrimitiveMapping mapping) {
            return new XmlQualifiedName(mapping.TypeDesc.DataType.Name, XmlSchema.Namespace); 
        } 

        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);
                } 
                //
                XmlSchemaAttribute attr = new XmlSchemaAttribute();
                attr.RefName = 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 = 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);
        }

        void ExportElementAccessors(XmlSchemaGroupBase group, ElementAccessor[] accessors, bool repeats, bool valueTypeOptional, string ns) { 
            if (accessors.Length == 0) return;
            if (accessors.Length == 1) { 
                ExportElementAccessor(group, accessors[0], repeats, valueTypeOptional, ns); 
            }
            else { 
                XmlSchemaChoice choice = new XmlSchemaChoice();
                choice.MaxOccurs = repeats ? decimal.MaxValue : 1;
                choice.MinOccurs = repeats ? 0 : 1;
                for (int i = 0; i < accessors.Length; i++) 
                    ExportElementAccessor(choice, accessors[i], false, valueTypeOptional, ns);
 
                if (choice.Items.Count > 0) group.Items.Add(choice); 
            }
        } 


        void ExportElementAccessor(XmlSchemaGroupBase group, ElementAccessor accessor, bool repeats, bool valueTypeOptional, string ns) {
            XmlSchemaElement element = new XmlSchemaElement(); 
            element.MinOccurs = repeats || valueTypeOptional ? 0 : 1;
            element.MaxOccurs = repeats ? decimal.MaxValue : 1; 
            element.Name = accessor.Name; 
            element.IsNillable = accessor.IsNullable || accessor.Mapping is NullableMapping;
            element.Form = XmlSchemaForm.Unqualified; 
            element.SchemaTypeName = ExportTypeMapping(accessor.Mapping, accessor.Namespace);

            group.Items.Add(element);
        } 

        XmlQualifiedName ExportRootMapping(StructMapping mapping) { 
            if (!exportedRoot) { 
                exportedRoot = true;
                ExportDerivedMappings(mapping); 
            }
            return new XmlQualifiedName(Soap.UrType, XmlSchema.Namespace);
        }
 
        XmlQualifiedName ExportStructMapping(StructMapping mapping, string ns) {
            if (mapping.TypeDesc.IsRoot) return ExportRootMapping(mapping); 
            XmlSchemaComplexType type = (XmlSchemaComplexType)types[mapping]; 
            if (type == null) {
                if (!mapping.IncludeInSchema) throw new InvalidOperationException(Res.GetString(Res.XmlSoapCannotIncludeInSchema, mapping.TypeDesc.Name)); 
                CheckForDuplicateType(mapping.TypeName, mapping.Namespace);
                type = new XmlSchemaComplexType();
                type.Name = mapping.TypeName;
                types.Add(mapping, type); 
                AddSchemaItem(type, mapping.Namespace, ns);
                type.IsAbstract = mapping.TypeDesc.IsAbstract; 
 
                if (mapping.BaseMapping != null && mapping.BaseMapping.IncludeInSchema) {
                    XmlSchemaComplexContentExtension extension = new XmlSchemaComplexContentExtension(); 
                    extension.BaseTypeName = ExportStructMapping(mapping.BaseMapping, mapping.Namespace);
                    XmlSchemaComplexContent model = new XmlSchemaComplexContent();
                    model.Content = extension;
                    type.ContentModel = model; 
                }
                ExportTypeMembers(type, mapping.Members, mapping.Namespace); 
                ExportDerivedMappings(mapping); 
            }
            else { 
                AddSchemaImport(mapping.Namespace, ns);
            }
            return new XmlQualifiedName(type.Name, mapping.Namespace);
        } 

        XmlQualifiedName ExportMembersMapping(MembersMapping mapping, string ns) { 
            XmlSchemaComplexType type = (XmlSchemaComplexType)types[mapping]; 
            if(type == null) {
                CheckForDuplicateType(mapping.TypeName, mapping.Namespace); 
                type = new XmlSchemaComplexType();
                type.Name = mapping.TypeName;
                types.Add(mapping, type);
                AddSchemaItem(type, mapping.Namespace, ns); 
                ExportTypeMembers(type, mapping.Members, mapping.Namespace);
            } 
            else { 
                AddSchemaImport(mapping.Namespace, ns);
            } 
            return new XmlQualifiedName(type.Name, mapping.Namespace);
        }

        void ExportTypeMembers(XmlSchemaComplexType type, MemberMapping[] members, string ns) { 
            XmlSchemaGroupBase seq = new XmlSchemaSequence();
            for (int i = 0; i < members.Length; i++) { 
                MemberMapping member = members[i]; 
                if (member.Elements.Length > 0) {
                    bool valueTypeOptional = member.CheckSpecified != SpecifiedAccessor.None || member.CheckShouldPersist || !member.TypeDesc.IsValueType; 
                    ExportElementAccessors(seq, member.Elements, false, valueTypeOptional, ns);
                }
            }
            if (seq.Items.Count > 0) { 
                if (type.ContentModel != null) {
                    if (type.ContentModel.Content is XmlSchemaComplexContentExtension) 
                        ((XmlSchemaComplexContentExtension)type.ContentModel.Content).Particle = seq; 
                    else if (type.ContentModel.Content is XmlSchemaComplexContentRestriction)
                        ((XmlSchemaComplexContentRestriction)type.ContentModel.Content).Particle = seq; 
                    else
                        throw new InvalidOperationException(Res.GetString(Res.XmlInvalidContent, type.ContentModel.Content.GetType().Name));
                }
                else { 
                    type.Particle = seq;
                } 
            } 
        }
 
        void ExportDerivedMappings(StructMapping mapping) {
            for (StructMapping derived = mapping.DerivedMappings; derived != null; derived = derived.NextDerivedMapping) {
                if (derived.IncludeInSchema) ExportStructMapping(derived, mapping.TypeDesc.IsRoot ? null : mapping.Namespace);
            } 
        }
 
        XmlQualifiedName ExportEnumMapping(EnumMapping mapping, string ns) { 
            XmlSchemaSimpleType dataType = (XmlSchemaSimpleType)types[mapping];
            if (dataType == null) { 
                CheckForDuplicateType(mapping.TypeName, mapping.Namespace);
                dataType = new XmlSchemaSimpleType();
                dataType.Name = mapping.TypeName;
                types.Add(mapping, dataType); 
                AddSchemaItem(dataType, mapping.Namespace, ns);
 
                XmlSchemaSimpleTypeRestriction restriction = new XmlSchemaSimpleTypeRestriction(); 
                restriction.BaseTypeName = new XmlQualifiedName("string", XmlSchema.Namespace);
 
                for (int i = 0; i < mapping.Constants.Length; i++) {
                    ConstantMapping constant = mapping.Constants[i];
                    XmlSchemaEnumerationFacet enumeration = new XmlSchemaEnumerationFacet();
                    enumeration.Value = constant.XmlName; 
                    restriction.Facets.Add(enumeration);
                } 
                if (!mapping.IsFlags) { 
                    dataType.Content = restriction;
                } 
                else {
                    XmlSchemaSimpleTypeList list = new XmlSchemaSimpleTypeList();
                    XmlSchemaSimpleType enumType = new XmlSchemaSimpleType();
                    enumType.Content =  restriction; 
                    list.ItemType = enumType;
                    dataType.Content =  list; 
                } 
            }
            else { 
                AddSchemaImport(mapping.Namespace, ns);
            }
            return new XmlQualifiedName(mapping.TypeName, mapping.Namespace);
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK