2010-01-20 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel.Description / WsdlImporter.cs
1 //
2 // WsdlImporter.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //      Ankit Jain <jankit@novell.com>  
7 //
8 // Copyright (C) 2005 Novell, Inc.  http://www.novell.com
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 // 
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 // 
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 //
29 using System;
30 using System.Collections.Generic;
31 using System.Collections.ObjectModel;
32 using System.ServiceModel;
33 using System.ServiceModel.Channels;
34 using System.Web.Services.Description;
35 using System.Xml;
36 using System.Xml.Schema;
37
38 using SMBinding = System.ServiceModel.Channels.Binding;
39 using WSServiceDescription = System.Web.Services.Description.ServiceDescription;
40 using WSBinding = System.Web.Services.Description.Binding;
41 using WSMessage = System.Web.Services.Description.Message;
42 using QName = System.Xml.XmlQualifiedName;
43
44 namespace System.ServiceModel.Description
45 {
46         [MonoTODO]
47         public class WsdlImporter : MetadataImporter
48         {
49                 ServiceDescriptionCollection wsdl_documents;
50                 XmlSchemaSet xmlschemas;
51                 List<XmlElement> policies; /* ?? */
52                 MetadataSet metadata;
53
54                 KeyedByTypeCollection<IWsdlImportExtension> wsdl_extensions;
55                         
56                 //Imported
57                 Collection<ContractDescription> contracts = null;
58                 ServiceEndpointCollection endpoint_colln = null;
59
60                 public WsdlImporter (
61                         MetadataSet metadata,
62                         IEnumerable<IPolicyImportExtension> policyImportExtensions,
63                         IEnumerable<IWsdlImportExtension> wsdlImportExtensions)
64                         : base (policyImportExtensions)
65                 {
66                         if (metadata == null)
67                                 throw new ArgumentNullException ("metadata");
68                         
69                         if (wsdlImportExtensions == null) {
70                                 wsdl_extensions = new KeyedByTypeCollection<IWsdlImportExtension> ();
71
72                                 wsdl_extensions.Add (new StandardBindingImporter ());
73                                 wsdl_extensions.Add (new TransportBindingElementImporter ());
74                                 //wsdl_extensions.Add (new MessageEncodingBindingElementImporter ());
75                                 wsdl_extensions.Add (new XmlSerializerMessageContractImporter ());
76                                 wsdl_extensions.Add (new DataContractSerializerMessageContractImporter ());
77                         } else {
78                                 wsdl_extensions = new KeyedByTypeCollection<IWsdlImportExtension> (wsdlImportExtensions);
79                         }
80
81                         this.metadata = metadata;
82                         this.wsdl_documents = new ServiceDescriptionCollection ();
83                         this.xmlschemas = new XmlSchemaSet ();
84                         this.policies = new List<XmlElement> ();
85
86                         foreach (MetadataSection ms in metadata.MetadataSections) {
87                                 if (ms.Dialect == MetadataSection.ServiceDescriptionDialect &&
88                                         ms.Metadata.GetType () == typeof (WSServiceDescription))
89                                         wsdl_documents.Add ((WSServiceDescription) ms.Metadata);
90                                 else
91                                 if (ms.Dialect == MetadataSection.XmlSchemaDialect &&
92                                         ms.Metadata.GetType () == typeof (XmlSchema))
93                                         xmlschemas.Add ((XmlSchema) ms.Metadata);
94                         }
95                 }
96
97                 public WsdlImporter (MetadataSet metadata)
98                         : this (metadata, null, null)
99                 {
100                 }
101
102                 public ServiceDescriptionCollection WsdlDocuments {
103                         get { return wsdl_documents; }
104                 }
105
106                 public KeyedByTypeCollection <IWsdlImportExtension> WsdlImportExtensions {
107                         get { return wsdl_extensions; }
108                 }
109
110                 public XmlSchemaSet XmlSchemas {
111                         get { return xmlschemas; }
112                 }
113
114                 public Collection<SMBinding> ImportAllBindings ()
115                 {
116                         Collection<SMBinding> bindings = new Collection<SMBinding> ();
117
118                         foreach (WSServiceDescription sd in wsdl_documents)
119                                 foreach (WSBinding binding in sd.Bindings)
120                                         bindings.Add (ImportBinding (binding));
121
122                         return bindings;
123                 }
124
125                 public SMBinding ImportBinding (WSBinding binding)
126                 {
127                         /* Default, CustomBinding.. */
128                         CustomBinding smbinding = new CustomBinding ();
129
130                         foreach (IWsdlImportExtension extension in wsdl_extensions)
131                                 extension.BeforeImport (wsdl_documents, xmlschemas, policies);
132
133                         smbinding.Name = binding.Name;
134                         smbinding.Namespace = binding.ServiceDescription.TargetNamespace;
135
136                         //FIXME: Added by MessageEncodingBindingElementConverter.ImportPolicy
137                         smbinding.Elements.Add (new TextMessageEncodingBindingElement ());
138
139                         /*ImportContract
140                         PortType portType = null;
141                         foreach (WSServiceDescription sd in wsdl_documents) {
142                                 portType = sd.PortTypes [binding.Type.Name];
143                                 if (portType != null)
144                                         break;
145                         }
146
147                         //FIXME: if portType == null
148                         */
149                         
150                         // FIXME: ImportContract here..
151
152                         return smbinding;
153                 }
154
155                 public override Collection<ContractDescription> ImportAllContracts ()
156                 {
157                         if (contracts != null)
158                                 return contracts;
159
160                         contracts = new Collection<ContractDescription> ();
161
162                         foreach (WSServiceDescription sd in wsdl_documents) {
163                                 foreach (PortType pt in sd.PortTypes)
164                                         contracts.Add (ImportContract (pt));
165                         }
166
167                         return contracts;
168                 }
169
170                 public override ServiceEndpointCollection ImportAllEndpoints ()
171                 {
172                         if (endpoint_colln != null)
173                                 return endpoint_colln;
174
175                         endpoint_colln = new ServiceEndpointCollection ();
176
177                         foreach (IWsdlImportExtension extension in wsdl_extensions) {
178                                 extension.BeforeImport (wsdl_documents, xmlschemas, policies);
179                         }
180
181                         foreach (WSServiceDescription wsd in wsdl_documents)
182                                 foreach (Service service in wsd.Services)
183                                         foreach (Port port in service.Ports)
184                                                 endpoint_colln.Add (ImportEndpoint (port));
185
186                         return endpoint_colln;
187                 }
188
189                 public ContractDescription ImportContract (PortType wsdlPortType)
190                 {
191                         foreach (IWsdlImportExtension extension in wsdl_extensions) {
192                                 extension.BeforeImport (wsdl_documents, xmlschemas, policies);
193                         }
194
195                         ContractDescription cd = new ContractDescription (wsdlPortType.Name, wsdlPortType.ServiceDescription.TargetNamespace);
196
197                         foreach (Operation op in wsdlPortType.Operations) {
198                                 OperationDescription op_descr = new OperationDescription (op.Name, cd);
199
200                                 foreach (OperationMessage opmsg in op.Messages) {
201                                         /* OperationMessageCollection */
202                                         MessageDescription msg_descr;
203                                         MessageDirection dir = MessageDirection.Input;
204                                         string action = "";
205
206                                         if (opmsg.GetType () == typeof (OperationInput))
207                                                 dir = MessageDirection.Input;
208                                         else if (opmsg.GetType () == typeof (OperationOutput))
209                                                 dir = MessageDirection.Output;
210                                         /* FIXME: OperationFault--> OperationDescription.Faults ? */
211
212                                         if (opmsg.ExtensibleAttributes != null) {
213                                                 for (int i = 0; i < opmsg.ExtensibleAttributes.Length; i++) {
214                                                         if (opmsg.ExtensibleAttributes [i].LocalName == "Action" &&
215                                                                 opmsg.ExtensibleAttributes [i].NamespaceURI == "http://www.w3.org/2006/05/addressing/wsdl")
216                                                                 /* addressing:Action */
217                                                                 action = opmsg.ExtensibleAttributes [i].Value;
218                                                         /* FIXME: other attributes ? */
219                                                 }
220                                         }
221
222                                         msg_descr = new MessageDescription (action, dir);
223                                         /* FIXME: Headers ? */
224
225                                         op_descr.Messages.Add (msg_descr);
226                                 }
227
228                                 cd.Operations.Add (op_descr);
229                         }
230
231                         WsdlContractConversionContext context = new WsdlContractConversionContext (cd, wsdlPortType);
232                         foreach (IWsdlImportExtension extension in wsdl_extensions)
233                                 extension.ImportContract (this, context);
234
235                         return cd;
236                 }
237
238                 public ServiceEndpoint ImportEndpoint (Port wsdlPort)
239                 {
240                         foreach (IWsdlImportExtension extension in wsdl_extensions) {
241                                 extension.BeforeImport (wsdl_documents, xmlschemas, policies);
242                         }
243
244                         //Get the corresponding contract
245                         //via the PortType
246                         WSBinding wsb = wsdlPort.Service.ServiceDescription.Bindings [wsdlPort.Binding.Name];
247                         if (wsb == null)
248                                 //FIXME
249                                 throw new Exception (String.Format ("Binding named {0} not found.", wsdlPort.Binding.Name));
250
251                         SMBinding binding = ImportBinding (wsb);
252
253                         PortType port_type = null;
254                         foreach (WSServiceDescription sd in wsdl_documents) {
255                                 port_type = sd.PortTypes [wsb.Type.Name];
256                                 if (port_type != null)
257                                         break;
258                         }
259
260                         if (port_type == null)
261                                 //FIXME
262                                 throw new Exception (String.Format ("PortType named {0} not found.", wsb.Type.Name));
263
264                         ContractDescription contract = ImportContract (port_type);
265                         ServiceEndpoint sep = new ServiceEndpoint (contract);
266
267                         sep.Binding = binding;
268
269                         WsdlContractConversionContext contract_context = new WsdlContractConversionContext (contract, port_type);
270                         WsdlEndpointConversionContext endpoint_context = new WsdlEndpointConversionContext (
271                                         contract_context, sep, wsdlPort, wsb);
272
273                         foreach (IWsdlImportExtension extension in wsdl_extensions)
274                                 extension.ImportEndpoint (this, endpoint_context);
275
276                         return sep;
277                 }
278
279                 public ServiceEndpointCollection ImportEndpoints (
280                         WSBinding binding)
281                 {
282                         throw new NotImplementedException ();
283                 }
284
285                 public ServiceEndpointCollection ImportEndpoints (
286                         PortType portType)
287                 {
288                         throw new NotImplementedException ();
289                 }
290
291                 public ServiceEndpointCollection ImportEndpoints (
292                         Service service)
293                 {
294                         throw new NotImplementedException ();
295                 }
296         }
297 }