(DISTFILES): Comment out a few missing files.
[mono-project.git] / mcs / class / System.Web.Services / System.Web.Services.Protocols / TypeStubManager.cs
blob71cd921359d242e2f3608c02eda8767ce8760226
1 //
2 // Methods.cs: Information about a method and its mapping to a SOAP web service.
3 //
4 // Author:
5 // Miguel de Icaza
6 // Lluis Sanchez Gual (lluis@ximian.com)
7 //
8 // (C) 2003 Ximian, Inc.
9 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 //
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System.Reflection;
33 using System.Collections;
34 using System.Xml;
35 using System.Xml.Serialization;
36 using System.Web.Services;
37 using System.Web.Services.Description;
39 namespace System.Web.Services.Protocols {
42 // This class represents all the information we extract from a MethodInfo
43 // in the WebClientProtocol derivative stub class
45 internal class MethodStubInfo
47 internal LogicalMethodInfo MethodInfo;
48 internal TypeStubInfo TypeStub;
50 // The name used by the stub class to reference this method.
51 internal string Name;
52 internal WebMethodAttribute MethodAttribute;
54 internal string OperationName
56 get { return MethodInfo.Name; }
60 // Constructor
62 public MethodStubInfo (TypeStubInfo parent, LogicalMethodInfo source)
64 TypeStub = parent;
65 MethodInfo = source;
67 object [] o = source.GetCustomAttributes (typeof (WebMethodAttribute));
68 if (o.Length > 0)
70 MethodAttribute = (WebMethodAttribute) o [0];
71 Name = MethodAttribute.MessageName;
72 if (Name == "") Name = source.Name;
74 else
75 Name = source.Name;
80 // Holds the metadata loaded from the type stub, as well as
81 // the metadata for all the methods in the type
83 internal class TypeStubInfo
85 Hashtable name_to_method = new Hashtable ();
86 MethodStubInfo[] methods;
87 ArrayList bindings = new ArrayList ();
88 LogicalTypeInfo logicalType;
89 string defaultBinding;
90 ArrayList mappings;
91 XmlSerializer[] serializers;
93 public TypeStubInfo (LogicalTypeInfo logicalTypeInfo)
95 this.logicalType = logicalTypeInfo;
97 defaultBinding = logicalType.WebServiceName + ProtocolName;
98 BindingInfo binfo = new BindingInfo (defaultBinding, logicalType.WebServiceNamespace);
99 Bindings.Add (binfo);
102 public LogicalTypeInfo LogicalType
104 get { return logicalType; }
107 public Type Type
109 get { return logicalType.Type; }
112 public string DefaultBinding
114 get { return defaultBinding; }
117 public virtual XmlReflectionImporter XmlImporter
119 get { return null; }
122 public virtual SoapReflectionImporter SoapImporter
124 get { return null; }
127 public virtual string ProtocolName
129 get { return null; }
132 public XmlSerializer GetSerializer (int n)
134 return serializers [n];
137 public int RegisterSerializer (XmlMapping map)
139 if (mappings == null) mappings = new ArrayList ();
140 return mappings.Add (map);
143 public void Initialize ()
145 BuildTypeMethods ();
147 if (mappings != null)
149 // Build all the serializers at once
150 XmlMapping[] maps = (XmlMapping[]) mappings.ToArray(typeof(XmlMapping));
151 serializers = XmlSerializer.FromMappings (maps);
156 // Extract all method information
158 protected virtual void BuildTypeMethods ()
160 bool isClientProxy = typeof(WebClientProtocol).IsAssignableFrom (Type);
162 ArrayList metStubs = new ArrayList ();
163 foreach (LogicalMethodInfo mi in logicalType.LogicalMethods)
165 if (!isClientProxy && mi.CustomAttributeProvider.GetCustomAttributes (typeof(WebMethodAttribute), true).Length == 0)
166 continue;
168 MethodStubInfo msi = CreateMethodStubInfo (this, mi, isClientProxy);
170 if (msi == null)
171 continue;
173 if (name_to_method.ContainsKey (msi.Name)) {
174 string msg = "Both " + msi.MethodInfo.ToString () + " and " + GetMethod (msi.Name).MethodInfo + " use the message name '" + msi.Name + "'. ";
175 msg += "Use the MessageName property of WebMethod custom attribute to specify unique message names for the methods";
176 throw new InvalidOperationException (msg);
179 name_to_method [msi.Name] = msi;
180 metStubs.Add (msi);
182 methods = (MethodStubInfo[]) metStubs.ToArray (typeof (MethodStubInfo));
185 protected virtual MethodStubInfo CreateMethodStubInfo (TypeStubInfo typeInfo, LogicalMethodInfo methodInfo, bool isClientProxy)
187 return new MethodStubInfo (typeInfo, methodInfo);
190 public MethodStubInfo GetMethod (string name)
192 return (MethodStubInfo) name_to_method [name];
195 public MethodStubInfo[] Methods
197 get { return methods; }
200 internal ArrayList Bindings
202 get { return bindings; }
205 internal void AddBinding (BindingInfo info)
207 bindings.Add (info);
210 internal BindingInfo GetBinding (string name)
212 if (name == null || name.Length == 0) return (BindingInfo) bindings[0];
214 for (int n=1; n<bindings.Count; n++)
215 if (((BindingInfo)bindings[n]).Name == name) return (BindingInfo)bindings[n];
216 return null;
220 internal class BindingInfo
222 public BindingInfo (WebServiceBindingAttribute at, string ns)
224 Name = at.Name;
225 Namespace = at.Namespace;
226 if (Namespace == "") Namespace = ns;
227 Location = at.Location;
230 public BindingInfo (string name, string ns)
232 Name = name;
233 Namespace = ns;
236 public string Name;
237 public string Namespace;
238 public string Location;
243 // This class has information abou a web service. Through providess
244 // access to the TypeStubInfo instances for each protocol.
246 internal class LogicalTypeInfo
248 LogicalMethodInfo[] logicalMethods;
250 internal string WebServiceName;
251 internal string WebServiceNamespace;
252 string WebServiceLiteralNamespace;
253 string WebServiceEncodedNamespace;
254 internal string WebServiceAbstractNamespace;
255 internal string Description;
256 internal Type Type;
257 bool useEncoded;
259 TypeStubInfo soapProtocol;
260 TypeStubInfo httpGetProtocol;
261 TypeStubInfo httpPostProtocol;
263 public LogicalTypeInfo (Type t)
265 this.Type = t;
267 object [] o = Type.GetCustomAttributes (typeof (WebServiceAttribute), false);
268 if (o.Length == 1){
269 WebServiceAttribute a = (WebServiceAttribute) o [0];
270 WebServiceName = (a.Name != string.Empty) ? a.Name : Type.Name;
271 WebServiceNamespace = (a.Namespace != string.Empty) ? a.Namespace : WebServiceAttribute.DefaultNamespace;
272 Description = a.Description;
273 } else {
274 WebServiceName = Type.Name;
275 WebServiceNamespace = WebServiceAttribute.DefaultNamespace;
278 // Determine the namespaces for literal and encoded schema types
280 useEncoded = false;
282 o = t.GetCustomAttributes (typeof(SoapDocumentServiceAttribute), true);
283 if (o.Length > 0) {
284 SoapDocumentServiceAttribute at = (SoapDocumentServiceAttribute) o[0];
285 useEncoded = (at.Use == SoapBindingUse.Encoded);
287 else if (t.GetCustomAttributes (typeof(SoapRpcServiceAttribute), true).Length > 0)
288 useEncoded = true;
290 string sep = WebServiceNamespace.EndsWith ("/") ? "" : "/";
292 if (useEncoded) {
293 WebServiceEncodedNamespace = WebServiceNamespace;
294 WebServiceLiteralNamespace = WebServiceNamespace + sep + "literalTypes";
296 else {
297 WebServiceEncodedNamespace = WebServiceNamespace + sep + "encodedTypes";
298 WebServiceLiteralNamespace = WebServiceNamespace;
301 WebServiceAbstractNamespace = WebServiceNamespace + sep + "AbstractTypes";
303 MethodInfo [] type_methods = Type.GetMethods (BindingFlags.Instance | BindingFlags.Public);
304 logicalMethods = LogicalMethodInfo.Create (type_methods, LogicalMethodTypes.Sync);
307 public LogicalMethodInfo[] LogicalMethods
309 get { return logicalMethods; }
312 public TypeStubInfo GetTypeStub (string protocolName)
314 lock (this)
316 switch (protocolName)
318 case "Soap":
319 if (soapProtocol == null) soapProtocol = CreateTypeStubInfo (typeof(SoapTypeStubInfo));
320 return soapProtocol;
321 case "HttpGet":
322 if (httpGetProtocol == null) httpGetProtocol = CreateTypeStubInfo (typeof(HttpGetTypeStubInfo));
323 return httpGetProtocol;
324 case "HttpPost":
325 if (httpPostProtocol == null) httpPostProtocol = CreateTypeStubInfo (typeof(HttpPostTypeStubInfo));
326 return httpPostProtocol;
329 throw new InvalidOperationException ("Protocol " + protocolName + " not supported");
332 TypeStubInfo CreateTypeStubInfo (Type type)
334 TypeStubInfo tsi = (TypeStubInfo) Activator.CreateInstance (type, new object[] {this});
335 tsi.Initialize ();
336 return tsi;
339 public string GetWebServiceLiteralNamespace (string baseNamespace)
341 if (useEncoded) {
342 string sep = baseNamespace.EndsWith ("/") ? "" : "/";
343 return baseNamespace + sep + "literalTypes";
345 else
346 return baseNamespace;
349 public string GetWebServiceEncodedNamespace (string baseNamespace)
351 if (useEncoded)
352 return baseNamespace;
353 else {
354 string sep = baseNamespace.EndsWith ("/") ? "" : "/";
355 return baseNamespace + sep + "encodedTypes";
359 public string GetWebServiceNamespace (string baseNamespace, SoapBindingUse use)
361 if (use == SoapBindingUse.Literal) return GetWebServiceLiteralNamespace (baseNamespace);
362 else return GetWebServiceEncodedNamespace (baseNamespace);
368 // Manages type stubs
370 internal class TypeStubManager
372 static Hashtable type_to_manager;
374 static TypeStubManager ()
376 type_to_manager = new Hashtable ();
379 static internal TypeStubInfo GetTypeStub (Type t, string protocolName)
381 LogicalTypeInfo tm = GetLogicalTypeInfo (t);
382 return tm.GetTypeStub (protocolName);
386 // This needs to be thread safe
388 static internal LogicalTypeInfo GetLogicalTypeInfo (Type t)
390 lock (type_to_manager)
392 LogicalTypeInfo tm = (LogicalTypeInfo) type_to_manager [t];
394 if (tm != null)
395 return tm;
397 tm = (LogicalTypeInfo) type_to_manager [t];
399 if (tm != null)
400 return tm;
402 tm = new LogicalTypeInfo (t);
403 type_to_manager [t] = tm;
405 return tm;