ProtocolReflector.cs 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. //
  2. // System.Web.Services.Description.ProtocolReflector.cs
  3. //
  4. // Author:
  5. // Tim Coleman ([email protected])
  6. // Lluis Sanchez Gual ([email protected])
  7. //
  8. // Copyright (C) Tim Coleman, 2002
  9. //
  10. using System.Web.Services;
  11. using System.Web.Services.Protocols;
  12. using System.Xml.Serialization;
  13. using System.Xml;
  14. using System.Xml.Schema;
  15. using System.Collections;
  16. namespace System.Web.Services.Description {
  17. public abstract class ProtocolReflector {
  18. #region Fields
  19. Binding binding;
  20. string defaultNamespace;
  21. MessageCollection headerMessages;
  22. Message inputMessage;
  23. LogicalMethodInfo[] methods;
  24. Operation operation;
  25. OperationBinding operationBinding;
  26. Message outputMessage;
  27. Port port;
  28. PortType portType;
  29. string protocolName;
  30. XmlSchemaExporter schemaExporter;
  31. Service service;
  32. ServiceDescription serviceDescription;
  33. Type serviceType;
  34. string serviceUrl;
  35. SoapSchemaExporter soapSchemaExporter;
  36. MethodStubInfo methodStubInfo;
  37. TypeStubInfo typeInfo;
  38. ArrayList extensionReflectors;
  39. ServiceDescriptionReflector serviceReflector;
  40. XmlReflectionImporter reflectionImporter;
  41. SoapReflectionImporter soapReflectionImporter;
  42. #endregion // Fields
  43. #region Constructors
  44. protected ProtocolReflector ()
  45. {
  46. defaultNamespace = WebServiceAttribute.DefaultNamespace;
  47. extensionReflectors = ExtensionManager.BuildExtensionReflectors ();
  48. }
  49. #endregion // Constructors
  50. #region Properties
  51. public Binding Binding {
  52. get { return binding; }
  53. }
  54. public string DefaultNamespace {
  55. get { return defaultNamespace; }
  56. }
  57. public MessageCollection HeaderMessages {
  58. get { return headerMessages; } // TODO: set
  59. }
  60. public Message InputMessage {
  61. get { return inputMessage; }
  62. }
  63. public LogicalMethodInfo Method {
  64. get { return methodStubInfo.MethodInfo; }
  65. }
  66. public WebMethodAttribute MethodAttribute {
  67. get { return methodStubInfo.MethodAttribute; }
  68. }
  69. public LogicalMethodInfo[] Methods {
  70. get { return typeInfo.LogicalType.LogicalMethods; }
  71. }
  72. public Operation Operation {
  73. get { return operation; }
  74. }
  75. public OperationBinding OperationBinding {
  76. get { return operationBinding; }
  77. }
  78. public Message OutputMessage {
  79. get { return outputMessage; }
  80. }
  81. public Port Port {
  82. get { return port; }
  83. }
  84. public PortType PortType {
  85. get { return portType; }
  86. }
  87. public abstract string ProtocolName {
  88. get;
  89. }
  90. public XmlReflectionImporter ReflectionImporter
  91. {
  92. get
  93. {
  94. if (reflectionImporter == null) {
  95. reflectionImporter = typeInfo.XmlImporter;
  96. if (reflectionImporter == null)
  97. reflectionImporter = new XmlReflectionImporter();
  98. }
  99. return reflectionImporter;
  100. }
  101. }
  102. internal SoapReflectionImporter SoapReflectionImporter
  103. {
  104. get
  105. {
  106. if (soapReflectionImporter == null) {
  107. soapReflectionImporter = typeInfo.SoapImporter;
  108. if (soapReflectionImporter == null)
  109. soapReflectionImporter = new SoapReflectionImporter();
  110. }
  111. return soapReflectionImporter;
  112. }
  113. }
  114. public XmlSchemaExporter SchemaExporter {
  115. get { return schemaExporter; }
  116. }
  117. public SoapSchemaExporter SoapSchemaExporter {
  118. get { return soapSchemaExporter; }
  119. }
  120. public XmlSchemas Schemas {
  121. get { return serviceReflector.Schemas; }
  122. }
  123. public Service Service {
  124. get { return service; }
  125. }
  126. public ServiceDescription ServiceDescription {
  127. get { return serviceDescription; }
  128. }
  129. public ServiceDescriptionCollection ServiceDescriptions {
  130. get { return serviceReflector.ServiceDescriptions; }
  131. }
  132. public Type ServiceType {
  133. get { return serviceType; }
  134. }
  135. public string ServiceUrl {
  136. get { return serviceUrl; }
  137. }
  138. internal MethodStubInfo MethodStubInfo {
  139. get { return methodStubInfo; }
  140. }
  141. internal TypeStubInfo TypeInfo {
  142. get { return typeInfo; }
  143. }
  144. #endregion // Properties
  145. #region Methods
  146. internal void Reflect (ServiceDescriptionReflector serviceReflector, Type type, string url, XmlSchemaExporter xxporter, SoapSchemaExporter sxporter)
  147. {
  148. this.serviceReflector = serviceReflector;
  149. serviceUrl = url;
  150. serviceType = type;
  151. schemaExporter = xxporter;
  152. soapSchemaExporter = sxporter;
  153. typeInfo = TypeStubManager.GetTypeStub (type, ProtocolName);
  154. ServiceDescription desc = ServiceDescriptions [typeInfo.LogicalType.WebServiceNamespace];
  155. if (desc == null)
  156. {
  157. desc = new ServiceDescription ();
  158. desc.TargetNamespace = typeInfo.LogicalType.WebServiceNamespace;
  159. desc.Name = typeInfo.LogicalType.WebServiceName;
  160. ServiceDescriptions.Add (desc);
  161. }
  162. ImportService (desc, typeInfo, url);
  163. }
  164. void ImportService (ServiceDescription desc, TypeStubInfo typeInfo, string url)
  165. {
  166. service = desc.Services [typeInfo.LogicalType.WebServiceName];
  167. if (service == null)
  168. {
  169. service = new Service ();
  170. service.Name = typeInfo.LogicalType.WebServiceName;
  171. service.Documentation = typeInfo.LogicalType.Description;
  172. desc.Services.Add (service);
  173. }
  174. foreach (BindingInfo binfo in typeInfo.Bindings)
  175. ImportBinding (desc, service, typeInfo, url, binfo);
  176. }
  177. void ImportBinding (ServiceDescription desc, Service service, TypeStubInfo typeInfo, string url, BindingInfo binfo)
  178. {
  179. port = new Port ();
  180. port.Name = binfo.Name;
  181. port.Binding = new XmlQualifiedName (binfo.Name, binfo.Namespace);
  182. service.Ports.Add (port);
  183. if (binfo.Namespace != desc.TargetNamespace)
  184. {
  185. if (binfo.Location == null || binfo.Location == string.Empty)
  186. {
  187. ServiceDescription newDesc = new ServiceDescription();
  188. newDesc.TargetNamespace = binfo.Namespace;
  189. int id = ServiceDescriptions.Add (newDesc);
  190. AddImport (desc, binfo.Namespace, GetWsdlUrl (url,id));
  191. ImportBindingContent (newDesc, typeInfo, url, binfo);
  192. }
  193. else
  194. AddImport (desc, binfo.Namespace, binfo.Location);
  195. }
  196. else
  197. ImportBindingContent (desc, typeInfo, url, binfo);
  198. }
  199. void ImportBindingContent (ServiceDescription desc, TypeStubInfo typeInfo, string url, BindingInfo binfo)
  200. {
  201. serviceDescription = desc;
  202. binding = new Binding ();
  203. binding.Name = binfo.Name;
  204. binding.Type = new XmlQualifiedName (binfo.Name, binfo.Namespace);
  205. desc.Bindings.Add (binding);
  206. portType = new PortType ();
  207. portType.Name = binding.Name;
  208. desc.PortTypes.Add (portType);
  209. BeginClass ();
  210. foreach (MethodStubInfo method in typeInfo.Methods)
  211. {
  212. methodStubInfo = method;
  213. string metBinding = ReflectMethodBinding ();
  214. if (metBinding != null && (metBinding != binding.Name)) continue;
  215. operation = new Operation ();
  216. operation.Name = method.OperationName;
  217. operation.Documentation = method.MethodAttribute.Description;
  218. inputMessage = new Message ();
  219. inputMessage.Name = method.Name + ProtocolName + "In";
  220. ServiceDescription.Messages.Add (inputMessage);
  221. outputMessage = new Message ();
  222. outputMessage.Name = method.Name + ProtocolName + "Out";
  223. ServiceDescription.Messages.Add (outputMessage);
  224. OperationInput inOp = new OperationInput ();
  225. if (method.Name != method.OperationName) inOp.Name = method.Name;
  226. Operation.Messages.Add (inOp);
  227. inOp.Message = new XmlQualifiedName (inputMessage.Name, ServiceDescription.TargetNamespace);
  228. OperationOutput outOp = new OperationOutput ();
  229. if (method.Name != method.OperationName) outOp.Name = method.Name;
  230. Operation.Messages.Add (outOp);
  231. outOp.Message = new XmlQualifiedName (outputMessage.Name, ServiceDescription.TargetNamespace);
  232. portType.Operations.Add (operation);
  233. ImportOperationBinding ();
  234. ReflectMethod ();
  235. foreach (SoapExtensionReflector reflector in extensionReflectors)
  236. {
  237. reflector.ReflectionContext = this;
  238. reflector.ReflectMethod ();
  239. }
  240. }
  241. EndClass ();
  242. }
  243. void ImportOperationBinding ()
  244. {
  245. operationBinding = new OperationBinding ();
  246. operationBinding.Name = methodStubInfo.OperationName;
  247. InputBinding inOp = new InputBinding ();
  248. operationBinding.Input = inOp;
  249. OutputBinding outOp = new OutputBinding ();
  250. operationBinding.Output = outOp;
  251. if (methodStubInfo.OperationName != methodStubInfo.Name)
  252. inOp.Name = outOp.Name = methodStubInfo.Name;
  253. binding.Operations.Add (operationBinding);
  254. }
  255. internal static void AddImport (ServiceDescription desc, string ns, string location)
  256. {
  257. Import im = new Import();
  258. im.Namespace = ns;
  259. im.Location = location;
  260. desc.Imports.Add (im);
  261. }
  262. string GetWsdlUrl (string baseUrl, int id)
  263. {
  264. return baseUrl + "?wsdl=" + id;
  265. }
  266. protected virtual void BeginClass ()
  267. {
  268. }
  269. protected virtual void EndClass ()
  270. {
  271. }
  272. public ServiceDescription GetServiceDescription (string ns)
  273. {
  274. return ServiceDescriptions [ns];
  275. }
  276. protected abstract bool ReflectMethod ();
  277. protected virtual string ReflectMethodBinding ()
  278. {
  279. return null;
  280. }
  281. #endregion
  282. }
  283. }