Merge pull request #762 from echampet/wsdl
[mono.git] / mcs / class / System.Web.Services / System.Web.Services.Description / SoapProtocolReflector.cs
index 72317a9b4a1e150a0c2e9e41e0411c18cca22d98..85e610a2043151a4323e3953c29147201161a7bf 100644 (file)
@@ -8,6 +8,27 @@
 // Copyright (C) Tim Coleman, 2002
 //
 
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
 using System.Web.Services;
 using System.Web.Services.Protocols;
 using System.Xml.Serialization;
@@ -16,11 +37,10 @@ using System.Xml;
 
 namespace System.Web.Services.Description {
 
-       internal class SoapProtocolReflector : ProtocolReflector 
+       internal abstract class SoapProtocolReflector : ProtocolReflector 
        {
                #region Fields
 
-               const string EncodingNamespace = "http://schemas.xmlsoap.org/soap/encoding/";
                SoapBinding soapBinding;
 
                #endregion // Fields
@@ -35,24 +55,15 @@ namespace System.Web.Services.Description {
 
                #region Properties
 
-               public override string ProtocolName {
-                       get { return "Soap"; }
-               }
+               public abstract SoapExtensionReflector ExtensionReflector { get; }
 
-               #endregion // Properties
+               #endregion
 
                #region Methods
 
                protected override void BeginClass ()
                {
-                       SoapBinding sb = new SoapBinding ();
-                       sb.Transport = SoapBinding.HttpTransport;
-                       sb.Style = ((SoapTypeStubInfo)TypeInfo).SoapBindingStyle;
-                       Binding.Extensions.Add (sb);
-
-                       SoapAddressBinding abind = new SoapAddressBinding ();
-                       abind.Location = ServiceUrl;
-                       Port.Extensions.Add (abind);
+                       ExtensionReflector.ReflectDescription ();
                }
 
                protected override void EndClass ()
@@ -61,21 +72,36 @@ namespace System.Web.Services.Description {
 
                protected override bool ReflectMethod ()
                {
-                       SoapOperationBinding sob = new SoapOperationBinding();
                        SoapMethodStubInfo method = (SoapMethodStubInfo) MethodStubInfo;
-                       
-                       sob.SoapAction = method.Action;
-                       sob.Style = method.SoapBindingStyle;
-                       OperationBinding.Extensions.Add (sob);
-                       
+                       bool existing = false;
+#if NET_2_0
+                       if (Parent != null) {
+                               if (Parent.MappedMessagesIn.ContainsKey (method.MethodInfo))
+                                       existing = true;
+                               else {
+                                       Parent.MappedMessagesIn [method.MethodInfo] = InputMessage;
+                                       Parent.MappedMessagesOut [method.MethodInfo] = OutputMessage;
+                               }
+                       }
+#endif
+                       if (!existing)
+                               ImportMessageParts ();
+                       ExtensionReflector.ReflectMethod ();
+
+                       return !existing;
+               }
+               
+               void ImportMessageParts ()
+               {
+                       SoapMethodStubInfo method = (SoapMethodStubInfo) MethodStubInfo;
                        ImportMessage (method.InputMembersMapping, InputMessage);
                        ImportMessage (method.OutputMembersMapping, OutputMessage);
                                
-                       AddOperationMsgBindings (method, OperationBinding.Input);
-                       AddOperationMsgBindings (method, OperationBinding.Output);
 
-                       foreach (HeaderInfo hf in method.Headers)
+                       foreach (SoapHeaderMapping hf in method.Headers)
                        {
+                               if (hf.Custom) continue;
+                               
                                Message msg = new Message ();
                                msg.Name = Operation.Name + hf.HeaderType.Name;
                                MessagePart part = new MessagePart ();
@@ -83,51 +109,40 @@ namespace System.Web.Services.Description {
                                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 = method.Use;
-                               
                                if (method.Use == SoapBindingUse.Literal)
                                {
-                                       XmlTypeMapping mapping = ReflectionImporter.ImportTypeMapping (hf.HeaderType, ServiceDescription.TargetNamespace);
+                                       // MS.NET reflects header classes in a weird way. The root element
+                                       // name is the CLR class name unless it is specified in an XmlRootAttribute.
+                                       // The usual is to use the xml type name by default, but not in this case.
+                               
+                                       XmlRootAttribute root;
+                                       XmlAttributes ats = new XmlAttributes (hf.HeaderType);
+                                       if (ats.XmlRoot != null) root = ats.XmlRoot;
+                                       else root = new XmlRootAttribute (hf.HeaderType.Name);
+                                       
+                                       if (root.Namespace == null) root.Namespace = TypeInfo.LogicalType.GetWebServiceLiteralNamespace (ServiceDescription.TargetNamespace);
+                                       if (root.ElementName == null) root.ElementName = hf.HeaderType.Name;
+                                       
+                                       XmlTypeMapping mapping = ReflectionImporter.ImportTypeMapping (hf.HeaderType, root);
                                        part.Element = new XmlQualifiedName (mapping.ElementName, mapping.Namespace);
                                        SchemaExporter.ExportTypeMapping (mapping);
                                }
                                else
                                {
-                                       XmlTypeMapping mapping = SoapReflectionImporter.ImportTypeMapping (hf.HeaderType, ServiceDescription.TargetNamespace);
+                                       XmlTypeMapping mapping = SoapReflectionImporter.ImportTypeMapping (hf.HeaderType, TypeInfo.LogicalType.GetWebServiceEncodedNamespace (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 (SoapMethodStubInfo method, MessageBinding msg)
-               {
-                       SoapBodyBinding sbbo = new SoapBodyBinding();
-                       msg.Extensions.Add (sbbo);
-                       sbbo.Use = method.Use;
-                       if (method.Use == SoapBindingUse.Encoded)
-                       {
-                               sbbo.Namespace = ServiceDescription.TargetNamespace;
-                               sbbo.Encoding = EncodingNamespace;
                        }
                }
                
                void ImportMessage (XmlMembersMapping members, Message msg)
                {
                        SoapMethodStubInfo method = (SoapMethodStubInfo) MethodStubInfo;
-                       
-                       if (method.ParameterStyle == SoapParameterStyle.Wrapped)
+                       bool needsEnclosingElement = (method.ParameterStyle == SoapParameterStyle.Wrapped && 
+                                                                                       method.SoapBindingStyle == SoapBindingStyle.Document);
+
+                       if (needsEnclosingElement)
                        {
                                MessagePart part = new MessagePart ();
                                part.Name = "parameters";
@@ -144,11 +159,15 @@ namespace System.Web.Services.Description {
                                        part.Name = members[n].MemberName;
                                        
                                        if (method.Use == SoapBindingUse.Literal) {
-                                               part.Element = new XmlQualifiedName (members[n].MemberName, members[n].Namespace);
+                                               if (members[n].Any)
+                                                       part.Type = new XmlQualifiedName ("any", members[n].Namespace);
+                                               else
+                                                       part.Element = new XmlQualifiedName (members[n].ElementName, members[n].Namespace);
                                        }
                                        else {
                                                string namesp = members[n].TypeNamespace;
-                                               if (namesp == "") namesp = XmlSchema.Namespace;
+                                               if (namesp == "") namesp = members[n].Namespace;
+                                               part.Name = members[n].ElementName;
                                                part.Type = new XmlQualifiedName (members[n].TypeName, namesp);
                                        }
                                        msg.Parts.Add (part);
@@ -159,7 +178,7 @@ namespace System.Web.Services.Description {
                        if (method.Use == SoapBindingUse.Literal)
                                SchemaExporter.ExportMembersMapping (members);
                        else
-                               SoapSchemaExporter.ExportMembersMapping (members);
+                               SoapSchemaExporter.ExportMembersMapping (members, needsEnclosingElement);
                }
 
                protected override string ReflectMethodBinding ()
@@ -169,4 +188,44 @@ namespace System.Web.Services.Description {
 
                #endregion
        }
+
+       internal class Soap11ProtocolReflector : SoapProtocolReflector
+       {
+               SoapExtensionReflector reflector;
+               
+               public Soap11ProtocolReflector ()
+               {
+                       reflector = new Soap11BindingExtensionReflector ();
+                       reflector.ReflectionContext = this;
+               }
+
+               public override string ProtocolName {
+                       get { return "Soap"; }
+               }
+
+               public override SoapExtensionReflector ExtensionReflector {
+                       get { return reflector; }
+               }
+       }
+
+#if NET_2_0
+       internal class Soap12ProtocolReflector : SoapProtocolReflector
+       {
+               SoapExtensionReflector reflector;
+               
+               public Soap12ProtocolReflector ()
+               {
+                       reflector = new Soap12BindingExtensionReflector ();
+                       reflector.ReflectionContext = this;
+               }
+
+               public override string ProtocolName {
+                       get { return "Soap12"; }
+               }
+
+               public override SoapExtensionReflector ExtensionReflector {
+                       get { return reflector; }
+               }
+       }
+#endif
 }