2006-12-14 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System.Web.Services / System.Web.Services.Description / ServiceDescriptionImporter.cs
1 // 
2 // System.Web.Services.Description.ServiceDescriptionImporter.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;
33 using System.CodeDom;
34 using System.CodeDom.Compiler;
35 using System.Web.Services;
36 using System.Web.Services.Protocols;
37 using System.Web.Services.Description;
38 using System.Xml.Serialization;
39 using System.Xml;
40 using System.Xml.Schema;
41 using System.Collections;
42 using System.Collections.Specialized;
43 using System.Configuration;
44
45 namespace System.Web.Services.Description {
46         public class ServiceDescriptionImporter {
47
48                 #region Fields
49
50                 string protocolName;
51                 XmlSchemas schemas;
52                 ServiceDescriptionCollection serviceDescriptions;
53                 ServiceDescriptionImportStyle style;
54                 
55 #if NET_2_0
56                 CodeGenerationOptions options;
57                 CodeDomProvider codeGenerator;
58                 ImportContext context;
59 #endif
60
61                 ArrayList importInfo = new ArrayList ();
62                 
63
64                 #endregion // Fields
65
66                 #region Constructors
67         
68                 public ServiceDescriptionImporter ()
69                 {
70                         protocolName = String.Empty;
71                         schemas = new XmlSchemas ();
72                         serviceDescriptions = new ServiceDescriptionCollection ();
73                         serviceDescriptions.SetImporter (this);
74                         style = ServiceDescriptionImportStyle.Client;
75                 }
76                 
77                 #endregion // Constructors
78
79                 #region Properties
80
81                 public string ProtocolName {
82                         get { return protocolName; }
83                         set { protocolName = value; }
84                 }
85
86                 public XmlSchemas Schemas {
87                         get { return schemas; }
88                 }
89
90                 public ServiceDescriptionCollection ServiceDescriptions {
91                         get { return serviceDescriptions; }
92                 }
93
94                 public ServiceDescriptionImportStyle Style {
95                         get { return style; }
96                         set { style = value; }
97                 }
98                 
99 #if NET_2_0
100                 [System.Runtime.InteropServices.ComVisible(false)]
101                 public CodeGenerationOptions CodeGenerationOptions {
102                         get { return options; }
103                         set { options = value; }
104                 }
105                 
106                 [System.Runtime.InteropServices.ComVisible(false)]
107                 public CodeDomProvider CodeGenerator {
108                         get { return codeGenerator; }
109                         set { codeGenerator = value; }
110                 }
111                 
112                 
113                 internal ImportContext Context {
114                         get { return context; }
115                         set { context = value; }
116                 }
117 #endif
118         
119                 #endregion // Properties
120
121                 #region Methods
122
123                 public void AddServiceDescription (ServiceDescription serviceDescription, string appSettingUrlKey, string appSettingBaseUrl)
124                 {
125                         if (appSettingUrlKey != null && appSettingUrlKey == string.Empty && style == ServiceDescriptionImportStyle.Server)
126                                 throw new InvalidOperationException ("Cannot set appSettingUrlKey if Style is Server");
127
128                         serviceDescriptions.Add (serviceDescription, appSettingUrlKey, appSettingBaseUrl);
129                 }
130
131                 internal void OnServiceDescriptionAdded (ServiceDescription serviceDescription, string appSettingUrlKey, string appSettingBaseUrl)
132                 {
133                         ImportInfo info = new ImportInfo (serviceDescription, appSettingUrlKey, appSettingBaseUrl);
134                         importInfo.Add (info);
135                         
136                         if (serviceDescription.Types != null)
137                                 schemas.Add (serviceDescription.Types.Schemas);
138                 }
139
140                 public ServiceDescriptionImportWarnings Import (CodeNamespace codeNamespace, CodeCompileUnit codeCompileUnit)
141                 {
142                         ProtocolImporter importer = GetImporter ();
143                         
144                         if (!importer.Import (this, codeNamespace, codeCompileUnit, importInfo))
145                                 throw new Exception ("None of the supported bindings was found");
146                                 
147                         return importer.Warnings;
148                 }
149                 
150                 ProtocolImporter GetImporter ()
151                 {
152                         ArrayList importers = GetSupportedImporters ();
153                         if (protocolName == null || protocolName == "") protocolName = "Soap";
154                         foreach (ProtocolImporter importer in importers) {
155                                 if (importer.ProtocolName.ToUpper () == protocolName.ToUpper ())
156                                         return importer;
157                         }
158                         
159                         throw new Exception ("Protocol " + protocolName + " not supported");
160                 }
161                 
162                 ArrayList GetSupportedImporters ()
163                 {
164                         ArrayList list = new ArrayList ();
165                         list.Add (new SoapProtocolImporter ());
166 #if NET_2_0
167                         list.Add (new Soap12ProtocolImporter ());
168 #endif
169                         list.Add (new HttpGetProtocolImporter ());
170                         list.Add (new HttpPostProtocolImporter ());
171                         return list;
172                 }
173                 
174 #if NET_2_0
175
176                 [MonoTODO] // where to use Verbose and Extensions in options?
177                 public static StringCollection GenerateWebReferences (
178                         WebReferenceCollection webReferences, 
179                         CodeDomProvider codeGenerator, 
180                         CodeCompileUnit codeCompileUnit, 
181                         WebReferenceOptions options)
182                 {
183                         StringCollection allWarnings = new StringCollection ();
184                         ImportContext context = new ImportContext (new CodeIdentifiers(), true);
185                         
186                         foreach (WebReference reference in webReferences) 
187                         {
188                                 ServiceDescriptionImporter importer = new ServiceDescriptionImporter ();
189                                 importer.CodeGenerator = codeGenerator;
190                                 importer.CodeGenerationOptions = options.CodeGenerationOptions;
191                                 importer.Context = context;
192                                 importer.Style = options.Style;
193                                 importer.ProtocolName = reference.ProtocolName;
194                                 
195                                 importer.AddReference (reference);
196                                 
197                                 reference.Warnings = importer.Import (reference.ProxyCode, codeCompileUnit);
198                                 reference.SetValidationWarnings (context.Warnings);
199                                 foreach (string s in context.Warnings)
200                                         allWarnings.Add (s);
201
202                                 context.Warnings.Clear ();
203                         }
204
205                         return allWarnings;
206                 }
207                 
208                 internal void AddReference (WebReference reference)
209                 {
210                         foreach (object doc in reference.Documents.Values)
211                         {
212                                 if (doc is ServiceDescription) {
213                                         ServiceDescription service = (ServiceDescription) doc;
214                                         ImportInfo info = new ImportInfo (service, reference);
215                                         importInfo.Add (info);
216                                         serviceDescriptions.Add (service);
217                                         
218                                         if (service.Types != null)
219                                                 schemas.Add (service.Types.Schemas);
220                                 }
221                                 else if (doc is XmlSchema) {
222                                         schemas.Add ((XmlSchema) doc);
223                                 }
224                         }
225                 }
226                 
227 #endif
228
229 #endregion
230         }
231
232         internal class ImportInfo
233         {
234                 string _appSettingUrlKey;
235                 string _appSettingBaseUrl;
236                 ServiceDescription _serviceDescription;
237                 
238                 public WebReference _reference;
239                 
240                 public ImportInfo (ServiceDescription serviceDescription, string appSettingUrlKey, string appSettingBaseUrl)
241                 {
242                         _serviceDescription = serviceDescription;
243                         _appSettingUrlKey = appSettingUrlKey;
244                         _appSettingBaseUrl = appSettingBaseUrl;
245                 }
246                 
247                 public ImportInfo (ServiceDescription serviceDescription, WebReference reference)
248                 {
249                         _reference = reference;
250                         _serviceDescription = serviceDescription;
251                 }
252                 
253                 public WebReference Reference {
254                         get { return _reference; }
255                 }
256                 
257                 public ServiceDescription ServiceDescription {
258                         get { return _serviceDescription; }
259                 }
260                 
261                 public string AppSettingUrlKey {
262                         get {
263                                 if (_reference != null) return _reference.AppSettingUrlKey;
264                                 else return _appSettingUrlKey;
265                         }
266                         set {
267                                 _appSettingUrlKey = value;
268                         }
269                 }
270                 
271                 public string AppSettingBaseUrl {
272                         get {
273                                 if (_reference != null) return _reference.AppSettingBaseUrl;
274                                 else return _appSettingBaseUrl;
275                         }
276                         set {
277                                 _appSettingBaseUrl = value;
278                         }
279                 }
280         }
281
282 }