< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.Xml.Serialization.Soap
Assembly: CoreWCF.Primitives
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Xml/Serialization/SoapSchemaExporter.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 1
Coverable lines: 1
Total lines: 478
Line coverage: 0%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor()100%110%

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/Xml/Serialization/SoapSchemaExporter.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System;
 5using System.Collections;
 6using System.Xml.Schema;
 7using System.Xml;
 8using System.ComponentModel;
 9using System.Diagnostics;
 10using System.Xml.Serialization;
 11using CoreWCF.Runtime;
 12
 13namespace CoreWCF.Xml.Serialization
 14{
 15    /// <include file='doc\SoapSchemaExporter.uex' path='docs/doc[@for="SoapSchemaExporter"]/*' />
 16    /// <internalonly/>
 17    public class SoapSchemaExporter
 18    {
 19        internal const XmlSchemaForm elementFormDefault = XmlSchemaForm.Qualified;
 20        XmlSchemas schemas;
 21        Hashtable types = new Hashtable();      // StructMapping/EnumMapping -> XmlSchemaComplexType/XmlSchemaSimpleType
 22        bool exportedRoot;
 23        object scope;
 24        XmlDocument document;
 25
 26        static XmlQualifiedName ArrayQName = new XmlQualifiedName(Soap.Array, Soap.Encoding);
 27        static XmlQualifiedName ArrayTypeQName = new XmlQualifiedName(Soap.ArrayType, Soap.Encoding);
 28
 29        /// <include file='doc\SoapSchemaExporter.uex' path='docs/doc[@for="SoapSchemaExporter.SoapSchemaExporter"]/*' /
 30        /// <devdoc>
 31        ///    <para>[To be supplied.]</para>
 32        /// </devdoc>
 33        public SoapSchemaExporter(XmlSchemas schemas)
 34        {
 35            this.schemas = schemas;
 36        }
 37
 38        //        /// <include file='doc\SoapSchemaExporter.uex' path='docs/doc[@for="SoapSchemaExporter.ExportTypeMappi
 39        //        /// <devdoc>
 40        //        ///    <para>[To be supplied.]</para>
 41        //        /// </devdoc>
 42        //        public void ExportTypeMapping(XmlTypeMapping xmlTypeMapping)
 43        //        {
 44        //            CheckScope(xmlTypeMapping.Scope);
 45        //            ExportTypeMapping(xmlTypeMapping.Mapping, null);
 46        //        }
 47
 48        /// <include file='doc\SoapSchemaExporter.uex' path='docs/doc[@for="SoapSchemaExporter.ExportMembersMapping"]/*'
 49        /// <devdoc>
 50        ///    <para>[To be supplied.]</para>
 51        /// </devdoc>
 52        public void ExportMembersMapping(XmlMembersMapping xmlMembersMapping)
 53        {
 54            ExportMembersMapping(xmlMembersMapping, false);
 55        }
 56
 57        /// <include file='doc\SoapSchemaExporter.uex' path='docs/doc[@for="SoapSchemaExporter.ExportMembersMapping1"]/*
 58        /// <devdoc>
 59        ///    <para>[To be supplied.]</para>
 60        /// </devdoc>
 61        public void ExportMembersMapping(XmlMembersMapping xmlMembersMapping, bool exportEnclosingType)
 62        {
 63            CheckScope(xmlMembersMapping.GetScope());
 64            var membersMapping = xmlMembersMapping.GetAccessor().Mapping.AsMembersMappingSurrogate();
 65            if (exportEnclosingType)
 66            {
 67                Fx.Assert("Not expecting to export enclosing type");
 68                //ExportTypeMapping(membersMapping, null);
 69            }
 70            else
 71            {
 72                foreach (MemberMappingSurrogate memberMapping in membersMapping.Members)
 73                {
 74                    if (memberMapping.Elements.Length > 0)
 75                        ExportTypeMapping(memberMapping.Elements[0].Mapping, null);
 76                }
 77            }
 78        }
 79
 80        void CheckScope(object scope)
 81        {
 82            if (this.scope == null)
 83            {
 84                this.scope = scope;
 85            }
 86            else if (this.scope != scope)
 87            {
 88                throw new InvalidOperationException(SR.XmlMappingsScopeMismatch);
 89            }
 90        }
 91
 92        internal XmlDocument Document
 93        {
 94            get
 95            {
 96                if (document == null) document = new XmlDocument();
 97                return document;
 98            }
 99        }
 100
 101        void CheckForDuplicateType(string newTypeName, string newNamespace)
 102        {
 103            XmlSchema schema = schemas[newNamespace];
 104            if (schema != null)
 105            {
 106                foreach (XmlSchemaObject o in schema.Items)
 107                {
 108                    XmlSchemaType type = o as XmlSchemaType;
 109                    if (type != null && type.Name == newTypeName)
 110                        throw new InvalidOperationException(SR.Format(SR.XmlDuplicateTypeName, newTypeName, newNamespace
 111
 112                }
 113            }
 114        }
 115
 116        void AddSchemaItem(XmlSchemaObject item, string ns, string referencingNs)
 117        {
 118            if (!SchemaContainsItem(item, ns))
 119            {
 120                XmlSchema schema = schemas[ns];
 121                if (schema == null)
 122                {
 123                    schema = new XmlSchema();
 124                    schema.TargetNamespace = ns == null || ns.Length == 0 ? null : ns;
 125                    schema.ElementFormDefault = elementFormDefault;
 126                    schemas.Add(schema);
 127                }
 128                schema.Items.Add(item);
 129            }
 130            if (referencingNs != null)
 131                AddSchemaImport(ns, referencingNs);
 132        }
 133
 134        void AddSchemaImport(string ns, string referencingNs)
 135        {
 136            if (referencingNs == null || ns == null) return;
 137            if (ns == referencingNs) return;
 138            XmlSchema schema = schemas[referencingNs];
 139            if (schema == null) throw new InvalidOperationException(SR.Format(SR.XmlMissingSchema, referencingNs));
 140            if (ns.Length > 0 && FindImport(schema, ns) == null)
 141            {
 142                XmlSchemaImport import = new XmlSchemaImport();
 143                import.Namespace = ns;
 144                schema.Includes.Add(import);
 145            }
 146        }
 147
 148        bool SchemaContainsItem(XmlSchemaObject item, string ns)
 149        {
 150            XmlSchema schema = schemas[ns];
 151            if (schema != null)
 152            {
 153                return schema.Items.Contains(item);
 154            }
 155            return false;
 156        }
 157
 158        XmlSchemaImport FindImport(XmlSchema schema, string ns)
 159        {
 160            foreach (object item in schema.Includes)
 161            {
 162                if (item is XmlSchemaImport)
 163                {
 164                    XmlSchemaImport import = (XmlSchemaImport)item;
 165                    if (import.Namespace == ns)
 166                    {
 167                        return import;
 168                    }
 169                }
 170            }
 171            return null;
 172        }
 173
 174        XmlQualifiedName ExportTypeMapping(MappingSurrogate mapping, string ns)
 175        {
 176            if (mapping.IsArrayMapping)
 177                return ExportArrayMapping(mapping.AsArrayMappingSurrogate(), ns);
 178            else if (mapping.IsEnumMapping)
 179                return ExportEnumMapping(mapping.AsEnumMappingSurrogate(), ns);
 180            else if (mapping.IsPrimitiveMapping)
 181            {
 182                PrimitiveMappingSurrogate pm = mapping.AsPrimitiveMappingSurrogate();
 183                if (pm.TypeDesc.IsXsdType)
 184                {
 185                    return ExportPrimitiveMapping(pm);
 186                }
 187                else
 188                {
 189                    return ExportNonXsdPrimitiveMapping(pm, ns);
 190                }
 191            }
 192            else if (mapping.IsStructMapping)
 193                return ExportStructMapping(mapping.AsStructMappingSurrogate(), ns);
 194            else if (mapping.IsNullableMapping)
 195                return ExportTypeMapping(mapping.AsNullableMappingSurrogate().BaseMapping, ns);
 196            else if (mapping.IsMembersMapping)
 197                return ExportMembersMapping(mapping.AsMembersMappingSurrogate(), ns);
 198            else
 199                throw new ArgumentException(SR.XmlInternalError, "mapping");
 200        }
 201
 202        XmlQualifiedName ExportNonXsdPrimitiveMapping(PrimitiveMappingSurrogate mapping, string ns)
 203        {
 204            XmlSchemaType type = mapping.TypeDesc.DataType;
 205            if (!SchemaContainsItem(type, UrtTypes.Namespace))
 206            {
 207                AddSchemaItem(type, UrtTypes.Namespace, ns);
 208            }
 209            else
 210            {
 211                AddSchemaImport(UrtTypes.Namespace, ns);
 212            }
 213            return new XmlQualifiedName(mapping.TypeDesc.DataType.Name, UrtTypes.Namespace);
 214        }
 215
 216        XmlQualifiedName ExportPrimitiveMapping(PrimitiveMappingSurrogate mapping)
 217        {
 218            return new XmlQualifiedName(mapping.TypeDesc.DataType.Name, XmlSchema.Namespace);
 219        }
 220
 221        XmlQualifiedName ExportArrayMapping(ArrayMappingSurrogate mapping, string ns)
 222        {
 223            // for the Rpc ArrayMapping different mappings could have the same schema type
 224            // we link all mappings corresponding to the same type together
 225            // loop through all mapping that will map to the same complexType, and export only one,
 226            // the obvious choice is the last one.
 227            while (mapping.Next != null)
 228            {
 229                mapping = mapping.Next;
 230            }
 231
 232            XmlSchemaComplexType type = (XmlSchemaComplexType)types[mapping];
 233            if (type == null)
 234            {
 235                CheckForDuplicateType(mapping.TypeName, mapping.Namespace);
 236                type = new XmlSchemaComplexType();
 237                type.Name = mapping.TypeName;
 238                types.Add(mapping, type);
 239
 240                // we need to add the type first, to make sure that the schema get created
 241                AddSchemaItem(type, mapping.Namespace, ns);
 242                AddSchemaImport(Soap.Encoding, mapping.Namespace);
 243                AddSchemaImport(Wsdl.Namespace, mapping.Namespace);
 244
 245                XmlSchemaComplexContentRestriction restriction = new XmlSchemaComplexContentRestriction();
 246                XmlQualifiedName qname = ExportTypeMapping(mapping.Elements[0].Mapping, mapping.Namespace);
 247
 248                if (qname.IsEmpty)
 249                {
 250                    // this is a root mapping
 251                    qname = new XmlQualifiedName(Soap.UrType, XmlSchema.Namespace);
 252                }
 253                //<attribute ref="soapenc:arrayType" wsdl:arrayType="xsd:float[]"/>
 254                XmlSchemaAttribute attr = new XmlSchemaAttribute();
 255                attr.RefName = ArrayTypeQName;
 256                XmlAttribute attribute = XmlMembersMappingExtensions.CreateXmlAttribute("wsdl", Wsdl.ArrayType, Wsdl.Nam
 257                attribute.Value = qname.Namespace + ":" + qname.Name + "[]";
 258
 259                attr.UnhandledAttributes = new XmlAttribute[] { attribute };
 260                restriction.Attributes.Add(attr);
 261                restriction.BaseTypeName = ArrayQName;
 262                XmlSchemaComplexContent model = new XmlSchemaComplexContent();
 263                model.Content = restriction;
 264                type.ContentModel = model;
 265                if (qname.Namespace != XmlSchema.Namespace)
 266                    AddSchemaImport(qname.Namespace, mapping.Namespace);
 267            }
 268            else
 269            {
 270                AddSchemaImport(mapping.Namespace, ns);
 271            }
 272            return new XmlQualifiedName(mapping.TypeName, mapping.Namespace);
 273        }
 274
 275        void ExportElementAccessors(XmlSchemaGroupBase group, ElementAccessorSurrogate[] accessors, bool repeats, bool v
 276        {
 277            if (accessors.Length == 0) return;
 278            if (accessors.Length == 1)
 279            {
 280                ExportElementAccessor(group, accessors[0], repeats, valueTypeOptional, ns);
 281            }
 282            else
 283            {
 284                XmlSchemaChoice choice = new XmlSchemaChoice();
 285                choice.MaxOccurs = repeats ? decimal.MaxValue : 1;
 286                choice.MinOccurs = repeats ? 0 : 1;
 287                for (int i = 0; i < accessors.Length; i++)
 288                    ExportElementAccessor(choice, accessors[i], false, valueTypeOptional, ns);
 289
 290                if (choice.Items.Count > 0) group.Items.Add(choice);
 291            }
 292        }
 293
 294
 295        void ExportElementAccessor(XmlSchemaGroupBase group, ElementAccessorSurrogate accessor, bool repeats, bool value
 296        {
 297            XmlSchemaElement element = new XmlSchemaElement();
 298            element.MinOccurs = repeats || valueTypeOptional ? 0 : 1;
 299            element.MaxOccurs = repeats ? decimal.MaxValue : 1;
 300            element.Name = accessor.Name;
 301            element.IsNillable = accessor.IsNullable || accessor.Mapping.IsNullableMapping;
 302            element.Form = XmlSchemaForm.Unqualified;
 303            element.SchemaTypeName = ExportTypeMapping(accessor.Mapping, accessor.Namespace);
 304
 305            group.Items.Add(element);
 306        }
 307
 308        XmlQualifiedName ExportRootMapping(StructMappingSurrogate mapping)
 309        {
 310            if (!exportedRoot)
 311            {
 312                exportedRoot = true;
 313                ExportDerivedMappings(mapping);
 314            }
 315            return new XmlQualifiedName(Soap.UrType, XmlSchema.Namespace);
 316        }
 317
 318        XmlQualifiedName ExportStructMapping(StructMappingSurrogate mapping, string ns)
 319        {
 320            if (mapping.TypeDesc.IsRoot) return ExportRootMapping(mapping);
 321            XmlSchemaComplexType type = (XmlSchemaComplexType)types[mapping];
 322            if (type == null)
 323            {
 324                if (!mapping.IncludeInSchema) throw new InvalidOperationException(SR.Format(SR.XmlSoapCannotIncludeInSch
 325                CheckForDuplicateType(mapping.TypeName, mapping.Namespace);
 326                type = new XmlSchemaComplexType();
 327                type.Name = mapping.TypeName;
 328                types.Add(mapping, type);
 329                AddSchemaItem(type, mapping.Namespace, ns);
 330                type.IsAbstract = mapping.TypeDesc.IsAbstract;
 331
 332                if (mapping.BaseMapping != null && mapping.BaseMapping.IncludeInSchema)
 333                {
 334                    XmlSchemaComplexContentExtension extension = new XmlSchemaComplexContentExtension();
 335                    extension.BaseTypeName = ExportStructMapping(mapping.BaseMapping, mapping.Namespace);
 336                    XmlSchemaComplexContent model = new XmlSchemaComplexContent();
 337                    model.Content = extension;
 338                    type.ContentModel = model;
 339                }
 340                ExportTypeMembers(type, mapping.Members, mapping.Namespace);
 341                ExportDerivedMappings(mapping);
 342            }
 343            else
 344            {
 345                AddSchemaImport(mapping.Namespace, ns);
 346            }
 347            return new XmlQualifiedName(type.Name, mapping.Namespace);
 348        }
 349
 350        XmlQualifiedName ExportMembersMapping(MembersMappingSurrogate mapping, string ns)
 351        {
 352            XmlSchemaComplexType type = (XmlSchemaComplexType)types[mapping];
 353            if (type == null)
 354            {
 355                CheckForDuplicateType(mapping.TypeName, mapping.Namespace);
 356                type = new XmlSchemaComplexType();
 357                type.Name = mapping.TypeName;
 358                types.Add(mapping, type);
 359                AddSchemaItem(type, mapping.Namespace, ns);
 360                ExportTypeMembers(type, mapping.Members, mapping.Namespace);
 361            }
 362            else
 363            {
 364                AddSchemaImport(mapping.Namespace, ns);
 365            }
 366            return new XmlQualifiedName(type.Name, mapping.Namespace);
 367        }
 368
 369        void ExportTypeMembers(XmlSchemaComplexType type, MemberMappingSurrogate[] members, string ns)
 370        {
 371            XmlSchemaGroupBase seq = new XmlSchemaSequence();
 372            for (int i = 0; i < members.Length; i++)
 373            {
 374                MemberMappingSurrogate member = members[i];
 375                if (member.Elements.Length > 0)
 376                {
 377                    bool valueTypeOptional = member.CheckSpecified != MemberMappingSurrogate.SpecifiedAccessor.None || m
 378                    ExportElementAccessors(seq, member.Elements, false, valueTypeOptional, ns);
 379                }
 380            }
 381            if (seq.Items.Count > 0)
 382            {
 383                if (type.ContentModel != null)
 384                {
 385                    if (type.ContentModel.Content is XmlSchemaComplexContentExtension)
 386                        ((XmlSchemaComplexContentExtension)type.ContentModel.Content).Particle = seq;
 387                    else if (type.ContentModel.Content is XmlSchemaComplexContentRestriction)
 388                        ((XmlSchemaComplexContentRestriction)type.ContentModel.Content).Particle = seq;
 389                    else
 390                        throw new InvalidOperationException(SR.Format(SR.XmlInvalidContent, type.ContentModel.Content.Ge
 391                }
 392                else
 393                {
 394                    type.Particle = seq;
 395                }
 396            }
 397        }
 398
 399        void ExportDerivedMappings(StructMappingSurrogate mapping)
 400        {
 401            for (StructMappingSurrogate derived = mapping.DerivedMappings; derived != null; derived = derived.NextDerive
 402            {
 403                if (derived.IncludeInSchema) ExportStructMapping(derived, mapping.TypeDesc.IsRoot ? null : mapping.Names
 404            }
 405        }
 406
 407        XmlQualifiedName ExportEnumMapping(EnumMappingSurrogate mapping, string ns)
 408        {
 409            XmlSchemaSimpleType dataType = (XmlSchemaSimpleType)types[mapping];
 410            if (dataType == null)
 411            {
 412                CheckForDuplicateType(mapping.TypeName, mapping.Namespace);
 413                dataType = new XmlSchemaSimpleType();
 414                dataType.Name = mapping.TypeName;
 415                types.Add(mapping, dataType);
 416                AddSchemaItem(dataType, mapping.Namespace, ns);
 417
 418                XmlSchemaSimpleTypeRestriction restriction = new XmlSchemaSimpleTypeRestriction();
 419                restriction.BaseTypeName = new XmlQualifiedName("string", XmlSchema.Namespace);
 420
 421                for (int i = 0; i < mapping.Constants.Length; i++)
 422                {
 423                    ConstantMappingSurrogate constant = mapping.Constants[i];
 424                    XmlSchemaEnumerationFacet enumeration = new XmlSchemaEnumerationFacet();
 425                    enumeration.Value = constant.XmlName;
 426                    restriction.Facets.Add(enumeration);
 427                }
 428                if (!mapping.IsFlags)
 429                {
 430                    dataType.Content = restriction;
 431                }
 432                else
 433                {
 434                    XmlSchemaSimpleTypeList list = new XmlSchemaSimpleTypeList();
 435                    XmlSchemaSimpleType enumType = new XmlSchemaSimpleType();
 436                    enumType.Content = restriction;
 437                    list.ItemType = enumType;
 438                    dataType.Content = list;
 439                }
 440            }
 441            else
 442            {
 443                AddSchemaImport(mapping.Namespace, ns);
 444            }
 445            return new XmlQualifiedName(mapping.TypeName, mapping.Namespace);
 446        }
 447    }
 448
 449    internal class Soap
 450    {
 0451        private Soap() { }
 452        internal const string Encoding = "http://schemas.xmlsoap.org/soap/encoding/";
 453        internal const string UrType = "anyType";
 454        internal const string Array = "Array";
 455        internal const string ArrayType = "arrayType";
 456    }
 457
 458    //internal class Soap12
 459    //{
 460    //    private Soap12() { }
 461    //    internal const string Encoding = "http://www.w3.org/2003/05/soap-encoding";
 462    //    internal const string RpcNamespace = "http://www.w3.org/2003/05/soap-rpc";
 463    //    internal const string RpcResult = "result";
 464    //}
 465
 466    internal class Wsdl
 467    {
 468        private Wsdl() { }
 469        internal const string Namespace = "http://schemas.xmlsoap.org/wsdl/";
 470        internal const string ArrayType = "arrayType";
 471    }
 472
 473    internal class UrtTypes
 474    {
 475        private UrtTypes() { }
 476        internal const string Namespace = "http://microsoft.com/wsdl/types/";
 477    }
 478}

Methods/Properties

.ctor()