Merge pull request #4169 from evincarofautumn/fix-xmm-scanning-mac-x86
[mono.git] / mcs / class / System.Web.Services / System.Web.Services.Protocols / Methods.cs
index 10a81b8501554be277a2f51f7addd32f5df21fd6..6171dba1c016299be98bea6dc48695dd04e83386 100644 (file)
@@ -29,6 +29,8 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
+using HeaderInfo = System.Web.Services.Protocols.SoapHeaderMapping;
+
 using System.Reflection;
 using System.Collections;
 using System.Xml;
@@ -44,39 +46,39 @@ namespace System.Web.Services.Protocols {
        //
        internal class SoapMethodStubInfo : MethodStubInfo
        {
-               internal string Action;
-               internal string Binding;
+               internal readonly string Action;
+               internal readonly string Binding;
 
                // The name/namespace of the request 
-               internal string RequestName;
-               internal string RequestNamespace;
+               internal readonly string RequestName;
+               internal readonly string RequestNamespace;
 
                // The name/namespace of the response.
-               internal string ResponseName;
-               internal string ResponseNamespace;
-               
-               internal bool OneWay;
-               internal SoapParameterStyle ParameterStyle;
-               internal SoapBindingStyle SoapBindingStyle;
-               internal SoapBindingUse Use;
-
-               internal HeaderInfo[] Headers;
-               internal HeaderInfo[] InHeaders;
-               internal HeaderInfo[] OutHeaders;
-               internal HeaderInfo[] FaultHeaders;
-               internal SoapExtensionRuntimeConfig[] SoapExtensions;
-               
-               internal XmlMembersMapping InputMembersMapping;
-               internal XmlMembersMapping OutputMembersMapping;
-               internal XmlMembersMapping InputHeaderMembersMapping;
-               internal XmlMembersMapping OutputHeaderMembersMapping;
-               internal XmlMembersMapping FaultHeaderMembersMapping;
-               
-               private int requestSerializerId;
-               private int responseSerializerId;
-               private int requestHeadersSerializerId = -1;
-               private int responseHeadersSerializerId = -1;
-               private int faultHeadersSerializerId = -1;
+               internal readonly string ResponseName;
+               internal readonly string ResponseNamespace;
+
+               internal readonly bool OneWay;
+               internal readonly SoapParameterStyle ParameterStyle;
+               internal readonly SoapBindingStyle SoapBindingStyle;
+               internal readonly SoapBindingUse Use;
+
+               internal readonly HeaderInfo [] Headers;
+               internal readonly HeaderInfo [] InHeaders;
+               internal readonly HeaderInfo [] OutHeaders;
+               internal readonly HeaderInfo [] FaultHeaders;
+               internal readonly SoapExtensionRuntimeConfig [] SoapExtensions;
+
+               internal readonly XmlMembersMapping InputMembersMapping;
+               internal readonly XmlMembersMapping OutputMembersMapping;
+               internal readonly XmlMembersMapping InputHeaderMembersMapping;
+               internal readonly XmlMembersMapping OutputHeaderMembersMapping;
+               internal readonly XmlMembersMapping FaultHeaderMembersMapping;
+
+               private readonly int requestSerializerId;
+               private readonly int responseSerializerId;
+               private readonly int requestHeadersSerializerId = -1;
+               private readonly int responseHeadersSerializerId = -1;
+               private readonly int faultHeadersSerializerId = -1;
                
                internal XmlSerializer RequestSerializer
                {
@@ -114,7 +116,7 @@ namespace System.Web.Services.Protocols {
                        XmlElementAttribute optional_ns = null;
 
                        if (kind == null) {
-                               Use = parent.Use;
+                               Use = parent.LogicalType.BindingUse;
                                RequestName = "";
                                RequestNamespace = "";
                                ResponseName = "";
@@ -122,6 +124,11 @@ namespace System.Web.Services.Protocols {
                                ParameterStyle = parent.ParameterStyle;
                                SoapBindingStyle = parent.SoapBindingStyle;
                                OneWay = false;
+// disabled (see bug #332150)
+//#if NET_2_0
+//                             if (parent.Type != source.DeclaringType)
+//                                     Binding = source.DeclaringType.Name + parent.ProtocolName;
+//#endif
                        }
                        else if (kind is SoapDocumentMethodAttribute){
                                SoapDocumentMethodAttribute dma = (SoapDocumentMethodAttribute) kind;
@@ -129,7 +136,7 @@ namespace System.Web.Services.Protocols {
                                Use = dma.Use;
                                if (Use == SoapBindingUse.Default) {
                                        if (parent.SoapBindingStyle == SoapBindingStyle.Document)
-                                               Use = parent.Use;
+                                               Use = parent.LogicalType.BindingUse;
                                        else
                                                Use = SoapBindingUse.Literal;
                                }
@@ -150,6 +157,8 @@ namespace System.Web.Services.Protocols {
                                Use = SoapBindingUse.Encoded;   // RPC always use encoded
 
                                Action = rma.Action;
+                               if (Action != null && Action.Length == 0)
+                                       Action = null;
                                Binding = rma.Binding;
                                
                                // When using RPC, MS.NET seems to ignore RequestElementName and
@@ -185,7 +194,7 @@ namespace System.Web.Services.Protocols {
                        if (ResponseNamespace == "") ResponseNamespace = parent.LogicalType.GetWebServiceNamespace (serviceNamespace, Use);
                        if (RequestName == "") RequestName = Name;
                        if (ResponseName == "") ResponseName = Name + "Response";
-                       if (Action == null || Action == "")
+                       if (Action == null)
                                Action = serviceNamespace.EndsWith("/") ? (serviceNamespace + Name) : (serviceNamespace + "/" + Name);
                        
                        bool hasWrappingElem = (ParameterStyle == SoapParameterStyle.Wrapped);
@@ -205,6 +214,9 @@ namespace System.Web.Services.Protocols {
                                OutputMembersMapping = soapImporter.ImportMembersMapping (ResponseName, ResponseNamespace, out_members, hasWrappingElem, writeAccessors);
                        }
 
+                       InputMembersMapping.SetKey(RequestName);
+                       OutputMembersMapping.SetKey(ResponseName);
+
                        requestSerializerId = parent.RegisterSerializer (InputMembersMapping);
                        responseSerializerId = parent.RegisterSerializer (OutputMembersMapping);
 
@@ -223,7 +235,7 @@ namespace System.Web.Services.Protocols {
                                
                                HeaderInfo header = new HeaderInfo (mems[0], att);
                                allHeaderList.Add (header);
-                               if (!header.IsUnknownHeader) {
+                               if (!header.Custom) {
                                        if ((header.Direction & SoapHeaderDirection.In) != 0)
                                                inHeaderList.Add (header);
                                        if ((header.Direction & SoapHeaderDirection.Out) != 0)
@@ -245,6 +257,8 @@ namespace System.Web.Services.Protocols {
                                else
                                        InputHeaderMembersMapping = soapImporter.ImportMembersMapping ("", RequestNamespace, members, false, false);
                                
+                               InputHeaderMembersMapping.SetKey(RequestName + ":InHeaders");
+                               
                                requestHeadersSerializerId = parent.RegisterSerializer (InputHeaderMembersMapping);
                        }
                        
@@ -256,7 +270,9 @@ namespace System.Web.Services.Protocols {
                                        OutputHeaderMembersMapping = xmlImporter.ImportMembersMapping ("", RequestNamespace, members, false);
                                else
                                        OutputHeaderMembersMapping = soapImporter.ImportMembersMapping ("", RequestNamespace, members, false, false);
-                               
+
+                               OutputHeaderMembersMapping.SetKey(ResponseName + ":OutHeaders");
+
                                responseHeadersSerializerId = parent.RegisterSerializer (OutputHeaderMembersMapping);
                        }
                        
@@ -311,7 +327,7 @@ namespace System.Web.Services.Protocols {
                        {
                                m = new XmlReflectionMember ();
                                m.IsReturnValue = true;
-                               m.MemberName = RequestName + "Result";
+                               m.MemberName = Name + "Result";
                                m.MemberType = MethodInfo.ReturnType;
 
                                m.XmlAttributes = new XmlAttributes (MethodInfo.ReturnTypeCustomAttributeProvider);
@@ -379,12 +395,12 @@ namespace System.Web.Services.Protocols {
                        return null;
                }
                
-               public XmlSerializer GetBodySerializer (SoapHeaderDirection dir)
+               public XmlSerializer GetBodySerializer (SoapHeaderDirection dir, bool soap12)
                {
                        switch (dir) {
                                case SoapHeaderDirection.In: return RequestSerializer;
                                case SoapHeaderDirection.Out: return ResponseSerializer;
-                               case SoapHeaderDirection.Fault: return Fault.Serializer;
+                               case SoapHeaderDirection.Fault: return soap12 ? Soap12Fault.Serializer : Fault.Serializer;
                                default: return null;
                        }
                }
@@ -427,78 +443,16 @@ namespace System.Web.Services.Protocols {
                }
        }
 
-       internal class HeaderInfo
-       {
-               internal MemberInfo Member;
-               internal SoapHeaderAttribute AttributeInfo;
-               internal Type HeaderType;
-               internal bool IsUnknownHeader;
-
-               public HeaderInfo (MemberInfo member, SoapHeaderAttribute attributeInfo)
-               {
-                       Member = member;
-                       AttributeInfo = attributeInfo;
-                       if (Member is PropertyInfo) HeaderType = ((PropertyInfo)Member).PropertyType;
-                       else HeaderType = ((FieldInfo)Member).FieldType;
-                       
-                       if (HeaderType == typeof(SoapHeader) || HeaderType == typeof(SoapUnknownHeader) ||
-                               HeaderType == typeof(SoapHeader[]) || HeaderType == typeof(SoapUnknownHeader[]))
-                       {
-                               IsUnknownHeader = true;
-                       }
-                       else if (!typeof(SoapHeader).IsAssignableFrom (HeaderType))
-                               throw new InvalidOperationException (string.Format ("Header members type must be a SoapHeader subclass"));
-               }
-               
-               public object GetHeaderValue (object ob)
-               {
-                       if (Member is PropertyInfo) return ((PropertyInfo)Member).GetValue (ob, null);
-                       else return ((FieldInfo)Member).GetValue (ob);
-               }
-
-               public void SetHeaderValue (object ob, SoapHeader header)
-               {
-                       object value = header;
-                       if (IsUnknownHeader && HeaderType.IsArray)
-                       {
-                               SoapUnknownHeader uheader = header as SoapUnknownHeader;
-                               SoapUnknownHeader[] array = (SoapUnknownHeader[]) GetHeaderValue (ob);
-                               if (array == null || array.Length == 0) {
-                                       value = new SoapUnknownHeader[] { uheader };
-                               }
-                               else {
-                                       SoapUnknownHeader[] newArray = new SoapUnknownHeader [array.Length+1];
-                                       Array.Copy (array, newArray, array.Length);
-                                       newArray [array.Length] = uheader;
-                                       value = newArray;
-                               }
-                       }
-                       
-                       if (Member is PropertyInfo) ((PropertyInfo)Member).SetValue (ob, value, null);
-                       else ((FieldInfo)Member).SetValue (ob, value);
-               }
-               
-               public SoapHeaderDirection Direction
-               {
-                       get { return AttributeInfo.Direction; }
-               }
-       }
-
-
        //
        // Holds the metadata loaded from the type stub, as well as
        // the metadata for all the methods in the type
        //
        internal class SoapTypeStubInfo : TypeStubInfo
        {
-               Hashtable[] header_serializers = new Hashtable [3];
-               Hashtable[] header_serializers_byname = new Hashtable [3];
                Hashtable methods_byaction = new Hashtable (); 
 
                // Precomputed
                internal SoapParameterStyle      ParameterStyle;
-               internal SoapServiceRoutingStyle RoutingStyle;
-               internal SoapBindingUse          Use;
                internal SoapExtensionRuntimeConfig[][] SoapExtensions;
                internal SoapBindingStyle SoapBindingStyle;
                internal XmlReflectionImporter  xmlImporter;
@@ -509,58 +463,46 @@ namespace System.Web.Services.Protocols {
                {
                        xmlImporter = new XmlReflectionImporter ();
                        soapImporter = new SoapReflectionImporter ();
-                       
-                       object [] o;
-
-                       o = Type.GetCustomAttributes (typeof (WebServiceBindingAttribute), false);
-                       
+                               
                        if (typeof (SoapHttpClientProtocol).IsAssignableFrom (Type))
                        {
-                               if (o.Length == 0)
+                               if (Bindings.Count == 0 || ((BindingInfo)Bindings[0]).WebServiceBindingAttribute == null)
                                        throw new InvalidOperationException ("WebServiceBindingAttribute is required on proxy class '" + Type + "'.");
-                               if (o.Length > 1)
+                               if (Bindings.Count > 1)
                                        throw new InvalidOperationException ("Only one WebServiceBinding attribute may be specified on type '" + Type + "'.");
-                                       
-                               // Remove the default binding, it is not needed since there is always
-                               // a binding attribute.
-                               Bindings.Clear ();
                        }
-                               
-                       foreach (WebServiceBindingAttribute at in o)
-                               AddBinding (new BindingInfo (at, LogicalType.WebServiceNamespace));
 
-                       o = Type.GetCustomAttributes (typeof (SoapDocumentServiceAttribute), false);
+                       object [] o = Type.GetCustomAttributes (typeof (SoapDocumentServiceAttribute), false);
                        if (o.Length == 1){
                                SoapDocumentServiceAttribute a = (SoapDocumentServiceAttribute) o [0];
 
                                ParameterStyle = a.ParameterStyle;
-                               RoutingStyle = a.RoutingStyle;
-                               Use = a.Use;
                                SoapBindingStyle = SoapBindingStyle.Document;
                        } else {
                                o = Type.GetCustomAttributes (typeof (SoapRpcServiceAttribute), false);
                                if (o.Length == 1){
-                                       SoapRpcServiceAttribute srs = (SoapRpcServiceAttribute) o [0];
-                                       
                                        ParameterStyle = SoapParameterStyle.Wrapped;
-                                       RoutingStyle = srs.RoutingStyle;
-                                       Use = SoapBindingUse.Encoded;
                                        SoapBindingStyle = SoapBindingStyle.Rpc;
                                } else {
                                        ParameterStyle = SoapParameterStyle.Wrapped;
-                                       RoutingStyle = SoapServiceRoutingStyle.SoapAction;
-                                       Use = SoapBindingUse.Literal;
                                        SoapBindingStyle = SoapBindingStyle.Document;
                                }
                        }
                        
                        if (ParameterStyle == SoapParameterStyle.Default) ParameterStyle = SoapParameterStyle.Wrapped;
-                       if (Use == SoapBindingUse.Default) Use = SoapBindingUse.Literal;
                        
                        xmlImporter.IncludeTypes (Type);
                        soapImporter.IncludeTypes (Type);
 
+#if MOBILE || XAMMAC_4_5
+                       SoapExtensions = new SoapExtensionRuntimeConfig [2][];
+#else
                        SoapExtensions = SoapExtension.GetTypeExtensions (Type);
+#endif
+               }
+
+               internal SoapServiceRoutingStyle RoutingStyle {
+                       get { return LogicalType.RoutingStyle; }
                }
 
                public override XmlReflectionImporter XmlImporter 
@@ -600,4 +542,17 @@ namespace System.Web.Services.Protocols {
                        return (SoapMethodStubInfo) methods_byaction [name.Trim ('"',' ')];
                }
        }
+
+       internal class Soap12TypeStubInfo : SoapTypeStubInfo
+       {
+               public Soap12TypeStubInfo (LogicalTypeInfo logicalTypeInfo)
+               : base (logicalTypeInfo)
+               {
+               }
+
+               public override string ProtocolName
+               {
+                       get { return "Soap12"; }
+               }
+       }
 }