2006-12-12 Atsushi Enomoto <atsushi@ximian.com>
[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;
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));
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                         ns.Add ("soapenc", "http://schemas.xmlsoap.org/soap/encoding/");
310                         ns.Add ("s", XmlSchema.Namespace);
311                         ns.Add ("http", HttpBinding.Namespace);
312                         ns.Add ("mime", MimeContentBinding.Namespace);
313                         ns.Add ("tm", MimeTextBinding.Namespace);
314                         ns.Add ("s0", TargetNamespace);
315                         
316                         AddExtensionNamespaces (ns, Extensions);
317                         
318                         if (Types != null) AddExtensionNamespaces (ns, Types.Extensions);
319                         
320                         foreach (Service ser in Services)
321                                 foreach (Port port in ser.Ports)
322                                         AddExtensionNamespaces (ns, port.Extensions);
323
324                         foreach (Binding bin in Bindings)
325                         {
326                                 AddExtensionNamespaces (ns, bin.Extensions);
327                                 foreach (OperationBinding op in bin.Operations)
328                                 {
329                                         AddExtensionNamespaces (ns, op.Extensions);
330                                         if (op.Input != null) AddExtensionNamespaces (ns, op.Input.Extensions);
331                                         if (op.Output != null) AddExtensionNamespaces (ns, op.Output.Extensions);
332                                 }
333                         }
334                         return ns;
335                 }
336                 
337                 void AddExtensionNamespaces (XmlSerializerNamespaces ns, ServiceDescriptionFormatExtensionCollection extensions)
338                 {
339                         foreach (ServiceDescriptionFormatExtension ext in extensions)
340                         {
341                                 ExtensionInfo einf = ExtensionManager.GetFormatExtensionInfo (ext.GetType ());
342                                 foreach (XmlQualifiedName qname in einf.NamespaceDeclarations)
343                                         ns.Add (qname.Name, qname.Namespace);
344                         }
345                 }
346                 
347                 internal static void WriteExtensions (XmlWriter writer, object ob)
348                 {
349                         ServiceDescriptionFormatExtensionCollection extensions = ExtensionManager.GetExtensionPoint (ob);
350                         if (extensions != null)
351                         {
352                                 foreach (ServiceDescriptionFormatExtension ext in extensions)
353                                         WriteExtension (writer, ext);
354                         }
355                 }
356                 
357                 static void WriteExtension (XmlWriter writer, ServiceDescriptionFormatExtension ext)
358                 {
359                         Type type = ext.GetType ();
360                         ExtensionInfo info = ExtensionManager.GetFormatExtensionInfo (type);
361                         
362 //                              if (prefix != null && prefix != "")
363 //                                      Writer.WriteStartElement (prefix, info.ElementName, info.Namespace);
364 //                              else
365 //                                      WriteStartElement (info.ElementName, info.Namespace, false);
366
367                         XmlSerializerNamespaces ns = new XmlSerializerNamespaces ();
368                         ns.Add ("","");
369                         info.Serializer.Serialize (writer, ext, ns);
370                 }
371                 
372                 internal static void ReadExtension (XmlDocument doc, XmlReader reader, object ob)
373                 {
374                         ServiceDescriptionFormatExtensionCollection extensions = ExtensionManager.GetExtensionPoint (ob);
375                         if (extensions != null)
376                         {
377                                 ExtensionInfo info = ExtensionManager.GetFormatExtensionInfo (reader.LocalName, reader.NamespaceURI);
378                                 if (info != null)
379                                 {
380                                         object extension = info.Serializer.Deserialize (reader);
381                                         extensions.Add ((ServiceDescriptionFormatExtension)extension);
382                                         return;
383                                 }
384                         }
385
386                         //No XmlFormatExtensionPoint attribute found
387
388 #if NET_2_0
389                         //Add to DocumentableItem.Extensions property
390                         DocumentableItem item = ob as DocumentableItem;
391                         if (item == null) {
392                                 reader.Skip ();
393                                 return;
394                         }
395
396                         item.Extensions.Add (doc.ReadNode (reader));
397 #else
398                         reader.Skip ();
399 #endif
400                 }
401
402                 #endregion
403
404                 internal class ServiceDescriptionSerializer : XmlSerializer 
405                 {
406                         protected override void Serialize (object o, XmlSerializationWriter writer)
407                         {
408                                 ServiceDescriptionWriterBase xsWriter = writer as ServiceDescriptionWriterBase;
409                                 xsWriter.WriteRoot_ServiceDescription (o);
410                         }
411                         
412                         protected override object Deserialize (XmlSerializationReader reader)
413                         {
414                                 ServiceDescriptionReaderBase xsReader = reader as ServiceDescriptionReaderBase;
415                                 return xsReader.ReadRoot_ServiceDescription ();
416                         }
417                         
418                         protected override XmlSerializationWriter CreateWriter ()
419                         {
420                                 return new ServiceDescriptionWriterBase ();
421                         }
422                         
423                         protected override XmlSerializationReader CreateReader ()
424                         {
425                                 return new ServiceDescriptionReaderBase ();
426                         }
427                 }               
428         }
429 }