2 // System.Web.Services.Description.ProtocolReflector.cs
5 // Tim Coleman (tim@timcoleman.com)
6 // Lluis Sanchez Gual (lluis@ximian.com)
8 // Copyright (C) Tim Coleman, 2002
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:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
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.Web.Services;
33 using System.Web.Services.Protocols;
34 using System.Xml.Serialization;
36 using System.Xml.Schema;
37 using System.Collections;
39 namespace System.Web.Services.Description {
40 public abstract class ProtocolReflector {
45 string defaultNamespace;
46 MessageCollection headerMessages;
48 LogicalMethodInfo[] methods;
50 OperationBinding operationBinding;
51 Message outputMessage;
55 XmlSchemaExporter schemaExporter;
57 ServiceDescription serviceDescription;
60 SoapSchemaExporter soapSchemaExporter;
61 MethodStubInfo methodStubInfo;
62 TypeStubInfo typeInfo;
63 ArrayList extensionReflectors;
64 ServiceDescriptionReflector serviceReflector;
66 XmlReflectionImporter reflectionImporter;
67 SoapReflectionImporter soapReflectionImporter;
69 CodeIdentifiers portNames;
75 protected ProtocolReflector ()
77 defaultNamespace = WebServiceAttribute.DefaultNamespace;
78 extensionReflectors = ExtensionManager.BuildExtensionReflectors ();
81 #endregion // Constructors
85 public Binding Binding {
86 get { return binding; }
89 public string DefaultNamespace {
90 get { return defaultNamespace; }
93 public MessageCollection HeaderMessages {
94 get { return headerMessages; } // TODO: set
97 public Message InputMessage {
98 get { return inputMessage; }
101 public LogicalMethodInfo Method {
102 get { return methodStubInfo.MethodInfo; }
105 public WebMethodAttribute MethodAttribute {
106 get { return methodStubInfo.MethodAttribute; }
109 public LogicalMethodInfo[] Methods {
110 get { return typeInfo.LogicalType.LogicalMethods; }
113 public Operation Operation {
114 get { return operation; }
117 public OperationBinding OperationBinding {
118 get { return operationBinding; }
121 public Message OutputMessage {
122 get { return outputMessage; }
129 public PortType PortType {
130 get { return portType; }
133 public abstract string ProtocolName {
137 public XmlReflectionImporter ReflectionImporter
141 if (reflectionImporter == null) {
142 reflectionImporter = typeInfo.XmlImporter;
143 if (reflectionImporter == null)
144 reflectionImporter = new XmlReflectionImporter();
146 return reflectionImporter;
150 internal SoapReflectionImporter SoapReflectionImporter
154 if (soapReflectionImporter == null) {
155 soapReflectionImporter = typeInfo.SoapImporter;
156 if (soapReflectionImporter == null)
157 soapReflectionImporter = new SoapReflectionImporter();
159 return soapReflectionImporter;
163 public XmlSchemaExporter SchemaExporter {
164 get { return schemaExporter; }
167 internal SoapSchemaExporter SoapSchemaExporter {
168 get { return soapSchemaExporter; }
171 public XmlSchemas Schemas {
172 get { return serviceReflector.Schemas; }
175 public Service Service {
176 get { return service; }
179 public ServiceDescription ServiceDescription {
180 get { return serviceDescription; }
183 public ServiceDescriptionCollection ServiceDescriptions {
184 get { return serviceReflector.ServiceDescriptions; }
187 public Type ServiceType {
188 get { return serviceType; }
191 public string ServiceUrl {
192 get { return serviceUrl; }
195 internal MethodStubInfo MethodStubInfo {
196 get { return methodStubInfo; }
199 internal TypeStubInfo TypeInfo {
200 get { return typeInfo; }
204 #endregion // Properties
208 internal void Reflect (ServiceDescriptionReflector serviceReflector, Type type, string url, XmlSchemaExporter xxporter, SoapSchemaExporter sxporter)
210 portNames = new CodeIdentifiers ();
211 this.serviceReflector = serviceReflector;
215 schemaExporter = xxporter;
216 soapSchemaExporter = sxporter;
218 typeInfo = TypeStubManager.GetTypeStub (type, ProtocolName);
220 ServiceDescription desc = ServiceDescriptions [typeInfo.LogicalType.WebServiceNamespace];
224 desc = new ServiceDescription ();
225 desc.TargetNamespace = typeInfo.LogicalType.WebServiceNamespace;
226 desc.Name = typeInfo.LogicalType.WebServiceName;
227 ServiceDescriptions.Add (desc);
230 ImportService (desc, typeInfo, url);
233 void ImportService (ServiceDescription desc, TypeStubInfo typeInfo, string url)
235 service = desc.Services [typeInfo.LogicalType.WebServiceName];
238 service = new Service ();
239 service.Name = typeInfo.LogicalType.WebServiceName;
240 service.Documentation = typeInfo.LogicalType.Description;
241 desc.Services.Add (service);
244 foreach (BindingInfo binfo in typeInfo.Bindings)
245 ImportBinding (desc, service, typeInfo, url, binfo);
248 void ImportBinding (ServiceDescription desc, Service service, TypeStubInfo typeInfo, string url, BindingInfo binfo)
251 port.Name = portNames.AddUnique (binfo.Name, port);
252 bool bindingFull = true;
254 if (binfo.Namespace != desc.TargetNamespace)
256 if (binfo.Location == null || binfo.Location == string.Empty)
258 ServiceDescription newDesc = new ServiceDescription();
259 newDesc.TargetNamespace = binfo.Namespace;
260 newDesc.Name = binfo.Name;
261 bindingFull = ImportBindingContent (newDesc, typeInfo, url, binfo);
263 int id = ServiceDescriptions.Add (newDesc);
264 AddImport (desc, binfo.Namespace, GetWsdlUrl (url,id));
268 AddImport (desc, binfo.Namespace, binfo.Location);
273 bindingFull = ImportBindingContent (desc, typeInfo, url, binfo);
277 port.Binding = new XmlQualifiedName (binding.Name, binfo.Namespace);
278 service.Ports.Add (port);
282 bool ImportBindingContent (ServiceDescription desc, TypeStubInfo typeInfo, string url, BindingInfo binfo)
284 serviceDescription = desc;
286 // Look for an unused name
289 string name = binfo.Name;
294 foreach (Binding bi in desc.Bindings)
295 if (bi.Name == name) { found = true; n++; name = binfo.Name+n; break; }
299 // Create the binding
301 binding = new Binding ();
303 binding.Type = new XmlQualifiedName (binding.Name, binfo.Namespace);
305 portType = new PortType ();
306 portType.Name = binding.Name;
310 foreach (MethodStubInfo method in typeInfo.Methods)
312 methodStubInfo = method;
314 string metBinding = ReflectMethodBinding ();
315 if (typeInfo.GetBinding (metBinding) != binfo) continue;
317 operation = new Operation ();
318 operation.Name = method.OperationName;
319 operation.Documentation = method.MethodAttribute.Description;
321 inputMessage = new Message ();
322 inputMessage.Name = method.Name + ProtocolName + "In";
323 ServiceDescription.Messages.Add (inputMessage);
325 outputMessage = new Message ();
326 outputMessage.Name = method.Name + ProtocolName + "Out";
327 ServiceDescription.Messages.Add (outputMessage);
329 OperationInput inOp = new OperationInput ();
330 if (method.Name != method.OperationName) inOp.Name = method.Name;
331 Operation.Messages.Add (inOp);
332 inOp.Message = new XmlQualifiedName (inputMessage.Name, ServiceDescription.TargetNamespace);
334 OperationOutput outOp = new OperationOutput ();
335 if (method.Name != method.OperationName) outOp.Name = method.Name;
336 Operation.Messages.Add (outOp);
337 outOp.Message = new XmlQualifiedName (outputMessage.Name, ServiceDescription.TargetNamespace);
339 portType.Operations.Add (operation);
340 ImportOperationBinding ();
344 foreach (SoapExtensionReflector reflector in extensionReflectors)
346 reflector.ReflectionContext = this;
347 reflector.ReflectMethod ();
353 if (portType.Operations.Count > 0)
355 desc.Bindings.Add (binding);
356 desc.PortTypes.Add (portType);
363 void ImportOperationBinding ()
365 operationBinding = new OperationBinding ();
366 operationBinding.Name = methodStubInfo.OperationName;
368 InputBinding inOp = new InputBinding ();
369 operationBinding.Input = inOp;
371 OutputBinding outOp = new OutputBinding ();
372 operationBinding.Output = outOp;
374 if (methodStubInfo.OperationName != methodStubInfo.Name)
375 inOp.Name = outOp.Name = methodStubInfo.Name;
377 binding.Operations.Add (operationBinding);
380 internal static void AddImport (ServiceDescription desc, string ns, string location)
382 Import im = new Import();
384 im.Location = location;
385 desc.Imports.Add (im);
388 string GetWsdlUrl (string baseUrl, int id)
390 return baseUrl + "?wsdl=" + id;
393 protected virtual void BeginClass ()
397 protected virtual void EndClass ()
401 public ServiceDescription GetServiceDescription (string ns)
403 return ServiceDescriptions [ns];
406 protected abstract bool ReflectMethod ();
408 protected virtual string ReflectMethodBinding ()