557 lines
27 KiB
C#
557 lines
27 KiB
C#
//------------------------------------------------------------------------------
|
|
// <copyright file="ServiceDescriptionImporter.cs" company="Microsoft">
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// </copyright>
|
|
//------------------------------------------------------------------------------
|
|
|
|
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;
|
|
|
|
/// <include file='doc\ServiceDescriptionImporter.uex' path='docs/doc[@for="ServiceDescriptionImportWarnings"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
[Flags]
|
|
public enum ServiceDescriptionImportWarnings {
|
|
/// <include file='doc\ServiceDescriptionImporter.uex' path='docs/doc[@for="ServiceDescriptionImportWarnings.NoCodeGenerated"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
NoCodeGenerated = 0x1,
|
|
/// <include file='doc\ServiceDescriptionImporter.uex' path='docs/doc[@for="ServiceDescriptionImportWarnings.OptionalExtensionsIgnored"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
OptionalExtensionsIgnored = 0x2,
|
|
/// <include file='doc\ServiceDescriptionImporter.uex' path='docs/doc[@for="ServiceDescriptionImportWarnings.RequiredExtensionsIgnored"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
RequiredExtensionsIgnored = 0x4,
|
|
/// <include file='doc\ServiceDescriptionImporter.uex' path='docs/doc[@for="ServiceDescriptionImportWarnings.UnsupportedOperationsIgnored"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
UnsupportedOperationsIgnored = 0x8,
|
|
/// <include file='doc\ServiceDescriptionImporter.uex' path='docs/doc[@for="ServiceDescriptionImportWarnings.UnsupportedBindingsIgnored"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
UnsupportedBindingsIgnored = 0x10,
|
|
/// <include file='doc\ServiceDescriptionImporter.uex' path='docs/doc[@for="ServiceDescriptionImportWarnings.NoMethodsGenerated"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
NoMethodsGenerated = 0x20,
|
|
|
|
/// <include file='doc\ServiceDescriptionImporter.uex' path='docs/doc[@for="ServiceDescriptionImportWarnings.SchemaValidation"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
SchemaValidation = 0x40,
|
|
|
|
/// <include file='doc\ServiceDescriptionImporter.uex' path='docs/doc[@for="ServiceDescriptionImportWarnings.WSIConformance"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
WsiConformance = 0x80,
|
|
}
|
|
|
|
/// <include file='doc\ServiceDescriptionImporter.uex' path='docs/doc[@for="ServiceDescriptionImportStyle"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public enum ServiceDescriptionImportStyle {
|
|
/// <include file='doc\ServiceDescriptionImporter.uex' path='docs/doc[@for="ServiceDescriptionImportStyle.Client"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
[XmlEnum("client")]
|
|
Client,
|
|
/// <include file='doc\ServiceDescriptionImporter.uex' path='docs/doc[@for="ServiceDescriptionImportStyle.Server"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
[XmlEnum("server")]
|
|
Server,
|
|
/// <include file='doc\ServiceDescriptionImporter.uex' path='docs/doc[@for="ServiceDescriptionImportStyle.ServerInterface"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
[XmlEnum("serverInterface")]
|
|
ServerInterface,
|
|
}
|
|
|
|
/// <include file='doc\ServiceDescriptionImporter.uex' path='docs/doc[@for="ServiceDescriptionImporter"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
[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<Type> extensions;
|
|
|
|
/// <include file='doc\ServiceDescriptionImporter.uex' path='docs/doc[@for="ServiceDescriptionImporter.ServiceDescriptionImporter"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
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;
|
|
}
|
|
/// <include file='doc\ServiceDescriptionImporter.uex' path='docs/doc[@for="ServiceDescriptionImporter.ServiceDescriptions"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public ServiceDescriptionCollection ServiceDescriptions {
|
|
get { return serviceDescriptions; }
|
|
}
|
|
|
|
/// <include file='doc\ServiceDescriptionImporter.uex' path='docs/doc[@for="ServiceDescriptionImporter.Schemas"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public XmlSchemas Schemas {
|
|
get { return schemas; }
|
|
}
|
|
|
|
/// <include file='doc\ServiceDescriptionImporter.uex' path='docs/doc[@for="ServiceDescriptionImporter.Style"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
public ServiceDescriptionImportStyle Style {
|
|
get { return style; }
|
|
set { style = value; }
|
|
}
|
|
|
|
/// <include file='doc\ServiceDescriptionImporter.uex' path='docs/doc[@for="ServiceDescriptionImporter.CodeGenerationOptions"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
[ComVisible(false)]
|
|
public CodeGenerationOptions CodeGenerationOptions {
|
|
get { return options; }
|
|
set { options = value; }
|
|
}
|
|
|
|
internal CodeCompileUnit CodeCompileUnit {
|
|
get { return codeCompileUnit; }
|
|
}
|
|
|
|
/// <include file='doc\ServiceDescriptionImporter.uex' path='docs/doc[@for="ServiceDescriptionImporter.CodeGenerator"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
[ComVisible(false)]
|
|
public CodeDomProvider CodeGenerator {
|
|
get {
|
|
if (codeProvider == null)
|
|
codeProvider = new Microsoft.CSharp.CSharpCodeProvider();
|
|
return codeProvider;
|
|
}
|
|
set { codeProvider = value; }
|
|
}
|
|
|
|
internal List<Type> Extensions {
|
|
get {
|
|
if (extensions == null) {
|
|
extensions = new List<Type>();
|
|
}
|
|
return extensions;
|
|
}
|
|
}
|
|
/// <include file='doc\ServiceDescriptionImporter.uex' path='docs/doc[@for="ServiceDescriptionImporter.ProtocolName"]/*' />
|
|
/// <devdoc>
|
|
/// <para>[To be supplied.]</para>
|
|
/// </devdoc>
|
|
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; }
|
|
}
|
|
|
|
/// <include file='doc\ServiceDescriptionImporter.uex' path='docs/doc[@for="ServiceDescriptionImporter.AddServiceDescription"]/*' />
|
|
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);
|
|
}
|
|
|
|
/// <include file='doc\ServiceDescriptionImporter.uex' path='docs/doc[@for="ServiceDescriptionImporter.Import"]/*' />
|
|
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());
|
|
}
|
|
|
|
/// <include file='doc\ServiceDescriptionImporter.uex' path='docs/doc[@for="ServiceDescriptionImporter.GenerateWebReferences1"]/*' />
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|