ServiceDescriptionImporter.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Services / Web / System / Web / Services / Description / ServiceDescriptionImporter.cs / 1305376 / ServiceDescriptionImporter.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

namespace System.Web.Services.Description { 
 
    using System.Web.Services;
    using System.Web.Services.Protocols; 
    using System.Xml.Serialization;
    using System.Xml.Schema;
    using System.Collections;
    using System.Collections.Specialized; 
    using System.Collections.Generic;
    using System; 
    using System.Reflection; 
    using System.CodeDom.Compiler;
    using System.Web.Services.Configuration; 
    using System.Xml;
    using System.CodeDom;
    using System.Globalization;
    using System.Security.Permissions; 
    using System.Runtime.InteropServices;
 
    ///  
    /// 
    ///    [To be supplied.] 
    /// 
    [Flags]
    public enum ServiceDescriptionImportWarnings {
        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        NoCodeGenerated = 0x1,
        ///  
        /// 
        ///    [To be supplied.]
        /// 
        OptionalExtensionsIgnored = 0x2, 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        RequiredExtensionsIgnored = 0x4, 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        UnsupportedOperationsIgnored = 0x8,
        ///  
        ///  
        ///    [To be supplied.]
        ///  
        UnsupportedBindingsIgnored = 0x10,
        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        NoMethodsGenerated = 0x20, 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        SchemaValidation = 0x40,
 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        WsiConformance = 0x80, 
    }

    /// 
    ///  
    ///    [To be supplied.]
    ///  
    public enum ServiceDescriptionImportStyle { 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        [XmlEnum("client")]
        Client, 
        /// 
        ///  
        ///    [To be supplied.] 
        /// 
        [XmlEnum("server")] 
        Server,
        /// 
        /// 
        ///    [To be supplied.] 
        /// 
        [XmlEnum("serverInterface")] 
        ServerInterface, 
    }
 
    /// 
    /// 
    ///    [To be supplied.]
    ///  
    [PermissionSet(SecurityAction.InheritanceDemand, Name="FullTrust")]
    [PermissionSet(SecurityAction.LinkDemand, Name="FullTrust")] 
    public class ServiceDescriptionImporter { 
        ServiceDescriptionImportStyle style = ServiceDescriptionImportStyle.Client;
        ServiceDescriptionCollection serviceDescriptions = new ServiceDescriptionCollection(); 
        XmlSchemas schemas = new XmlSchemas(); // those external to SDLs
        XmlSchemas allSchemas = new XmlSchemas(); // all schemas, incl. those inside SDLs
        string protocolName;
        CodeGenerationOptions options = CodeGenerationOptions.GenerateOldAsync; 
        CodeCompileUnit codeCompileUnit;
        CodeDomProvider codeProvider; 
        ProtocolImporter[] importers; 
        XmlSchemas abstractSchemas = new XmlSchemas(); // all schemas containing abstract types
        XmlSchemas concreteSchemas = new XmlSchemas(); // all "real" xml schemas 
        List extensions;

        /// 
        ///  
        ///    [To be supplied.]
        ///  
        public ServiceDescriptionImporter() { 
            Type[] importerTypes = WebServicesSection.Current.ProtocolImporterTypes;
            importers = new ProtocolImporter[importerTypes.Length]; 
            for (int i = 0; i < importers.Length; i++) {
                importers[i] = (ProtocolImporter)Activator.CreateInstance(importerTypes[i]);
                importers[i].Initialize(this);
            } 
        }
 
        internal ServiceDescriptionImporter(CodeCompileUnit codeCompileUnit) : this() { 
            this.codeCompileUnit = codeCompileUnit;
        } 
        /// 
        /// 
        ///    [To be supplied.]
        ///  
        public ServiceDescriptionCollection ServiceDescriptions {
            get { return serviceDescriptions; } 
        } 

        ///  
        /// 
        ///    [To be supplied.]
        /// 
        public XmlSchemas Schemas { 
            get { return schemas; }
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        public ServiceDescriptionImportStyle Style {
            get { return style; } 
            set { style = value; }
        } 
 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        [ComVisible(false)]
        public CodeGenerationOptions CodeGenerationOptions { 
            get { return options; }
            set { options = value; } 
        } 

        internal CodeCompileUnit CodeCompileUnit { 
            get { return codeCompileUnit; }
        }

        ///  
        /// 
        ///    [To be supplied.] 
        ///  
        [ComVisible(false)]
        public CodeDomProvider CodeGenerator { 
            get {
                if (codeProvider == null)
                    codeProvider = new Microsoft.CSharp.CSharpCodeProvider();
                return codeProvider; 
            }
            set { codeProvider = value; } 
        } 

        internal List Extensions { 
            get {
                if (extensions == null) {
                    extensions = new List();
                } 
                return extensions;
            } 
        } 
        /// 
        ///  
        ///    [To be supplied.]
        /// 
        public String ProtocolName {
            get { return protocolName == null ? string.Empty : protocolName; } 
            set { protocolName = value; }
        } 
 
        ProtocolImporter FindImporterByName(string protocolName) {
            for (int i = 0; i < importers.Length; i++) { 
                ProtocolImporter importer = importers[i];
                if (string.Compare(ProtocolName, importer.ProtocolName, StringComparison.OrdinalIgnoreCase) == 0) {
                    return importer;
                } 
            }
            throw new ArgumentException(Res.GetString(Res.ProtocolWithNameIsNotRecognized1, protocolName), "protocolName"); 
        } 

        internal XmlSchemas AllSchemas { 
            get { return allSchemas; }
        }

        internal XmlSchemas AbstractSchemas { 
            get { return abstractSchemas; }
        } 
 
        internal XmlSchemas ConcreteSchemas {
            get { return concreteSchemas; } 
        }

        /// 
        public void AddServiceDescription(ServiceDescription serviceDescription, string appSettingUrlKey, string appSettingBaseUrl) { 
            if (serviceDescription == null)
                throw new ArgumentNullException("serviceDescription"); 
 
            serviceDescription.AppSettingUrlKey = appSettingUrlKey;
            serviceDescription.AppSettingBaseUrl = appSettingBaseUrl; 
            ServiceDescriptions.Add(serviceDescription);
        }

        ///  
        public ServiceDescriptionImportWarnings Import(CodeNamespace codeNamespace, CodeCompileUnit codeCompileUnit) {
            if (codeCompileUnit != null) { 
                codeCompileUnit.ReferencedAssemblies.Add("System.dll"); 
                codeCompileUnit.ReferencedAssemblies.Add("System.Xml.dll");
                codeCompileUnit.ReferencedAssemblies.Add("System.Web.Services.dll"); 
                codeCompileUnit.ReferencedAssemblies.Add("System.EnterpriseServices.dll");
            }
            return Import(codeNamespace, new ImportContext(new CodeIdentifiers(), false), new Hashtable(), new StringCollection());
        } 

        ///  
        public static StringCollection GenerateWebReferences(WebReferenceCollection webReferences, CodeDomProvider codeProvider, CodeCompileUnit codeCompileUnit, WebReferenceOptions options) { 
            if (codeCompileUnit != null) {
                codeCompileUnit.ReferencedAssemblies.Add("System.dll"); 
                codeCompileUnit.ReferencedAssemblies.Add("System.Xml.dll");
                codeCompileUnit.ReferencedAssemblies.Add("System.Web.Services.dll");
                codeCompileUnit.ReferencedAssemblies.Add("System.EnterpriseServices.dll");
            } 
            Hashtable namespaces = new Hashtable();
            Hashtable exportedMappings = new Hashtable(); 
            foreach (WebReference webReference in webReferences) { 
                ServiceDescriptionImporter importer = new ServiceDescriptionImporter(codeCompileUnit);
 
                // separate descriptions and schemas
                XmlSchemas schemas = new XmlSchemas();
                ServiceDescriptionCollection descriptions = new ServiceDescriptionCollection();
 
                foreach (DictionaryEntry entry in webReference.Documents) {
                    AddDocument((string)entry.Key, entry.Value, schemas, descriptions, webReference.ValidationWarnings); 
                } 

                importer.Schemas.Add(schemas); 
                foreach(ServiceDescription source in descriptions)
                    importer.AddServiceDescription(source, webReference.AppSettingUrlKey, webReference.AppSettingBaseUrl);
                importer.CodeGenerator = codeProvider;
                importer.ProtocolName = webReference.ProtocolName; 
                importer.Style = options.Style;
                importer.CodeGenerationOptions = options.CodeGenerationOptions; 
                foreach (string extensionType in options.SchemaImporterExtensions) { 
                    importer.Extensions.Add(Type.GetType(extensionType, true /*throwOnError*/));
                } 
                ImportContext context = Context(webReference.ProxyCode, namespaces, options.Verbose);

                webReference.Warnings = importer.Import(webReference.ProxyCode, context, exportedMappings, webReference.ValidationWarnings);
                if (webReference.ValidationWarnings.Count != 0) { 
                    webReference.Warnings |= ServiceDescriptionImportWarnings.SchemaValidation;
                } 
            } 

            StringCollection shareWarnings = new StringCollection(); 

            if (options.Verbose) {
                foreach (ImportContext context in namespaces.Values) {
                    foreach (string warning in context.Warnings) { 
                        shareWarnings.Add(warning);
                    } 
                } 
            }
            return shareWarnings; 
        }

        internal static ImportContext Context(CodeNamespace ns, Hashtable namespaces, bool verbose) {
            if (namespaces[ns.Name] == null) { 
                namespaces[ns.Name] = new ImportContext(new CodeIdentifiers(), true);
            } 
            return (ImportContext)namespaces[ns.Name]; 
        }
 
        internal static void AddDocument(string path, object document, XmlSchemas schemas, ServiceDescriptionCollection descriptions, StringCollection warnings) {
            ServiceDescription serviceDescription = document as ServiceDescription;
            if (serviceDescription != null) {
                descriptions.Add(serviceDescription); 
            }
            else { 
                XmlSchema schema = document as XmlSchema; 
                if (schema != null) {
                    schemas.Add(schema); 
                }
            }
        }
 
        private void FindUse(MessagePart part, out bool isEncoded, out bool isLiteral) {
            isEncoded = false; 
            isLiteral = false; 
            string messageName = part.Message.Name;
            Operation associatedOperation = null; 
            ServiceDescription description = part.Message.ServiceDescription;
            foreach (PortType portType in description.PortTypes) {
                foreach (Operation operation in portType.Operations) {
                    foreach (OperationMessage message in operation.Messages) { 
                        if (message.Message.Equals(new XmlQualifiedName(part.Message.Name, description.TargetNamespace))) {
                            associatedOperation = operation; 
                            FindUse(associatedOperation, description, messageName, ref isEncoded, ref isLiteral); 
                        }
                    } 
                }
            }
            if (associatedOperation == null)
                FindUse(null, description, messageName, ref isEncoded, ref isLiteral); 
        }
 
        private void FindUse(Operation operation, ServiceDescription description, string messageName, ref bool isEncoded, ref bool isLiteral) { 
            string targetNamespace = description.TargetNamespace;
            foreach (Binding binding in description.Bindings) { 
                if (operation != null && !new XmlQualifiedName(operation.PortType.Name, targetNamespace).Equals(binding.Type))
                    continue;
                foreach (OperationBinding bindingOperation in binding.Operations) {
                    if (bindingOperation.Input != null) foreach (object extension in bindingOperation.Input.Extensions) { 
                        if (operation != null) {
                            SoapBodyBinding body = extension as SoapBodyBinding; 
                            if (body != null && operation.IsBoundBy(bindingOperation)) { 
                                if (body.Use == SoapBindingUse.Encoded)
                                    isEncoded = true; 
                                else if (body.Use == SoapBindingUse.Literal)
                                    isLiteral = true;
                            }
                        } 
                        else {
                            SoapHeaderBinding header = extension as SoapHeaderBinding; 
                            if (header != null && header.Message.Name == messageName) { 
                                if (header.Use == SoapBindingUse.Encoded)
                                    isEncoded = true; 
                                else if (header.Use == SoapBindingUse.Literal)
                                    isLiteral = true;
                            }
                        } 
                    }
                    if (bindingOperation.Output != null) foreach (object extension in bindingOperation.Output.Extensions) { 
                        if (operation != null) { 
                            if (operation.IsBoundBy(bindingOperation)) {
                                SoapBodyBinding body = extension as SoapBodyBinding; 
                                if (body != null) {
                                    if (body.Use == SoapBindingUse.Encoded)
                                        isEncoded = true;
                                    else if (body.Use == SoapBindingUse.Literal) 
                                        isLiteral = true;
                                } 
                                else if (extension is MimeXmlBinding) 
                                    isLiteral = true;
                            } 
                        }
                        else {
                            SoapHeaderBinding header = extension as SoapHeaderBinding;
                            if (header != null && header.Message.Name == messageName) { 
                                if (header.Use == SoapBindingUse.Encoded)
                                    isEncoded = true; 
                                else if (header.Use == SoapBindingUse.Literal) 
                                    isLiteral = true;
                            } 
                        }
                    }
                }
            } 
        }
 
        private void AddImport(XmlSchema schema, Hashtable imports) { 
            if (schema == null || imports[schema] != null)
                return; 
            imports.Add(schema, schema);
            foreach (XmlSchemaExternal external in schema.Includes) {
                if (external is XmlSchemaImport) {
                    XmlSchemaImport import = (XmlSchemaImport)external; 
                    foreach(XmlSchema s in allSchemas.GetSchemas(import.Namespace)) {
                        AddImport(s, imports); 
                    } 
                }
            } 
        }

        private ServiceDescriptionImportWarnings Import(CodeNamespace codeNamespace, ImportContext importContext, Hashtable exportContext, StringCollection warnings) {
            allSchemas = new XmlSchemas(); 
            foreach (XmlSchema schema in schemas) {
                allSchemas.Add(schema); 
            } 
            foreach (ServiceDescription description in serviceDescriptions) {
                foreach (XmlSchema schema in description.Types.Schemas) { 
                    allSchemas.Add(schema);
                }
            }
            Hashtable references = new Hashtable(); 
            if (!allSchemas.Contains(ServiceDescription.Namespace)) {
                allSchemas.AddReference(ServiceDescription.Schema); 
                references[ServiceDescription.Schema] = ServiceDescription.Schema; 
            }
            if (!allSchemas.Contains(Soap.Encoding)) { 
                allSchemas.AddReference(ServiceDescription.SoapEncodingSchema);
                references[ServiceDescription.SoapEncodingSchema] = ServiceDescription.SoapEncodingSchema;
            }
            allSchemas.Compile(null, false); 

            // Segregate the schemas containing abstract types from those 
            // containing regular XML definitions.  This is important because 
            // when you import something returning the ur-type (object), then
            // you need to import ALL types/elements within ALL schemas.  We 
            // don't want the RPC-based types leaking over into the XML-based
            // element definitions.  This also occurs when you have derivation:
            // we need to search the schemas for derived types: but WHICH schemas
            // should we search. 
            foreach (ServiceDescription description in serviceDescriptions) {
                foreach (Message message in description.Messages) { 
                    foreach (MessagePart part in message.Parts) { 
                        bool isEncoded;
                        bool isLiteral; 
                        FindUse(part, out isEncoded, out isLiteral);
                        if (part.Element != null && !part.Element.IsEmpty) {
                            if (isEncoded) throw new InvalidOperationException(Res.GetString(Res.CanTSpecifyElementOnEncodedMessagePartsPart, part.Name, message.Name));
                            XmlSchemaElement element = (XmlSchemaElement)allSchemas.Find(part.Element, typeof(XmlSchemaElement)); 
                            if (element != null) {
                                AddSchema(element.Parent as XmlSchema, isEncoded, isLiteral, abstractSchemas, concreteSchemas, references); 
                                if (element.SchemaTypeName != null && !element.SchemaTypeName.IsEmpty) { 
                                    XmlSchemaType type = (XmlSchemaType)allSchemas.Find(element.SchemaTypeName, typeof(XmlSchemaType));
                                    if (type != null) { 
                                        AddSchema(type.Parent as XmlSchema, isEncoded, isLiteral, abstractSchemas, concreteSchemas, references);
                                    }
                                }
                            } 
                        }
                        if (part.Type != null && !part.Type.IsEmpty) { 
                            XmlSchemaType type = (XmlSchemaType)allSchemas.Find(part.Type, typeof(XmlSchemaType)); 
                            if (type != null) {
                                AddSchema(type.Parent as XmlSchema, isEncoded, isLiteral, abstractSchemas, concreteSchemas, references); 
                            }
                        }
                    }
                } 
            }
 
            Hashtable imports; 
            foreach (XmlSchemas xmlschemas in new XmlSchemas[] { abstractSchemas, concreteSchemas }) {
                // collect all imports 
                imports = new Hashtable();
                foreach (XmlSchema schema in xmlschemas) {
                    AddImport(schema, imports);
                } 
                // make sure we add them to the corresponding schema collections
                foreach (XmlSchema schema in imports.Keys) { 
                    if (references[schema] == null && !xmlschemas.Contains(schema)) { 
                        xmlschemas.Add(schema);
                    } 
                }
            }

            // If a schema was not referenced by either a literal or an encoded message part, 
            // add it to both collections. There's no way to tell which it should be.
            imports = new Hashtable(); 
            foreach (XmlSchema schema in allSchemas) { 
                if (!abstractSchemas.Contains(schema) && !concreteSchemas.Contains(schema)) {
                    AddImport(schema, imports); 
                }
            }

            // make sure we add them to the corresponding schema collections 
            foreach (XmlSchema schema in imports.Keys) {
                if (references[schema] != null) 
                    continue; 
                if (!abstractSchemas.Contains(schema)) {
                    abstractSchemas.Add(schema); 
                }
                if (!concreteSchemas.Contains(schema)) {
                    concreteSchemas.Add(schema);
                } 
            }
            if (abstractSchemas.Count > 0) { 
                foreach (XmlSchema schema in references.Values) { 
                    abstractSchemas.AddReference(schema);
                } 
                StringCollection schemaWarnings = SchemaCompiler.Compile(abstractSchemas);
                foreach (string warning in schemaWarnings)
                    warnings.Add(warning);
            } 
            if (concreteSchemas.Count > 0) {
                foreach (XmlSchema schema in references.Values) { 
                    concreteSchemas.AddReference(schema); 
                }
                StringCollection schemaWarnings = SchemaCompiler.Compile(concreteSchemas); 
                foreach (string warning in schemaWarnings)
                    warnings.Add(warning);
            }
            if (ProtocolName.Length > 0) { 
                // If a protocol was specified, only try that one
                ProtocolImporter importer = FindImporterByName(ProtocolName); 
                if (importer.GenerateCode(codeNamespace, importContext, exportContext)) return importer.Warnings; 
            }
            else { 
                // Otherwise, do "best" protocol (first one that generates something)
                for (int i = 0; i < importers.Length; i++) {
                    ProtocolImporter importer = importers[i];
                    if (importer.GenerateCode(codeNamespace, importContext, exportContext)) { 
                        return importer.Warnings;
                    } 
                } 
            }
            return ServiceDescriptionImportWarnings.NoCodeGenerated; 
        }

        private static void AddSchema(XmlSchema schema, bool isEncoded, bool isLiteral, XmlSchemas abstractSchemas, XmlSchemas concreteSchemas, Hashtable references) {
            if (schema != null) { 
                if (isEncoded && !abstractSchemas.Contains(schema)) {
                    if (references.Contains(schema)) { 
                        abstractSchemas.AddReference(schema); 
                    }
                    else { 
                        abstractSchemas.Add(schema);
                    }
                }
                if (isLiteral && !concreteSchemas.Contains(schema)) { 
                    if (references.Contains(schema)) {
                        concreteSchemas.AddReference(schema); 
                    } 
                    else {
                        concreteSchemas.Add(schema); 
                    }
                }
            }
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

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