Added methods for getting extension importers and reflectors.
* ProtocolImporter.cs: Implemented.
* ProtocolReflector.cs: Implemented.
* ServiceDescriptionCollection.cs: Fixed some methods for finding wsdl
elements.
* ServiceDescriptionImporter.cs: moved most of the code to ProtocolImporter.
* ServiceDescriptionReflector.cs: moved most of the code to
ProtocolReflector and SoapProtocolReflector.
* SoapProtocolImporter.cs: Implemented.
* SoapProtocolReflector.cs: Implemented.
* SoapTransportImporter.cs: Implemented.
* SoapHttpTransportImporter.cs: Implemented.
* wsdl.genxs: Added.
svn path=/trunk/mcs/; revision=18345
+2003-09-28 Lluis Sanchez Gual <lluis@ximian.com>
+
+ * ExtensionManager.cs: Read extension types from the configuration file.
+ Added methods for getting extension importers and reflectors.
+ * ProtocolImporter.cs: Implemented.
+ * ProtocolReflector.cs: Implemented.
+ * ServiceDescriptionCollection.cs: Fixed some methods for finding wsdl
+ elements.
+ * ServiceDescriptionImporter.cs: moved most of the code to ProtocolImporter.
+ * ServiceDescriptionReflector.cs: moved most of the code to
+ ProtocolReflector and SoapProtocolReflector.
+ * SoapProtocolImporter.cs: Implemented.
+ * SoapProtocolReflector.cs: Implemented.
+ * SoapTransportImporter.cs: Implemented.
+ * SoapHttpTransportImporter.cs: Implemented.
+ * wsdl.genxs: Added.
+
2003-09-14 Lluis Sanchez Gual <lluis@ximian.com>
* DocumentableItem.cs MimeContentBinding.cs OperationMessage.cs
RegisterExtensionType (typeof (SoapHeaderBinding));\r
RegisterExtensionType (typeof (SoapHeaderFaultBinding));\r
RegisterExtensionType (typeof (SoapOperationBinding));\r
+ \r
+ foreach (Type type in WSConfig.Instance.FormatExtensionTypes)\r
+ RegisterExtensionType (type);\r
}\r
\r
public static void RegisterExtensionType (Type type)\r
ext.ElementName = at.ElementName;\r
if (at.Namespace != null) ext.Namespace = at.Namespace;\r
}\r
- \r
+\r
XmlRootAttribute root = new XmlRootAttribute ();\r
root.ElementName = ext.ElementName;\r
if (ext.Namespace != null) root.Namespace = ext.Namespace;\r
throw new InvalidOperationException ("XmlFormatExtensionPointAttribute: Member " + at.MemberName + " not found");\r
}\r
}\r
+ \r
+ public static ArrayList BuildExtensionImporters ()\r
+ {\r
+ return BuildExtensionList (WSConfig.Instance.ExtensionImporterTypes);\r
+ }\r
+ \r
+ public static ArrayList BuildExtensionReflectors ()\r
+ {\r
+ return BuildExtensionList (WSConfig.Instance.ExtensionReflectorTypes);\r
+ }\r
+ \r
+ public static ArrayList BuildExtensionList (ArrayList exts)\r
+ {\r
+ ArrayList extensionTypes = new ArrayList ();\r
+ \r
+ if (exts != null)\r
+ {\r
+ foreach (WSExtensionConfig econf in exts)\r
+ {\r
+ bool added = false;\r
+ for (int n=0; n<extensionTypes.Count && !added; n++)\r
+ {\r
+ WSExtensionConfig cureconf = (WSExtensionConfig) extensionTypes [n];\r
+ \r
+ if ((econf.Group < cureconf.Group) || ((econf.Group == cureconf.Group) && (econf.Priority < cureconf.Priority))) {\r
+ extensionTypes.Insert (n, econf);\r
+ added = true;\r
+ }\r
+ }\r
+ if (!added) extensionTypes.Add (econf);\r
+ }\r
+ }\r
+\r
+ ArrayList extensions = new ArrayList (extensionTypes.Count);\r
+ foreach (WSExtensionConfig econf in extensionTypes)\r
+ extensions.Add (Activator.CreateInstance (econf.Type));\r
+ \r
+ return extensions;\r
+ }\r
}\r
\r
internal class ExtensionInfo\r
-// \r
-// System.Web.Services.Description.ProtocolImporter.cs\r
-//\r
-// Author:\r
-// Tim Coleman (tim@timcoleman.com)\r
-//\r
-// Copyright (C) Tim Coleman, 2002\r
-//\r
-\r
-using System.CodeDom;\r
-using System.Web.Services;\r
-using System.Xml.Serialization;\r
-\r
-namespace System.Web.Services.Description {\r
- public abstract class ProtocolImporter {\r
-\r
- #region Fields\r
-\r
- XmlSchemas abstractSchemas;\r
- Binding binding;\r
- string className;\r
- CodeIdentifiers classNames;\r
- CodeNamespace codeNamespace;\r
- CodeTypeDeclaration codeTypeDeclaration;\r
- XmlSchemas concreteSchemas;\r
- Message inputMessage;\r
- string methodName;\r
- Operation operation;\r
- OperationBinding operationBinding;\r
- Message outputMessage; \r
- Port port;\r
- PortType portType;\r
- string protocolName;\r
- XmlSchemas schemas;\r
- Service service;\r
- ServiceDescriptionCollection serviceDescriptions;\r
- ServiceDescriptionImportStyle style;\r
- ServiceDescriptionImportWarnings warnings; \r
-\r
- #endregion // Fields\r
-\r
- #region Constructors\r
- \r
- [MonoTODO] \r
- protected ProtocolImporter ()\r
- {\r
- throw new NotImplementedException ();\r
- }\r
- \r
- #endregion // Constructors\r
-\r
- #region Properties\r
-\r
- public XmlSchemas AbstractSchemas {\r
- get { return abstractSchemas; }\r
- }\r
-\r
- public Binding Binding {\r
- get { return binding; }\r
- }\r
-\r
- public string ClassName {\r
- get { return className; }\r
- }\r
-\r
- public CodeIdentifiers ClassNames {\r
- get { return classNames; }\r
- }\r
-\r
- public CodeNamespace CodeNamespace {\r
- get { return codeNamespace; }\r
- }\r
-\r
- public CodeTypeDeclaration CodeTypeDeclaration {\r
- get { return codeTypeDeclaration; }\r
- }\r
-\r
- public XmlSchemas ConcreteSchemas {\r
- get { return concreteSchemas; }\r
- }\r
-\r
- public Message InputMessage {\r
- get { return inputMessage; }\r
- }\r
-\r
- public string MethodName {\r
- get { return methodName; }\r
- }\r
-\r
- public Operation Operation {\r
- get { return operation; }\r
- }\r
-\r
- public OperationBinding OperationBinding {\r
- get { return operationBinding; }\r
- }\r
-\r
- public Message OutputMessage {\r
- get { return outputMessage; }\r
- }\r
-\r
- public Port Port {\r
- get { return port; }\r
- }\r
-\r
- public PortType PortType {\r
- get { return portType; }\r
- }\r
-\r
- public abstract string ProtocolName {\r
- get; \r
- }\r
-\r
- public XmlSchemas Schemas {\r
- get { return schemas; }\r
- }\r
-\r
- public Service Service {\r
- get { return service; } \r
- }\r
-\r
- public ServiceDescriptionCollection ServiceDescriptions {\r
- get { return serviceDescriptions; }\r
- }\r
-\r
- public ServiceDescriptionImportStyle Style {\r
- get { return style; }\r
- }\r
-\r
- public ServiceDescriptionImportWarnings Warnings {\r
- get { return warnings; }\r
- set { warnings = value; }\r
- }\r
-\r
- #endregion // Properties\r
-\r
- #region Methods\r
-\r
- [MonoTODO]\r
- public void AddExtensionWarningComments (CodeCommentStatementCollection comments, ServiceDescriptionFormatExtensionCollection extensions) \r
- {\r
- throw new NotImplementedException ();\r
- }\r
-\r
- protected abstract CodeTypeDeclaration BeginClass ();\r
-\r
- [MonoTODO]\r
- protected virtual void BeginNamespace ()\r
- {\r
- throw new NotImplementedException ();\r
- }\r
-\r
- [MonoTODO]\r
- protected virtual void EndClass ()\r
- {\r
- throw new NotImplementedException ();\r
- }\r
-\r
- [MonoTODO]\r
- protected virtual void EndNamespace ()\r
- {\r
- throw new NotImplementedException ();\r
- }\r
-\r
- protected abstract CodeMemberMethod GenerateMethod ();\r
- protected abstract bool IsBindingSupported ();\r
- protected abstract bool IsOperationFlowSupported (OperationFlow flow);\r
- \r
- [MonoTODO]\r
- public Exception OperationBindingSyntaxException (string text)\r
- {\r
- throw new NotImplementedException ();\r
- }\r
-\r
- [MonoTODO]\r
- public Exception OperationSyntaxException (string text)\r
- {\r
- throw new NotImplementedException ();\r
- }\r
-\r
- [MonoTODO]\r
- public void UnsupportedBindingWarning (string text)\r
- {\r
- throw new NotImplementedException ();\r
- }\r
-\r
- [MonoTODO]\r
- public void UnsupportedOperationBindingWarning (string text)\r
- {\r
- throw new NotImplementedException ();\r
- }\r
-\r
- [MonoTODO]\r
- public void UnsupportedOperationWarning (string text)\r
- {\r
- throw new NotImplementedException ();\r
- }\r
-\r
- #endregion\r
- }\r
-}\r
+//
+// System.Web.Services.Description.ProtocolImporter.cs
+//
+// Author:
+// Tim Coleman (tim@timcoleman.com)
+// Lluis Sanchez Gual (lluis@ximian.com)
+//
+// Copyright (C) Tim Coleman, 2002
+//
+
+using System;
+using System.CodeDom;
+using System.Web.Services;
+using System.Web.Services.Protocols;
+using System.Xml.Serialization;
+using System.Xml;
+using System.Collections;
+using System.Configuration;
+
+namespace System.Web.Services.Description {
+ public abstract class ProtocolImporter {
+
+ #region Fields
+
+ Binding binding;
+ string className;
+ CodeIdentifiers classNames;
+ CodeNamespace codeNamespace;
+ CodeCompileUnit codeCompileUnit;
+ CodeTypeDeclaration codeTypeDeclaration;
+ Message inputMessage;
+ string methodName;
+ Operation operation;
+ OperationBinding operationBinding;
+ Message outputMessage;
+ Port port;
+ PortType portType;
+ string protocolName;
+ Service service;
+ ServiceDescriptionImportWarnings warnings = (ServiceDescriptionImportWarnings)0;
+ ServiceDescriptionImporter descriptionImporter;
+ ImportInfo iinfo;
+
+ #endregion // Fields
+
+ #region Constructors
+
+ protected ProtocolImporter ()
+ {
+ }
+
+ #endregion // Constructors
+
+ #region Properties
+
+ [MonoTODO]
+ public XmlSchemas AbstractSchemas {
+ get { return descriptionImporter.Schemas; }
+ }
+
+ public Binding Binding {
+ get { return binding; }
+ }
+
+ public string ClassName {
+ get { return className; }
+ }
+
+ public CodeIdentifiers ClassNames {
+ get { return classNames; }
+ }
+
+ public CodeNamespace CodeNamespace {
+ get { return codeNamespace; }
+ }
+
+ public CodeTypeDeclaration CodeTypeDeclaration {
+ get { return codeTypeDeclaration; }
+ }
+
+ [MonoTODO]
+ public XmlSchemas ConcreteSchemas {
+ get { return descriptionImporter.Schemas; }
+ }
+
+ public Message InputMessage {
+ get { return inputMessage; }
+ }
+
+ public string MethodName {
+ get { return methodName; }
+ }
+
+ public Operation Operation {
+ get { return operation; }
+ }
+
+ public OperationBinding OperationBinding {
+ get { return operationBinding; }
+ }
+
+ public Message OutputMessage {
+ get { return outputMessage; }
+ }
+
+ public Port Port {
+ get { return port; }
+ }
+
+ public PortType PortType {
+ get { return portType; }
+ }
+
+ public abstract string ProtocolName {
+ get;
+ }
+
+ public XmlSchemas Schemas {
+ get { return descriptionImporter.Schemas; }
+ }
+
+ public Service Service {
+ get { return service; }
+ }
+
+ public ServiceDescriptionCollection ServiceDescriptions {
+ get { return descriptionImporter.ServiceDescriptions; }
+ }
+
+ public ServiceDescriptionImportStyle Style {
+ get { return descriptionImporter.Style; }
+ }
+
+ public ServiceDescriptionImportWarnings Warnings {
+ get { return warnings; }
+ set { warnings = value; }
+ }
+
+ internal ImportInfo ImportInfo
+ {
+ get { return iinfo; }
+ }
+
+ #endregion // Properties
+
+ #region Methods
+
+ internal void Import (ServiceDescriptionImporter descriptionImporter, CodeNamespace codeNamespace, CodeCompileUnit codeCompileUnit, ArrayList importInfo)
+ {
+ this.descriptionImporter = descriptionImporter;
+ warnings = (ServiceDescriptionImportWarnings) 0;
+
+ this.codeNamespace = codeNamespace;
+ this.codeCompileUnit = codeCompileUnit;
+
+ bool classesGenerated = false;
+ classNames = new CodeIdentifiers();
+
+ BeginNamespace ();
+
+ foreach (ImportInfo info in importInfo)
+ {
+ iinfo = info;
+ foreach (Service s in info.ServiceDescription.Services)
+ {
+ service = s;
+ foreach (Port p in service.Ports)
+ {
+ port = p;
+ classesGenerated = ImportPortBinding () || classesGenerated;
+ }
+ }
+ }
+
+ EndNamespace ();
+
+ if (!classesGenerated) warnings |= ServiceDescriptionImportWarnings.NoCodeGenerated;
+ }
+
+ bool ImportPortBinding ()
+ {
+ if (service.Ports.Count > 1) className = port.Name;
+ else className = service.Name;
+
+ className = classNames.AddUnique (CodeIdentifier.MakeValid (className), port);
+ binding = ServiceDescriptions.GetBinding (port.Binding);
+
+ try
+ {
+ portType = ServiceDescriptions.GetPortType (binding.Type);
+ if (portType == null) throw new Exception ("Port type not found: " + binding.Type);
+
+ CodeTypeDeclaration codeClass = BeginClass ();
+ codeTypeDeclaration = codeClass;
+ AddCodeType (codeClass, port.Documentation);
+ codeClass.Attributes = MemberAttributes.Public;
+
+ if (service.Documentation != null && service.Documentation != "")
+ AddComments (codeClass, service.Documentation);
+
+ CodeAttributeDeclaration att = new CodeAttributeDeclaration ("System.Diagnostics.DebuggerStepThroughAttribute");
+ AddCustomAttribute (codeClass, att, true);
+
+ att = new CodeAttributeDeclaration ("System.ComponentModel.DesignerCategoryAttribute");
+ att.Arguments.Add (GetArg ("code"));
+ AddCustomAttribute (codeClass, att, true);
+
+ att = new CodeAttributeDeclaration ("System.Web.Services.WebServiceBinding");
+ att.Arguments.Add (GetArg ("Name", port.Name));
+ att.Arguments.Add (GetArg ("Namespace", port.Binding.Namespace));
+ AddCustomAttribute (codeClass, att, true);
+
+ if (binding.Operations.Count == 0) {
+ warnings |= ServiceDescriptionImportWarnings.NoMethodsGenerated;
+ return true;
+ }
+
+ foreach (OperationBinding oper in binding.Operations)
+ {
+ operationBinding = oper;
+ operation = FindPortOperation ();
+ if (operation == null) throw new Exception ("Operation " + operationBinding.Name + " not found in portType " + PortType.Name);
+
+ foreach (OperationMessage omsg in operation.Messages)
+ {
+ Message msg = ServiceDescriptions.GetMessage (omsg.Message);
+ if (msg == null) throw new Exception ("Message not found: " + omsg.Message);
+
+ if (omsg is OperationInput)
+ inputMessage = msg;
+ else
+ outputMessage = msg;
+ }
+
+ CodeMemberMethod method = GenerateMethod ();
+ methodName = method.Name;
+
+ if (operation.Documentation != null && operation.Documentation != "")
+ AddComments (method, operation.Documentation);
+ }
+
+ EndClass ();
+ }
+ catch (Exception ex)
+ {
+ UnsupportedBindingWarning (ex.Message);
+ return false;
+ }
+ return true;
+ }
+
+ Operation FindPortOperation ()
+ {
+ string inMessage = (operationBinding.Input.Name != "") ? operationBinding.Input.Name : operationBinding.Name;
+ string outMessage = (operationBinding.Output.Name != "") ? operationBinding.Output.Name : operationBinding.Name;
+ string operName = operationBinding.Name;
+
+ foreach (Operation oper in PortType.Operations)
+ {
+ if (oper.Name == operName)
+ {
+ int hits = 0;
+ foreach (OperationMessage omsg in oper.Messages)
+ {
+ if (omsg is OperationInput && GetOperMessageName (omsg, operName) == inMessage) hits++;
+ if (omsg is OperationOutput && GetOperMessageName (omsg, operName) == outMessage) hits++;
+ }
+ if (hits == 2) return oper;
+ }
+ }
+ return null;
+ }
+
+ string GetOperMessageName (OperationMessage msg, string operName)
+ {
+ if (msg.Name == null) return operName;
+ else return msg.Name;
+ }
+
+ [MonoTODO]
+ public void AddExtensionWarningComments (CodeCommentStatementCollection comments, ServiceDescriptionFormatExtensionCollection extensions)
+ {
+ throw new NotImplementedException ();
+ }
+
+ protected abstract CodeTypeDeclaration BeginClass ();
+
+ protected virtual void BeginNamespace ()
+ {
+ }
+
+ protected virtual void EndClass ()
+ {
+ }
+
+ protected virtual void EndNamespace ()
+ {
+ }
+
+ protected abstract CodeMemberMethod GenerateMethod ();
+ protected abstract bool IsBindingSupported ();
+ protected abstract bool IsOperationFlowSupported (OperationFlow flow);
+
+ [MonoTODO]
+ public Exception OperationBindingSyntaxException (string text)
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public Exception OperationSyntaxException (string text)
+ {
+ throw new NotImplementedException ();
+ }
+
+ public void UnsupportedBindingWarning (string text)
+ {
+ AddGlobalComments ("WARNING: Could not generate proxy for binding " + binding.Name + ". " + text);
+ }
+
+ public void UnsupportedOperationBindingWarning (string text)
+ {
+ AddGlobalComments ("WARNING: Could not generate operation " + OperationBinding.Name + ". " + text);
+ }
+
+ public void UnsupportedOperationWarning (string text)
+ {
+ AddGlobalComments ("WARNING: Could not generate operation " + OperationBinding.Name + ". " + text);
+ }
+
+ void AddGlobalComments (string comments)
+ {
+ codeNamespace.Comments.Add (new CodeCommentStatement (comments, false));
+ }
+
+ void AddComments (CodeTypeMember member, string comments)
+ {
+ if (comments == null || comments == "") member.Comments.Add (new CodeCommentStatement ("<remarks/>", true));
+ else member.Comments.Add (new CodeCommentStatement ("<remarks>\n" + comments + "\n</remarks>", true));
+ }
+
+ void AddCodeType (CodeTypeDeclaration type, string comments)
+ {
+ AddComments (type, comments);
+ codeNamespace.Types.Add (type);
+ }
+
+ internal void AddCustomAttribute (CodeTypeMember ctm, CodeAttributeDeclaration att, bool addIfNoParams)
+ {
+ if (att.Arguments.Count == 0 && !addIfNoParams) return;
+
+ if (ctm.CustomAttributes == null) ctm.CustomAttributes = new CodeAttributeDeclarationCollection ();
+ ctm.CustomAttributes.Add (att);
+ }
+
+ internal void AddCustomAttribute (CodeTypeMember ctm, string name, params CodeAttributeArgument[] args)
+ {
+ if (ctm.CustomAttributes == null) ctm.CustomAttributes = new CodeAttributeDeclarationCollection ();
+ ctm.CustomAttributes.Add (new CodeAttributeDeclaration (name, args));
+ }
+
+ internal CodeAttributeArgument GetArg (string name, object value)
+ {
+ return new CodeAttributeArgument (name, new CodePrimitiveExpression(value));
+ }
+
+ internal CodeAttributeArgument GetEnumArg (string name, string enumType, string enumValue)
+ {
+ return new CodeAttributeArgument (name, new CodeFieldReferenceExpression (new CodeTypeReferenceExpression(enumType), enumValue));
+ }
+
+ internal CodeAttributeArgument GetArg (object value)
+ {
+ return new CodeAttributeArgument (new CodePrimitiveExpression(value));
+ }
+
+ internal CodeAttributeArgument GetTypeArg (string name, string typeName)
+ {
+ return new CodeAttributeArgument (name, new CodeTypeOfExpression(typeName));
+ }
+
+ #endregion
+ }
+}
-// \r
-// System.Web.Services.Description.ProtocolReflector.cs\r
-//\r
-// Author:\r
-// Tim Coleman (tim@timcoleman.com)\r
-//\r
-// Copyright (C) Tim Coleman, 2002\r
-//\r
-\r
-using System.Web.Services;\r
-using System.Web.Services.Protocols;\r
-using System.Xml.Serialization;\r
-\r
-namespace System.Web.Services.Description {\r
- public abstract class ProtocolReflector {\r
-\r
- #region Fields\r
-\r
- Binding binding;\r
- string defaultNamespace;\r
- MessageCollection headerMessages;\r
- Message inputMessage;\r
- LogicalMethodInfo method;\r
- WebMethodAttribute methodAttribute;\r
- LogicalMethodInfo[] methods;\r
- Operation operation;\r
- OperationBinding operationBinding;\r
- Message outputMessage; \r
- Port port;\r
- PortType portType;\r
- string protocolName;\r
- XmlReflectionImporter reflectionImporter;\r
- XmlSchemaExporter schemaExporter;\r
- XmlSchemas schemas;\r
- Service service;\r
- ServiceDescription serviceDescription;\r
- ServiceDescriptionCollection serviceDescriptions;\r
- Type serviceType;\r
- string serviceUrl;\r
-\r
- #endregion // Fields\r
-\r
- #region Constructors\r
- \r
- [MonoTODO] \r
- protected ProtocolReflector ()\r
- {\r
- throw new NotImplementedException ();\r
- }\r
- \r
- #endregion // Constructors\r
-\r
- #region Properties\r
-\r
- public Binding Binding {\r
- get { return binding; }\r
- }\r
-\r
- public string DefaultNamespace {\r
- get { return defaultNamespace; }\r
- }\r
-\r
- public MessageCollection HeaderMessages {\r
- get { return headerMessages; }\r
- }\r
-\r
- public Message InputMessage {\r
- get { return inputMessage; }\r
- }\r
-\r
- public LogicalMethodInfo Method {\r
- get { return method; }\r
- }\r
-\r
- public WebMethodAttribute MethodAttribute {\r
- get { return methodAttribute; }\r
- }\r
-\r
- public LogicalMethodInfo[] Methods {\r
- get { return methods; }\r
- }\r
- \r
- public Operation Operation {\r
- get { return operation; }\r
- }\r
-\r
- public OperationBinding OperationBinding {\r
- get { return operationBinding; }\r
- }\r
-\r
- public Message OutputMessage {\r
- get { return outputMessage; }\r
- }\r
-\r
- public Port Port {\r
- get { return port; }\r
- }\r
-\r
- public PortType PortType {\r
- get { return portType; }\r
- }\r
-\r
- public abstract string ProtocolName {\r
- get; \r
- }\r
-\r
- public XmlReflectionImporter ReflectionImporter {\r
- get { return reflectionImporter; }\r
- }\r
-\r
- public XmlSchemaExporter SchemaExporter {\r
- get { return schemaExporter; }\r
- }\r
-\r
- public XmlSchemas Schemas {\r
- get { return schemas; }\r
- }\r
-\r
- public Service Service {\r
- get { return service; }\r
- }\r
-\r
- public ServiceDescription ServiceDescription {\r
- get { return serviceDescription; }\r
- }\r
-\r
- public ServiceDescriptionCollection ServiceDescriptions {\r
- get { return serviceDescriptions; }\r
- }\r
-\r
- public Type ServiceType {\r
- get { return serviceType; }\r
- }\r
-\r
- public string ServiceUrl {\r
- get { return serviceUrl; }\r
- }\r
-\r
- #endregion // Properties\r
-\r
- #region Methods\r
-\r
- [MonoTODO]\r
- protected virtual void BeginClass ()\r
- {\r
- throw new NotImplementedException ();\r
- }\r
-\r
- [MonoTODO]\r
- protected virtual void EndClass ()\r
- {\r
- throw new NotImplementedException ();\r
- }\r
-\r
- public ServiceDescription GetServiceDescription (string ns)\r
- {\r
- return serviceDescriptions [ns];\r
- }\r
-\r
- protected abstract bool ReflectMethod ();\r
-\r
- [MonoTODO]\r
- protected virtual string ReflectMethodBinding ()\r
- {\r
- throw new NotImplementedException ();\r
- }\r
-\r
- #endregion\r
- }\r
-}\r
+//
+// System.Web.Services.Description.ProtocolReflector.cs
+//
+// Author:
+// Tim Coleman (tim@timcoleman.com)
+// Lluis Sanchez Gual (lluis@ximian.com)
+//
+// Copyright (C) Tim Coleman, 2002
+//
+
+using System.Web.Services;
+using System.Web.Services.Protocols;
+using System.Xml.Serialization;
+using System.Xml;
+using System.Xml.Schema;
+using System.Collections;
+
+namespace System.Web.Services.Description {
+ public abstract class ProtocolReflector {
+
+ #region Fields
+
+ Binding binding;
+ string defaultNamespace;
+ MessageCollection headerMessages;
+ Message inputMessage;
+ LogicalMethodInfo[] methods;
+ Operation operation;
+ OperationBinding operationBinding;
+ Message outputMessage;
+ Port port;
+ PortType portType;
+ string protocolName;
+ XmlSchemaExporter schemaExporter;
+ Service service;
+ ServiceDescription serviceDescription;
+ ServiceDescriptionCollection serviceDescriptions;
+ Type serviceType;
+ string serviceUrl;
+ SoapSchemaExporter soapSchemaExporter;
+ Types types;
+ MethodStubInfo methodStubInfo;
+ TypeStubInfo typeInfo;
+ ArrayList extensionReflectors;
+
+ #endregion // Fields
+
+ #region Constructors
+
+ protected ProtocolReflector ()
+ {
+ defaultNamespace = WebServiceAttribute.DefaultNamespace;
+ extensionReflectors = ExtensionManager.BuildExtensionReflectors ();
+ types = new Types ();
+ serviceDescriptions = new ServiceDescriptionCollection ();
+ }
+
+ #endregion // Constructors
+
+ #region Properties
+
+ public Binding Binding {
+ get { return binding; }
+ }
+
+ public string DefaultNamespace {
+ get { return defaultNamespace; }
+ }
+
+ public MessageCollection HeaderMessages {
+ get { return headerMessages; } // TODO: set
+ }
+
+ public Message InputMessage {
+ get { return inputMessage; }
+ }
+
+ public LogicalMethodInfo Method {
+ get { return methodStubInfo.MethodInfo; }
+ }
+
+ public WebMethodAttribute MethodAttribute {
+ get { return methodStubInfo.MethodAttribute; }
+ }
+
+ public LogicalMethodInfo[] Methods {
+ get { return methods; }
+ }
+
+ public Operation Operation {
+ get { return operation; }
+ }
+
+ public OperationBinding OperationBinding {
+ get { return operationBinding; }
+ }
+
+ public Message OutputMessage {
+ get { return outputMessage; }
+ }
+
+ public Port Port {
+ get { return port; }
+ }
+
+ public PortType PortType {
+ get { return portType; }
+ }
+
+ public abstract string ProtocolName {
+ get;
+ }
+
+ public XmlReflectionImporter ReflectionImporter {
+ get { return typeInfo.XmlImporter;; }
+ }
+
+ internal SoapReflectionImporter SoapReflectionImporter {
+ get { return typeInfo.SoapImporter;; }
+ }
+
+ public XmlSchemaExporter SchemaExporter {
+ get { return schemaExporter; }
+ }
+
+ public SoapSchemaExporter SoapSchemaExporter {
+ get { return soapSchemaExporter; }
+ }
+
+ public XmlSchemas Schemas {
+ get { return types.Schemas; }
+ }
+
+ public Service Service {
+ get { return service; }
+ }
+
+ public ServiceDescription ServiceDescription {
+ get { return serviceDescription; }
+ }
+
+ public ServiceDescriptionCollection ServiceDescriptions {
+ get { return serviceDescriptions; }
+ }
+
+ public Type ServiceType {
+ get { return serviceType; }
+ }
+
+ public string ServiceUrl {
+ get { return serviceUrl; }
+ }
+
+ internal MethodStubInfo MethodStubInfo {
+ get { return methodStubInfo; }
+ }
+
+ internal TypeStubInfo TypeInfo {
+ get { return typeInfo; }
+ }
+
+
+ #endregion // Properties
+
+ #region Methods
+
+ internal void Reflect (Type type, string url)
+ {
+ serviceUrl = url;
+ serviceType = type;
+
+ schemaExporter = new XmlSchemaExporter (types.Schemas);
+ soapSchemaExporter = new SoapSchemaExporter (types.Schemas);
+
+ typeInfo = TypeStubManager.GetTypeStub (type);
+
+ ServiceDescription desc = new ServiceDescription ();
+ desc.TargetNamespace = typeInfo.WebServiceNamespace;
+ desc.Name = typeInfo.WebServiceName;
+ serviceDescriptions.Add (desc);
+
+ methods = new LogicalMethodInfo[typeInfo.Methods.Count];
+ for (int n=0; n<typeInfo.Methods.Count; n++)
+ methods [n] = ((MethodStubInfo) typeInfo.Methods [n]).MethodInfo;
+
+ ImportService (desc, typeInfo, url);
+
+ if (serviceDescriptions.Count == 1)
+ desc.Types = types;
+ else
+ {
+ foreach (ServiceDescription d in serviceDescriptions)
+ {
+ d.Types = new Types();
+ for (int n=0; n<types.Schemas.Count; n++)
+ AddImport (d, types.Schemas[n].TargetNamespace, GetSchemaUrl (url, n));
+ }
+ }
+ }
+
+ void ImportService (ServiceDescription desc, TypeStubInfo typeInfo, string url)
+ {
+ service = new Service ();
+ service.Name = typeInfo.WebServiceName;
+ service.Documentation = typeInfo.Description;
+
+ desc.Services.Add (service);
+
+ foreach (BindingInfo binfo in typeInfo.Bindings)
+ ImportBinding (desc, service, typeInfo, url, binfo);
+ }
+
+ void ImportBinding (ServiceDescription desc, Service service, TypeStubInfo typeInfo, string url, BindingInfo binfo)
+ {
+ port = new Port ();
+ port.Name = binfo.Name;
+ port.Binding = new XmlQualifiedName (binfo.Name, binfo.Namespace);
+ service.Ports.Add (port);
+
+ if (binfo.Namespace != desc.TargetNamespace)
+ {
+ if (binfo.Location == null || binfo.Location == string.Empty)
+ {
+ ServiceDescription newDesc = new ServiceDescription();
+ newDesc.TargetNamespace = binfo.Namespace;
+ int id = serviceDescriptions.Add (newDesc);
+ AddImport (desc, binfo.Namespace, GetWsdlUrl (url,id));
+ ImportBindingContent (newDesc, typeInfo, url, binfo);
+ }
+ else
+ AddImport (desc, binfo.Namespace, binfo.Location);
+ }
+ else
+ ImportBindingContent (desc, typeInfo, url, binfo);
+ }
+
+ void ImportBindingContent (ServiceDescription desc, TypeStubInfo typeInfo, string url, BindingInfo binfo)
+ {
+ serviceDescription = desc;
+ binding = new Binding ();
+ binding.Name = binfo.Name;
+ binding.Type = new XmlQualifiedName (binfo.Name, binfo.Namespace);
+ desc.Bindings.Add (binding);
+
+ portType = new PortType ();
+ portType.Name = binding.Name;
+ desc.PortTypes.Add (portType);
+
+ BeginClass ();
+
+ foreach (MethodStubInfo method in typeInfo.Methods)
+ {
+ methodStubInfo = method;
+
+ string metBinding = ReflectMethodBinding ();
+ if (metBinding != null && (metBinding != binding.Name)) continue;
+
+ operation = new Operation ();
+ operation.Name = method.Name;
+ operation.Documentation = method.Description;
+
+ OperationInput inOp = new OperationInput ();
+ inOp.Message = ImportMessage (operation.Name + "SoapIn", method.InputMembersMapping, method, out inputMessage);
+ operation.Messages.Add (inOp);
+
+ OperationOutput outOp = new OperationOutput ();
+ outOp.Message = ImportMessage (operation.Name + "SoapOut", method.OutputMembersMapping, method, out outputMessage);
+ operation.Messages.Add (outOp);
+
+ portType.Operations.Add (operation);
+ ImportOperationBinding ();
+
+ ReflectMethod ();
+
+ foreach (SoapExtensionReflector reflector in extensionReflectors)
+ {
+ reflector.ReflectionContext = this;
+ reflector.ReflectMethod ();
+ }
+ }
+
+ EndClass ();
+ }
+
+ void ImportOperationBinding ()
+ {
+ operationBinding = new OperationBinding ();
+ operationBinding.Name = methodStubInfo.Name;
+
+ InputBinding inOp = new InputBinding ();
+ operationBinding.Input = inOp;
+
+ OutputBinding outOp = new OutputBinding ();
+ operationBinding.Output = outOp;
+
+ binding.Operations.Add (operationBinding);
+ }
+
+ XmlQualifiedName ImportMessage (string name, XmlMembersMapping members, MethodStubInfo method, out Message msg)
+ {
+ msg = new Message ();
+ msg.Name = name;
+
+ if (method.ParameterStyle == SoapParameterStyle.Wrapped)
+ {
+ MessagePart part = new MessagePart ();
+ part.Name = "parameters";
+ XmlQualifiedName qname = new XmlQualifiedName (members.ElementName, members.Namespace);
+ if (method.Use == SoapBindingUse.Literal) part.Element = qname;
+ else part.Type = qname;
+ msg.Parts.Add (part);
+ }
+ else
+ {
+ for (int n=0; n<members.Count; n++)
+ {
+ MessagePart part = new MessagePart ();
+ part.Name = members[n].MemberName;
+
+ if (method.Use == SoapBindingUse.Literal) {
+ part.Element = new XmlQualifiedName (members[n].MemberName, members[n].Namespace);
+ }
+ else {
+ string namesp = members[n].TypeNamespace;
+ if (namesp == "") namesp = XmlSchema.Namespace;
+ part.Type = new XmlQualifiedName (members[n].TypeName, namesp);
+ }
+ msg.Parts.Add (part);
+ }
+ }
+
+ serviceDescription.Messages.Add (msg);
+
+ if (method.Use == SoapBindingUse.Literal)
+ schemaExporter.ExportMembersMapping (members);
+ else
+ soapSchemaExporter.ExportMembersMapping (members);
+
+ return new XmlQualifiedName (name, members.Namespace);
+ }
+
+ void AddImport (ServiceDescription desc, string ns, string location)
+ {
+ Import im = new Import();
+ im.Namespace = ns;
+ im.Location = location;
+ desc.Imports.Add (im);
+ }
+
+ string GetWsdlUrl (string baseUrl, int id)
+ {
+ return baseUrl + "?wsdl=" + id;
+ }
+
+ string GetSchemaUrl (string baseUrl, int id)
+ {
+ return baseUrl + "?schema=" + id;
+ }
+
+ protected virtual void BeginClass ()
+ {
+ }
+
+ protected virtual void EndClass ()
+ {
+ }
+
+ public ServiceDescription GetServiceDescription (string ns)
+ {
+ return serviceDescriptions [ns];
+ }
+
+ protected abstract bool ReflectMethod ();
+
+ protected virtual string ReflectMethodBinding ()
+ {
+ return null;
+ }
+
+ #endregion
+ }
+}
//\r
// Author:\r
// Tim Coleman (tim@timcoleman.com)\r
+// Lluis Sanchez Gual (lluis@ximian.com)\r
//\r
// Copyright (C) Tim Coleman, 2002\r
//\r
\r
public ServiceDescription this [string ns] {\r
get { \r
- int index = IndexOf ((ServiceDescription) Table[ns]);\r
- if (index >= 0)\r
- return this[index]; \r
- return null;\r
+ return (ServiceDescription) Table[ns];\r
}\r
}\r
\r
\r
public Binding GetBinding (XmlQualifiedName name)\r
{\r
- foreach (object value in List) \r
- foreach (Binding binding in ((ServiceDescription) value).Bindings) \r
+ ServiceDescription desc = (ServiceDescription) Table[name.Namespace];\r
+ if (desc != null) {\r
+ foreach (Binding binding in desc.Bindings) \r
if (binding.Name == name.Name)\r
return binding;\r
- throw new Exception ();\r
+ }\r
+ throw new InvalidOperationException ("Binding '" + name + "' not found");\r
}\r
\r
protected override string GetKey (object value) \r
{\r
- if (!(value is ServiceDescription))\r
- throw new InvalidCastException ();\r
return ((ServiceDescription) value).TargetNamespace;\r
}\r
\r
public Message GetMessage (XmlQualifiedName name)\r
{\r
- foreach (object value in List) \r
- foreach (Message message in ((ServiceDescription) value).Messages) \r
+ ServiceDescription desc = (ServiceDescription) Table[name.Namespace];\r
+ if (desc != null) {\r
+ foreach (Message message in desc.Messages) \r
if (message.Name == name.Name)\r
return message;\r
- throw new Exception ();\r
+ }\r
+ throw new InvalidOperationException ("Message '" + name + "' not found");\r
}\r
\r
public PortType GetPortType (XmlQualifiedName name)\r
{\r
- foreach (object value in List) \r
- foreach (PortType portType in ((ServiceDescription) value).PortTypes) \r
+ ServiceDescription desc = (ServiceDescription) Table[name.Namespace];\r
+ if (desc != null) {\r
+ foreach (PortType portType in desc.PortTypes) \r
if (portType.Name == name.Name)\r
return portType;\r
- throw new Exception ();\r
+ }\r
+ throw new InvalidOperationException ("Port type '" + name + "' not found");\r
}\r
\r
public Service GetService (XmlQualifiedName name)\r
{\r
- foreach (object value in List) \r
- foreach (Service service in ((ServiceDescription) value).Services) \r
+ ServiceDescription desc = (ServiceDescription) Table[name.Namespace];\r
+ if (desc != null) {\r
+ foreach (Service service in desc.Services) \r
if (service.Name == name.Name)\r
return service;\r
- throw new Exception ();\r
+ }\r
+ throw new InvalidOperationException ("Service '" + name + "' not found");\r
}\r
\r
public int IndexOf (ServiceDescription serviceDescription)\r
\r
#endregion // Methods\r
}\r
-}\r
+}
XmlSchemas schemas;\r
ServiceDescriptionCollection serviceDescriptions;\r
ServiceDescriptionImportStyle style;\r
- CodeIdentifiers classIds;\r
- XmlSchemaImporter schemaImporter;\r
- SoapSchemaImporter soapSchemaImporter;\r
- XmlCodeExporter codeExporter;\r
- \r
- CodeNamespace codeNamespace;\r
- CodeCompileUnit codeCompileUnit;\r
- ServiceDescriptionImportWarnings warnings;\r
\r
ArrayList importInfo = new ArrayList ();\r
\r
- class ImportInfo\r
- {\r
- public ServiceDescription ServiceDescription;\r
- public string AppSettingUrlKey;\r
- public string AppSettingBaseUrl;\r
- }\r
-\r
\r
#endregion // Fields\r
\r
\r
public ServiceDescriptionImportWarnings Import (CodeNamespace codeNamespace, CodeCompileUnit codeCompileUnit)\r
{\r
- warnings = (ServiceDescriptionImportWarnings) 0;\r
- \r
- schemaImporter = new XmlSchemaImporter (schemas);\r
- soapSchemaImporter = new SoapSchemaImporter (schemas);\r
- codeExporter = new XmlCodeExporter (codeNamespace, codeCompileUnit);\r
+ ProtocolImporter importer = GetImporter ();\r
+ importer.Import (this, codeNamespace, codeCompileUnit, importInfo);\r
\r
- this.codeNamespace = codeNamespace;\r
- this.codeCompileUnit = codeCompileUnit;\r
-\r
- bool classesGenerated = false;\r
- classIds = new CodeIdentifiers();\r
- \r
- ArrayList services = new ArrayList ();\r
- foreach (ImportInfo info in importInfo)\r
- foreach (Service service in info.ServiceDescription.Services)\r
- foreach (Port port in service.Ports)\r
- classesGenerated = ImportPortBinding (service, info, port) || classesGenerated;\r
- \r
- if (!classesGenerated) SetWarning (ServiceDescriptionImportWarnings.NoCodeGenerated);\r
- return warnings;\r
- }\r
- \r
- bool ImportPortBinding (Service service, ImportInfo iinfo, Port port)\r
- {\r
- string className = classIds.AddUnique (CodeIdentifier.MakeValid (port.Name), port);\r
- Binding binding = serviceDescriptions.GetBinding (port.Binding);\r
- \r
- try\r
- {\r
- PortType portType = serviceDescriptions.GetPortType (binding.Type);\r
- if (portType == null) throw new Exception ("Port type not found: " + binding.Type);\r
-\r
- SoapBinding sb = (SoapBinding) binding.Extensions.Find (typeof(SoapBinding));\r
-\r
- if (sb == null) throw new Exception ("None of the supported bindings was found");\r
- \r
- if (sb.Style != SoapBindingStyle.Document) throw new Exception ("Binding style not supported");\r
- if (sb.Transport != SoapBinding.HttpTransport) throw new Exception ("Transport namespace '" + sb.Transport + "' not supported");\r
- \r
- string url = GetServiceUrl (iinfo, port); \r
- \r
- CodeTypeDeclaration codeClass = new CodeTypeDeclaration (className);\r
- AddCodeType (codeClass, port.Documentation);\r
- codeClass.Attributes = MemberAttributes.Public;\r
- \r
- if (service.Documentation != null && service.Documentation != "")\r
- AddComments (codeClass, service.Documentation);\r
-\r
- CodeAttributeDeclaration att = new CodeAttributeDeclaration ("System.Diagnostics.DebuggerStepThroughAttribute");\r
- AddCustomAttribute (codeClass, att, true);\r
-\r
- att = new CodeAttributeDeclaration ("System.ComponentModel.DesignerCategoryAttribute");\r
- att.Arguments.Add (GetArg ("code"));\r
- AddCustomAttribute (codeClass, att, true);\r
-\r
- att = new CodeAttributeDeclaration ("System.Web.Services.WebServiceBinding");\r
- att.Arguments.Add (GetArg ("Name", port.Name));\r
- att.Arguments.Add (GetArg ("Namespace", port.Binding.Namespace));\r
- AddCustomAttribute (codeClass, att, true);\r
- \r
- CodeTypeReference ctr = new CodeTypeReference ("System.Web.Services.Protocols.SoapHttpClientProtocol");\r
- codeClass.BaseTypes.Add (ctr);\r
- \r
- CodeConstructor cc = new CodeConstructor ();\r
- cc.Attributes = MemberAttributes.Public;\r
- CodeExpression ce = new CodeFieldReferenceExpression (new CodeThisReferenceExpression(), "Url");\r
- CodeAssignStatement cas = new CodeAssignStatement (ce, new CodePrimitiveExpression (url));\r
- cc.Statements.Add (cas);\r
- codeClass.Members.Add (cc);\r
- \r
- if (binding.Operations.Count == 0) {\r
- SetWarning (ServiceDescriptionImportWarnings.NoMethodsGenerated);\r
- return true;\r
- }\r
- \r
- CodeIdentifiers memberIds = new CodeIdentifiers ();\r
- foreach (OperationBinding oper in binding.Operations)\r
- ImportOperationBinding (codeClass, memberIds, portType, oper);\r
- }\r
- catch (Exception ex)\r
- {\r
- GenerateErrorComment (binding, ex.Message);\r
- return false;\r
- }\r
- return true;\r
- }\r
- \r
- void ImportOperationBinding (CodeTypeDeclaration codeClass, CodeIdentifiers memberIds, PortType portType, OperationBinding oper)\r
- {\r
- try\r
- {\r
- SoapOperationBinding soapOper = oper.Extensions.Find (typeof (SoapOperationBinding)) as SoapOperationBinding;\r
- if (soapOper == null) throw new Exception ("Soap operation binding not found in operation " + oper.Name);\r
- if (soapOper.Style != SoapBindingStyle.Document) throw new Exception ("Operation binding style not supported in operation " + oper.Name);\r
-\r
- SoapBodyBinding isbb = oper.Input.Extensions.Find (typeof(SoapBodyBinding)) as SoapBodyBinding;\r
- if (isbb == null) throw new Exception ("Soap body binding not found in operation " + oper.Name);\r
- string iname = (oper.Input.Name != "") ? oper.Input.Name : oper.Name;\r
- \r
- SoapBodyBinding osbb = oper.Output.Extensions.Find (typeof(SoapBodyBinding)) as SoapBodyBinding;\r
- if (osbb == null) throw new Exception ("Soap body binding not found in operation " + oper.Name);\r
- string oname = (oper.Output.Name != "") ? oper.Output.Name : oper.Name;\r
- \r
- Operation ptoper = FindPortOperation (portType, oper.Name, iname, oname);\r
- if (ptoper == null) throw new Exception ("Operation " + oper.Name + " not found in portType " + portType.Name);\r
-\r
- XmlMembersMapping inputMembers = null;\r
- XmlMembersMapping outputMembers = null;\r
- \r
- foreach (OperationMessage omsg in ptoper.Messages)\r
- {\r
- if (omsg is OperationInput)\r
- inputMembers = ImportMembersMapping (omsg, ptoper, isbb, soapOper);\r
- else\r
- outputMembers = ImportMembersMapping (omsg, ptoper, osbb, soapOper);\r
- }\r
- \r
- if (inputMembers == null) throw new Exception ("Input message not declared in operation " + oper.Name);\r
- if (outputMembers == null) throw new Exception ("Output message not declared in operation " + oper.Name);\r
- \r
- GenerateMethod (codeClass, memberIds, ptoper, soapOper, isbb, inputMembers, outputMembers);\r
- \r
- codeExporter.ExportMembersMapping (inputMembers);\r
- codeExporter.ExportMembersMapping (outputMembers);\r
- }\r
- catch (Exception ex)\r
- {\r
- GenerateErrorComment (oper, ex.Message);\r
- Console.WriteLine (ex);\r
- }\r
- }\r
- \r
- XmlMembersMapping ImportMembersMapping (OperationMessage omsg, Operation ptoper, SoapBodyBinding sbb, SoapOperationBinding soapOper)\r
- {\r
- Message msg = serviceDescriptions.GetMessage (omsg.Message);\r
- if (msg == null) throw new Exception ("Message not found: " + omsg.Message);\r
-\r
- XmlQualifiedName elem = null;\r
- if (msg.Parts.Count == 1 && msg.Parts[0].Name == "parameters")\r
- {\r
- // Wrapped parameter style\r
- \r
- MessagePart part = msg.Parts[0];\r
- if (sbb.Use == SoapBindingUse.Encoded)\r
- {\r
- SoapSchemaMember ssm = new SoapSchemaMember ();\r
- ssm.MemberName = part.Name;\r
- ssm.MemberType = part.Type;\r
- return soapSchemaImporter.ImportMembersMapping (ptoper.Name, omsg.Message.Namespace, ssm);\r
- }\r
- else\r
- return schemaImporter.ImportMembersMapping (part.Element); \r
- }\r
- else\r
- {\r
- if (sbb.Use == SoapBindingUse.Encoded)\r
- {\r
- SoapSchemaMember[] mems = new SoapSchemaMember [msg.Parts.Count];\r
- for (int n=0; n<mems.Length; n++)\r
- {\r
- SoapSchemaMember mem = new SoapSchemaMember();\r
- mem.MemberName = msg.Parts[n].Name;\r
- mem.MemberType = msg.Parts[n].Type;\r
- mems[n] = mem;\r
- }\r
- return soapSchemaImporter.ImportMembersMapping (ptoper.Name, omsg.Message.Namespace, mems);\r
- }\r
- else\r
- {\r
- XmlQualifiedName[] pnames = new XmlQualifiedName [msg.Parts.Count];\r
- for (int n=0; n<pnames.Length; n++)\r
- pnames[n] = msg.Parts[n].Element;\r
- return schemaImporter.ImportMembersMapping (pnames);\r
- }\r
- }\r
+ return importer.Warnings;\r
}\r
\r
- \r
- void GenerateMethod (CodeTypeDeclaration codeClass, CodeIdentifiers memberIds, Operation oper, SoapOperationBinding soapOper, SoapBodyBinding bodyBinding, XmlMembersMapping inputMembers, XmlMembersMapping outputMembers)\r
+ ProtocolImporter GetImporter ()\r
{\r
- CodeIdentifiers pids = new CodeIdentifiers ();\r
- CodeMemberMethod method = new CodeMemberMethod ();\r
- CodeMemberMethod methodBegin = new CodeMemberMethod ();\r
- CodeMemberMethod methodEnd = new CodeMemberMethod ();\r
- method.Attributes = MemberAttributes.Public;\r
- methodBegin.Attributes = MemberAttributes.Public;\r
- methodEnd.Attributes = MemberAttributes.Public;\r
- \r
- // Find unique names for temporary variables\r
- \r
- for (int n=0; n<inputMembers.Count; n++)\r
- pids.AddUnique (inputMembers[n].MemberName, inputMembers[n]);\r
-\r
- for (int n=0; n<outputMembers.Count; n++)\r
- pids.AddUnique (outputMembers[n].MemberName, outputMembers[n]);\r
- \r
- string varAsyncResult = pids.AddUnique ("asyncResult","asyncResult");\r
- string varResults = pids.AddUnique ("results","results");\r
- string varCallback = pids.AddUnique ("callback","callback");\r
- string varAsyncState = pids.AddUnique ("asyncState","asyncState");\r
-\r
- string messageName = memberIds.AddUnique(CodeIdentifier.MakeValid(oper.Name),method);\r
-\r
- method.Name = oper.Name;\r
- methodBegin.Name = memberIds.AddUnique(CodeIdentifier.MakeValid("Begin" + memberIds.MakeRightCase(oper.Name)),method);\r
- methodEnd.Name = memberIds.AddUnique(CodeIdentifier.MakeValid("End" + memberIds.MakeRightCase(oper.Name)),method);\r
-\r
- method.ReturnType = new CodeTypeReference (typeof(void));\r
- methodEnd.ReturnType = new CodeTypeReference (typeof(void));\r
- methodEnd.Parameters.Add (new CodeParameterDeclarationExpression (typeof (IAsyncResult),varAsyncResult));\r
-\r
- CodeExpression[] paramArray = new CodeExpression [inputMembers.Count];\r
- CodeParameterDeclarationExpression[] outParams = new CodeParameterDeclarationExpression [outputMembers.Count];\r
-\r
- for (int n=0; n<inputMembers.Count; n++)\r
- {\r
- CodeParameterDeclarationExpression param = GenerateParameter (inputMembers[n], FieldDirection.In);\r
- method.Parameters.Add (param);\r
- GenerateMemberAttributes (inputMembers, inputMembers[n], param);\r
- methodBegin.Parameters.Add (GenerateParameter (inputMembers[n], FieldDirection.In));\r
- paramArray [n] = new CodeVariableReferenceExpression (param.Name);\r
- }\r
-\r
- for (int n=0; n<outputMembers.Count; n++)\r
- {\r
- CodeParameterDeclarationExpression cpd = GenerateParameter (outputMembers[n], FieldDirection.Out);\r
- outParams [n] = cpd;\r
- \r
- bool found = false;\r
- foreach (CodeParameterDeclarationExpression ip in method.Parameters)\r
- {\r
- if (ip.Name == cpd.Name && ip.Type.BaseType == cpd.Type.BaseType) {\r
- ip.Direction = FieldDirection.Ref;\r
- methodEnd.Parameters.Add (GenerateParameter (outputMembers[n], FieldDirection.Out));\r
- found = true;\r
- break;\r
- }\r
- }\r
- \r
- if (found) continue;\r
-\r
- if ((outputMembers [n].ElementName == oper.Name + "Result") || (inputMembers.Count==0 && outputMembers.Count==1)) {\r
- method.ReturnType = cpd.Type;\r
- methodEnd.ReturnType = cpd.Type;\r
- GenerateReturnAttributes (outputMembers, outputMembers[n], method);\r
- outParams [n] = null;\r
- continue;\r
- }\r
- \r
- method.Parameters.Add (cpd);\r
- GenerateMemberAttributes (outputMembers, outputMembers[n], cpd);\r
- methodEnd.Parameters.Add (GenerateParameter (outputMembers[n], FieldDirection.Out));\r
- }\r
-\r
- methodBegin.Parameters.Add (new CodeParameterDeclarationExpression (typeof (AsyncCallback),varCallback));\r
- methodBegin.Parameters.Add (new CodeParameterDeclarationExpression (typeof (object),varAsyncState));\r
- methodBegin.ReturnType = new CodeTypeReference (typeof(IAsyncResult));\r
-\r
- // Array of input parameters\r
- \r
- CodeArrayCreateExpression methodParams;\r
- if (paramArray.Length > 0)\r
- methodParams = new CodeArrayCreateExpression (typeof(object), paramArray);\r
- else\r
- methodParams = new CodeArrayCreateExpression (typeof(object), 0);\r
-\r
- // Assignment of output parameters\r
- \r
- CodeStatementCollection outAssign = new CodeStatementCollection ();\r
- CodeVariableReferenceExpression arrVar = new CodeVariableReferenceExpression (varResults);\r
- for (int n=0; n<outParams.Length; n++)\r
+ switch ((protocolName != null && protocolName != "") ? protocolName : "Soap")\r
{\r
- CodeExpression index = new CodePrimitiveExpression (n);\r
- if (outParams[n] == null)\r
- {\r
- CodeExpression res = new CodeCastExpression (method.ReturnType, new CodeArrayIndexerExpression (arrVar, index));\r
- outAssign.Add (new CodeMethodReturnStatement (res));\r
- }\r
- else\r
- {\r
- CodeExpression res = new CodeCastExpression (outParams[n].Type, new CodeArrayIndexerExpression (arrVar, index));\r
- CodeExpression var = new CodeVariableReferenceExpression (outParams[n].Name);\r
- outAssign.Insert (0, new CodeAssignStatement (var, res));\r
- }\r
+ case "Soap": return new SoapProtocolImporter ();\r
+ default: throw new NotSupportedException ();\r
}\r
- \r
- // Invoke call\r
- \r
- CodeThisReferenceExpression ethis = new CodeThisReferenceExpression();\r
- CodePrimitiveExpression varMsgName = new CodePrimitiveExpression (messageName);\r
- CodeMethodInvokeExpression inv;\r
-\r
- inv = new CodeMethodInvokeExpression (ethis, "Invoke", varMsgName, methodParams);\r
- CodeVariableDeclarationStatement dec = new CodeVariableDeclarationStatement (typeof(object[]), varResults, inv);\r
- method.Statements.Add (dec);\r
- method.Statements.AddRange (outAssign);\r
- \r
- // Begin Invoke Call\r
- \r
- CodeExpression expCallb = new CodeVariableReferenceExpression (varCallback);\r
- CodeExpression expAsyncs = new CodeVariableReferenceExpression (varAsyncState);\r
- inv = new CodeMethodInvokeExpression (ethis, "BeginInvoke", varMsgName, methodParams, expCallb, expAsyncs);\r
- methodBegin.Statements.Add (new CodeMethodReturnStatement (inv));\r
- \r
- // End Invoke call\r
- \r
- CodeExpression varAsyncr = new CodeVariableReferenceExpression (varAsyncResult);\r
- inv = new CodeMethodInvokeExpression (ethis, "EndInvoke", varAsyncr);\r
- dec = new CodeVariableDeclarationStatement (typeof(object[]), varResults, inv);\r
- methodEnd.Statements.Add (dec);\r
- methodEnd.Statements.AddRange (outAssign);\r
- \r
- // Attributes\r
- \r
- if (inputMembers.ElementName == "" && outputMembers.ElementName != "" || \r
- inputMembers.ElementName != "" && outputMembers.ElementName == "")\r
- throw new Exception ("Parameter style is not the same for the input message and output message");\r
-\r
- CodeAttributeDeclaration att = new CodeAttributeDeclaration ("System.Web.Services.Protocols.SoapDocumentMethodAttribute");\r
- att.Arguments.Add (GetArg (soapOper.SoapAction));\r
- if (inputMembers.ElementName != "") {\r
- if (inputMembers.ElementName != method.Name) att.Arguments.Add (GetArg ("RequestElementName", inputMembers.ElementName));\r
- if (outputMembers.ElementName != (method.Name + "Response")) att.Arguments.Add (GetArg ("RequestElementName", outputMembers.ElementName));\r
- att.Arguments.Add (GetArg ("RequestNamespace", inputMembers.Namespace));\r
- att.Arguments.Add (GetArg ("ResponseNamespace", outputMembers.Namespace));\r
- att.Arguments.Add (GetEnumArg ("ParameterStyle", "System.Web.Services.Protocols.SoapParameterStyle", "Wrapped"));\r
- }\r
- else\r
- att.Arguments.Add (GetEnumArg ("ParameterStyle", "System.Web.Services.Protocols.SoapParameterStyle", "Bare"));\r
- \r
- att.Arguments.Add (GetEnumArg ("Use", "System.Web.Services.Description.SoapBindingUse", bodyBinding.Use.ToString()));\r
- AddCustomAttribute (method, att, true);\r
- \r
- att = new CodeAttributeDeclaration ("System.Web.Services.WebMethodAttribute");\r
- if (messageName != method.Name) att.Arguments.Add (GetArg ("MessageName",messageName));\r
- AddCustomAttribute (method, att, false);\r
- \r
- if (oper.Documentation != null && oper.Documentation != "")\r
- AddComments (method, oper.Documentation);\r
- \r
- codeClass.Members.Add (method);\r
- codeClass.Members.Add (methodBegin);\r
- codeClass.Members.Add (methodEnd);\r
}\r
- \r
- CodeParameterDeclarationExpression GenerateParameter (XmlMemberMapping member, FieldDirection dir)\r
- {\r
- CodeParameterDeclarationExpression par = new CodeParameterDeclarationExpression (member.TypeFullName, member.MemberName);\r
- par.Direction = dir;\r
- return par;\r
- }\r
- \r
- void GenerateMemberAttributes (XmlMembersMapping members, XmlMemberMapping member, CodeParameterDeclarationExpression param)\r
- {\r
- GenerateMemberAttributes (members, member, member.MemberName, param.CustomAttributes);\r
- }\r
- \r
- void GenerateReturnAttributes (XmlMembersMapping members, XmlMemberMapping member, CodeMemberMethod method)\r
- {\r
- GenerateMemberAttributes (members, member, method.Name + "Result", method.ReturnTypeCustomAttributes);\r
- }\r
- \r
- void GenerateMemberAttributes (XmlMembersMapping members, XmlMemberMapping member, string memberName, CodeAttributeDeclarationCollection atts)\r
- {\r
- CodeAttributeDeclaration att;\r
- \r
- if (member.TypeFullName.EndsWith ("]") && Array.IndexOf (primitiveArrays, member.TypeName) == -1)\r
- {\r
- // Array parameter\r
- att = new CodeAttributeDeclaration ("System.Xml.Serialization.XmlArray");\r
- if (member.ElementName != memberName) att.Arguments.Add (GetArg ("ElementName", member.ElementName));\r
- if (member.Namespace != members.Namespace) att.Arguments.Add (GetArg ("Namespace", member.Namespace));\r
- if (att.Arguments.Count > 0) atts.Add (att);\r
- }\r
- else\r
- {\r
- att = new CodeAttributeDeclaration ("System.Xml.Serialization.XmlElement");\r
- if (member.ElementName != memberName) att.Arguments.Add (GetArg ("ElementName", member.ElementName));\r
- if (member.Namespace != members.Namespace) att.Arguments.Add (GetArg ("Namespace", member.Namespace));\r
- if (member.TypeNamespace == "" && Array.IndexOf (defaultSchemaTypes, member.TypeName) == -1) att.Arguments.Add (GetArg ("DataType", member.TypeName));\r
- if (att.Arguments.Count > 0) atts.Add (att);\r
- }\r
- }\r
- \r
- Operation FindPortOperation (PortType portType, string operName, string inMessage, string outMessage)\r
- {\r
- foreach (Operation oper in portType.Operations)\r
- {\r
- if (oper.Name == operName)\r
- {\r
- int hits = 0;\r
- foreach (OperationMessage omsg in oper.Messages)\r
- {\r
- if (omsg is OperationInput && GetOperMessageName (omsg, operName) == inMessage) hits++;\r
- if (omsg is OperationOutput && GetOperMessageName (omsg, operName) == outMessage) hits++;\r
- }\r
- if (hits == 2) return oper;\r
- }\r
- }\r
- return null;\r
- }\r
- \r
- string GetOperMessageName (OperationMessage msg, string operName)\r
- {\r
- if (msg.Name == null) return operName;\r
- else return msg.Name;\r
- }\r
- \r
- void GenerateErrorComment (Binding binding, string message)\r
- {\r
- AddGlobalComments ("WARNING: Could not generate proxy for binding " + binding.Name + ". " + message);\r
- }\r
- \r
- void GenerateErrorComment (OperationBinding oper, string message)\r
- {\r
- AddGlobalComments ("WARNING: Could not generate operation " + oper.Name + ". " + message);\r
- }\r
- \r
- string GetServiceUrl (ImportInfo info, Port port)\r
- {\r
- string location = null;\r
- \r
- SoapAddressBinding sab = (SoapAddressBinding) port.Extensions.Find (typeof(SoapAddressBinding));\r
- if (sab != null) location = sab.Location;\r
- \r
- if (info.AppSettingUrlKey == null || info.AppSettingUrlKey == string.Empty)\r
- return location;\r
- else\r
- {\r
- string url;\r
- if (style == ServiceDescriptionImportStyle.Server) throw new InvalidOperationException ("Cannot set appSettingUrlKey if Style is Server");\r
- url = ConfigurationSettings.AppSettings [info.AppSettingUrlKey];\r
- if (info.AppSettingBaseUrl != null && info.AppSettingBaseUrl != string.Empty)\r
- url += "/" + info.AppSettingBaseUrl + "/" + location;\r
- return url;\r
- }\r
- }\r
-\r
- void AddGlobalComments (string comments)\r
- {\r
- codeNamespace.Comments.Add (new CodeCommentStatement (comments, false));\r
- }\r
-\r
- void AddComments (CodeTypeMember member, string comments)\r
- {\r
- if (comments == null || comments == "") member.Comments.Add (new CodeCommentStatement ("<remarks/>", true));\r
- else member.Comments.Add (new CodeCommentStatement ("<remarks>\n" + comments + "\n</remarks>", true));\r
- }\r
-\r
- void AddCodeType (CodeTypeDeclaration type, string comments)\r
- {\r
- AddComments (type, comments);\r
- codeNamespace.Types.Add (type);\r
- }\r
-\r
- void AddCustomAttribute (CodeTypeMember ctm, CodeAttributeDeclaration att, bool addIfNoParams)\r
- {\r
- if (att.Arguments.Count == 0 && !addIfNoParams) return;\r
- \r
- if (ctm.CustomAttributes == null) ctm.CustomAttributes = new CodeAttributeDeclarationCollection ();\r
- ctm.CustomAttributes.Add (att);\r
- }\r
-\r
- void AddCustomAttribute (CodeTypeMember ctm, string name, params CodeAttributeArgument[] args)\r
- {\r
- if (ctm.CustomAttributes == null) ctm.CustomAttributes = new CodeAttributeDeclarationCollection ();\r
- ctm.CustomAttributes.Add (new CodeAttributeDeclaration (name, args));\r
- }\r
-\r
- CodeAttributeArgument GetArg (string name, object value)\r
- {\r
- return new CodeAttributeArgument (name, new CodePrimitiveExpression(value));\r
- }\r
-\r
- CodeAttributeArgument GetEnumArg (string name, string enumType, string enumValue)\r
- {\r
- return new CodeAttributeArgument (name, new CodeFieldReferenceExpression (new CodeTypeReferenceExpression(enumType), enumValue));\r
- }\r
-\r
- CodeAttributeArgument GetArg (object value)\r
- {\r
- return new CodeAttributeArgument (new CodePrimitiveExpression(value));\r
- }\r
-\r
- CodeAttributeArgument GetTypeArg (string name, string typeName)\r
- {\r
- return new CodeAttributeArgument (name, new CodeTypeOfExpression(typeName));\r
- }\r
- \r
- void SetWarning (ServiceDescriptionImportWarnings w)\r
- {\r
- warnings |= w;\r
- }\r
-\r
- static string[] defaultSchemaTypes = new string[] \r
- {\r
- "string", "int", "long", "short", "boolean", "dateTime", "float", "unsignedShort",\r
- "unsignedInt", "unsignedLong", "double", "decimal", "QName", "unsignedByte", "byte",\r
- "char", "duration", "base64Binary", "anyURI", "guid"\r
- };\r
- \r
- static string[] primitiveArrays = new string[]\r
- {\r
- "NMTOKENS", "ENTITIES", "hexBinary", "IDREFS", "base64Binary"\r
- };\r
-\r
#endregion\r
}\r
+\r
+ internal class ImportInfo\r
+ {\r
+ public ServiceDescription ServiceDescription;\r
+ public string AppSettingUrlKey;\r
+ public string AppSettingBaseUrl;\r
+ }\r
+\r
}
namespace System.Web.Services.Description {\r
public class ServiceDescriptionReflector {\r
\r
- #region Fields\r
-\r
- Types types;\r
- ServiceDescriptionCollection serviceDescriptions;\r
- XmlSchemaExporter schemaExporter;\r
- SoapSchemaExporter soapSchemaExporter;\r
-\r
- #endregion // Fields\r
-\r
+ ProtocolReflector reflector;\r
+ \r
#region Constructors\r
\r
public ServiceDescriptionReflector ()\r
{\r
- types = new Types ();\r
- serviceDescriptions = new ServiceDescriptionCollection ();\r
- schemaExporter = new XmlSchemaExporter (types.Schemas);\r
- soapSchemaExporter = new SoapSchemaExporter (types.Schemas);\r
+ reflector = new SoapProtocolReflector ();\r
}\r
\r
#endregion // Constructors\r
#region Properties\r
\r
public XmlSchemas Schemas {\r
- get { return types.Schemas; }\r
+ get { return reflector.Schemas; }\r
}\r
\r
public ServiceDescriptionCollection ServiceDescriptions {\r
- get { return serviceDescriptions; }\r
+ get { return reflector.ServiceDescriptions; }\r
}\r
\r
- \r
+\r
#endregion // Properties\r
\r
#region Methods\r
\r
- [MonoTODO]\r
public void Reflect (Type type, string url)\r
{\r
- ServiceDescription desc = new ServiceDescription ();\r
- serviceDescriptions.Add (desc);\r
- \r
- TypeStubInfo typeInfo = TypeStubManager.GetTypeStub (type);\r
- desc.TargetNamespace = typeInfo.WebServiceNamespace;\r
- desc.Name = typeInfo.WebServiceName;\r
- \r
- ImportService (desc, typeInfo, url);\r
- \r
- if (serviceDescriptions.Count == 1)\r
- desc.Types = types;\r
- else\r
- {\r
- foreach (ServiceDescription d in serviceDescriptions)\r
- {\r
- d.Types = new Types();\r
- for (int n=0; n<types.Schemas.Count; n++)\r
- AddImport (d, types.Schemas[n].TargetNamespace, GetSchemaUrl (url, n));\r
- }\r
- }\r
- }\r
- \r
- Service ImportService (ServiceDescription desc, TypeStubInfo typeInfo, string url)\r
- {\r
- Service service = new Service ();\r
- service.Name = typeInfo.WebServiceName;\r
- service.Documentation = typeInfo.Description;\r
-\r
- desc.Services.Add (service);\r
- \r
- foreach (BindingInfo binfo in typeInfo.Bindings)\r
- ImportBinding (desc, service, typeInfo, url, binfo);\r
-\r
- return service;\r
- }\r
- \r
- void ImportBinding (ServiceDescription desc, Service service, TypeStubInfo typeInfo, string url, BindingInfo binfo)\r
- {\r
- Port port = new Port ();\r
- port.Name = binfo.Name;\r
- port.Binding = new XmlQualifiedName (binfo.Name, binfo.Namespace);\r
- service.Ports.Add (port);\r
-\r
- SoapAddressBinding abind = new SoapAddressBinding ();\r
- abind.Location = url;\r
- port.Extensions.Add (abind);\r
- \r
- if (binfo.Namespace != desc.TargetNamespace)\r
- {\r
- if (binfo.Location == null || binfo.Location == string.Empty)\r
- {\r
- ServiceDescription newDesc = new ServiceDescription();\r
- newDesc.TargetNamespace = binfo.Namespace;\r
- int id = serviceDescriptions.Add (newDesc);\r
- AddImport (desc, binfo.Namespace, GetWsdlUrl (url,id));\r
- ImportBindingContent (newDesc, typeInfo, url, binfo);\r
- }\r
- else\r
- AddImport (desc, binfo.Namespace, binfo.Location);\r
- }\r
- else\r
- ImportBindingContent (desc, typeInfo, url, binfo);\r
- }\r
- \r
- void ImportBindingContent (ServiceDescription desc, TypeStubInfo typeInfo, string url, BindingInfo binfo)\r
- {\r
- Binding binding = new Binding ();\r
- binding.Name = binfo.Name;\r
- binding.Type = new XmlQualifiedName (binfo.Name, binfo.Namespace);\r
- desc.Bindings.Add (binding);\r
- \r
- SoapBinding sb = new SoapBinding ();\r
- sb.Transport = SoapBinding.HttpTransport;\r
- sb.Style = typeInfo.SoapBindingStyle;\r
- binding.Extensions.Add (sb);\r
- \r
- PortType ptype = new PortType ();\r
- ptype.Name = binding.Name;\r
- desc.PortTypes.Add (ptype);\r
-\r
- foreach (MethodStubInfo method in typeInfo.Methods)\r
- {\r
- if (method.Binding != binding.Name) continue;\r
- \r
- Operation oper = ImportOperation (desc, method);\r
- ptype.Operations.Add (oper);\r
-\r
- OperationBinding operb = ImportOperationBinding (desc, method);\r
- binding.Operations.Add (operb);\r
- }\r
- }\r
- \r
- Operation ImportOperation (ServiceDescription desc, MethodStubInfo method)\r
- {\r
- Operation oper = new Operation ();\r
- oper.Name = method.Name;\r
- oper.Documentation = method.Description;\r
- \r
- OperationInput inOp = new OperationInput ();\r
- inOp.Message = ImportMessage (desc, oper.Name + "In", method.InputMembersMapping, method);\r
- oper.Messages.Add (inOp);\r
- \r
- OperationOutput outOp = new OperationOutput ();\r
- outOp.Message = ImportMessage (desc, oper.Name + "Out", method.OutputMembersMapping, method);\r
- oper.Messages.Add (outOp);\r
- \r
- return oper;\r
- }\r
- \r
- OperationBinding ImportOperationBinding (ServiceDescription desc, MethodStubInfo method)\r
- {\r
- OperationBinding oper = new OperationBinding ();\r
- oper.Name = method.Name;\r
- \r
- SoapOperationBinding sob = new SoapOperationBinding();\r
- sob.SoapAction = method.Action;\r
- sob.Style = method.SoapBindingStyle;\r
- oper.Extensions.Add (sob);\r
- \r
- InputBinding inOp = new InputBinding ();\r
- AddOperationMsgBindings (desc, inOp, method);\r
- oper.Input = inOp;\r
- \r
- OutputBinding outOp = new OutputBinding ();\r
- AddOperationMsgBindings (desc, outOp, method);\r
- oper.Output = outOp;\r
- \r
- return oper;\r
- }\r
- \r
- void AddOperationMsgBindings (ServiceDescription desc, MessageBinding msg, MethodStubInfo method)\r
- {\r
- SoapBodyBinding sbbo = new SoapBodyBinding();\r
- msg.Extensions.Add (sbbo);\r
- sbbo.Use = method.Use;\r
- if (method.Use == SoapBindingUse.Encoded)\r
- {\r
- sbbo.Namespace = desc.TargetNamespace;\r
- sbbo.Encoding = "http://schemas.xmlsoap.org/soap/encoding/";\r
- }\r
- }\r
- \r
- XmlQualifiedName ImportMessage (ServiceDescription desc, string name, XmlMembersMapping members, MethodStubInfo method)\r
- {\r
- Message msg = new Message ();\r
- msg.Name = name;\r
- \r
- if (method.ParameterStyle == SoapParameterStyle.Wrapped)\r
- {\r
- MessagePart part = new MessagePart ();\r
- part.Name = "parameters";\r
- XmlQualifiedName qname = new XmlQualifiedName (members.ElementName, members.Namespace);\r
- if (method.Use == SoapBindingUse.Literal) part.Element = qname;\r
- else part.Type = qname;\r
- msg.Parts.Add (part);\r
- }\r
- else\r
- {\r
- for (int n=0; n<members.Count; n++)\r
- {\r
- MessagePart part = new MessagePart ();\r
- part.Name = members[n].MemberName;\r
- \r
- if (method.Use == SoapBindingUse.Literal) {\r
- part.Element = new XmlQualifiedName (members[n].MemberName, members[n].Namespace);\r
- }\r
- else {\r
- string namesp = members[n].TypeNamespace;\r
- if (namesp == "") namesp = XmlSchema.Namespace;\r
- part.Type = new XmlQualifiedName (members[n].TypeName, namesp);\r
- }\r
- msg.Parts.Add (part);\r
- }\r
- }\r
- \r
- desc.Messages.Add (msg);\r
- \r
- if (method.Use == SoapBindingUse.Literal)\r
- schemaExporter.ExportMembersMapping (members);\r
- else\r
- soapSchemaExporter.ExportMembersMapping (members);\r
- \r
- return new XmlQualifiedName (name, members.Namespace);\r
- }\r
-\r
- void AddImport (ServiceDescription desc, string ns, string location)\r
- {\r
- Import im = new Import();\r
- im.Namespace = ns;\r
- im.Location = location;\r
- desc.Imports.Add (im);\r
+ reflector.Reflect (type, url);\r
}\r
\r
- string GetWsdlUrl (string baseUrl, int id)\r
- {\r
- return baseUrl + "?wsdl=" + id;\r
- }\r
- \r
- string GetSchemaUrl (string baseUrl, int id)\r
- {\r
- return baseUrl + "?schema=" + id;\r
- }\r
\r
#endregion\r
}\r
--- /dev/null
+//
+// System.Web.Services.Description.SoapHttpTransportImporter.cs
+//
+// Author:
+// Lluis Sanchez Gual (lluis@ximian.com)
+//
+// Copyright (C) Ximian, Inc. 2003
+//
+
+
+namespace System.Web.Services.Description
+{
+ internal class SoapHttpTransportImporter : SoapTransportImporter
+ {
+ public SoapHttpTransportImporter ()
+ {
+ }
+
+ public override void ImportClass ()
+ {
+ }
+
+ public override bool IsSupportedTransport (string transport)
+ {
+ return (transport == SoapBinding.HttpTransport);
+ }
+ }
+}
-// \r
-// System.Web.Services.Description.SoapProtocolImporter.cs\r
-//\r
-// Author:\r
-// Tim Coleman (tim@timcoleman.com)\r
-//\r
-// Copyright (C) Tim Coleman, 2002\r
-//\r
-\r
-using System.CodeDom;\r
-using System.Web.Services;\r
-using System.Xml.Serialization;\r
-\r
-namespace System.Web.Services.Description {\r
- public sealed class SoapProtocolImporter : ProtocolImporter {\r
-\r
- #region Fields\r
-\r
- SoapBinding soapBinding;\r
- SoapCodeExporter soapExporter;\r
- SoapSchemaImporter soapImporter;\r
- XmlCodeExporter xmlExporter;\r
- XmlSchemaImporter xmlImporter;\r
- \r
- #endregion // Fields\r
-\r
- #region Constructors\r
-\r
- [MonoTODO] \r
- public SoapProtocolImporter ()\r
- {\r
- throw new NotImplementedException ();\r
- }\r
- \r
- #endregion // Constructors\r
-\r
- #region Properties\r
-\r
- public override string ProtocolName {\r
- get { return "Soap"; }\r
- }\r
-\r
- public SoapBinding SoapBinding {\r
- get { return soapBinding; }\r
- }\r
-\r
- public SoapCodeExporter SoapExporter {\r
- get { return soapExporter; }\r
- }\r
-\r
- public SoapSchemaImporter SoapImporter {\r
- get { return soapImporter; }\r
- }\r
-\r
- public XmlCodeExporter XmlExporter {\r
- get { return xmlExporter; }\r
- }\r
-\r
- public XmlSchemaImporter XmlImporter {\r
- get { return xmlImporter; }\r
- }\r
-\r
- #endregion // Properties\r
-\r
- #region Methods\r
-\r
- [MonoTODO]\r
- protected override CodeTypeDeclaration BeginClass ()\r
- {\r
- throw new NotImplementedException ();\r
- }\r
-\r
- [MonoTODO]\r
- protected override void BeginNamespace ()\r
- {\r
- throw new NotImplementedException ();\r
- }\r
-\r
- [MonoTODO]\r
- protected override void EndClass ()\r
- {\r
- throw new NotImplementedException ();\r
- }\r
-\r
- [MonoTODO]\r
- protected override void EndNamespace ()\r
- {\r
- throw new NotImplementedException ();\r
- }\r
-\r
- [MonoTODO]\r
- protected override CodeMemberMethod GenerateMethod ()\r
- {\r
- throw new NotImplementedException ();\r
- }\r
-\r
- [MonoTODO]\r
- protected override bool IsBindingSupported ()\r
- {\r
- throw new NotImplementedException ();\r
- }\r
-\r
- [MonoTODO]\r
- protected override bool IsOperationFlowSupported (OperationFlow flow)\r
- {\r
- throw new NotImplementedException ();\r
- }\r
-\r
- #endregion\r
- }\r
-}\r
+//
+// System.Web.Services.Description.SoapProtocolImporter.cs
+//
+// Author:
+// Tim Coleman (tim@timcoleman.com)
+// Lluis Sanchez Gual (lluis@ximian.com)
+//
+// Copyright (C) Tim Coleman, 2002
+//
+
+using System.CodeDom;
+using System.Web.Services;
+using System.Web.Services.Protocols;
+using System.Web.Services.Configuration;
+using System.Xml;
+using System.Xml.Serialization;
+using System.Configuration;
+using System.Collections;
+
+namespace System.Web.Services.Description {
+ public sealed class SoapProtocolImporter : ProtocolImporter {
+
+ #region Fields
+
+ SoapBinding soapBinding;
+ SoapCodeExporter soapExporter;
+ SoapSchemaImporter soapImporter;
+ XmlCodeExporter xmlExporter;
+ XmlSchemaImporter xmlImporter;
+ CodeIdentifiers memberIds;
+ ArrayList extensionImporters;
+ Hashtable headerVariables;
+
+ #endregion // Fields
+
+ #region Constructors
+
+ public SoapProtocolImporter ()
+ {
+ extensionImporters = ExtensionManager.BuildExtensionImporters ();
+ }
+
+ void SetBinding (SoapBinding soapBinding)
+ {
+ this.soapBinding = soapBinding;
+ }
+
+ #endregion // Constructors
+
+ #region Properties
+
+ public override string ProtocolName {
+ get { return "Soap"; }
+ }
+
+ public SoapBinding SoapBinding {
+ get { return soapBinding; }
+ }
+
+ public SoapCodeExporter SoapExporter {
+ get { return soapExporter; }
+ }
+
+ public SoapSchemaImporter SoapImporter {
+ get { return soapImporter; }
+ }
+
+ public XmlCodeExporter XmlExporter {
+ get { return xmlExporter; }
+ }
+
+ public XmlSchemaImporter XmlImporter {
+ get { return xmlImporter; }
+ }
+
+ #endregion // Properties
+
+ #region Methods
+
+ protected override CodeTypeDeclaration BeginClass ()
+ {
+ soapBinding = (SoapBinding) Binding.Extensions.Find (typeof(SoapBinding));
+
+ if (soapBinding == null) throw new Exception ("None of the supported bindings was found");
+ if (soapBinding.Style != SoapBindingStyle.Document) throw new Exception ("Binding style not supported");
+
+ CodeTypeDeclaration codeClass = new CodeTypeDeclaration (ClassName);
+
+ string url = GetServiceUrl ();
+
+ CodeTypeReference ctr = new CodeTypeReference ("System.Web.Services.Protocols.SoapHttpClientProtocol");
+ codeClass.BaseTypes.Add (ctr);
+
+ CodeConstructor cc = new CodeConstructor ();
+ cc.Attributes = MemberAttributes.Public;
+ CodeExpression ce = new CodeFieldReferenceExpression (new CodeThisReferenceExpression(), "Url");
+ CodeAssignStatement cas = new CodeAssignStatement (ce, new CodePrimitiveExpression (url));
+ cc.Statements.Add (cas);
+ codeClass.Members.Add (cc);
+
+ memberIds = new CodeIdentifiers ();
+ headerVariables = new Hashtable ();
+ return codeClass;
+ }
+
+ string GetServiceUrl ()
+ {
+ string location = null;
+
+ SoapAddressBinding sab = (SoapAddressBinding) Port.Extensions.Find (typeof(SoapAddressBinding));
+ if (sab != null) location = sab.Location;
+
+ if (ImportInfo.AppSettingUrlKey == null || ImportInfo.AppSettingUrlKey == string.Empty)
+ return location;
+ else
+ {
+ string url;
+ if (Style == ServiceDescriptionImportStyle.Server) throw new InvalidOperationException ("Cannot set appSettingUrlKey if Style is Server");
+ url = ConfigurationSettings.AppSettings [ImportInfo.AppSettingUrlKey];
+ if (ImportInfo.AppSettingBaseUrl != null && ImportInfo.AppSettingBaseUrl != string.Empty)
+ url += "/" + ImportInfo.AppSettingBaseUrl + "/" + location;
+ return url;
+ }
+ }
+
+ protected override void BeginNamespace ()
+ {
+ xmlImporter = new XmlSchemaImporter (Schemas);
+ soapImporter = new SoapSchemaImporter (Schemas);
+ xmlExporter = new XmlCodeExporter (CodeNamespace, null);
+ }
+
+ protected override void EndClass ()
+ {
+ SoapTransportImporter transportImporter = SoapTransportImporter.FindTransportImporter (soapBinding.Transport);
+ if (transportImporter == null) throw new Exception ("Transport '" + soapBinding.Transport + "' not supported");
+ transportImporter.ImportContext = this;
+ transportImporter.ImportClass ();
+ }
+
+ protected override void EndNamespace ()
+ {
+ }
+
+ [MonoTODO]
+ protected override bool IsBindingSupported ()
+ {
+ throw new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ protected override bool IsOperationFlowSupported (OperationFlow flow)
+ {
+ throw new NotImplementedException ();
+ }
+
+ void AddComments (CodeTypeMember member, string comments)
+ {
+ if (comments == null || comments == "") member.Comments.Add (new CodeCommentStatement ("<remarks/>", true));
+ else member.Comments.Add (new CodeCommentStatement ("<remarks>\n" + comments + "\n</remarks>", true));
+ }
+
+ protected override CodeMemberMethod GenerateMethod ()
+ {
+ try
+ {
+ SoapOperationBinding soapOper = OperationBinding.Extensions.Find (typeof (SoapOperationBinding)) as SoapOperationBinding;
+ if (soapOper == null) throw new Exception ("Soap operation binding not found in operation " + OperationBinding.Name);
+ if (soapOper.Style != SoapBindingStyle.Document) throw new Exception ("Operation binding style not supported in operation " + OperationBinding.Name);
+
+ SoapBodyBinding isbb = OperationBinding.Input.Extensions.Find (typeof(SoapBodyBinding)) as SoapBodyBinding;
+ if (isbb == null) throw new Exception ("Soap body binding not found in operation " + OperationBinding.Name);
+
+ SoapBodyBinding osbb = OperationBinding.Output.Extensions.Find (typeof(SoapBodyBinding)) as SoapBodyBinding;
+ if (osbb == null) throw new Exception ("Soap body binding not found in operation " + OperationBinding.Name);
+
+ XmlMembersMapping inputMembers = ImportMembersMapping (InputMessage, isbb, soapOper);
+ if (inputMembers == null) throw new Exception ("Input message not declared in operation " + OperationBinding.Name);
+
+ XmlMembersMapping outputMembers = ImportMembersMapping (OutputMessage, osbb, soapOper);
+ if (outputMembers == null) throw new Exception ("Output message not declared in operation " + OperationBinding.Name);
+
+ CodeMemberMethod met = GenerateMethod (memberIds, soapOper, isbb, inputMembers, outputMembers);
+
+ xmlExporter.ExportMembersMapping (inputMembers);
+ xmlExporter.ExportMembersMapping (outputMembers);
+
+ foreach (SoapExtensionImporter eximporter in extensionImporters)
+ {
+ eximporter.ImportContext = this;
+ eximporter.ImportMethod (met.CustomAttributes);
+ }
+
+ return met;
+ }
+ catch (Exception ex)
+ {
+ UnsupportedOperationBindingWarning (ex.Message);
+ return null;
+ }
+ }
+
+ XmlMembersMapping ImportMembersMapping (Message msg, SoapBodyBinding sbb, SoapOperationBinding soapOper)
+ {
+ XmlQualifiedName elem = null;
+ if (msg.Parts.Count == 1 && msg.Parts[0].Name == "parameters")
+ {
+ // Wrapped parameter style
+
+ MessagePart part = msg.Parts[0];
+ if (sbb.Use == SoapBindingUse.Encoded)
+ {
+ SoapSchemaMember ssm = new SoapSchemaMember ();
+ ssm.MemberName = part.Name;
+ ssm.MemberType = part.Type;
+ return soapImporter.ImportMembersMapping (Operation.Name, part.Type.Namespace, ssm);
+ }
+ else
+ return xmlImporter.ImportMembersMapping (part.Element);
+ }
+ else
+ {
+ if (sbb.Use == SoapBindingUse.Encoded)
+ {
+ SoapSchemaMember[] mems = new SoapSchemaMember [msg.Parts.Count];
+ for (int n=0; n<mems.Length; n++)
+ {
+ SoapSchemaMember mem = new SoapSchemaMember();
+ mem.MemberName = msg.Parts[n].Name;
+ mem.MemberType = msg.Parts[n].Type;
+ mems[n] = mem;
+ }
+ return soapImporter.ImportMembersMapping (Operation.Name, "", mems);
+ }
+ else
+ {
+ XmlQualifiedName[] pnames = new XmlQualifiedName [msg.Parts.Count];
+ for (int n=0; n<pnames.Length; n++)
+ pnames[n] = msg.Parts[n].Element;
+ return xmlImporter.ImportMembersMapping (pnames);
+ }
+ }
+ }
+
+ CodeMemberMethod GenerateMethod (CodeIdentifiers memberIds, SoapOperationBinding soapOper, SoapBodyBinding bodyBinding, XmlMembersMapping inputMembers, XmlMembersMapping outputMembers)
+ {
+ CodeIdentifiers pids = new CodeIdentifiers ();
+ CodeMemberMethod method = new CodeMemberMethod ();
+ CodeMemberMethod methodBegin = new CodeMemberMethod ();
+ CodeMemberMethod methodEnd = new CodeMemberMethod ();
+ method.Attributes = MemberAttributes.Public;
+ methodBegin.Attributes = MemberAttributes.Public;
+ methodEnd.Attributes = MemberAttributes.Public;
+
+ // Find unique names for temporary variables
+
+ for (int n=0; n<inputMembers.Count; n++)
+ pids.AddUnique (inputMembers[n].MemberName, inputMembers[n]);
+
+ for (int n=0; n<outputMembers.Count; n++)
+ pids.AddUnique (outputMembers[n].MemberName, outputMembers[n]);
+
+ string varAsyncResult = pids.AddUnique ("asyncResult","asyncResult");
+ string varResults = pids.AddUnique ("results","results");
+ string varCallback = pids.AddUnique ("callback","callback");
+ string varAsyncState = pids.AddUnique ("asyncState","asyncState");
+
+ string messageName = memberIds.AddUnique(CodeIdentifier.MakeValid(Operation.Name),method);
+
+ method.Name = Operation.Name;
+ methodBegin.Name = memberIds.AddUnique(CodeIdentifier.MakeValid("Begin" + memberIds.MakeRightCase(Operation.Name)),method);
+ methodEnd.Name = memberIds.AddUnique(CodeIdentifier.MakeValid("End" + memberIds.MakeRightCase(Operation.Name)),method);
+
+ method.ReturnType = new CodeTypeReference (typeof(void));
+ methodEnd.ReturnType = new CodeTypeReference (typeof(void));
+ methodEnd.Parameters.Add (new CodeParameterDeclarationExpression (typeof (IAsyncResult),varAsyncResult));
+
+ CodeExpression[] paramArray = new CodeExpression [inputMembers.Count];
+ CodeParameterDeclarationExpression[] outParams = new CodeParameterDeclarationExpression [outputMembers.Count];
+
+ for (int n=0; n<inputMembers.Count; n++)
+ {
+ CodeParameterDeclarationExpression param = GenerateParameter (inputMembers[n], FieldDirection.In);
+ method.Parameters.Add (param);
+ GenerateMemberAttributes (inputMembers, inputMembers[n], param);
+ methodBegin.Parameters.Add (GenerateParameter (inputMembers[n], FieldDirection.In));
+ paramArray [n] = new CodeVariableReferenceExpression (param.Name);
+ }
+
+ for (int n=0; n<outputMembers.Count; n++)
+ {
+ CodeParameterDeclarationExpression cpd = GenerateParameter (outputMembers[n], FieldDirection.Out);
+ outParams [n] = cpd;
+
+ bool found = false;
+ foreach (CodeParameterDeclarationExpression ip in method.Parameters)
+ {
+ if (ip.Name == cpd.Name && ip.Type.BaseType == cpd.Type.BaseType) {
+ ip.Direction = FieldDirection.Ref;
+ methodEnd.Parameters.Add (GenerateParameter (outputMembers[n], FieldDirection.Out));
+ found = true;
+ break;
+ }
+ }
+
+ if (found) continue;
+
+ if ((outputMembers [n].ElementName == Operation.Name + "Result") || (inputMembers.Count==0 && outputMembers.Count==1)) {
+ method.ReturnType = cpd.Type;
+ methodEnd.ReturnType = cpd.Type;
+ GenerateReturnAttributes (outputMembers, outputMembers[n], method);
+ outParams [n] = null;
+ continue;
+ }
+
+ method.Parameters.Add (cpd);
+ GenerateMemberAttributes (outputMembers, outputMembers[n], cpd);
+ methodEnd.Parameters.Add (GenerateParameter (outputMembers[n], FieldDirection.Out));
+ }
+
+ methodBegin.Parameters.Add (new CodeParameterDeclarationExpression (typeof (AsyncCallback),varCallback));
+ methodBegin.Parameters.Add (new CodeParameterDeclarationExpression (typeof (object),varAsyncState));
+ methodBegin.ReturnType = new CodeTypeReference (typeof(IAsyncResult));
+
+ // Array of input parameters
+
+ CodeArrayCreateExpression methodParams;
+ if (paramArray.Length > 0)
+ methodParams = new CodeArrayCreateExpression (typeof(object), paramArray);
+ else
+ methodParams = new CodeArrayCreateExpression (typeof(object), 0);
+
+ // Assignment of output parameters
+
+ CodeStatementCollection outAssign = new CodeStatementCollection ();
+ CodeVariableReferenceExpression arrVar = new CodeVariableReferenceExpression (varResults);
+ for (int n=0; n<outParams.Length; n++)
+ {
+ CodeExpression index = new CodePrimitiveExpression (n);
+ if (outParams[n] == null)
+ {
+ CodeExpression res = new CodeCastExpression (method.ReturnType, new CodeArrayIndexerExpression (arrVar, index));
+ outAssign.Add (new CodeMethodReturnStatement (res));
+ }
+ else
+ {
+ CodeExpression res = new CodeCastExpression (outParams[n].Type, new CodeArrayIndexerExpression (arrVar, index));
+ CodeExpression var = new CodeVariableReferenceExpression (outParams[n].Name);
+ outAssign.Insert (0, new CodeAssignStatement (var, res));
+ }
+ }
+
+ // Invoke call
+
+ CodeThisReferenceExpression ethis = new CodeThisReferenceExpression();
+ CodePrimitiveExpression varMsgName = new CodePrimitiveExpression (messageName);
+ CodeMethodInvokeExpression inv;
+
+ inv = new CodeMethodInvokeExpression (ethis, "Invoke", varMsgName, methodParams);
+ CodeVariableDeclarationStatement dec = new CodeVariableDeclarationStatement (typeof(object[]), varResults, inv);
+ method.Statements.Add (dec);
+ method.Statements.AddRange (outAssign);
+
+ // Begin Invoke Call
+
+ CodeExpression expCallb = new CodeVariableReferenceExpression (varCallback);
+ CodeExpression expAsyncs = new CodeVariableReferenceExpression (varAsyncState);
+ inv = new CodeMethodInvokeExpression (ethis, "BeginInvoke", varMsgName, methodParams, expCallb, expAsyncs);
+ methodBegin.Statements.Add (new CodeMethodReturnStatement (inv));
+
+ // End Invoke call
+
+ CodeExpression varAsyncr = new CodeVariableReferenceExpression (varAsyncResult);
+ inv = new CodeMethodInvokeExpression (ethis, "EndInvoke", varAsyncr);
+ dec = new CodeVariableDeclarationStatement (typeof(object[]), varResults, inv);
+ methodEnd.Statements.Add (dec);
+ methodEnd.Statements.AddRange (outAssign);
+
+ // Attributes
+
+ if (inputMembers.ElementName == "" && outputMembers.ElementName != "" ||
+ inputMembers.ElementName != "" && outputMembers.ElementName == "")
+ throw new Exception ("Parameter style is not the same for the input message and output message");
+
+ CodeAttributeDeclaration att = new CodeAttributeDeclaration ("System.Web.Services.Protocols.SoapDocumentMethodAttribute");
+ att.Arguments.Add (GetArg (soapOper.SoapAction));
+ if (inputMembers.ElementName != "") {
+ if (inputMembers.ElementName != method.Name) att.Arguments.Add (GetArg ("RequestElementName", inputMembers.ElementName));
+ if (outputMembers.ElementName != (method.Name + "Response")) att.Arguments.Add (GetArg ("RequestElementName", outputMembers.ElementName));
+ att.Arguments.Add (GetArg ("RequestNamespace", inputMembers.Namespace));
+ att.Arguments.Add (GetArg ("ResponseNamespace", outputMembers.Namespace));
+ att.Arguments.Add (GetEnumArg ("ParameterStyle", "System.Web.Services.Protocols.SoapParameterStyle", "Wrapped"));
+ }
+ else
+ att.Arguments.Add (GetEnumArg ("ParameterStyle", "System.Web.Services.Protocols.SoapParameterStyle", "Bare"));
+
+ att.Arguments.Add (GetEnumArg ("Use", "System.Web.Services.Description.SoapBindingUse", bodyBinding.Use.ToString()));
+ AddCustomAttribute (method, att, true);
+
+ att = new CodeAttributeDeclaration ("System.Web.Services.WebMethodAttribute");
+ if (messageName != method.Name) att.Arguments.Add (GetArg ("MessageName",messageName));
+ AddCustomAttribute (method, att, false);
+
+ ImportHeaders (method);
+
+ CodeTypeDeclaration.Members.Add (method);
+ CodeTypeDeclaration.Members.Add (methodBegin);
+ CodeTypeDeclaration.Members.Add (methodEnd);
+
+ return method;
+ }
+
+ CodeParameterDeclarationExpression GenerateParameter (XmlMemberMapping member, FieldDirection dir)
+ {
+ CodeParameterDeclarationExpression par = new CodeParameterDeclarationExpression (member.TypeFullName, member.MemberName);
+ par.Direction = dir;
+ return par;
+ }
+
+ void GenerateMemberAttributes (XmlMembersMapping members, XmlMemberMapping member, CodeParameterDeclarationExpression param)
+ {
+ xmlExporter.AddMappingMetadata (param.CustomAttributes, member, members.Namespace);
+ }
+
+ void GenerateReturnAttributes (XmlMembersMapping members, XmlMemberMapping member, CodeMemberMethod method)
+ {
+ xmlExporter.AddMappingMetadata (method.ReturnTypeCustomAttributes, member, members.Namespace, (member.ElementName != method.Name + "Result"));
+ }
+
+ void ImportHeaders (CodeMemberMethod method)
+ {
+ foreach (object ob in OperationBinding.Input.Extensions)
+ {
+ SoapHeaderBinding hb = ob as SoapHeaderBinding;
+ if (hb == null) continue;
+ if (HasHeader (OperationBinding.Output, hb))
+ ImportHeader (method, hb, SoapHeaderDirection.In | SoapHeaderDirection.Out);
+ else
+ ImportHeader (method, hb, SoapHeaderDirection.In);
+ }
+
+ foreach (object ob in OperationBinding.Output.Extensions)
+ {
+ SoapHeaderBinding hb = ob as SoapHeaderBinding;
+ if (hb == null) continue;
+ if (!HasHeader (OperationBinding.Input, hb))
+ ImportHeader (method, hb, SoapHeaderDirection.Out);
+ }
+ }
+
+ bool HasHeader (MessageBinding msg, SoapHeaderBinding hb)
+ {
+ foreach (object ob in msg.Extensions)
+ {
+ SoapHeaderBinding mhb = ob as SoapHeaderBinding;
+ if ((mhb != null) && (mhb.Message == hb.Message) && (mhb.Part == hb.Part))
+ return true;
+ }
+ return false;
+ }
+
+ void ImportHeader (CodeMemberMethod method, SoapHeaderBinding hb, SoapHeaderDirection direction)
+ {
+ Message msg = ServiceDescriptions.GetMessage (hb.Message);
+ if (msg == null) throw new Exception ("Message " + hb.Message + " not found");
+ MessagePart part = msg.Parts [hb.Part];
+ if (part == null) throw new Exception ("Message part " + hb.Part + " not found in message " + hb.Message);
+
+ XmlTypeMapping map;
+ if (hb.Use == SoapBindingUse.Literal)
+ map = xmlImporter.ImportDerivedTypeMapping (part.Element, typeof (SoapHeader));
+ else
+ map = soapImporter.ImportDerivedTypeMapping (part.Type, typeof (SoapHeader), true);
+
+ xmlExporter.ExportTypeMapping (map);
+ bool required = false;
+
+ string varName = headerVariables [map] as string;
+ if (varName == null)
+ {
+ varName = memberIds.AddUnique(CodeIdentifier.MakeValid (map.TypeName + "Value"),hb);
+ headerVariables.Add (map, varName);
+ CodeMemberField codeField = new CodeMemberField (map.TypeFullName, varName);
+ codeField.Attributes = MemberAttributes.Public;
+ CodeTypeDeclaration.Members.Add (codeField);
+ }
+
+ CodeAttributeDeclaration att = new CodeAttributeDeclaration ("System.Web.Services.Protocols.SoapHeaderAttribute");
+ att.Arguments.Add (GetArg (varName));
+ att.Arguments.Add (GetArg ("Required", required));
+ if (direction != SoapHeaderDirection.In) att.Arguments.Add (GetEnumArg ("Direction", "System.Web.Services.Protocols.SoapHeaderDirection", direction.ToString ()));
+ AddCustomAttribute (method, att, true);
+ }
+
+ #endregion
+ }
+}
-// \r
-// System.Web.Services.Description.SoapProtocolReflector.cs\r
-//\r
-// Author:\r
-// Tim Coleman (tim@timcoleman.com)\r
-//\r
-// Copyright (C) Tim Coleman, 2002\r
-//\r
-\r
-using System.Web.Services;\r
-using System.Web.Services.Protocols;\r
-using System.Xml.Serialization;\r
-\r
-namespace System.Web.Services.Description {\r
- [MonoTODO ("This class is based on conjecture and guesswork.")]\r
- internal class SoapProtocolReflector : ProtocolReflector {\r
-\r
- #region Fields\r
-\r
- SoapBinding soapBinding;\r
-\r
- #endregion // Fields\r
-\r
- #region Constructors\r
-\r
- [MonoTODO]\r
- public SoapProtocolReflector ()\r
- {\r
- throw new NotImplementedException ();\r
- }\r
- \r
- #endregion // Constructors\r
-\r
- #region Properties\r
-\r
- public override string ProtocolName {\r
- get { return "Soap"; }\r
- }\r
-\r
- #endregion // Properties\r
-\r
- #region Methods\r
-\r
- [MonoTODO]\r
- protected override void BeginClass ()\r
- {\r
- throw new NotImplementedException ();\r
- }\r
-\r
- [MonoTODO]\r
- protected override void EndClass ()\r
- {\r
- throw new NotImplementedException ();\r
- }\r
-\r
- [MonoTODO]\r
- protected override bool ReflectMethod ()\r
- {\r
- throw new NotImplementedException ();\r
- }\r
-\r
- [MonoTODO]\r
- protected override string ReflectMethodBinding ()\r
- {\r
- throw new NotImplementedException ();\r
- }\r
-\r
- #endregion\r
- }\r
-}\r
+//
+// System.Web.Services.Description.SoapProtocolReflector.cs
+//
+// Author:
+// Tim Coleman (tim@timcoleman.com)
+// Lluis Sanchez Gual (lluis@ximian.com)
+//
+// Copyright (C) Tim Coleman, 2002
+//
+
+using System.Web.Services;
+using System.Web.Services.Protocols;
+using System.Xml.Serialization;
+using System.Xml;
+
+namespace System.Web.Services.Description {
+
+ internal class SoapProtocolReflector : ProtocolReflector
+ {
+ #region Fields
+
+ const string EncodingNamespace = "http://schemas.xmlsoap.org/soap/encoding/";
+ SoapBinding soapBinding;
+
+ #endregion // Fields
+
+ #region Constructors
+
+ public SoapProtocolReflector ()
+ {
+ }
+
+ #endregion // Constructors
+
+ #region Properties
+
+ public override string ProtocolName {
+ get { return "Soap"; }
+ }
+
+ #endregion // Properties
+
+ #region Methods
+
+ protected override void BeginClass ()
+ {
+ SoapBinding sb = new SoapBinding ();
+ sb.Transport = SoapBinding.HttpTransport;
+ sb.Style = TypeInfo.SoapBindingStyle;
+ Binding.Extensions.Add (sb);
+
+ SoapAddressBinding abind = new SoapAddressBinding ();
+ abind.Location = ServiceUrl;
+ Port.Extensions.Add (abind);
+ }
+
+ protected override void EndClass ()
+ {
+ }
+
+ protected override bool ReflectMethod ()
+ {
+ SoapOperationBinding sob = new SoapOperationBinding();
+ sob.SoapAction = MethodStubInfo.Action;
+ sob.Style = MethodStubInfo.SoapBindingStyle;
+ OperationBinding.Extensions.Add (sob);
+
+ AddOperationMsgBindings (OperationBinding.Input);
+ AddOperationMsgBindings (OperationBinding.Output);
+
+ foreach (HeaderInfo hf in MethodStubInfo.Headers)
+ {
+ Message msg = new Message ();
+ msg.Name = Operation.Name + hf.HeaderType.Name;
+ MessagePart part = new MessagePart ();
+ part.Name = hf.HeaderType.Name;
+ msg.Parts.Add (part);
+ ServiceDescription.Messages.Add (msg);
+
+ SoapHeaderBinding hb = new SoapHeaderBinding ();
+ hb.Message = new XmlQualifiedName (msg.Name, ServiceDescription.TargetNamespace);
+ hb.Part = part.Name;
+ hb.Use = MethodStubInfo.Use;
+
+ if (MethodStubInfo.Use == SoapBindingUse.Literal)
+ {
+ XmlTypeMapping mapping = ReflectionImporter.ImportTypeMapping (hf.HeaderType, ServiceDescription.TargetNamespace);
+ part.Element = new XmlQualifiedName (mapping.ElementName, mapping.Namespace);
+ SchemaExporter.ExportTypeMapping (mapping);
+ }
+ else
+ {
+ XmlTypeMapping mapping = SoapReflectionImporter.ImportTypeMapping (hf.HeaderType, ServiceDescription.TargetNamespace);
+ part.Type = new XmlQualifiedName (mapping.ElementName, mapping.Namespace);
+ SoapSchemaExporter.ExportTypeMapping (mapping);
+ hb.Encoding = EncodingNamespace;
+ }
+
+ if ((hf.Direction & SoapHeaderDirection.Out) != 0)
+ OperationBinding.Output.Extensions.Add (hb);
+ if ((hf.Direction & SoapHeaderDirection.In) != 0)
+ OperationBinding.Input.Extensions.Add (hb);
+ }
+
+ return true;
+ }
+
+ void AddOperationMsgBindings (MessageBinding msg)
+ {
+ SoapBodyBinding sbbo = new SoapBodyBinding();
+ msg.Extensions.Add (sbbo);
+ sbbo.Use = MethodStubInfo.Use;
+ if (MethodStubInfo.Use == SoapBindingUse.Encoded)
+ {
+ sbbo.Namespace = ServiceDescription.TargetNamespace;
+ sbbo.Encoding = EncodingNamespace;
+ }
+ }
+
+ protected override string ReflectMethodBinding ()
+ {
+ return MethodStubInfo.Binding;
+ }
+
+ #endregion
+ }
+}
-// \r
-// System.Web.Services.Description.SoapTransportImporter.cs\r
-//\r
-// Author:\r
-// Tim Coleman (tim@timcoleman.com)\r
-//\r
-// Copyright (C) Tim Coleman, 2002\r
-//\r
-\r
-namespace System.Web.Services.Description {\r
- public abstract class SoapTransportImporter {\r
-\r
- #region Fields\r
-\r
- SoapProtocolImporter importContext;\r
-\r
- #endregion // Fields\r
-\r
- #region Constructors\r
- \r
- protected SoapTransportImporter ()\r
- {\r
- importContext = null;\r
- }\r
- \r
- #endregion // Constructors\r
-\r
- #region Properties\r
-\r
- public SoapProtocolImporter ImportContext {\r
- get { return importContext; }\r
- set { importContext = value; }\r
- }\r
-\r
- #endregion // Properties\r
-\r
- #region Methods\r
-\r
- public abstract void ImportClass ();\r
- public abstract bool IsSupportedTransport (string transport);\r
-\r
- #endregion\r
- }\r
-}\r
+//
+// System.Web.Services.Description.SoapTransportImporter.cs
+//
+// Author:
+// Tim Coleman (tim@timcoleman.com)
+// Lluis Sanchez Gual (lluis@ximian.com)
+//
+// Copyright (C) Tim Coleman, 2002
+//
+
+using System.Collections;
+
+namespace System.Web.Services.Description {
+ public abstract class SoapTransportImporter {
+
+ #region Fields
+
+ static ArrayList transportImporters;
+ SoapProtocolImporter importContext;
+
+ #endregion // Fields
+
+ #region Constructors
+
+ static SoapTransportImporter ()
+ {
+ transportImporters = new ArrayList ();
+ transportImporters.Add (new SoapHttpTransportImporter ());
+ }
+
+ protected SoapTransportImporter ()
+ {
+ importContext = null;
+ }
+
+ #endregion // Constructors
+
+ #region Properties
+
+ public SoapProtocolImporter ImportContext {
+ get { return importContext; }
+ set { importContext = value; }
+ }
+
+ #endregion // Properties
+
+ #region Methods
+
+ public abstract void ImportClass ();
+ public abstract bool IsSupportedTransport (string transport);
+
+ internal static SoapTransportImporter FindTransportImporter (string uri)
+ {
+ foreach (SoapHttpTransportImporter imp in transportImporters)
+ if (imp.IsSupportedTransport (uri)) return imp;
+ return null;
+ }
+
+ #endregion
+ }
+}
--- /dev/null
+<configuration>
+ <serializer class="System.Web.Services.Description.ServiceDescription" assembly="System.Web.Services">
+ <reader>ServiceDescriptionReaderBase</reader>
+ <writer>ServiceDescriptionWriterBase</writer>
+ <namespace>System.Web.Services.Description</namespace>
+ <outFileName>ServiceDescriptionSerializerBase.cs</outFileName>
+ <readerHooks>
+ <hook type="unknownElement">
+ <select>
+ <typeAttribute>System.Web.Services.Configuration.XmlFormatExtensionPointAttribute</typeAttribute>
+ </select>
+ <replace>ServiceDescription.ReadExtension (Reader, $OBJECT);</replace>
+ </hook>
+ <hook type="type">
+ <select>
+ <typeName>System.Xml.Schema.XmlSchema</typeName>
+ </select>
+ <replace>$OBJECT = System.Xml.Schema.XmlSchema.Read (Reader, null);</replace>
+ </hook>
+ </readerHooks>
+ <writerHooks>
+ <hook type="elements">
+ <select>
+ <typeAttribute>System.Web.Services.Configuration.XmlFormatExtensionPointAttribute</typeAttribute>
+ </select>
+ <insertBefore>ServiceDescription.WriteExtensions (Writer, $OBJECT);</insertBefore>
+ </hook>
+ <hook type="type">
+ <select>
+ <typeName>System.Xml.Schema.XmlSchema</typeName>
+ </select>
+ <replace>$OBJECT.Write (Writer);</replace>
+ </hook>
+ </writerHooks>
+ </serializer>
+</configuration>