5 // Atsushi Enomoto <atsushi@ximian.com>
6 // Ankit Jain <jankit@novell.com>
8 // Copyright (C) 2005 Novell, Inc. http://www.novell.com
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:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
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.
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;
36 using System.Xml.Schema;
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;
44 namespace System.ServiceModel.Description
47 public class WsdlImporter : MetadataImporter
49 ServiceDescriptionCollection wsdl_documents;
50 XmlSchemaSet xmlschemas;
51 List<XmlElement> policies; /* ?? */
54 KeyedByTypeCollection<IWsdlImportExtension> wsdl_extensions;
57 Collection<ContractDescription> contracts = null;
58 ServiceEndpointCollection endpoint_colln = null;
62 IEnumerable<IPolicyImportExtension> policyImportExtensions,
63 IEnumerable<IWsdlImportExtension> wsdlImportExtensions)
64 : base (policyImportExtensions)
67 throw new ArgumentNullException ("metadata");
69 if (wsdlImportExtensions == null) {
70 wsdl_extensions = new KeyedByTypeCollection<IWsdlImportExtension> ();
72 wsdl_extensions.Add (new DataContractSerializerMessageContractImporter ());
73 wsdl_extensions.Add (new XmlSerializerMessageContractImporter ());
74 //wsdl_extensions.Add (new MessageEncodingBindingElementImporter ());
75 wsdl_extensions.Add (new TransportBindingElementImporter ());
76 wsdl_extensions.Add (new StandardBindingImporter ());
78 wsdl_extensions = new KeyedByTypeCollection<IWsdlImportExtension> (wsdlImportExtensions);
81 // It is okay to fill these members immediately when WsdlImporter.ctor() is invoked
82 // i.e. after this .ctor(), those metadata docs are not considered anymore.
83 this.metadata = metadata;
84 this.wsdl_documents = new ServiceDescriptionCollection ();
85 this.xmlschemas = new XmlSchemaSet ();
86 this.policies = new List<XmlElement> ();
88 foreach (MetadataSection ms in metadata.MetadataSections) {
89 if (ms.Dialect == MetadataSection.ServiceDescriptionDialect &&
90 ms.Metadata.GetType () == typeof (WSServiceDescription))
91 wsdl_documents.Add ((WSServiceDescription) ms.Metadata);
93 if (ms.Dialect == MetadataSection.XmlSchemaDialect &&
94 ms.Metadata.GetType () == typeof (XmlSchema))
95 xmlschemas.Add ((XmlSchema) ms.Metadata);
99 public WsdlImporter (MetadataSet metadata)
100 : this (metadata, null, null)
104 public ServiceDescriptionCollection WsdlDocuments {
105 get { return wsdl_documents; }
108 public KeyedByTypeCollection <IWsdlImportExtension> WsdlImportExtensions {
109 get { return wsdl_extensions; }
112 public XmlSchemaSet XmlSchemas {
113 get { return xmlschemas; }
116 public Collection<SMBinding> ImportAllBindings ()
118 Collection<SMBinding> bindings = new Collection<SMBinding> ();
120 foreach (WSServiceDescription sd in wsdl_documents)
121 foreach (WSBinding binding in sd.Bindings)
122 bindings.Add (ImportBinding (binding));
127 public SMBinding ImportBinding (WSBinding binding)
129 /* Default, CustomBinding.. */
130 CustomBinding smbinding = new CustomBinding ();
132 foreach (IWsdlImportExtension extension in wsdl_extensions)
133 extension.BeforeImport (wsdl_documents, xmlschemas, policies);
135 smbinding.Name = binding.Name;
136 smbinding.Namespace = binding.ServiceDescription.TargetNamespace;
138 //FIXME: Added by MessageEncodingBindingElementConverter.ImportPolicy
139 smbinding.Elements.Add (new TextMessageEncodingBindingElement ());
142 PortType portType = null;
143 foreach (WSServiceDescription sd in wsdl_documents) {
144 portType = sd.PortTypes [binding.Type.Name];
145 if (portType != null)
149 //FIXME: if portType == null
152 // FIXME: ImportContract here..
157 public override Collection<ContractDescription> ImportAllContracts ()
159 if (contracts != null)
162 contracts = new Collection<ContractDescription> ();
164 foreach (WSServiceDescription sd in wsdl_documents) {
165 foreach (PortType pt in sd.PortTypes)
166 contracts.Add (ImportContract (pt));
172 public override ServiceEndpointCollection ImportAllEndpoints ()
174 if (endpoint_colln != null)
175 return endpoint_colln;
177 endpoint_colln = new ServiceEndpointCollection ();
179 foreach (IWsdlImportExtension extension in wsdl_extensions) {
180 extension.BeforeImport (wsdl_documents, xmlschemas, policies);
183 foreach (WSServiceDescription wsd in wsdl_documents)
184 foreach (Service service in wsd.Services)
185 foreach (Port port in service.Ports)
186 endpoint_colln.Add (ImportEndpoint (port));
188 return endpoint_colln;
191 public ContractDescription ImportContract (PortType wsdlPortType)
193 foreach (IWsdlImportExtension extension in wsdl_extensions) {
194 extension.BeforeImport (wsdl_documents, xmlschemas, policies);
197 ContractDescription cd = new ContractDescription (wsdlPortType.Name, wsdlPortType.ServiceDescription.TargetNamespace);
199 foreach (Operation op in wsdlPortType.Operations) {
200 OperationDescription op_descr = new OperationDescription (op.Name, cd);
202 foreach (OperationMessage opmsg in op.Messages) {
203 /* OperationMessageCollection */
204 MessageDescription msg_descr;
205 MessageDirection dir = MessageDirection.Input;
208 if (opmsg.GetType () == typeof (OperationInput))
209 dir = MessageDirection.Input;
210 else if (opmsg.GetType () == typeof (OperationOutput))
211 dir = MessageDirection.Output;
212 /* FIXME: OperationFault--> OperationDescription.Faults ? */
214 if (opmsg.ExtensibleAttributes != null) {
215 for (int i = 0; i < opmsg.ExtensibleAttributes.Length; i++) {
216 if (opmsg.ExtensibleAttributes [i].LocalName == "Action" &&
217 opmsg.ExtensibleAttributes [i].NamespaceURI == "http://www.w3.org/2006/05/addressing/wsdl")
218 /* addressing:Action */
219 action = opmsg.ExtensibleAttributes [i].Value;
220 /* FIXME: other attributes ? */
224 // fill Action from operation binding if required.
226 if (dir != MessageDirection.Input)
227 action = GetActionFromOperationBinding (wsdlPortType, op.Name);
232 msg_descr = new MessageDescription (action, dir);
233 /* FIXME: Headers ? */
235 op_descr.Messages.Add (msg_descr);
238 cd.Operations.Add (op_descr);
241 WsdlContractConversionContext context = new WsdlContractConversionContext (cd, wsdlPortType);
242 foreach (IWsdlImportExtension extension in wsdl_extensions)
243 extension.ImportContract (this, context);
248 string GetActionFromOperationBinding (PortType pt, string opName)
250 foreach (WSBinding binding in pt.ServiceDescription.Bindings) {
251 foreach (OperationBinding ob in binding.Operations) {
252 if (ob.Name != opName)
254 foreach (var ext in ob.Extensions) {
255 var sob = ext as SoapOperationBinding;
258 return sob.SoapAction;
266 public ServiceEndpoint ImportEndpoint (Port wsdlPort)
268 foreach (IWsdlImportExtension extension in wsdl_extensions) {
269 extension.BeforeImport (wsdl_documents, xmlschemas, policies);
272 //Get the corresponding contract
274 WSBinding wsb = wsdlPort.Service.ServiceDescription.Bindings [wsdlPort.Binding.Name];
277 throw new Exception (String.Format ("Binding named {0} not found.", wsdlPort.Binding.Name));
279 SMBinding binding = ImportBinding (wsb);
281 PortType port_type = null;
282 foreach (WSServiceDescription sd in wsdl_documents) {
283 port_type = sd.PortTypes [wsb.Type.Name];
284 if (port_type != null)
288 if (port_type == null)
290 throw new Exception (String.Format ("PortType named {0} not found.", wsb.Type.Name));
292 ContractDescription contract = ImportContract (port_type);
293 ServiceEndpoint sep = new ServiceEndpoint (contract);
295 sep.Binding = binding;
297 WsdlContractConversionContext contract_context = new WsdlContractConversionContext (contract, port_type);
298 WsdlEndpointConversionContext endpoint_context = new WsdlEndpointConversionContext (
299 contract_context, sep, wsdlPort, wsb);
301 foreach (IWsdlImportExtension extension in wsdl_extensions)
302 extension.ImportEndpoint (this, endpoint_context);
307 public ServiceEndpointCollection ImportEndpoints (
310 throw new NotImplementedException ();
313 public ServiceEndpointCollection ImportEndpoints (
316 throw new NotImplementedException ();
319 public ServiceEndpointCollection ImportEndpoints (
322 throw new NotImplementedException ();