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