|
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.ServiceModel.Description
{
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Dispatcher;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using WsdlNS = System.Web.Services.Description;
abstract class MessageContractExporter
{
readonly protected WsdlContractConversionContext contractContext;
readonly protected WsdlExporter exporter;
readonly protected OperationDescription operation;
readonly protected IOperationBehavior extension;
static internal void ExportMessageBinding(WsdlExporter exporter, WsdlEndpointConversionContext endpointContext, Type messageContractExporterType, OperationDescription operation)
{
new MessageBindingExporter(exporter, endpointContext).ExportMessageBinding(operation, messageContractExporterType);
}
protected abstract object OnExportMessageContract();
protected abstract void ExportHeaders(int messageIndex, object state);
protected abstract void ExportBody(int messageIndex, object state);
protected abstract void ExportKnownTypes();
protected abstract bool IsRpcStyle();
protected abstract bool IsEncoded();
protected abstract object GetExtensionData();
protected MessageExportContext ExportedMessages
{
get { return GetMessageExportContext(exporter); }
}
void AddElementToSchema(XmlSchemaElement element, string elementNs, XmlSchemaSet schemaSet)
{
OperationDescription parentOperation = this.operation;
if (parentOperation.OperationMethod != null)
{
XmlQualifiedName qname = new XmlQualifiedName(element.Name, elementNs);
OperationElement existingElement;
if (ExportedMessages.ElementTypes.TryGetValue(qname, out existingElement))
{
if (existingElement.Operation.OperationMethod == parentOperation.OperationMethod)
return;
if (!SchemaHelper.IsMatch(element, existingElement.Element))
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.CannotHaveTwoOperationsWithTheSameElement5, parentOperation.OperationMethod.DeclaringType, parentOperation.OperationMethod.Name, qname, existingElement.Operation.OperationMethod.DeclaringType, existingElement.Operation.Name)));
}
return;
}
else
{
ExportedMessages.ElementTypes.Add(qname, new OperationElement(element, parentOperation));
}
}
SchemaHelper.AddElementToSchema(element, SchemaHelper.GetSchema(elementNs, schemaSet), schemaSet);
}
static MessageExportContext GetMessageExportContext(WsdlExporter exporter)
{
object messageExportContext;
if (!exporter.State.TryGetValue(typeof(MessageExportContext), out messageExportContext))
{
messageExportContext = new MessageExportContext();
exporter.State[typeof(MessageExportContext)] = messageExportContext;
}
return (MessageExportContext)messageExportContext;
}
protected MessageContractExporter(WsdlExporter exporter, WsdlContractConversionContext context, OperationDescription operation, IOperationBehavior extension)
{
this.exporter = exporter;
this.contractContext = context;
this.operation = operation;
this.extension = extension;
}
internal void ExportMessageContract()
{
if (extension == null)
return;
object state = OnExportMessageContract();
OperationFormatter.Validate(operation, IsRpcStyle(), IsEncoded());
ExportKnownTypes();
for (int messageIndex = 0; messageIndex < operation.Messages.Count; messageIndex++)
ExportMessage(messageIndex, state);
if (!operation.IsOneWay)
{
ExportFaults(state);
}
foreach (XmlSchema schema in exporter.GeneratedXmlSchemas.Schemas())
EnsureXsdImport(schema.TargetNamespace, contractContext.WsdlPortType.ServiceDescription);
}
void ExportMessage(int messageIndex, object state)
{
try
{
MessageDescription description = operation.Messages[messageIndex];
WsdlNS.Message wsdlMessage;
if (CreateMessage(description, messageIndex, out wsdlMessage))
{
if (description.IsUntypedMessage)
{
ExportAnyMessage(wsdlMessage, description.Body.ReturnValue ?? description.Body.Parts[0]);
return;
}
bool isRequest = (messageIndex == 0);
StreamFormatter streamFormatter = StreamFormatter.Create(description, operation.Name, isRequest);
if (streamFormatter != null)
{
ExportStreamBody(wsdlMessage, streamFormatter.WrapperName, streamFormatter.WrapperNamespace, streamFormatter.PartName, streamFormatter.PartNamespace, IsRpcStyle(), false /*IsOperationInherited(operation)*/);
}
else
{
ExportBody(messageIndex, state);
}
}
if (!description.IsUntypedMessage)
{
ExportHeaders(messageIndex, state);
}
}
finally
{
Compile();
}
}
protected virtual void ExportFaults(object state)
{
foreach (FaultDescription fault in operation.Faults)
{
ExportFault(fault);
}
}
protected bool IsOperationInherited()
{
return operation.DeclaringContract != contractContext.Contract;
}
void ExportAnyMessage(WsdlNS.Message message, MessagePartDescription part)
{
XmlSchemaSet schemas = this.exporter.GeneratedXmlSchemas;
XmlSchema schema = SchemaHelper.GetSchema(DataContractSerializerMessageContractImporter.GenericMessageTypeName.Namespace, schemas);
if (!schema.SchemaTypes.Contains(DataContractSerializerMessageContractImporter.GenericMessageTypeName))
{
XmlSchemaComplexType genericMessageType = new XmlSchemaComplexType();
genericMessageType.Name = DataContractSerializerMessageContractImporter.GenericMessageTypeName.Name;
XmlSchemaSequence bodySequence = new XmlSchemaSequence();
genericMessageType.Particle = bodySequence;
XmlSchemaAny anyElement = new XmlSchemaAny();
anyElement.MinOccurs = 0;
anyElement.MaxOccurs = decimal.MaxValue;
anyElement.Namespace = "##any";
bodySequence.Items.Add(anyElement);
SchemaHelper.AddTypeToSchema(genericMessageType, schema, schemas);
}
string partName = string.IsNullOrEmpty(part.UniquePartName) ? part.Name : part.UniquePartName;
WsdlNS.MessagePart wsdlPart = AddMessagePart(message, partName, XmlQualifiedName.Empty, DataContractSerializerMessageContractImporter.GenericMessageTypeName);
part.UniquePartName = wsdlPart.Name;
}
protected void ExportStreamBody(WsdlNS.Message message, string wrapperName, string wrapperNs, string partName, string partNs, bool isRpc, bool skipSchemaExport)
{
XmlSchemaSet schemas = this.exporter.GeneratedXmlSchemas;
XmlSchema schema = SchemaHelper.GetSchema(DataContractSerializerMessageContractImporter.StreamBodyTypeName.Namespace, schemas);
if (!schema.SchemaTypes.Contains(DataContractSerializerMessageContractImporter.StreamBodyTypeName))
{
XmlSchemaSimpleType streamBodyType = new XmlSchemaSimpleType();
streamBodyType.Name = DataContractSerializerMessageContractImporter.StreamBodyTypeName.Name;
XmlSchemaSimpleTypeRestriction contentRestriction = new XmlSchemaSimpleTypeRestriction();
contentRestriction.BaseTypeName = XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.Base64Binary).QualifiedName;
streamBodyType.Content = contentRestriction;
SchemaHelper.AddTypeToSchema(streamBodyType, schema, schemas);
}
XmlSchemaSequence wrapperSequence = null;
if (!isRpc && wrapperName != null)
wrapperSequence = ExportWrappedPart(message, wrapperName, wrapperNs, schemas, skipSchemaExport);
MessagePartDescription streamPart = new MessagePartDescription(partName, partNs);
ExportMessagePart(message, streamPart, DataContractSerializerMessageContractImporter.StreamBodyTypeName, null/*xsdType*/, false/*isOptional*/, false/*isNillable*/, skipSchemaExport, !isRpc, wrapperNs, wrapperSequence, schemas);
}
void ExportFault(FaultDescription fault)
{
WsdlNS.Message faultMessage = new WsdlNS.Message();
faultMessage.Name = GetFaultMessageName(fault.Name);
XmlQualifiedName elementName = ExportFaultElement(fault);
this.contractContext.WsdlPortType.ServiceDescription.Messages.Add(faultMessage);
AddMessagePart(faultMessage, "detail", elementName, null);
// create a wsdl:fault to put inside the wsdl:portType/wsdl:operation
WsdlNS.OperationFault operationFault = contractContext.GetOperationFault(fault);
WsdlExporter.WSAddressingHelper.AddActionAttribute(fault.Action, operationFault, this.exporter.PolicyVersion);
operationFault.Message = new XmlQualifiedName(faultMessage.Name, faultMessage.ServiceDescription.TargetNamespace);
}
XmlQualifiedName ExportFaultElement(FaultDescription fault)
{
XmlSchemaType xsdType;
XmlQualifiedName typeName = ExportType(fault.DetailType, fault.Name, operation.Name, out xsdType);
XmlQualifiedName elementName;
if (XmlName.IsNullOrEmpty(fault.ElementName))
{
elementName = DataContractExporter.GetRootElementName(fault.DetailType);
if (elementName == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxFaultTypeAnonymous, operation.Name, fault.DetailType.FullName)));
}
else
elementName = new XmlQualifiedName(fault.ElementName.EncodedName, fault.Namespace);
ExportGlobalElement(elementName.Name, elementName.Namespace, true/*isNillable*/, typeName, xsdType, this.exporter.GeneratedXmlSchemas);
return elementName;
}
protected XsdDataContractExporter DataContractExporter
{
get
{
object dataContractExporter;
if (!exporter.State.TryGetValue(typeof(XsdDataContractExporter), out dataContractExporter))
{
dataContractExporter = new XsdDataContractExporter(this.exporter.GeneratedXmlSchemas);
exporter.State.Add(typeof(XsdDataContractExporter), dataContractExporter);
}
return (XsdDataContractExporter)dataContractExporter;
}
}
protected XmlQualifiedName ExportType(Type type, string partName, string operationName, out XmlSchemaType xsdType)
{
xsdType = null;
if (type == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxExportMustHaveType, operationName, partName)));
if (type == typeof(void))
return null;
DataContractExporter.Export(type);
XmlQualifiedName typeName = DataContractExporter.GetSchemaTypeName(type);
if (IsNullOrEmpty(typeName))
xsdType = DataContractExporter.GetSchemaType(type);
return typeName;
}
protected XmlSchemaSet SchemaSet
{
get
{
return exporter.GeneratedXmlSchemas;
}
}
static protected WsdlNS.MessagePart AddMessagePart(WsdlNS.Message message, string partName, XmlQualifiedName elementName, XmlQualifiedName typeName)
{
if (message.Parts[partName] != null)
{
if (IsNullOrEmpty(elementName))
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.SFxPartNameMustBeUniqueInRpc, partName)));
int i = 1;
while (message.Parts[partName + i] != null)
{
if (i == Int32.MaxValue)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.SFxTooManyPartsWithSameName, partName)));
i++;
}
partName = partName + i.ToString(CultureInfo.InvariantCulture);
}
WsdlNS.MessagePart part = new WsdlNS.MessagePart();
part.Name = partName;
part.Element = elementName;
part.Type = typeName;
message.Parts.Add(part);
EnsureXsdImport(IsNullOrEmpty(elementName) ? typeName.Namespace : elementName.Namespace, message.ServiceDescription);
return part;
}
static void EnsureXsdImport(string ns, WsdlNS.ServiceDescription wsdl)
{
string refNs = wsdl.TargetNamespace;
if (!refNs.EndsWith("/", StringComparison.Ordinal))
refNs = refNs + "/Imports";
else
refNs += "Imports";
if (refNs == ns)
refNs = wsdl.TargetNamespace;
XmlSchema xsd = GetContainedSchema(wsdl, refNs);
if (xsd != null)
{
foreach (object include in xsd.Includes)
{
XmlSchemaImport import = include as XmlSchemaImport;
if (import != null && SchemaHelper.NamespacesEqual(import.Namespace, ns))
return;
}
}
else
{
xsd = new XmlSchema();
xsd.TargetNamespace = refNs;
wsdl.Types.Schemas.Add(xsd);
}
XmlSchemaImport imp = new XmlSchemaImport();
if (ns != null && ns.Length > 0)
imp.Namespace = ns;
xsd.Includes.Add(imp);
}
static XmlSchema GetContainedSchema(WsdlNS.ServiceDescription wsdl, string ns)
{
foreach (XmlSchema xsd in wsdl.Types.Schemas)
if (SchemaHelper.NamespacesEqual(xsd.TargetNamespace, ns))
return xsd;
return null;
}
static protected bool IsNullOrEmpty(XmlQualifiedName qname)
{
return qname == null || qname.IsEmpty;
}
protected void ExportGlobalElement(string elementName, string elementNs, bool isNillable, XmlQualifiedName typeName, XmlSchemaType xsdType, XmlSchemaSet schemaSet)
{
#if DEBUG
Fx.Assert(NamingHelper.IsValidNCName(elementName), "Name value has to be a valid NCName.");
if (xsdType == null)
Fx.Assert(NamingHelper.IsValidNCName(typeName.Name), "Name value has to be a valid NCName.");
#endif
XmlSchemaElement element = new XmlSchemaElement();
element.Name = elementName;
if (xsdType != null)
element.SchemaType = xsdType;
else
element.SchemaTypeName = typeName;
element.IsNillable = isNillable;
AddElementToSchema(element, elementNs, schemaSet);
}
void ExportLocalElement(string wrapperNs, string elementName, string elementNs, XmlQualifiedName typeName, XmlSchemaType xsdType, bool multiple, bool isOptional, bool isNillable, XmlSchemaSequence sequence, XmlSchemaSet schemaSet)
{
#if DEBUG
Fx.Assert(NamingHelper.IsValidNCName(elementName), "Name value has to be a valid NCName.");
if (xsdType == null)
Fx.Assert(NamingHelper.IsValidNCName(typeName.Name), "Name value has to be a valid NCName.");
#endif
XmlSchema schema = SchemaHelper.GetSchema(wrapperNs, schemaSet);
XmlSchemaElement element = new XmlSchemaElement();
if (elementNs == wrapperNs)
{
element.Name = elementName;
if (xsdType != null)
element.SchemaType = xsdType;
else
{
element.SchemaTypeName = typeName;
SchemaHelper.AddImportToSchema(element.SchemaTypeName.Namespace, schema);
}
SchemaHelper.AddElementForm(element, schema);
element.IsNillable = isNillable;
}
else
{
element.RefName = new XmlQualifiedName(elementName, elementNs);
SchemaHelper.AddImportToSchema(elementNs, schema);
ExportGlobalElement(elementName, elementNs, isNillable, typeName, xsdType, schemaSet);
}
if (multiple)
element.MaxOccurs = Decimal.MaxValue;
if (isOptional)
element.MinOccurs = 0;
sequence.Items.Add(element);
}
static readonly XmlSchemaSequence emptySequence = new XmlSchemaSequence();
protected XmlSchemaSequence ExportWrappedPart(WsdlNS.Message message, string elementName, string elementNs, XmlSchemaSet schemaSet, bool skipSchemaExport)
{
#if DEBUG
Fx.Assert(NamingHelper.IsValidNCName(elementName), "Name value has to be a valid NCName.");
#endif
AddMessagePart(message, "parameters", new XmlQualifiedName(elementName, elementNs), XmlQualifiedName.Empty);
if (skipSchemaExport)
return emptySequence; //return empty to denote it is wrapped part
XmlSchemaElement wrapperGlobalElement = new XmlSchemaElement();
wrapperGlobalElement.Name = elementName;
XmlSchemaComplexType wrapperType = new XmlSchemaComplexType();
wrapperGlobalElement.SchemaType = wrapperType; // generating an anonymous type for wrapper
XmlSchemaSequence rootSequence = new XmlSchemaSequence();
wrapperType.Particle = rootSequence;
AddElementToSchema(wrapperGlobalElement, elementNs, schemaSet);
return rootSequence;
}
protected bool CreateMessage(MessageDescription message, int messageIndex, out WsdlNS.Message wsdlMessage)
{
wsdlMessage = null;
bool isNewMessage = true;
if (ExportedMessages.WsdlMessages.ContainsKey(new MessageDescriptionDictionaryKey(contractContext.Contract, message)))
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.MultipleCallsToExportContractWithSameContract)));
TypedMessageKey typedMessageKey = null;
OperationMessageKey messageKey = null;
if (message.IsTypedMessage)
{
typedMessageKey = new TypedMessageKey(message.MessageType, operation.DeclaringContract.Namespace, this.GetExtensionData());
if (ExportedMessages.TypedMessages.TryGetValue(typedMessageKey, out wsdlMessage))
isNewMessage = false;
}
else if (operation.OperationMethod != null)
{
messageKey = new OperationMessageKey(operation, messageIndex);
if (ExportedMessages.ParameterMessages.TryGetValue(messageKey, out wsdlMessage))
isNewMessage = false;
}
WsdlNS.ServiceDescription wsdl = contractContext.WsdlPortType.ServiceDescription;
if (isNewMessage)
{
wsdlMessage = new WsdlNS.Message();
wsdlMessage.Name = GetMessageName(message);
wsdl.Messages.Add(wsdlMessage);
if (message.IsTypedMessage)
ExportedMessages.TypedMessages.Add(typedMessageKey, wsdlMessage);
else if (messageKey != null)
ExportedMessages.ParameterMessages.Add(messageKey, wsdlMessage);
}
//Add Name to OperationMessage
WsdlNS.OperationMessage wsdlOperationMessage = contractContext.GetOperationMessage(message);
wsdlOperationMessage.Message = new XmlQualifiedName(wsdlMessage.Name, wsdlMessage.ServiceDescription.TargetNamespace);
this.ExportedMessages.WsdlMessages.Add(new MessageDescriptionDictionaryKey(contractContext.Contract, message), wsdlMessage);
return isNewMessage;
}
protected bool CreateHeaderMessage(MessageDescription message, out WsdlNS.Message wsdlMessage)
{
wsdlMessage = null;
if (ExportedMessages.WsdlHeaderMessages.ContainsKey(new MessageDescriptionDictionaryKey(contractContext.Contract, message)))
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.MultipleCallsToExportContractWithSameContract)));
TypedMessageKey typedMessageKey = null;
if (message.IsTypedMessage)
{
typedMessageKey = new TypedMessageKey(message.MessageType, operation.DeclaringContract.Namespace, GetExtensionData());
if (ExportedMessages.TypedHeaderMessages.TryGetValue(typedMessageKey, out wsdlMessage))
{
this.ExportedMessages.WsdlHeaderMessages.Add(new MessageDescriptionDictionaryKey(contractContext.Contract, message), wsdlMessage);
return false;
}
}
string messageName = GetHeaderMessageName(message);
wsdlMessage = new WsdlNS.Message();
wsdlMessage.Name = messageName;
contractContext.WsdlPortType.ServiceDescription.Messages.Add(wsdlMessage);
if (message.IsTypedMessage)
ExportedMessages.TypedHeaderMessages.Add(typedMessageKey, wsdlMessage);
this.ExportedMessages.WsdlHeaderMessages.Add(new MessageDescriptionDictionaryKey(contractContext.Contract, message), wsdlMessage);
return true;
}
string GetMessageName(MessageDescription messageDescription)
{
string messageNameBase = XmlName.IsNullOrEmpty(messageDescription.MessageName) ? null : messageDescription.MessageName.EncodedName;
//If there wasn't one in the Message Description we create one.
if (string.IsNullOrEmpty(messageNameBase))
{
string portTypeName = contractContext.WsdlPortType.Name;
string operationName = contractContext.GetOperation(operation).Name;
string callbackString = operation.IsServerInitiated() ? "Callback" : string.Empty;
// Microsoft: composing names have potential problem of generating name that looks like an encoded name, consider avoiding '_'
if (messageDescription.Direction == MessageDirection.Input)
messageNameBase = string.Format(System.Globalization.CultureInfo.InvariantCulture,
"{0}_{1}_Input{2}Message", portTypeName, operationName, callbackString);
else
messageNameBase = string.Format(System.Globalization.CultureInfo.InvariantCulture,
"{0}_{1}_Output{2}Message", portTypeName, operationName, callbackString);
}
WsdlNS.ServiceDescription wsdl = contractContext.WsdlPortType.ServiceDescription;
return GetUniqueMessageName(wsdl, messageNameBase);
}
string GetHeaderMessageName(MessageDescription messageDescription)
{
WsdlNS.Message wsdlBodyMessage = this.ExportedMessages.WsdlMessages[new MessageDescriptionDictionaryKey(this.contractContext.Contract, messageDescription)];
string messageNameBase = string.Format(System.Globalization.CultureInfo.InvariantCulture,
"{0}_Headers", wsdlBodyMessage.Name);
WsdlNS.ServiceDescription wsdl = contractContext.WsdlPortType.ServiceDescription;
return GetUniqueMessageName(wsdl, messageNameBase);
}
protected string GetFaultMessageName(string faultName)
{
string portTypeName = contractContext.WsdlPortType.Name;
string operationName = contractContext.GetOperation(operation).Name;
// Microsoft: composing names have potential problem of generating name that looks like an encoded name, consider avoiding '_'
string faultNameBase = String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}_{1}_{2}_FaultMessage", portTypeName, operationName, faultName);
WsdlNS.ServiceDescription wsdl = contractContext.WsdlPortType.ServiceDescription;
return GetUniqueMessageName(wsdl, faultNameBase);
}
static bool DoesMessageNameExist(string messageName, object wsdlObject)
{
return ((WsdlNS.ServiceDescription)wsdlObject).Messages[messageName] != null;
}
string GetUniqueMessageName(WsdlNS.ServiceDescription wsdl, string messageNameBase)
{
return NamingHelper.GetUniqueName(messageNameBase, DoesMessageNameExist, wsdl);
}
protected void ExportMessagePart(WsdlNS.Message message, MessagePartDescription part, XmlQualifiedName typeName, XmlSchemaType xsdType, bool isOptional, bool isNillable, bool skipSchemaExport, bool generateElement, string wrapperNs, XmlSchemaSequence wrapperSequence, XmlSchemaSet schemaSet)
{
if (IsNullOrEmpty(typeName) && xsdType == null)
return;
#if DEBUG
if (xsdType == null)
Fx.Assert(NamingHelper.IsValidNCName(typeName.Name), "Name value has to be a valid NCName.");
#endif
string elementName = part.Name;
string partName = string.IsNullOrEmpty(part.UniquePartName) ? elementName : part.UniquePartName;
WsdlNS.MessagePart wsdlPart = null;
if (generateElement)
{
if (wrapperSequence != null)
{
if (!skipSchemaExport)
ExportLocalElement(wrapperNs, partName, part.Namespace, typeName, xsdType, part.Multiple, isOptional, isNillable, wrapperSequence, schemaSet);
}
else
{
if (!skipSchemaExport)
ExportGlobalElement(elementName, part.Namespace, isNillable, typeName, xsdType, schemaSet);
wsdlPart = AddMessagePart(message, partName, new XmlQualifiedName(elementName, part.Namespace), XmlQualifiedName.Empty);
}
}
else
{
if (String.IsNullOrEmpty(typeName.Name))
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxAnonymousTypeNotSupported, message.Name, partName)));
wsdlPart = AddMessagePart(message, partName, XmlQualifiedName.Empty, typeName);
}
if (wsdlPart != null)
{
part.UniquePartName = wsdlPart.Name;
}
}
protected void AddParameterOrder(MessageDescription message)
{
if (operation == null)
return;
WsdlNS.Operation wsdlOperation = contractContext.GetOperation(operation);
if (wsdlOperation != null)
{
if (wsdlOperation.ParameterOrder == null)
{
wsdlOperation.ParameterOrder = new string[GetParameterCount()];
}
if (wsdlOperation.ParameterOrder.Length == 0)
return;
foreach (MessagePartDescription part in message.Body.Parts)
{
ParameterInfo paramInfo = part.AdditionalAttributesProvider as ParameterInfo;
if (paramInfo != null && paramInfo.Position >= 0)
wsdlOperation.ParameterOrder[paramInfo.Position] = part.Name;
}
}
}
int GetParameterCount()
{
int count = -1;
foreach (MessageDescription message in operation.Messages)
{
foreach (MessagePartDescription part in message.Body.Parts)
{
ParameterInfo paramInfo = part.AdditionalAttributesProvider as ParameterInfo;
if (paramInfo == null)
return 0;
if (count < paramInfo.Position)
count = paramInfo.Position;
}
}
return count + 1;
}
protected virtual void Compile()
{
foreach (XmlSchema schema in SchemaSet.Schemas())
SchemaSet.Reprocess(schema);
SchemaHelper.Compile(SchemaSet, exporter.Errors);
}
class MessageBindingExporter
{
WsdlEndpointConversionContext endpointContext;
MessageExportContext exportedMessages;
EnvelopeVersion soapVersion;
WsdlExporter exporter;
internal MessageBindingExporter(WsdlExporter exporter, WsdlEndpointConversionContext endpointContext)
{
this.endpointContext = endpointContext;
this.exportedMessages = (MessageExportContext)exporter.State[typeof(MessageExportContext)];
this.soapVersion = SoapHelper.GetSoapVersion(endpointContext.WsdlBinding);
this.exporter = exporter;
}
internal void ExportMessageBinding(OperationDescription operation, Type messageContractExporterType)
{
WsdlNS.OperationBinding wsdlOperationBinding = endpointContext.GetOperationBinding(operation);
bool isRpc, isEncoded;
if (!GetStyleAndUse(operation, messageContractExporterType, out isRpc, out isEncoded))
return;
WsdlNS.SoapOperationBinding soapOperationBinding = SoapHelper.GetOrCreateSoapOperationBinding(endpointContext, operation, exporter);
if (soapOperationBinding == null)
return;
soapOperationBinding.Style = isRpc ? WsdlNS.SoapBindingStyle.Rpc : WsdlNS.SoapBindingStyle.Document;
if (isRpc)
{
WsdlNS.SoapBinding soapBinding = (WsdlNS.SoapBinding)endpointContext.WsdlBinding.Extensions.Find(typeof(WsdlNS.SoapBinding));
soapBinding.Style = soapOperationBinding.Style;
}
soapOperationBinding.SoapAction = operation.Messages[0].Action;
foreach (MessageDescription message in operation.Messages)
{
WsdlNS.MessageBinding wsdlMessageBinding = endpointContext.GetMessageBinding(message);
WsdlNS.Message headerMessage;
if (this.exportedMessages.WsdlHeaderMessages.TryGetValue(new MessageDescriptionDictionaryKey(this.endpointContext.Endpoint.Contract, message), out headerMessage))
{
XmlQualifiedName wsdlHeaderMessageName = new XmlQualifiedName(headerMessage.Name, headerMessage.ServiceDescription.TargetNamespace);
foreach (MessageHeaderDescription header in message.Headers)
{
if (header.IsUnknownHeaderCollection)
continue;
ExportMessageHeaderBinding(header, wsdlHeaderMessageName, isEncoded, wsdlMessageBinding);
}
}
ExportMessageBodyBinding(message, isRpc, isEncoded, wsdlMessageBinding);
}
foreach (FaultDescription fault in operation.Faults)
{
ExportFaultBinding(fault, isEncoded, wsdlOperationBinding);
}
}
void ExportFaultBinding(FaultDescription fault, bool isEncoded, WsdlNS.OperationBinding operationBinding)
{
SoapHelper.CreateSoapFaultBinding(fault.Name, endpointContext, endpointContext.GetFaultBinding(fault), isEncoded);
}
void ExportMessageBodyBinding(MessageDescription messageDescription, bool isRpc, bool isEncoded, WsdlNS.MessageBinding messageBinding)
{
WsdlNS.SoapBodyBinding bodyBinding = SoapHelper.GetOrCreateSoapBodyBinding(endpointContext, messageBinding, exporter);
if (bodyBinding == null)
return;
bodyBinding.Use = isEncoded ? WsdlNS.SoapBindingUse.Encoded : WsdlNS.SoapBindingUse.Literal;
if (isRpc)
{
string ns;
if (!ExportedMessages.WrapperNamespaces.TryGetValue(new MessageDescriptionDictionaryKey(endpointContext.ContractConversionContext.Contract, messageDescription), out ns))
ns = messageDescription.Body.WrapperNamespace;
bodyBinding.Namespace = ns;
}
if (isEncoded)
bodyBinding.Encoding = XmlSerializerOperationFormatter.GetEncoding(soapVersion);
}
void ExportMessageHeaderBinding(MessageHeaderDescription header, XmlQualifiedName messageName, bool isEncoded, WsdlNS.MessageBinding messageBinding)
{
#if DEBUG
Fx.Assert(NamingHelper.IsValidNCName(messageName.Name), "Name value has to be a valid NCName.");
#endif
WsdlNS.SoapHeaderBinding headerBinding = SoapHelper.CreateSoapHeaderBinding(endpointContext, messageBinding);
headerBinding.Part = string.IsNullOrEmpty(header.UniquePartName) ? header.Name : header.UniquePartName;
headerBinding.Message = messageName;
headerBinding.Use = isEncoded ? WsdlNS.SoapBindingUse.Encoded : WsdlNS.SoapBindingUse.Literal;
if (isEncoded)
headerBinding.Encoding = XmlSerializerOperationFormatter.GetEncoding(soapVersion);
}
static bool GetStyleAndUse(OperationDescription operation, Type messageContractExporterType, out bool isRpc, out bool isEncoded)
{
isRpc = isEncoded = false;
if (messageContractExporterType == typeof(DataContractSerializerMessageContractExporter) || messageContractExporterType == null)
{
DataContractSerializerOperationBehavior dataContractSerializerBehavior = operation.Behaviors.Find<DataContractSerializerOperationBehavior>();
if (dataContractSerializerBehavior != null)
{
isRpc = dataContractSerializerBehavior.DataContractFormatAttribute.Style == OperationFormatStyle.Rpc;
isEncoded = false;
return true;
}
if (messageContractExporterType == typeof(DataContractSerializerMessageContractExporter))
return false;
}
if (messageContractExporterType == typeof(XmlSerializerMessageContractExporter) || messageContractExporterType == null)
{
XmlSerializerOperationBehavior xmlSerializerBehavior = operation.Behaviors.Find<XmlSerializerOperationBehavior>();
if (xmlSerializerBehavior != null)
{
isRpc = xmlSerializerBehavior.XmlSerializerFormatAttribute.Style == OperationFormatStyle.Rpc;
isEncoded = xmlSerializerBehavior.XmlSerializerFormatAttribute.IsEncoded;
return true;
}
return false;
}
return false;
}
MessageExportContext ExportedMessages
{
get { return GetMessageExportContext(exporter); }
}
}
protected class MessageExportContext
{
readonly internal Dictionary<MessageDescriptionDictionaryKey, WsdlNS.Message> WsdlMessages = new Dictionary<MessageDescriptionDictionaryKey, System.Web.Services.Description.Message>();
readonly internal Dictionary<MessageDescriptionDictionaryKey, WsdlNS.Message> WsdlHeaderMessages = new Dictionary<MessageDescriptionDictionaryKey, System.Web.Services.Description.Message>();
readonly internal Dictionary<MessageDescriptionDictionaryKey, string> WrapperNamespaces = new Dictionary<MessageDescriptionDictionaryKey, string>();
readonly internal Dictionary<TypedMessageKey, WsdlNS.Message> TypedMessages = new Dictionary<TypedMessageKey, WsdlNS.Message>();
readonly internal Dictionary<TypedMessageKey, WsdlNS.Message> TypedHeaderMessages = new Dictionary<TypedMessageKey, WsdlNS.Message>();
readonly internal Dictionary<OperationMessageKey, WsdlNS.Message> ParameterMessages = new Dictionary<OperationMessageKey, WsdlNS.Message>();
readonly internal Dictionary<XmlQualifiedName, OperationElement> ElementTypes = new Dictionary<XmlQualifiedName, OperationElement>();
}
protected sealed class MessageDescriptionDictionaryKey
{
public readonly ContractDescription Contract;
public readonly MessageDescription MessageDescription;
public MessageDescriptionDictionaryKey(ContractDescription contract, MessageDescription MessageDescription)
{
this.Contract = contract;
this.MessageDescription = MessageDescription;
}
public override bool Equals(object obj)
{
MessageDescriptionDictionaryKey key = obj as MessageDescriptionDictionaryKey;
if (key != null && key.MessageDescription == this.MessageDescription && key.Contract == this.Contract)
return true;
return false;
}
public override int GetHashCode()
{
return this.Contract.GetHashCode() ^ this.MessageDescription.GetHashCode();
}
}
internal sealed class TypedMessageKey
{
Type type;
string contractNS;
object extensionData;
public TypedMessageKey(Type type, string contractNS, object extensionData)
{
this.type = type;
this.contractNS = contractNS;
this.extensionData = extensionData;
}
public override bool Equals(object obj)
{
TypedMessageKey key = obj as TypedMessageKey;
if (key != null && key.type == this.type &&
key.contractNS == this.contractNS &&
key.extensionData.Equals(this.extensionData))
return true;
return false;
}
[SuppressMessage(FxCop.Category.Usage, "CA2303:FlagTypeGetHashCode", Justification = "The hashcode is not used for identity purposes for embedded types.")]
public override int GetHashCode()
{
return type.GetHashCode();
}
}
internal sealed class OperationMessageKey
{
MethodInfo methodInfo;
int messageIndex;
ContractDescription declaringContract;
public OperationMessageKey(OperationDescription operation, int messageIndex)
{
this.methodInfo = operation.OperationMethod;
this.messageIndex = messageIndex;
this.declaringContract = operation.DeclaringContract;
}
public override bool Equals(object obj)
{
OperationMessageKey key = obj as OperationMessageKey;
if (key != null && key.methodInfo == this.methodInfo &&
key.messageIndex == this.messageIndex &&
key.declaringContract.Name == this.declaringContract.Name &&
key.declaringContract.Namespace == this.declaringContract.Namespace)
return true;
return false;
}
public override int GetHashCode()
{
return methodInfo.GetHashCode() ^ messageIndex;
}
}
internal sealed class OperationElement
{
XmlSchemaElement element;
OperationDescription operation;
internal OperationElement(XmlSchemaElement element, OperationDescription operation)
{
this.element = element;
this.operation = operation;
}
internal XmlSchemaElement Element { get { return element; } }
internal OperationDescription Operation { get { return operation; } }
}
}
class DataContractSerializerMessageContractExporter : MessageContractExporter
{
internal DataContractSerializerMessageContractExporter(WsdlExporter exporter, WsdlContractConversionContext context, OperationDescription operation, IOperationBehavior extension)
: base(exporter, context, operation, extension)
{
}
protected override void Compile()
{
XmlSchema wsdl = StockSchemas.CreateWsdl();
XmlSchema soap = StockSchemas.CreateSoap();
XmlSchema soapEncoding = StockSchemas.CreateSoapEncoding();
XmlSchema fakeXsdSchema = StockSchemas.CreateFakeXsdSchema();
SchemaSet.Add(wsdl);
SchemaSet.Add(soap);
SchemaSet.Add(soapEncoding);
SchemaSet.Add(fakeXsdSchema);
base.Compile();
SchemaSet.Remove(wsdl);
SchemaSet.Remove(soap);
SchemaSet.Remove(soapEncoding);
SchemaSet.Remove(fakeXsdSchema);
}
protected override bool IsRpcStyle()
{
return ((DataContractSerializerOperationBehavior)extension).DataContractFormatAttribute.Style == OperationFormatStyle.Rpc;
}
protected override bool IsEncoded()
{
return false;
}
protected override object OnExportMessageContract()
{
return null;
}
protected override void ExportHeaders(int messageIndex, object state)
{
MessageDescription description = operation.Messages[messageIndex];
if (description.Headers.Count > 0)
{
WsdlNS.Message wsdlMessage;
if (CreateHeaderMessage(description, out wsdlMessage))
{
foreach (MessageHeaderDescription header in description.Headers)
{
if (header.IsUnknownHeaderCollection)
continue;
XmlSchemaType xsdType;
bool isQueryable;
Type dataContractType = DataContractSerializerOperationFormatter.GetSubstituteDataContractType(header.Type, out isQueryable);
XmlQualifiedName typeName = ExportType(dataContractType, header.Name, operation.Name, out xsdType);
ExportMessagePart(wsdlMessage, header, typeName, xsdType, true/*isOptional*/, IsTypeNullable(header.Type), false/*IsOperationInherited(operation)*/, true /*generateElement*/, null/*wrapperNamespace*/, null/*wrapperSequence*/, SchemaSet);
}
}
}
}
static internal bool IsTypeNullable(Type type)
{
return !type.IsValueType ||
(type.IsGenericType &&
type.GetGenericTypeDefinition() == typeof(Nullable<>));
}
protected override void ExportBody(int messageIndex, object state)
{
MessageDescription description = operation.Messages[messageIndex];
WsdlNS.Message wsdlMessage = this.ExportedMessages.WsdlMessages[new MessageDescriptionDictionaryKey(this.contractContext.Contract, description)];
DataContractFormatAttribute dataContractFormatAttribute = ((DataContractSerializerOperationBehavior)extension).DataContractFormatAttribute;
XmlSchemaSequence wrapperSequence = null;
bool isWrapped = description.Body.WrapperName != null;
//bool isOperationInherited = IsOperationInherited(operation);
if (dataContractFormatAttribute.Style == OperationFormatStyle.Document && isWrapped)
wrapperSequence = ExportWrappedPart(wsdlMessage, description.Body.WrapperName, description.Body.WrapperNamespace, SchemaSet, false /*isOperationInherited*/);
XmlSchemaType xsdType;
if (OperationFormatter.IsValidReturnValue(description.Body.ReturnValue))
{
bool isQueryable;
Type dataContractType = DataContractSerializerOperationFormatter.GetSubstituteDataContractType(description.Body.ReturnValue.Type, out isQueryable);
XmlQualifiedName typeName = ExportType(dataContractType, description.Body.ReturnValue.Name, operation.Name, out xsdType);
ExportMessagePart(wsdlMessage, description.Body.ReturnValue, typeName, xsdType, true/*isOptional*/, IsTypeNullable(description.Body.ReturnValue.Type), false/*isOperationInherited*/, dataContractFormatAttribute.Style != OperationFormatStyle.Rpc, description.Body.WrapperNamespace, wrapperSequence, SchemaSet);
}
foreach (MessagePartDescription bodyPart in description.Body.Parts)
{
bool isQueryable;
Type dataContractType = DataContractSerializerOperationFormatter.GetSubstituteDataContractType(bodyPart.Type, out isQueryable);
XmlQualifiedName typeName = ExportType(dataContractType, bodyPart.Name, operation.Name, out xsdType);
ExportMessagePart(wsdlMessage, bodyPart, typeName, xsdType, true/*isOptional*/, IsTypeNullable(bodyPart.Type), false/*isOperationInherited*/, dataContractFormatAttribute.Style != OperationFormatStyle.Rpc, description.Body.WrapperNamespace, wrapperSequence, SchemaSet);
}
if (dataContractFormatAttribute.Style == OperationFormatStyle.Rpc)
{
AddParameterOrder(description);
}
}
protected override void ExportKnownTypes()
{
foreach (Type knownType in operation.KnownTypes)
{
DataContractExporter.Export(knownType);
}
}
protected override object GetExtensionData()
{
return new ExtensionData(((DataContractSerializerOperationBehavior)extension).DataContractFormatAttribute);
}
class ExtensionData
{
DataContractFormatAttribute dcFormatAttr;
internal ExtensionData(DataContractFormatAttribute dcFormatAttr)
{
this.dcFormatAttr = dcFormatAttr;
}
public override bool Equals(object obj)
{
if (object.ReferenceEquals(dcFormatAttr, obj))
return true;
ExtensionData otherExtensionData = obj as ExtensionData;
if (otherExtensionData == null)
return false;
return dcFormatAttr.Style == otherExtensionData.dcFormatAttr.Style;
}
public override int GetHashCode()
{
return 1; //This is never called
}
}
}
class XmlSerializerMessageContractExporter : MessageContractExporter
{
internal XmlSerializerMessageContractExporter(WsdlExporter exporter, WsdlContractConversionContext context, OperationDescription operation, IOperationBehavior extension)
: base(exporter, context, operation, extension)
{
}
protected override bool IsRpcStyle()
{
return ((XmlSerializerOperationBehavior)extension).XmlSerializerFormatAttribute.Style == OperationFormatStyle.Rpc;
}
protected override bool IsEncoded()
{
return ((XmlSerializerOperationBehavior)extension).XmlSerializerFormatAttribute.IsEncoded;
}
protected override object OnExportMessageContract()
{
object result = Reflector.ReflectOperation(operation);
if (result == null)
{
// If result is null, that means that XmlSerializerFormatAttribute wasn't available in reflection,
// so we need to get it from the XmlSerializerOperationBehavior instead
XmlSerializerOperationBehavior serializerBehavior = this.extension as XmlSerializerOperationBehavior;
if (serializerBehavior != null)
{
result = Reflector.ReflectOperation(operation, serializerBehavior.XmlSerializerFormatAttribute);
}
}
return result;
}
protected override void ExportHeaders(int messageIndex, object state)
{
string portTypeName = contractContext.WsdlPortType.Name;
string portTypeNs = contractContext.WsdlPortType.ServiceDescription.TargetNamespace;
MessageDescription description = operation.Messages[messageIndex];
if (description.Headers.Count > 0)
{
XmlSerializerOperationBehavior.Reflector.OperationReflector operationReflector = (XmlSerializerOperationBehavior.Reflector.OperationReflector)state;
XmlMembersMapping membersMapping = null;
if (messageIndex == 0)
{
membersMapping = operationReflector.Request.HeadersMapping;
}
else
{
membersMapping = operationReflector.Reply.HeadersMapping;
}
if (membersMapping != null)
{
WsdlNS.Message wsdlMessage;
if (CreateHeaderMessage(description, out wsdlMessage))
{
ExportMembersMapping(membersMapping, wsdlMessage, false /*IsOperationInherited(operation)*/, operationReflector.IsEncoded, false/*isRpc*/, false/*isWrapped*/, true/*isHeader*/);
}
}
}
}
protected override void ExportBody(int messageIndex, object state)
{
MessageDescription description = operation.Messages[messageIndex];
string portTypeName = contractContext.WsdlPortType.Name;
string portTypeNs = contractContext.WsdlPortType.ServiceDescription.TargetNamespace;
MessageDescriptionDictionaryKey key = new MessageDescriptionDictionaryKey(this.contractContext.Contract, description);
WsdlNS.Message wsdlMessage = this.ExportedMessages.WsdlMessages[key];
XmlSerializerOperationBehavior.Reflector.OperationReflector operationReflector = (XmlSerializerOperationBehavior.Reflector.OperationReflector)state;
XmlMembersMapping membersMapping = null;
if (messageIndex == 0)
{
membersMapping = operationReflector.Request.BodyMapping;
}
else
{
membersMapping = operationReflector.Reply.BodyMapping;
}
if (membersMapping != null)
{
bool isDocWrapped = !operationReflector.IsRpc && description.Body.WrapperName != null;
ExportMembersMapping(membersMapping, wsdlMessage, false /*IsOperationInherited(operation)*/, operationReflector.IsEncoded, operationReflector.IsRpc, isDocWrapped, false/*isHeader*/);
if (operationReflector.IsRpc)
{
AddParameterOrder(operation.Messages[messageIndex]);
this.ExportedMessages.WrapperNamespaces.Add(key, membersMapping.Namespace);
}
}
}
protected override void ExportFaults(object state)
{
XmlSerializerOperationBehavior.Reflector.OperationReflector operationReflector = (XmlSerializerOperationBehavior.Reflector.OperationReflector)state;
if (operationReflector.Attribute.SupportFaults)
{
foreach (FaultDescription fault in operation.Faults)
{
ExportFault(fault, operationReflector);
}
Compile();
}
else
{
base.ExportFaults(state);
}
}
void ExportFault(FaultDescription fault, XmlSerializerOperationBehavior.Reflector.OperationReflector operationReflector)
{
WsdlNS.Message faultMessage = new WsdlNS.Message();
faultMessage.Name = GetFaultMessageName(fault.Name);
XmlQualifiedName elementName = ExportFaultElement(fault, operationReflector);
this.contractContext.WsdlPortType.ServiceDescription.Messages.Add(faultMessage);
AddMessagePart(faultMessage, "detail", elementName, null);
// create a wsdl:fault to put inside the wsdl:portType/wsdl:operation
WsdlNS.OperationFault operationFault = contractContext.GetOperationFault(fault);
WsdlExporter.WSAddressingHelper.AddActionAttribute(fault.Action, operationFault, this.exporter.PolicyVersion);
operationFault.Message = new XmlQualifiedName(faultMessage.Name, faultMessage.ServiceDescription.TargetNamespace);
}
XmlQualifiedName ExportFaultElement(FaultDescription fault, XmlSerializerOperationBehavior.Reflector.OperationReflector operationReflector)
{
XmlQualifiedName elementName;
XmlMembersMapping mapping = operationReflector.ImportFaultElement(fault, out elementName);
if (operationReflector.IsEncoded)
SoapExporter.ExportMembersMapping(mapping);
else
XmlExporter.ExportMembersMapping(mapping);
return elementName;
}
protected override void ExportKnownTypes()
{
}
protected override object GetExtensionData()
{
return new ExtensionData(((XmlSerializerOperationBehavior)this.extension).XmlSerializerFormatAttribute);
}
class ExtensionData
{
XmlSerializerFormatAttribute xsFormatAttr;
internal ExtensionData(XmlSerializerFormatAttribute xsFormatAttr)
{
this.xsFormatAttr = xsFormatAttr;
}
public override bool Equals(object obj)
{
if (object.ReferenceEquals(xsFormatAttr, obj))
return true;
ExtensionData otherExtensionData = obj as ExtensionData;
if (otherExtensionData == null)
return false;
return xsFormatAttr.Style == otherExtensionData.xsFormatAttr.Style &&
xsFormatAttr.Use == otherExtensionData.xsFormatAttr.Use;
}
public override int GetHashCode()
{
return 1; //This is never called
}
}
void ExportMembersMapping(XmlMembersMapping membersMapping, WsdlNS.Message message, bool skipSchemaExport, bool isEncoded, bool isRpc, bool isDocWrapped, bool isHeader)
{
if (!skipSchemaExport)
{
if (isEncoded)
SoapExporter.ExportMembersMapping(membersMapping);
else
XmlExporter.ExportMembersMapping(membersMapping, !isRpc);
}
if (isDocWrapped)
{
if (isHeader)
{
Fx.Assert("Header cannot be Document Wrapped");
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Header cannot be Document Wrapped")));
}
AddMessagePart(message, "parameters", new XmlQualifiedName(membersMapping.XsdElementName, membersMapping.Namespace), XmlQualifiedName.Empty);
return;
}
bool generateElement = !isRpc && !isEncoded;
for (int i = 0; i < membersMapping.Count; i++)
{
XmlMemberMapping member = membersMapping[i];
string partName = (isHeader || generateElement) ? NamingHelper.XmlName(member.MemberName) : member.XsdElementName;
if (generateElement)
AddMessagePart(message, partName, new XmlQualifiedName(member.XsdElementName, member.Namespace), XmlQualifiedName.Empty);
else
{
if (string.IsNullOrEmpty(member.TypeName))
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxAnonymousTypeNotSupported, message.Name, partName)));
AddMessagePart(message, partName, XmlQualifiedName.Empty, new XmlQualifiedName(member.TypeName, member.TypeNamespace));
}
}
}
XmlSerializerOperationBehavior.Reflector Reflector
{
get
{
object reflector;
if (!exporter.State.TryGetValue(typeof(XmlSerializerOperationBehavior.Reflector), out reflector))
{
reflector = new XmlSerializerOperationBehavior.Reflector(contractContext.Contract.Namespace, contractContext.Contract.ContractType);
exporter.State.Add(typeof(XmlSerializerOperationBehavior.Reflector), reflector);
}
return (XmlSerializerOperationBehavior.Reflector)reflector;
}
}
SoapSchemaExporter SoapExporter
{
get
{
object soapExporter;
if (!exporter.State.TryGetValue(typeof(SoapSchemaExporter), out soapExporter))
{
soapExporter = new SoapSchemaExporter(Schemas);
exporter.State.Add(typeof(SoapSchemaExporter), soapExporter);
}
return (SoapSchemaExporter)soapExporter;
}
}
XmlSchemaExporter XmlExporter
{
get
{
object xmlExporter;
if (!exporter.State.TryGetValue(typeof(XmlSchemaExporter), out xmlExporter))
{
xmlExporter = new XmlSchemaExporter(Schemas);
exporter.State.Add(typeof(XmlSchemaExporter), xmlExporter);
}
return (XmlSchemaExporter)xmlExporter;
}
}
XmlSchemas Schemas
{
get
{
object schemas;
if (!exporter.State.TryGetValue(typeof(XmlSchemas), out schemas))
{
schemas = new XmlSchemas();
foreach (XmlSchema schema in this.SchemaSet.Schemas())
if (!((XmlSchemas)schemas).Contains(schema.TargetNamespace))
((XmlSchemas)schemas).Add(schema);
exporter.State.Add(typeof(XmlSchemas), schemas);
}
return (XmlSchemas)schemas;
}
}
protected override void Compile()
{
XmlSchema wsdl = StockSchemas.CreateWsdl();
XmlSchema soap = StockSchemas.CreateSoap();
XmlSchema soapEncoding = StockSchemas.CreateSoapEncoding();
XmlSchema fakeXsdSchema = StockSchemas.CreateFakeXsdSchema();
MoveSchemas();
SchemaSet.Add(wsdl);
SchemaSet.Add(soap);
SchemaSet.Add(soapEncoding);
SchemaSet.Add(fakeXsdSchema);
base.Compile();
SchemaSet.Remove(wsdl);
SchemaSet.Remove(soap);
SchemaSet.Remove(soapEncoding);
SchemaSet.Remove(fakeXsdSchema);
}
void MoveSchemas()
{
XmlSchemas schemas = this.Schemas;
XmlSchemaSet schemaSet = this.SchemaSet;
if (schemas != null)
{
schemas.Compile(
delegate(object sender, ValidationEventArgs args)
{
SchemaHelper.HandleSchemaValidationError(sender, args, exporter.Errors);
},
false/*fullCompile*/
);
foreach (XmlSchema srcSchema in schemas)
{
if (!schemaSet.Contains(srcSchema))
{
schemaSet.Add(srcSchema);
schemaSet.Reprocess(srcSchema);
}
}
}
}
}
static class StockSchemas
{
internal static XmlSchema CreateWsdl()
{
StringReader reader = new StringReader(wsdl);
return XmlSchema.Read(new XmlTextReader(reader) { DtdProcessing = DtdProcessing.Prohibit }, null);
}
internal static XmlSchema CreateSoap()
{
StringReader reader = new StringReader(soap);
return XmlSchema.Read(new XmlTextReader(reader) { DtdProcessing = DtdProcessing.Prohibit }, null);
}
internal static XmlSchema CreateSoapEncoding()
{
StringReader reader = new StringReader(soapEncoding);
return XmlSchema.Read(new XmlTextReader(reader) { DtdProcessing = DtdProcessing.Prohibit }, null);
}
internal static XmlSchema CreateFakeSoapEncoding()
{
StringReader reader = new StringReader(fakeSoapEncoding);
return XmlSchema.Read(new XmlTextReader(reader) { DtdProcessing = DtdProcessing.Prohibit }, null);
}
internal static XmlSchema CreateFakeXsdSchema()
{
StringReader reader = new StringReader(fakeXsd);
return XmlSchema.Read(new XmlTextReader(reader) { DtdProcessing = DtdProcessing.Prohibit }, null);
}
internal static XmlSchema CreateFakeXmlSchema()
{
StringReader reader = new StringReader(fakeXmlSchema);
return XmlSchema.Read(new XmlTextReader(reader) { DtdProcessing = DtdProcessing.Prohibit }, null);
}
internal static bool IsKnownSchema(string ns)
{
return ns == XmlSchema.Namespace || ns == "http://schemas.xmlsoap.org/wsdl/soap/" || ns == "http://schemas.xmlsoap.org/soap/encoding/";
}
internal const string WsdlNamespace = "http://schemas.xmlsoap.org/wsdl/";
internal const string SoapNamespace = "http://schemas.xmlsoap.org/wsdl/soap/";
internal const string SoapEncodingNamespace = "http://schemas.xmlsoap.org/soap/encoding/";
const string wsdl = @"<?xml version='1.0' encoding='UTF-8' ?>
<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'
xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'
targetNamespace='http://schemas.xmlsoap.org/wsdl/'
elementFormDefault='qualified' >
<xs:complexType mixed='true' name='tDocumentation' >
<xs:sequence>
<xs:any minOccurs='0' maxOccurs='unbounded' processContents='lax' />
</xs:sequence>
</xs:complexType>
<xs:complexType name='tDocumented' >
<xs:annotation>
<xs:documentation>
This type is extended by component types to allow them to be documented
</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name='documentation' type='wsdl:tDocumentation' minOccurs='0' />
</xs:sequence>
</xs:complexType>
<!-- allow extensibility via elements and attributes on all elements swa124 -->
<xs:complexType name='tExtensibleAttributesDocumented' abstract='true' >
<xs:complexContent>
<xs:extension base='wsdl:tDocumented' >
<xs:annotation>
<xs:documentation>
This type is extended by component types to allow attributes from other namespaces to be added.
</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:any namespace='##other' minOccurs='0' maxOccurs='unbounded' processContents='lax' />
</xs:sequence>
<xs:anyAttribute namespace='##other' processContents='lax' />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name='tExtensibleDocumented' abstract='true' >
<xs:complexContent>
<xs:extension base='wsdl:tDocumented' >
<xs:annotation>
<xs:documentation>
This type is extended by component types to allow elements from other namespaces to be added.
</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:any namespace='##other' minOccurs='0' maxOccurs='unbounded' processContents='lax' />
</xs:sequence>
<xs:anyAttribute namespace='##other' processContents='lax' />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<!-- original wsdl removed as part of swa124 resolution
<xs:complexType name='tExtensibleAttributesDocumented' abstract='true' >
<xs:complexContent>
<xs:extension base='wsdl:tDocumented' >
<xs:annotation>
<xs:documentation>
This type is extended by component types to allow attributes from other namespaces to be added.
</xs:documentation>
</xs:annotation>
<xs:anyAttribute namespace='##other' processContents='lax' />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name='tExtensibleDocumented' abstract='true' >
<xs:complexContent>
<xs:extension base='wsdl:tDocumented' >
<xs:annotation>
<xs:documentation>
This type is extended by component types to allow elements from other namespaces to be added.
</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:any namespace='##other' minOccurs='0' maxOccurs='unbounded' processContents='lax' />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
-->
<xs:element name='definitions' type='wsdl:tDefinitions' >
<xs:key name='message' >
<xs:selector xpath='wsdl:message' />
<xs:field xpath='@name' />
</xs:key>
<xs:key name='portType' >
<xs:selector xpath='wsdl:portType' />
<xs:field xpath='@name' />
</xs:key>
<xs:key name='binding' >
<xs:selector xpath='wsdl:binding' />
<xs:field xpath='@name' />
</xs:key>
<xs:key name='service' >
<xs:selector xpath='wsdl:service' />
<xs:field xpath='@name' />
</xs:key>
<xs:key name='import' >
<xs:selector xpath='wsdl:import' />
<xs:field xpath='@namespace' />
</xs:key>
</xs:element>
<xs:group name='anyTopLevelOptionalElement' >
<xs:annotation>
<xs:documentation>
Any top level optional element allowed to appear more then once - any child of definitions element except wsdl:types. Any extensibility element is allowed in any place.
</xs:documentation>
</xs:annotation>
<xs:choice>
<xs:element name='import' type='wsdl:tImport' />
<xs:element name='types' type='wsdl:tTypes' />
<xs:element name='message' type='wsdl:tMessage' >
<xs:unique name='part' >
<xs:selector xpath='wsdl:part' />
<xs:field xpath='@name' />
</xs:unique>
</xs:element>
<xs:element name='portType' type='wsdl:tPortType' />
<xs:element name='binding' type='wsdl:tBinding' />
<xs:element name='service' type='wsdl:tService' >
<xs:unique name='port' >
<xs:selector xpath='wsdl:port' />
<xs:field xpath='@name' />
</xs:unique>
</xs:element>
</xs:choice>
</xs:group>
<xs:complexType name='tDefinitions' >
<xs:complexContent>
<xs:extension base='wsdl:tExtensibleDocumented' >
<xs:sequence>
<xs:group ref='wsdl:anyTopLevelOptionalElement' minOccurs='0' maxOccurs='unbounded' />
</xs:sequence>
<xs:attribute name='targetNamespace' type='xs:anyURI' use='optional' />
<xs:attribute name='name' type='xs:NCName' use='optional' />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name='tImport' >
<xs:complexContent>
<xs:extension base='wsdl:tExtensibleAttributesDocumented' >
<xs:attribute name='namespace' type='xs:anyURI' use='required' />
<xs:attribute name='location' type='xs:anyURI' use='required' />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name='tTypes' >
<xs:complexContent>
<xs:extension base='wsdl:tExtensibleDocumented' />
</xs:complexContent>
</xs:complexType>
<xs:complexType name='tMessage' >
<xs:complexContent>
<xs:extension base='wsdl:tExtensibleDocumented' >
<xs:sequence>
<xs:element name='part' type='wsdl:tPart' minOccurs='0' maxOccurs='unbounded' />
</xs:sequence>
<xs:attribute name='name' type='xs:NCName' use='required' />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name='tPart' >
<xs:complexContent>
<xs:extension base='wsdl:tExtensibleAttributesDocumented' >
<xs:attribute name='name' type='xs:NCName' use='required' />
<xs:attribute name='element' type='xs:QName' use='optional' />
<xs:attribute name='type' type='xs:QName' use='optional' />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name='tPortType' >
<xs:complexContent>
<xs:extension base='wsdl:tExtensibleAttributesDocumented' >
<xs:sequence>
<xs:element name='operation' type='wsdl:tOperation' minOccurs='0' maxOccurs='unbounded' />
</xs:sequence>
<xs:attribute name='name' type='xs:NCName' use='required' />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name='tOperation' >
<xs:complexContent>
<xs:extension base='wsdl:tExtensibleDocumented' >
<xs:sequence>
<xs:choice>
<xs:group ref='wsdl:request-response-or-one-way-operation' />
<xs:group ref='wsdl:solicit-response-or-notification-operation' />
</xs:choice>
</xs:sequence>
<xs:attribute name='name' type='xs:NCName' use='required' />
<xs:attribute name='parameterOrder' type='xs:NMTOKENS' use='optional' />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:group name='request-response-or-one-way-operation' >
<xs:sequence>
<xs:element name='input' type='wsdl:tParam' />
<xs:sequence minOccurs='0' >
<xs:element name='output' type='wsdl:tParam' />
<xs:element name='fault' type='wsdl:tFault' minOccurs='0' maxOccurs='unbounded' />
</xs:sequence>
</xs:sequence>
</xs:group>
<xs:group name='solicit-response-or-notification-operation' >
<xs:sequence>
<xs:element name='output' type='wsdl:tParam' />
<xs:sequence minOccurs='0' >
<xs:element name='input' type='wsdl:tParam' />
<xs:element name='fault' type='wsdl:tFault' minOccurs='0' maxOccurs='unbounded' />
</xs:sequence>
</xs:sequence>
</xs:group>
<xs:complexType name='tParam' >
<xs:complexContent>
<xs:extension base='wsdl:tExtensibleAttributesDocumented' >
<xs:attribute name='name' type='xs:NCName' use='optional' />
<xs:attribute name='message' type='xs:QName' use='required' />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name='tFault' >
<xs:complexContent>
<xs:extension base='wsdl:tExtensibleAttributesDocumented' >
<xs:attribute name='name' type='xs:NCName' use='required' />
<xs:attribute name='message' type='xs:QName' use='required' />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name='tBinding' >
<xs:complexContent>
<xs:extension base='wsdl:tExtensibleDocumented' >
<xs:sequence>
<xs:element name='operation' type='wsdl:tBindingOperation' minOccurs='0' maxOccurs='unbounded' />
</xs:sequence>
<xs:attribute name='name' type='xs:NCName' use='required' />
<xs:attribute name='type' type='xs:QName' use='required' />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name='tBindingOperationMessage' >
<xs:complexContent>
<xs:extension base='wsdl:tExtensibleDocumented' >
<xs:attribute name='name' type='xs:NCName' use='optional' />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name='tBindingOperationFault' >
<xs:complexContent>
<xs:extension base='wsdl:tExtensibleDocumented' >
<xs:attribute name='name' type='xs:NCName' use='required' />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name='tBindingOperation' >
<xs:complexContent>
<xs:extension base='wsdl:tExtensibleDocumented' >
<xs:sequence>
<xs:element name='input' type='wsdl:tBindingOperationMessage' minOccurs='0' />
<xs:element name='output' type='wsdl:tBindingOperationMessage' minOccurs='0' />
<xs:element name='fault' type='wsdl:tBindingOperationFault' minOccurs='0' maxOccurs='unbounded' />
</xs:sequence>
<xs:attribute name='name' type='xs:NCName' use='required' />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name='tService' >
<xs:complexContent>
<xs:extension base='wsdl:tExtensibleDocumented' >
<xs:sequence>
<xs:element name='port' type='wsdl:tPort' minOccurs='0' maxOccurs='unbounded' />
</xs:sequence>
<xs:attribute name='name' type='xs:NCName' use='required' />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name='tPort' >
<xs:complexContent>
<xs:extension base='wsdl:tExtensibleDocumented' >
<xs:attribute name='name' type='xs:NCName' use='required' />
<xs:attribute name='binding' type='xs:QName' use='required' />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:attribute name='arrayType' type='xs:string' />
<xs:attribute name='required' type='xs:boolean' />
<xs:complexType name='tExtensibilityElement' abstract='true' >
<xs:attribute ref='wsdl:required' use='optional' />
</xs:complexType>
</xs:schema>";
const string soap = @"<?xml version='1.0' encoding='UTF-8' ?>
<xs:schema xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/' xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/' targetNamespace='http://schemas.xmlsoap.org/wsdl/soap/' xmlns:xs='http://www.w3.org/2001/XMLSchema'>
<xs:import namespace='http://schemas.xmlsoap.org/wsdl/' />
<xs:simpleType name='encodingStyle'>
<xs:annotation>
<xs:documentation>
'encodingStyle' indicates any canonicalization conventions followed in the contents of the containing element. For example, the value 'http://schemas.xmlsoap.org/soap/encoding/' indicates the pattern described in SOAP specification
</xs:documentation>
</xs:annotation>
<xs:list itemType='xs:anyURI' />
</xs:simpleType>
<xs:element name='binding' type='soap:tBinding' />
<xs:complexType name='tBinding'>
<xs:complexContent mixed='false'>
<xs:extension base='wsdl:tExtensibilityElement'>
<xs:attribute name='transport' type='xs:anyURI' use='required' />
<xs:attribute name='style' type='soap:tStyleChoice' use='optional' />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:simpleType name='tStyleChoice'>
<xs:restriction base='xs:string'>
<xs:enumeration value='rpc' />
<xs:enumeration value='document' />
</xs:restriction>
</xs:simpleType>
<xs:element name='operation' type='soap:tOperation' />
<xs:complexType name='tOperation'>
<xs:complexContent mixed='false'>
<xs:extension base='wsdl:tExtensibilityElement'>
<xs:attribute name='soapAction' type='xs:anyURI' use='optional' />
<xs:attribute name='style' type='soap:tStyleChoice' use='optional' />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name='body' type='soap:tBody' />
<xs:attributeGroup name='tBodyAttributes'>
<xs:attribute name='encodingStyle' type='soap:encodingStyle' use='optional' />
<xs:attribute name='use' type='soap:useChoice' use='optional' />
<xs:attribute name='namespace' type='xs:anyURI' use='optional' />
</xs:attributeGroup>
<xs:complexType name='tBody'>
<xs:complexContent mixed='false'>
<xs:extension base='wsdl:tExtensibilityElement'>
<xs:attribute name='parts' type='xs:NMTOKENS' use='optional' />
<xs:attributeGroup ref='soap:tBodyAttributes' />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:simpleType name='useChoice'>
<xs:restriction base='xs:string'>
<xs:enumeration value='literal' />
<xs:enumeration value='encoded' />
</xs:restriction>
</xs:simpleType>
<xs:element name='fault' type='soap:tFault' />
<xs:complexType name='tFaultRes' abstract='true'>
<xs:complexContent mixed='false'>
<xs:restriction base='soap:tBody'>
<xs:attribute ref='wsdl:required' use='optional' />
<xs:attribute name='parts' type='xs:NMTOKENS' use='prohibited' />
<xs:attributeGroup ref='soap:tBodyAttributes' />
</xs:restriction>
</xs:complexContent>
</xs:complexType>
<xs:complexType name='tFault'>
<xs:complexContent mixed='false'>
<xs:extension base='soap:tFaultRes'>
<xs:attribute name='name' type='xs:NCName' use='required' />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name='header' type='soap:tHeader' />
<xs:attributeGroup name='tHeaderAttributes'>
<xs:attribute name='message' type='xs:QName' use='required' />
<xs:attribute name='part' type='xs:NMTOKEN' use='required' />
<xs:attribute name='use' type='soap:useChoice' use='required' />
<xs:attribute name='encodingStyle' type='soap:encodingStyle' use='optional' />
<xs:attribute name='namespace' type='xs:anyURI' use='optional' />
</xs:attributeGroup>
<xs:complexType name='tHeader'>
<xs:complexContent mixed='false'>
<xs:extension base='wsdl:tExtensibilityElement'>
<xs:sequence>
<xs:element minOccurs='0' maxOccurs='unbounded' ref='soap:headerfault' />
</xs:sequence>
<xs:attributeGroup ref='soap:tHeaderAttributes' />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name='headerfault' type='soap:tHeaderFault' />
<xs:complexType name='tHeaderFault'>
<xs:attributeGroup ref='soap:tHeaderAttributes' />
</xs:complexType>
<xs:element name='address' type='soap:tAddress' />
<xs:complexType name='tAddress'>
<xs:complexContent mixed='false'>
<xs:extension base='wsdl:tExtensibilityElement'>
<xs:attribute name='location' type='xs:anyURI' use='required' />
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>";
const string soapEncoding = @"<?xml version='1.0' encoding='UTF-8' ?>
<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'
xmlns:tns='http://schemas.xmlsoap.org/soap/encoding/'
targetNamespace='http://schemas.xmlsoap.org/soap/encoding/' >
<xs:attribute name='root' >
<xs:simpleType>
<xs:restriction base='xs:boolean'>
<xs:pattern value='0|1' />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attributeGroup name='commonAttributes' >
<xs:attribute name='id' type='xs:ID' />
<xs:attribute name='href' type='xs:anyURI' />
<xs:anyAttribute namespace='##other' processContents='lax' />
</xs:attributeGroup>
<xs:simpleType name='arrayCoordinate' >
<xs:restriction base='xs:string' />
</xs:simpleType>
<xs:attribute name='arrayType' type='xs:string' />
<xs:attribute name='offset' type='tns:arrayCoordinate' />
<xs:attributeGroup name='arrayAttributes' >
<xs:attribute ref='tns:arrayType' />
<xs:attribute ref='tns:offset' />
</xs:attributeGroup>
<xs:attribute name='position' type='tns:arrayCoordinate' />
<xs:attributeGroup name='arrayMemberAttributes' >
<xs:attribute ref='tns:position' />
</xs:attributeGroup>
<xs:group name='Array' >
<xs:sequence>
<xs:any namespace='##any' minOccurs='0' maxOccurs='unbounded' processContents='lax' />
</xs:sequence>
</xs:group>
<xs:element name='Array' type='tns:Array' />
<xs:complexType name='Array' >
<xs:group ref='tns:Array' minOccurs='0' />
<xs:attributeGroup ref='tns:arrayAttributes' />
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:complexType>
<xs:element name='Struct' type='tns:Struct' />
<xs:group name='Struct' >
<xs:sequence>
<xs:any namespace='##any' minOccurs='0' maxOccurs='unbounded' processContents='lax' />
</xs:sequence>
</xs:group>
<xs:complexType name='Struct' >
<xs:group ref='tns:Struct' minOccurs='0' />
<xs:attributeGroup ref='tns:commonAttributes'/>
</xs:complexType>
<xs:simpleType name='base64' >
<xs:restriction base='xs:base64Binary' />
</xs:simpleType>
<xs:element name='duration' type='tns:duration' />
<xs:complexType name='duration' >
<xs:simpleContent>
<xs:extension base='xs:duration' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='dateTime' type='tns:dateTime' />
<xs:complexType name='dateTime' >
<xs:simpleContent>
<xs:extension base='xs:dateTime' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='NOTATION' type='tns:NOTATION' />
<xs:complexType name='NOTATION' >
<xs:simpleContent>
<xs:extension base='xs:QName' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='time' type='tns:time' />
<xs:complexType name='time' >
<xs:simpleContent>
<xs:extension base='xs:time' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='date' type='tns:date' />
<xs:complexType name='date' >
<xs:simpleContent>
<xs:extension base='xs:date' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='gYearMonth' type='tns:gYearMonth' />
<xs:complexType name='gYearMonth' >
<xs:simpleContent>
<xs:extension base='xs:gYearMonth' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='gYear' type='tns:gYear' />
<xs:complexType name='gYear' >
<xs:simpleContent>
<xs:extension base='xs:gYear' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='gMonthDay' type='tns:gMonthDay' />
<xs:complexType name='gMonthDay' >
<xs:simpleContent>
<xs:extension base='xs:gMonthDay' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='gDay' type='tns:gDay' />
<xs:complexType name='gDay' >
<xs:simpleContent>
<xs:extension base='xs:gDay' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='gMonth' type='tns:gMonth' />
<xs:complexType name='gMonth' >
<xs:simpleContent>
<xs:extension base='xs:gMonth' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='boolean' type='tns:boolean' />
<xs:complexType name='boolean' >
<xs:simpleContent>
<xs:extension base='xs:boolean' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='base64Binary' type='tns:base64Binary' />
<xs:complexType name='base64Binary' >
<xs:simpleContent>
<xs:extension base='xs:base64Binary' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='hexBinary' type='tns:hexBinary' />
<xs:complexType name='hexBinary' >
<xs:simpleContent>
<xs:extension base='xs:hexBinary' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='float' type='tns:float' />
<xs:complexType name='float' >
<xs:simpleContent>
<xs:extension base='xs:float' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='double' type='tns:double' />
<xs:complexType name='double' >
<xs:simpleContent>
<xs:extension base='xs:double' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='anyURI' type='tns:anyURI' />
<xs:complexType name='anyURI' >
<xs:simpleContent>
<xs:extension base='xs:anyURI' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='QName' type='tns:QName' />
<xs:complexType name='QName' >
<xs:simpleContent>
<xs:extension base='xs:QName' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='string' type='tns:string' />
<xs:complexType name='string' >
<xs:simpleContent>
<xs:extension base='xs:string' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='normalizedString' type='tns:normalizedString' />
<xs:complexType name='normalizedString' >
<xs:simpleContent>
<xs:extension base='xs:normalizedString' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='token' type='tns:token' />
<xs:complexType name='token' >
<xs:simpleContent>
<xs:extension base='xs:token' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='language' type='tns:language' />
<xs:complexType name='language' >
<xs:simpleContent>
<xs:extension base='xs:language' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='Name' type='tns:Name' />
<xs:complexType name='Name' >
<xs:simpleContent>
<xs:extension base='xs:Name' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='NMTOKEN' type='tns:NMTOKEN' />
<xs:complexType name='NMTOKEN' >
<xs:simpleContent>
<xs:extension base='xs:NMTOKEN' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='NCName' type='tns:NCName' />
<xs:complexType name='NCName' >
<xs:simpleContent>
<xs:extension base='xs:NCName' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='NMTOKENS' type='tns:NMTOKENS' />
<xs:complexType name='NMTOKENS' >
<xs:simpleContent>
<xs:extension base='xs:NMTOKENS' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='ID' type='tns:ID' />
<xs:complexType name='ID' >
<xs:simpleContent>
<xs:extension base='xs:ID' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='IDREF' type='tns:IDREF' />
<xs:complexType name='IDREF' >
<xs:simpleContent>
<xs:extension base='xs:IDREF' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='ENTITY' type='tns:ENTITY' />
<xs:complexType name='ENTITY' >
<xs:simpleContent>
<xs:extension base='xs:ENTITY' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='IDREFS' type='tns:IDREFS' />
<xs:complexType name='IDREFS' >
<xs:simpleContent>
<xs:extension base='xs:IDREFS' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='ENTITIES' type='tns:ENTITIES' />
<xs:complexType name='ENTITIES' >
<xs:simpleContent>
<xs:extension base='xs:ENTITIES' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='decimal' type='tns:decimal' />
<xs:complexType name='decimal' >
<xs:simpleContent>
<xs:extension base='xs:decimal' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='integer' type='tns:integer' />
<xs:complexType name='integer' >
<xs:simpleContent>
<xs:extension base='xs:integer' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='nonPositiveInteger' type='tns:nonPositiveInteger' />
<xs:complexType name='nonPositiveInteger' >
<xs:simpleContent>
<xs:extension base='xs:nonPositiveInteger' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='negativeInteger' type='tns:negativeInteger' />
<xs:complexType name='negativeInteger' >
<xs:simpleContent>
<xs:extension base='xs:negativeInteger' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='long' type='tns:long' />
<xs:complexType name='long' >
<xs:simpleContent>
<xs:extension base='xs:long' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='int' type='tns:int' />
<xs:complexType name='int' >
<xs:simpleContent>
<xs:extension base='xs:int' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='short' type='tns:short' />
<xs:complexType name='short' >
<xs:simpleContent>
<xs:extension base='xs:short' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='byte' type='tns:byte' />
<xs:complexType name='byte' >
<xs:simpleContent>
<xs:extension base='xs:byte' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='nonNegativeInteger' type='tns:nonNegativeInteger' />
<xs:complexType name='nonNegativeInteger' >
<xs:simpleContent>
<xs:extension base='xs:nonNegativeInteger' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='unsignedLong' type='tns:unsignedLong' />
<xs:complexType name='unsignedLong' >
<xs:simpleContent>
<xs:extension base='xs:unsignedLong' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='unsignedInt' type='tns:unsignedInt' />
<xs:complexType name='unsignedInt' >
<xs:simpleContent>
<xs:extension base='xs:unsignedInt' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='unsignedShort' type='tns:unsignedShort' />
<xs:complexType name='unsignedShort' >
<xs:simpleContent>
<xs:extension base='xs:unsignedShort' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='unsignedByte' type='tns:unsignedByte' />
<xs:complexType name='unsignedByte' >
<xs:simpleContent>
<xs:extension base='xs:unsignedByte' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='positiveInteger' type='tns:positiveInteger' />
<xs:complexType name='positiveInteger' >
<xs:simpleContent>
<xs:extension base='xs:positiveInteger' >
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name='anyType' />
</xs:schema>";
const string fakeXsd = @"<?xml version='1.0' encoding='UTF-8' ?>
<xsd:schema targetNamespace=""http://www.w3.org/2001/XMLSchema"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
<xsd:element name=""schema"">
<xsd:complexType />
</xsd:element>
</xsd:schema>";
const string fakeXmlSchema = @"<xs:schema targetNamespace='http://www.w3.org/XML/1998/namespace' xmlns:xs='http://www.w3.org/2001/XMLSchema' xml:lang='en'>
<xs:attribute name='lang' type='xs:language'/>
<xs:attribute name='space'>
<xs:simpleType>
<xs:restriction base='xs:NCName'>
<xs:enumeration value='default'/>
<xs:enumeration value='preserve'/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name='base' type='xs:anyURI'/>
<xs:attribute name='id' type='xs:ID' />
<xs:attributeGroup name='specialAttrs'>
<xs:attribute ref='xml:base'/>
<xs:attribute ref='xml:lang'/>
<xs:attribute ref='xml:space'/>
</xs:attributeGroup>
</xs:schema>";
const string fakeSoapEncoding = @"<?xml version='1.0' encoding='UTF-8' ?>
<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'
xmlns:tns='http://schemas.xmlsoap.org/soap/encoding/'
targetNamespace='http://schemas.xmlsoap.org/soap/encoding/' >
<xs:attributeGroup name='commonAttributes' >
<xs:attribute name='id' type='xs:ID' />
<xs:attribute name='href' type='xs:anyURI' />
<xs:anyAttribute namespace='##other' processContents='lax' />
</xs:attributeGroup>
<xs:simpleType name='arrayCoordinate' >
<xs:restriction base='xs:string' />
</xs:simpleType>
<xs:attribute name='arrayType' type='xs:string' />
<xs:attribute name='offset' type='tns:arrayCoordinate' />
<xs:attributeGroup name='arrayAttributes' >
<xs:attribute ref='tns:arrayType' />
<xs:attribute ref='tns:offset' />
</xs:attributeGroup>
<xs:group name='Array' >
<xs:sequence>
<xs:any namespace='##any' minOccurs='0' maxOccurs='unbounded' processContents='lax' />
</xs:sequence>
</xs:group>
<xs:element name='Array' type='tns:Array' />
<xs:complexType name='Array' >
<xs:group ref='tns:Array' minOccurs='0' />
<xs:attributeGroup ref='tns:arrayAttributes' />
<xs:attributeGroup ref='tns:commonAttributes' />
</xs:complexType>
</xs:schema>";
}
}
|