Merge pull request #303 from ermshiperete/5278
[mono.git] / mcs / class / System.Web.Services / System.Web.Services.Discovery / ContractReference.cs
1 // 
2 // System.Web.Services.Discovery.ContractReference.cs
3 //
4 // Author:
5 //   Dave Bettin (javabettin@yahoo.com)
6 //   Lluis Sanchez Gual (lluis@ximian.com)
7 //
8 // Copyright (C) Dave Bettin, 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.Web.Services.Description;
34 using System.Xml.Serialization;
35 using System.Xml;
36 using System.Xml.Schema;
37
38 namespace System.Web.Services.Discovery {
39
40         [XmlRootAttribute("contractRef", Namespace="http://schemas.xmlsoap.org/disco/scl/", IsNullable=true)]
41         public class ContractReference : DiscoveryReference {
42
43                 #region Fields
44                 
45                 public const string Namespace = "http://schemas.xmlsoap.org/disco/scl/";
46
47                 private ServiceDescription contract;
48                 private string defaultFilename;
49                 private string docRef;
50                 private string href;
51                 
52                 #endregion // Fields
53                 
54                 #region Constructors
55
56                 public ContractReference () 
57                 {
58                 }
59                 
60                 public ContractReference (string href) : this() 
61                 {
62                         this.href = href;
63                 }
64                 
65                 public ContractReference (string href, string docRef)
66                 {
67                         this.href = href;
68                         this.docRef = docRef;
69                 }
70                 
71                 #endregion // Constructors
72
73                 #region Properties
74
75                 [XmlIgnore]
76                 public ServiceDescription Contract {
77                         get {
78                                 if (ClientProtocol == null) 
79                                         throw new InvalidOperationException ("The ClientProtocol property is a null reference");
80                                 
81                                 ServiceDescription desc = ClientProtocol.Documents [Url] as ServiceDescription;
82                                 if (desc == null)
83                                         throw new Exception ("The Documents property of ClientProtocol does not contain a WSDL document with the url " + Url);
84                                         
85                                 return desc; 
86                         }
87                 }
88
89                 [XmlIgnore]
90                 public override string DefaultFilename {
91                         get { return FilenameFromUrl (Url) + ".wsdl"; }
92                 }
93                 
94                 [XmlAttribute("docRef")]
95                 public string DocRef {
96                         get { return docRef; }
97                         set { docRef = value; }
98                 }
99                 
100                 [XmlAttribute("ref")]
101                 public string Ref {
102                         get { return href; }
103                         set { href = value; }
104                 }
105                 
106                 [XmlIgnore]
107                 public override string Url {
108                         get { return href;}                     
109                         set { href = value; }
110                 }
111                 
112                 #endregion // Properties
113
114                 #region Methods
115
116                 public override object ReadDocument (Stream stream)
117                 {
118                         return ServiceDescription.Read (stream);
119                 }
120                 
121                 protected internal override void Resolve (string contentType, Stream stream) 
122                 {
123                         ServiceDescription wsdl = ServiceDescription.Read (stream);
124                         
125                         if (!ClientProtocol.References.Contains (Url))
126                                 ClientProtocol.References.Add (this);
127
128                         ClientProtocol.Documents.Add (Url, wsdl);
129                         ResolveInternal (ClientProtocol, wsdl);
130                 }
131                 
132                 internal void ResolveInternal (DiscoveryClientProtocol prot, ServiceDescription wsdl) 
133                 {
134                         if (wsdl.Imports == null) return;
135                         
136                         foreach (Import import in wsdl.Imports)
137                         {
138                                 // Make relative uris to absoulte
139
140                                 Uri uri = new Uri (BaseUri, import.Location);
141                                 string url = uri.ToString ();
142
143                                 if (prot.Documents.Contains (url))      // Already resolved
144                                         continue;
145
146                                 try
147                                 {
148                                         string contentType = null;
149                                         Stream stream = prot.Download (ref url, ref contentType);
150                                         XmlTextReader reader = new XmlTextReader (url, stream);
151                                         reader.XmlResolver = null;
152                                         reader.MoveToContent ();
153                                         
154                                         DiscoveryReference refe;
155                                         if (ServiceDescription.CanRead (reader))
156                                         {
157                                                 ServiceDescription refWsdl = ServiceDescription.Read (reader);
158                                                 refe = new ContractReference ();
159                                                 refe.ClientProtocol = prot;
160                                                 refe.Url = url;
161                                                 ((ContractReference)refe).ResolveInternal (prot, refWsdl);
162                                                 prot.Documents.Add (url, refWsdl);
163                                         }
164                                         else
165                                         {
166                                                 XmlSchema schema = XmlSchema.Read (reader, null);
167                                                 refe = new SchemaReference ();
168                                                 refe.ClientProtocol = prot;
169                                                 refe.Url = url;
170                                                 prot.Documents.Add (url, schema);
171                                         }
172                                         
173                                         if (!prot.References.Contains (url))
174                                                 prot.References.Add (refe);
175                                                 
176                                         reader.Close ();
177                                 }
178                                 catch (Exception ex)
179                                 {
180                                         ReportError (url, ex);
181                                 }
182                         }
183
184                         foreach (XmlSchema schema in wsdl.Types.Schemas)
185                         {
186                                 // the schema itself is not added to the
187                                 // references, but it has to resolve includes.
188                                 Uri uri = BaseUri;
189                                 string url = uri.ToString ();
190                                 SchemaReference refe = new SchemaReference ();
191                                 refe.ClientProtocol = prot;
192                                 refe.Url = url;
193                                 refe.ResolveInternal (prot, schema);
194                         }
195                 }
196                 
197         public override void WriteDocument (object document, Stream stream) 
198                 {
199                         ((ServiceDescription)document).Write (stream);
200                 }
201
202                 #endregion // Methods
203         }
204 }