Merge pull request #1473 from esdrubal/sq
[mono.git] / mcs / class / System.Web.Services / System.Web.Services.Description / ServiceDescription.cs
1 // 
2 // System.Web.Services.Description.ServiceDescription.cs
3 //
4 // Author:
5 //   Tim Coleman (tim@timcoleman.com)
6 //   Lluis Sanchez Gual (lluis@ximian.com)
7 //
8 // Copyright (C) Tim Coleman, 2002
9 //
10
11 //
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.
30 //
31
32 using System.IO;
33 using System.Collections;
34 using System.Collections.Specialized;
35 using System.Reflection;
36 using System.Web.Services;
37 using System.Web.Services.Configuration;
38 using System.Xml;
39 using System.Xml.Schema;
40 using System.Xml.Serialization;
41
42 #if NET_2_0
43 using System.Collections.Generic;
44 #endif
45
46 namespace System.Web.Services.Description
47 {
48         [XmlFormatExtensionPoint ("Extensions")]
49         [XmlRoot ("definitions", Namespace = "http://schemas.xmlsoap.org/wsdl/")]
50         public sealed class ServiceDescription :
51 #if NET_2_0
52                 NamedItem
53 #else
54                 DocumentableItem 
55 #endif
56         {
57                 #region Fields
58
59                 public const string Namespace = "http://schemas.xmlsoap.org/wsdl/";
60
61                 BindingCollection bindings;
62                 ServiceDescriptionFormatExtensionCollection extensions;
63                 ImportCollection imports;
64                 MessageCollection messages;
65 #if !NET_2_0
66                 string name;
67 #endif
68                 PortTypeCollection portTypes;
69                 string retrievalUrl = String.Empty;
70                 ServiceDescriptionCollection serviceDescriptions;
71                 ServiceCollection services;
72                 string targetNamespace;
73                 Types types;
74                 static ServiceDescriptionSerializer serializer;
75 #if NET_2_0
76                 StringCollection validationWarnings;
77
78                 static XmlSchema schema;
79 #endif
80
81                 #endregion // Fields
82
83                 #region Constructors
84
85                 static ServiceDescription ()
86                 {
87                         serializer = new ServiceDescriptionSerializer ();
88                 }
89
90                 public ServiceDescription ()
91                 {
92                         bindings = new BindingCollection (this);
93                         extensions = new ServiceDescriptionFormatExtensionCollection (this);
94                         imports = new ImportCollection (this);
95                         messages = new MessageCollection (this);
96 #if !NET_2_0
97 //                      name = String.Empty;            
98 #endif
99                         portTypes = new PortTypeCollection (this);
100
101                         serviceDescriptions = null;
102                         services = new ServiceCollection (this);
103                         targetNamespace = null;
104                         types = new Types ();
105                 }
106                 
107                 #endregion // Constructors
108
109                 #region Properties
110
111 #if NET_2_0
112                 public static XmlSchema Schema {
113                         get {
114                                 if (schema == null) {
115                                         schema = XmlSchema.Read (typeof (ServiceDescription).Assembly.GetManifestResourceStream ("wsdl-1.1.xsd"), null);
116                                 }
117                                 return schema;
118                         }
119                 }
120 #endif
121
122                 [XmlElement ("import")]
123                 public ImportCollection Imports {
124                         get { return imports; }
125                 }
126
127                 [XmlElement ("types")]
128                 public Types Types {
129                         get { return types; }
130                         set { types = value; }
131                 }
132
133                 [XmlElement ("message")]
134                 public MessageCollection Messages {
135                         get { return messages; }
136                 }
137
138                 [XmlElement ("portType")]       
139                 public PortTypeCollection PortTypes {
140                         get { return portTypes; }
141                 }
142         
143                 [XmlElement ("binding")]
144                 public BindingCollection Bindings {
145                         get { return bindings; }
146                 }
147
148                 [XmlIgnore]
149                 public 
150 #if NET_2_0
151                 override
152 #endif
153                 ServiceDescriptionFormatExtensionCollection Extensions {        
154                         get { return extensions; }
155                 }
156
157 #if !NET_2_0
158                 [XmlAttribute ("name", DataType = "NMTOKEN")]   
159                 public string Name {
160                         get { return name; }
161                         set { name = value; }
162                 }
163 #endif
164
165                 [XmlIgnore]     
166                 public string RetrievalUrl {
167                         get { return retrievalUrl; }
168                         set { retrievalUrl = value; }
169                 }
170         
171                 [XmlIgnore]     
172                 public static XmlSerializer Serializer {
173                         get { return serializer; }
174                 }
175
176                 [XmlIgnore]
177                 public ServiceDescriptionCollection ServiceDescriptions {
178                         get { 
179                                 return serviceDescriptions; 
180                         }
181                 }
182
183                 [XmlElement ("service")]
184                 public ServiceCollection Services {
185                         get { return services; }
186                 }
187
188                 [XmlAttribute ("targetNamespace")]
189                 public string TargetNamespace {
190                         get { return targetNamespace; }
191                         set { targetNamespace = value; }
192                 }
193
194 #if NET_2_0
195                 [XmlIgnore]
196                 public StringCollection ValidationWarnings {
197                         get { return validationWarnings; }
198                 }
199 #endif
200
201                 #endregion // Properties
202
203                 #region Methods
204
205                 public static bool CanRead (XmlReader reader)
206                 {
207                         reader.MoveToContent ();
208                         return reader.LocalName == "definitions" && 
209                                 reader.NamespaceURI == "http://schemas.xmlsoap.org/wsdl/";
210                 }
211
212 #if NET_2_0
213                 public static ServiceDescription Read (string fileName, bool validate)
214                 {
215                         if (validate)
216                                 using (XmlReader reader = XmlReader.Create (fileName)) {
217                                         return Read (reader, true);
218                                 }
219                         else
220                                 return Read (fileName);
221                 }
222
223                 public static ServiceDescription Read (Stream stream, bool validate)
224                 {
225                         if (validate)
226                                 return Read (XmlReader.Create (stream), true);
227                         else
228                                 return Read (stream);
229                 }
230
231                 public static ServiceDescription Read (TextReader reader, bool validate)
232                 {
233                         if (validate)
234                                 return Read (XmlReader.Create (reader), true);
235                         else
236                                 return Read (reader);
237                 }
238
239                 public static ServiceDescription Read (XmlReader reader, bool validate)
240                 {
241                         if (validate) {
242                                 StringCollection sc = new StringCollection ();
243                                 XmlReaderSettings s = new XmlReaderSettings ();
244                                 s.ValidationType = ValidationType.Schema;
245                                 s.Schemas.Add (Schema);
246                                 s.ValidationEventHandler += delegate (object o, ValidationEventArgs e) {
247                                         sc.Add (e.Message);
248                                 };
249
250                                 ServiceDescription ret = Read (XmlReader.Create (reader, s));
251                                 ret.validationWarnings = sc;
252                                 return ret;
253                         }
254                         else
255                                 return Read (reader);
256                 }
257 #endif
258
259                 public static ServiceDescription Read (Stream stream)
260                 {
261                         return (ServiceDescription) serializer.Deserialize (stream);
262                 }
263
264                 public static ServiceDescription Read (string fileName)
265                 {
266                         return Read (new FileStream (fileName, FileMode.Open, FileAccess.Read));
267                 }
268
269                 public static ServiceDescription Read (TextReader textReader)
270                 {
271                         return (ServiceDescription) serializer.Deserialize (textReader);
272                 }
273
274                 public static ServiceDescription Read (XmlReader reader)
275                 {
276                         return (ServiceDescription) serializer.Deserialize (reader);
277                 }
278
279                 public void Write (Stream stream)
280                 {
281                         serializer.Serialize (stream, this, GetNamespaceList ());
282                 }
283
284                 public void Write (string fileName)
285                 {
286                         Write (new FileStream (fileName, FileMode.Create));
287                 }
288
289                 public void Write (TextWriter writer)
290                 {
291                         serializer.Serialize (writer, this, GetNamespaceList ());
292                 }
293
294                 public void Write (XmlWriter writer)
295                 {
296                         serializer.Serialize (writer, this, GetNamespaceList ());
297                 }
298
299                 internal void SetParent (ServiceDescriptionCollection serviceDescriptions)
300                 {
301                         this.serviceDescriptions = serviceDescriptions; 
302                 }
303                 
304                 XmlSerializerNamespaces GetNamespaceList ()
305                 {
306                         XmlSerializerNamespaces ns;
307                         ns = new XmlSerializerNamespaces ();
308                         ns.Add ("soap", SoapBinding.Namespace);
309 #if NET_2_0
310                         ns.Add ("soap12", Soap12Binding.Namespace);
311 #endif
312                         ns.Add ("soapenc", "http://schemas.xmlsoap.org/soap/encoding/");
313                         ns.Add ("s", XmlSchema.Namespace);
314                         ns.Add ("http", HttpBinding.Namespace);
315                         ns.Add ("mime", MimeContentBinding.Namespace);
316                         ns.Add ("tm", MimeTextBinding.Namespace);
317                         ns.Add ("s0", TargetNamespace);
318                         
319                         AddExtensionNamespaces (ns, Extensions);
320                         
321                         if (Types != null) AddExtensionNamespaces (ns, Types.Extensions);
322                         
323                         foreach (Service ser in Services)
324                                 foreach (Port port in ser.Ports)
325                                         AddExtensionNamespaces (ns, port.Extensions);
326
327                         foreach (Binding bin in Bindings)
328                         {
329                                 AddExtensionNamespaces (ns, bin.Extensions);
330                                 foreach (OperationBinding op in bin.Operations)
331                                 {
332                                         AddExtensionNamespaces (ns, op.Extensions);
333                                         if (op.Input != null) AddExtensionNamespaces (ns, op.Input.Extensions);
334                                         if (op.Output != null) AddExtensionNamespaces (ns, op.Output.Extensions);
335                                 }
336                         }
337                         return ns;
338                 }
339                 
340                 void AddExtensionNamespaces (XmlSerializerNamespaces ns, ServiceDescriptionFormatExtensionCollection extensions)
341                 {
342                         foreach (object o in extensions)
343                         {
344                                 ServiceDescriptionFormatExtension ext = o as ServiceDescriptionFormatExtension;
345                                 if (ext == null)
346                                         // o can be XmlElement, skipping that
347                                         continue;
348
349                                 ExtensionInfo einf = ExtensionManager.GetFormatExtensionInfo (ext.GetType ());
350                                 foreach (XmlQualifiedName qname in einf.NamespaceDeclarations)
351                                         ns.Add (qname.Name, qname.Namespace);
352                         }
353                 }
354                 
355                 internal static void WriteExtensions (XmlWriter writer, object ob)
356                 {
357                         ServiceDescriptionFormatExtensionCollection extensions = ExtensionManager.GetExtensionPoint (ob);
358                         if (extensions != null)
359                         {
360                                 foreach (object o in extensions) {
361                                         if (o is ServiceDescriptionFormatExtension)
362                                                 WriteExtension (writer, (ServiceDescriptionFormatExtension)o);
363                                         else if (o is XmlElement)
364                                                 ((XmlElement)o).WriteTo (writer);
365                                 }
366                         }
367                 }
368                 
369                 static void WriteExtension (XmlWriter writer, ServiceDescriptionFormatExtension ext)
370                 {
371                         Type type = ext.GetType ();
372                         ExtensionInfo info = ExtensionManager.GetFormatExtensionInfo (type);
373                         
374 //                              if (prefix != null && prefix != "")
375 //                                      Writer.WriteStartElement (prefix, info.ElementName, info.Namespace);
376 //                              else
377 //                                      WriteStartElement (info.ElementName, info.Namespace, false);
378
379                         XmlSerializerNamespaces ns = new XmlSerializerNamespaces ();
380                         ns.Add ("","");
381                         info.Serializer.Serialize (writer, ext, ns);
382                 }
383                 
384                 internal static void ReadExtension (XmlDocument doc, XmlReader reader, object ob)
385                 {
386                         ServiceDescriptionFormatExtensionCollection extensions = ExtensionManager.GetExtensionPoint (ob);
387                         if (extensions != null)
388                         {
389                                 ExtensionInfo info = ExtensionManager.GetFormatExtensionInfo (reader.LocalName, reader.NamespaceURI);
390                                 if (info != null)
391                                 {
392                                         object extension = info.Serializer.Deserialize (reader);
393                                         extensions.Add ((ServiceDescriptionFormatExtension)extension);
394                                         return;
395                                 }
396                         }
397
398                         //No XmlFormatExtensionPoint attribute found
399
400 #if NET_2_0
401                         //Add to DocumentableItem.Extensions property
402                         DocumentableItem item = ob as DocumentableItem;
403                         if (item == null) {
404                                 reader.Skip ();
405                                 return;
406                         }
407
408                         item.Extensions.Add (doc.ReadNode (reader));
409 #else
410                         reader.Skip ();
411 #endif
412                 }
413
414                 #endregion
415
416                 internal class ServiceDescriptionSerializer : XmlSerializer 
417                 {
418                         protected override void Serialize (object o, XmlSerializationWriter writer)
419                         {
420                                 ServiceDescriptionWriterBase xsWriter = writer as ServiceDescriptionWriterBase;
421                                 xsWriter.WriteRoot_ServiceDescription (o);
422                         }
423                         
424                         protected override object Deserialize (XmlSerializationReader reader)
425                         {
426                                 ServiceDescriptionReaderBase xsReader = reader as ServiceDescriptionReaderBase;
427                                 return xsReader.ReadRoot_ServiceDescription ();
428                         }
429                         
430                         protected override XmlSerializationWriter CreateWriter ()
431                         {
432                                 return new ServiceDescriptionWriterBase ();
433                         }
434                         
435                         protected override XmlSerializationReader CreateReader ()
436                         {
437                                 return new ServiceDescriptionReaderBase ();
438                         }
439                 }               
440         }
441 }