DataContractSerializerMessageContractImporter.cs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. //
  2. // DataContractSerializerMessageContractImporter.cs
  3. //
  4. // Author: Atsushi Enomoto ([email protected])
  5. // Ankit Jain ([email protected])
  6. //
  7. // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
  8. //
  9. // Permission is hereby granted, free of charge, to any person obtaining
  10. // a copy of this software and associated documentation files (the
  11. // "Software"), to deal in the Software without restriction, including
  12. // without limitation the rights to use, copy, modify, merge, publish,
  13. // distribute, sublicense, and/or sell copies of the Software, and to
  14. // permit persons to whom the Software is furnished to do so, subject to
  15. // the following conditions:
  16. //
  17. // The above copyright notice and this permission notice shall be
  18. // included in all copies or substantial portions of the Software.
  19. //
  20. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  21. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  22. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  23. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  24. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  25. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  26. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  27. //
  28. using System;
  29. using System.Collections.Generic;
  30. using System.Collections.ObjectModel;
  31. using System.ServiceModel;
  32. using System.Text;
  33. using System.Web.Services.Description;
  34. using System.Xml;
  35. using System.Xml.Schema;
  36. using System.Xml.Serialization;
  37. using QName = System.Xml.XmlQualifiedName;
  38. namespace System.ServiceModel.Description
  39. {
  40. [MonoTODO]
  41. public class DataContractSerializerMessageContractImporter
  42. : IWsdlImportExtension
  43. {
  44. bool enabled = true;
  45. public bool Enabled {
  46. get { return enabled; }
  47. set { enabled = value; }
  48. }
  49. void IWsdlImportExtension.BeforeImport (
  50. ServiceDescriptionCollection wsdlDocuments,
  51. XmlSchemaSet xmlSchemas,
  52. ICollection<XmlElement> policy)
  53. {
  54. }
  55. void IWsdlImportExtension.ImportContract (WsdlImporter importer,
  56. WsdlContractConversionContext context)
  57. {
  58. if (!enabled)
  59. return;
  60. PortType port_type = context.WsdlPortType;
  61. ContractDescription contract = context.Contract;
  62. int i, j;
  63. List<MessagePartDescription> parts = new List<MessagePartDescription> ();
  64. i = 0;
  65. foreach (Operation op in port_type.Operations) {
  66. OperationDescription opdescr = contract.Operations [i];
  67. j = 0;
  68. foreach (OperationMessage opmsg in op.Messages) {
  69. //SM.MessageDescription
  70. MessageDescription msgdescr = opdescr.Messages [j];
  71. //OpMsg's corresponding WSMessage
  72. Message msg = port_type.ServiceDescription.Messages [opmsg.Message.Name];
  73. msgdescr.Body.WrapperNamespace = port_type.ServiceDescription.TargetNamespace;
  74. if (opmsg is OperationOutput) {
  75. //ReturnValue
  76. msg = port_type.ServiceDescription.Messages [opmsg.Message.Name];
  77. resolveMessage (msg, msgdescr.Body, parts, importer);
  78. if (parts.Count > 0) {
  79. msgdescr.Body.ReturnValue = parts [0];
  80. parts.Clear ();
  81. }
  82. continue;
  83. }
  84. /* OperationInput */
  85. /* Parts, MessagePartDescription */
  86. resolveMessage (msg, msgdescr.Body, parts, importer);
  87. foreach (MessagePartDescription p in parts)
  88. msgdescr.Body.Parts.Add (p);
  89. parts.Clear ();
  90. j ++;
  91. }
  92. i ++;
  93. }
  94. }
  95. void resolveMessage (Message msg, MessageBodyDescription body, List<MessagePartDescription> parts, WsdlImporter importer)
  96. {
  97. foreach (MessagePart part in msg.Parts) {
  98. if (part.Name == "parameters") {
  99. if (!part.Element.IsEmpty) {
  100. body.WrapperName = part.Element.Name;
  101. resolveElement (part.Element, parts, importer, body.WrapperNamespace);
  102. } else {
  103. body.WrapperName = part.Type.Name;
  104. resolveType (part.Type, parts, importer, body.WrapperNamespace);
  105. }
  106. }
  107. //FIXME: non-parameters?
  108. }
  109. }
  110. void resolveElement (QName qname, List<MessagePartDescription> parts, WsdlImporter importer, string ns)
  111. {
  112. XmlSchemas xss = new XmlSchemas ();
  113. foreach (XmlSchema schema in importer.XmlSchemas.Schemas ())
  114. xss.Add (schema);
  115. XmlSchemaImporter schema_importer = new XmlSchemaImporter (xss);
  116. importer.XmlSchemas.Compile ();
  117. XmlSchemaElement element = (XmlSchemaElement) importer.XmlSchemas.GlobalElements [qname];
  118. if (element == null)
  119. //FIXME: What to do here?
  120. throw new Exception ("Could not resolve : " + qname.ToString ());
  121. resolveParticle (schema_importer, element, parts, ns, 2);
  122. }
  123. void resolveType (QName qname, List<MessagePartDescription> parts, WsdlImporter importer, string ns)
  124. {
  125. /*foreach (XmlSchema xs in importer.Schemas)
  126. if (xs.Types [qname] != null)
  127. return resolveParameters ((XmlSchemaElement) xs.Types [qname]., msgdescr, importer);
  128. //FIXME: What to do here?
  129. throw new Exception ("Could not resolve : " + qname.ToString ());*/
  130. throw new NotImplementedException ();
  131. }
  132. string GetCLRTypeName (QName qname)
  133. {
  134. if (qname.Namespace != "http://www.w3.org/2001/XMLSchema")
  135. return null;
  136. switch (qname.Name) {
  137. case "anyURI":
  138. return "System.String";
  139. case "boolean":
  140. return "System.Boolean";
  141. /*FIXME: case "base64Binary":
  142. case "dateTime":
  143. case "duration":*/
  144. case "QName":
  145. return "System.String";
  146. case "decimal":
  147. return "System.Decimal";
  148. case "double":
  149. return "System.Double";
  150. case "float":
  151. return "System.Double";
  152. case "byte":
  153. return "System.SByte";
  154. case "short":
  155. return "System.Int16";
  156. case "int":
  157. return "System.Int32";
  158. case "long":
  159. return "System.Int64";
  160. case "unsignedByte":
  161. return "System.Byte";
  162. case "unsignedShort":
  163. return "System.UInt16";
  164. case "unsignedInt":
  165. return "System.UInt32";
  166. case "unsignedLong":
  167. return "System.UInt64";
  168. case "string":
  169. return "System.String";
  170. /* FIXME:
  171. case "anyType":
  172. return true;
  173. default:
  174. return false;*/
  175. }
  176. return null;
  177. }
  178. void resolveParticle (XmlSchemaImporter schema_importer,
  179. XmlSchemaParticle particle,
  180. List<MessagePartDescription> parts,
  181. string ns,
  182. int depth)
  183. {
  184. if (particle is XmlSchemaGroupBase) {
  185. //sequence,
  186. //FIXME: others?
  187. if (depth <= 0)
  188. return;
  189. XmlSchemaGroupBase groupBase = particle as XmlSchemaGroupBase;
  190. foreach (XmlSchemaParticle item in groupBase.Items)
  191. resolveParticle (schema_importer, item, parts, ns, depth - 1);
  192. return;
  193. }
  194. XmlSchemaElement elem = particle as XmlSchemaElement;
  195. if (elem == null)
  196. return;
  197. MessagePartDescription msg_part = null;
  198. XmlSchemaComplexType ct = elem.ElementSchemaType as XmlSchemaComplexType;
  199. if (ct == null) {
  200. //Not a complex type
  201. XmlSchemaSimpleType simple = elem.ElementSchemaType as XmlSchemaSimpleType;
  202. msg_part = new MessagePartDescription (
  203. elem.Name, ns);
  204. if (elem.SchemaTypeName.Namespace != XmlSchema.Namespace)
  205. msg_part.XmlTypeMapping = schema_importer.ImportTypeMapping (elem.SchemaTypeName);
  206. msg_part.TypeName = new QName (GetCLRTypeName (elem.SchemaTypeName), "");
  207. parts.Add (msg_part);
  208. return;
  209. }
  210. if (depth > 0) {
  211. resolveParticle (schema_importer, ct.ContentTypeParticle, parts, ns, depth - 1);
  212. return;
  213. }
  214. //depth <= 0
  215. msg_part = new MessagePartDescription (elem.Name, ns);
  216. msg_part.XmlTypeMapping = schema_importer.ImportTypeMapping (elem.SchemaTypeName);
  217. msg_part.TypeName = elem.SchemaTypeName;
  218. parts.Add (msg_part);
  219. }
  220. void IWsdlImportExtension.ImportEndpoint (WsdlImporter importer,
  221. WsdlEndpointConversionContext context)
  222. {
  223. }
  224. }
  225. }