* ExtensionManager.cs: Read extension types from the configuration file.
authorLluis Sanchez <lluis@novell.com>
Sun, 28 Sep 2003 11:51:17 +0000 (11:51 -0000)
committerLluis Sanchez <lluis@novell.com>
Sun, 28 Sep 2003 11:51:17 +0000 (11:51 -0000)
  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

12 files changed:
mcs/class/System.Web.Services/System.Web.Services.Description/ChangeLog
mcs/class/System.Web.Services/System.Web.Services.Description/ExtensionManager.cs
mcs/class/System.Web.Services/System.Web.Services.Description/ProtocolImporter.cs
mcs/class/System.Web.Services/System.Web.Services.Description/ProtocolReflector.cs
mcs/class/System.Web.Services/System.Web.Services.Description/ServiceDescriptionCollection.cs
mcs/class/System.Web.Services/System.Web.Services.Description/ServiceDescriptionImporter.cs
mcs/class/System.Web.Services/System.Web.Services.Description/ServiceDescriptionReflector.cs
mcs/class/System.Web.Services/System.Web.Services.Description/SoapHttpTransportImporter.cs [new file with mode: 0644]
mcs/class/System.Web.Services/System.Web.Services.Description/SoapProtocolImporter.cs
mcs/class/System.Web.Services/System.Web.Services.Description/SoapProtocolReflector.cs
mcs/class/System.Web.Services/System.Web.Services.Description/SoapTransportImporter.cs
mcs/class/System.Web.Services/System.Web.Services.Description/wsdl.genxs [new file with mode: 0644]

index 44623b68134aeeba5ff7ac05268f865116f92ae5..abe15fe46c1f610fa3c0afea72967bb4369b9c9a 100644 (file)
@@ -1,3 +1,20 @@
+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 
index 6700fb200b721e15a652cd2affe9517906c3b4a5..c5d58e5753f7d69683a03de7671767bcb8f828e6 100644 (file)
@@ -40,6 +40,9 @@ namespace System.Web.Services.Description
                        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
@@ -62,7 +65,7 @@ namespace System.Web.Services.Description
                                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
@@ -112,6 +115,45 @@ namespace System.Web.Services.Description
                                        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
index f37547f788b9a028a100feca8b5adf74be288371..1749a28381a7b5172269ba371296ff0d676ca769 100644 (file)
-// \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
+       }
+}
index ad7b209387b426a2b3457f5e5250d42b6abe42af..ed0f9f01dca8a710e37bb4f398726879c2a8bb16 100644 (file)
-// \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
+       }
+}
index a572b3c7fc2ea136ca7a2f2f8607003db67943ae..2c98bb2d062d088c35050fea171a7ef8a6ff8c89 100644 (file)
@@ -3,6 +3,7 @@
 //\r
 // Author:\r
 //   Tim Coleman (tim@timcoleman.com)\r
+//   Lluis Sanchez Gual (lluis@ximian.com)\r
 //\r
 // Copyright (C) Tim Coleman, 2002\r
 //\r
@@ -36,10 +37,7 @@ namespace System.Web.Services.Description {
 \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
@@ -65,45 +63,51 @@ namespace System.Web.Services.Description {
 \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
@@ -123,4 +127,4 @@ namespace System.Web.Services.Description {
 \r
                #endregion // Methods\r
        }\r
-}\r
+}
index 7ca74caee7fb93be3217050a0b0a08f9ac05ccf2..0708d88683127f75ac46ede1cccd028af81011a9 100644 (file)
@@ -27,24 +27,9 @@ namespace System.Web.Services.Description {
                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
@@ -102,512 +87,28 @@ namespace System.Web.Services.Description {
 \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
 }
index 91e7ba521b1e7eed574bc7026c74b902053205e0..6263338f807afcfad13298b20a862c548f11b6d5 100644 (file)
@@ -17,23 +17,13 @@ using System.Web.Services.Protocols;
 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
@@ -41,223 +31,23 @@ namespace System.Web.Services.Description {
                #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
diff --git a/mcs/class/System.Web.Services/System.Web.Services.Description/SoapHttpTransportImporter.cs b/mcs/class/System.Web.Services/System.Web.Services.Description/SoapHttpTransportImporter.cs
new file mode 100644 (file)
index 0000000..85520af
--- /dev/null
@@ -0,0 +1,28 @@
+// 
+// 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);
+               }
+       }
+}
index f9982eeed20eb2bbce623df992c2e5155771dfa8..dff7694e22495162883c43d186d452fbd1c00b71 100644 (file)
-// \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
+       }
+}
index cc7fbe03af7eaedbc9c9637324cbfef95d9b5f07..1da63477a460a27db984517cd23a5e5b337a5a11 100644 (file)
-// \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
+       }
+}
index 22d76ed997820c11bb9ceb2731bd89df10562ce9..d37a2c53f9e7c1ae23e64acd7e42f7915fba01aa 100644 (file)
@@ -1,44 +1,61 @@
-// \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
+       }
+}
diff --git a/mcs/class/System.Web.Services/System.Web.Services.Description/wsdl.genxs b/mcs/class/System.Web.Services/System.Web.Services.Description/wsdl.genxs
new file mode 100644 (file)
index 0000000..c219733
--- /dev/null
@@ -0,0 +1,36 @@
+<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>