ServiceDescription.cs 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. //
  2. // System.Web.Services.Description.ServiceDescription.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.IO;
  11. using System.Collections;
  12. using System.Reflection;
  13. using System.Web.Services;
  14. using System.Web.Services.Configuration;
  15. using System.Xml;
  16. using System.Xml.Schema;
  17. using System.Xml.Serialization;
  18. namespace System.Web.Services.Description {
  19. [XmlFormatExtensionPoint ("Extensions")]
  20. [XmlRoot ("definitions", Namespace = "http://schemas.xmlsoap.org/wsdl/")]
  21. public sealed class ServiceDescription : DocumentableItem {
  22. #region Fields
  23. public const string Namespace = "http://schemas.xmlsoap.org/wsdl/";
  24. BindingCollection bindings;
  25. ServiceDescriptionFormatExtensionCollection extensions;
  26. ImportCollection imports;
  27. MessageCollection messages;
  28. string name;
  29. PortTypeCollection portTypes;
  30. string retrievalUrl;
  31. ServiceDescriptionCollection serviceDescriptions;
  32. ServiceCollection services;
  33. string targetNamespace;
  34. Types types;
  35. static ServiceDescriptionSerializer serializer;
  36. #endregion // Fields
  37. #region Constructors
  38. static ServiceDescription ()
  39. {
  40. serializer = new ServiceDescriptionSerializer ();
  41. }
  42. [MonoTODO ("Move namespaces to subtype, use ServiceDescriptionSerializer")]
  43. public ServiceDescription ()
  44. {
  45. bindings = new BindingCollection (this);
  46. extensions = new ServiceDescriptionFormatExtensionCollection (this);
  47. imports = new ImportCollection (this);
  48. messages = new MessageCollection (this);
  49. name = String.Empty;
  50. portTypes = new PortTypeCollection (this);
  51. serviceDescriptions = null;
  52. services = new ServiceCollection (this);
  53. targetNamespace = String.Empty;
  54. types = null;
  55. }
  56. #endregion // Constructors
  57. #region Properties
  58. [XmlElement ("import")]
  59. public ImportCollection Imports {
  60. get { return imports; }
  61. }
  62. [XmlElement ("types")]
  63. public Types Types {
  64. get { return types; }
  65. set { types = value; }
  66. }
  67. [XmlElement ("message")]
  68. public MessageCollection Messages {
  69. get { return messages; }
  70. }
  71. [XmlElement ("portType")]
  72. public PortTypeCollection PortTypes {
  73. get { return portTypes; }
  74. }
  75. [XmlElement ("binding")]
  76. public BindingCollection Bindings {
  77. get { return bindings; }
  78. }
  79. [XmlIgnore]
  80. public ServiceDescriptionFormatExtensionCollection Extensions {
  81. get { return extensions; }
  82. }
  83. [XmlAttribute ("name", DataType = "NMTOKEN")]
  84. public string Name {
  85. get { return name; }
  86. set { name = value; }
  87. }
  88. [XmlIgnore]
  89. public string RetrievalUrl {
  90. get { return retrievalUrl; }
  91. set { retrievalUrl = value; }
  92. }
  93. [XmlIgnore]
  94. public static XmlSerializer Serializer {
  95. get { return serializer; }
  96. }
  97. [XmlIgnore]
  98. public ServiceDescriptionCollection ServiceDescriptions {
  99. get {
  100. if (serviceDescriptions == null)
  101. throw new NullReferenceException ();
  102. return serviceDescriptions;
  103. }
  104. }
  105. [XmlElement ("service")]
  106. public ServiceCollection Services {
  107. get { return services; }
  108. }
  109. [XmlAttribute ("targetNamespace")]
  110. public string TargetNamespace {
  111. get { return targetNamespace; }
  112. set { targetNamespace = value; }
  113. }
  114. #endregion // Properties
  115. #region Methods
  116. public static bool CanRead (XmlReader reader)
  117. {
  118. return serializer.CanDeserialize (reader);
  119. }
  120. public static ServiceDescription Read (Stream stream)
  121. {
  122. return (ServiceDescription) serializer.Deserialize (stream);
  123. }
  124. public static ServiceDescription Read (string fileName)
  125. {
  126. return Read (new FileStream (fileName, FileMode.Open));
  127. }
  128. public static ServiceDescription Read (TextReader textReader)
  129. {
  130. return (ServiceDescription) serializer.Deserialize (textReader);
  131. }
  132. public static ServiceDescription Read (XmlReader reader)
  133. {
  134. return (ServiceDescription) serializer.Deserialize (reader);
  135. }
  136. public void Write (Stream stream)
  137. {
  138. serializer.Serialize (stream, this, GetNamespaceList ());
  139. }
  140. public void Write (string fileName)
  141. {
  142. Write (new FileStream (fileName, FileMode.Create));
  143. }
  144. public void Write (TextWriter writer)
  145. {
  146. serializer.Serialize (writer, this, GetNamespaceList ());
  147. }
  148. public void Write (XmlWriter writer)
  149. {
  150. serializer.Serialize (writer, this, GetNamespaceList ());
  151. }
  152. internal void SetParent (ServiceDescriptionCollection serviceDescriptions)
  153. {
  154. this.serviceDescriptions = serviceDescriptions;
  155. }
  156. XmlSerializerNamespaces GetNamespaceList ()
  157. {
  158. XmlSerializerNamespaces ns;
  159. ns = new XmlSerializerNamespaces ();
  160. ns.Add ("soap", SoapBinding.Namespace);
  161. ns.Add ("s", XmlSchema.Namespace);
  162. ns.Add ("http", HttpBinding.Namespace);
  163. ns.Add ("mime", MimeContentBinding.Namespace);
  164. ns.Add ("tm", MimeTextBinding.Namespace);
  165. ns.Add ("s0", TargetNamespace);
  166. return ns;
  167. }
  168. #endregion
  169. internal class ServiceDescriptionSerializer : XmlSerializer
  170. {
  171. static XmlTypeMapping _typeMap;
  172. static Type[] _builtinExtensionTypes = new Type[] {
  173. typeof (HttpAddressBinding),
  174. typeof (HttpBinding),
  175. typeof (HttpOperationBinding),
  176. typeof (HttpUrlEncodedBinding),
  177. typeof (HttpUrlReplacementBinding),
  178. typeof (MimeContentBinding),
  179. typeof (MimeMultipartRelatedBinding),
  180. typeof (MimePart),
  181. typeof (MimeTextBinding),
  182. typeof (MimeXmlBinding),
  183. typeof (SoapAddressBinding),
  184. typeof (SoapBinding),
  185. typeof (SoapBodyBinding),
  186. typeof (SoapFaultBinding),
  187. typeof (SoapHeaderBinding),
  188. typeof (SoapHeaderFaultBinding),
  189. typeof (SoapOperationBinding)
  190. };
  191. protected override void Serialize (object o, XmlSerializationWriter writer)
  192. {
  193. ServiceDescriptionWriter xsWriter = writer as ServiceDescriptionWriter;
  194. xsWriter.WriteObject (o);
  195. }
  196. protected override object Deserialize (XmlSerializationReader reader)
  197. {
  198. ServiceDescriptionReader xsReader = reader as ServiceDescriptionReader;
  199. return xsReader.ReadObject ();
  200. }
  201. protected override XmlSerializationWriter CreateWriter ()
  202. {
  203. return new ServiceDescriptionWriter (GetTypeMapping());
  204. }
  205. protected override XmlSerializationReader CreateReader ()
  206. {
  207. return new ServiceDescriptionReader (GetTypeMapping());
  208. }
  209. XmlTypeMapping GetTypeMapping ()
  210. {
  211. if (_typeMap == null) {
  212. XmlReflectionImporter ri = new XmlReflectionImporter (ServiceDescription.Namespace);
  213. foreach (Type t in _builtinExtensionTypes) ri.IncludeType (t);
  214. _typeMap = ri.ImportTypeMapping (typeof (ServiceDescription));
  215. }
  216. return _typeMap;
  217. }
  218. }
  219. internal class ServiceDescriptionWriter : XmlSerializationWriterInterpreter
  220. {
  221. public ServiceDescriptionWriter (XmlMapping typeMap)
  222. : base (typeMap)
  223. {
  224. }
  225. protected override void WriteObjectElementElements (XmlTypeMapping typeMap, object ob)
  226. {
  227. Type type = ob.GetType ();
  228. object[] ats = type.GetCustomAttributes (typeof(XmlFormatExtensionPointAttribute), true);
  229. if (ats.Length > 0)
  230. {
  231. XmlFormatExtensionPointAttribute at = (XmlFormatExtensionPointAttribute)ats[0];
  232. IEnumerable extensions = null;
  233. PropertyInfo prop = type.GetProperty (at.MemberName);
  234. if (prop != null)
  235. extensions = (IEnumerable) prop.GetValue (ob, null);
  236. else {
  237. FieldInfo field = type.GetField (at.MemberName);
  238. if (field != null)
  239. extensions = (IEnumerable) field.GetValue (ob);
  240. else
  241. throw new InvalidOperationException ("XmlFormatExtensionPointAttribute: Member " + at.MemberName + " not found");
  242. }
  243. if (extensions != null)
  244. {
  245. foreach (ServiceDescriptionFormatExtension ext in extensions)
  246. WriteExtension (ext);
  247. }
  248. }
  249. base.WriteObjectElementElements (typeMap, ob);
  250. }
  251. void WriteExtension (ServiceDescriptionFormatExtension ext)
  252. {
  253. string prefix = null;
  254. string ns = null;
  255. string name = null;
  256. Type type = ext.GetType ();
  257. object[] ats = type.GetCustomAttributes (typeof(XmlFormatExtensionPrefixAttribute), true);
  258. if (ats.Length > 0)
  259. {
  260. XmlFormatExtensionPrefixAttribute at = (XmlFormatExtensionPrefixAttribute)ats[0];
  261. prefix = at.Prefix;
  262. ns = at.Namespace;
  263. }
  264. ats = type.GetCustomAttributes (typeof(XmlFormatExtensionAttribute), true);
  265. if (ats.Length > 0)
  266. {
  267. XmlFormatExtensionAttribute at = (XmlFormatExtensionAttribute)ats[0];
  268. name = at.ElementName;
  269. if (at.Namespace != null) ns = at.Namespace;
  270. }
  271. if (name == null) throw new InvalidOperationException ("XmlFormatExtensionAttribute must be applied to type " + type);
  272. if (prefix == null || prefix == "") prefix = Writer.LookupPrefix (ns);
  273. if (prefix != null && prefix != "")
  274. Writer.WriteStartElement (prefix, name, ns);
  275. else
  276. WriteStartElement (name, ns, false);
  277. WriteObjectElement (GetTypeMap (type), ext, name, ns);
  278. WriteEndElement ();
  279. }
  280. }
  281. internal class ServiceDescriptionReader : XmlSerializationReaderInterpreter
  282. {
  283. public ServiceDescriptionReader (XmlMapping typeMap)
  284. : base (typeMap)
  285. {
  286. }
  287. }
  288. }
  289. }