1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.support.wsdl;
14
15 import java.util.ArrayList;
16 import java.util.Iterator;
17 import java.util.List;
18 import java.util.Map;
19
20 import javax.wsdl.Binding;
21 import javax.wsdl.BindingFault;
22 import javax.wsdl.BindingOperation;
23 import javax.wsdl.BindingOutput;
24 import javax.wsdl.Definition;
25 import javax.wsdl.Fault;
26 import javax.wsdl.Message;
27 import javax.wsdl.Operation;
28 import javax.wsdl.Part;
29 import javax.wsdl.Port;
30 import javax.wsdl.Service;
31 import javax.wsdl.extensions.ExtensibilityElement;
32 import javax.wsdl.extensions.mime.MIMEContent;
33 import javax.wsdl.extensions.mime.MIMEMultipartRelated;
34 import javax.wsdl.extensions.mime.MIMEPart;
35 import javax.wsdl.extensions.soap.SOAPAddress;
36 import javax.wsdl.extensions.soap.SOAPBinding;
37 import javax.wsdl.extensions.soap.SOAPBody;
38 import javax.wsdl.extensions.soap.SOAPFault;
39 import javax.wsdl.extensions.soap.SOAPHeader;
40 import javax.wsdl.extensions.soap.SOAPOperation;
41 import javax.wsdl.extensions.soap12.SOAP12Address;
42 import javax.wsdl.extensions.soap12.SOAP12Binding;
43 import javax.wsdl.extensions.soap12.SOAP12Body;
44 import javax.wsdl.extensions.soap12.SOAP12Fault;
45 import javax.wsdl.extensions.soap12.SOAP12Header;
46 import javax.wsdl.extensions.soap12.SOAP12Operation;
47 import javax.wsdl.factory.WSDLFactory;
48 import javax.wsdl.xml.WSDLReader;
49 import javax.xml.namespace.QName;
50
51 import org.apache.log4j.Logger;
52 import org.apache.xmlbeans.SchemaGlobalElement;
53 import org.apache.xmlbeans.SchemaType;
54
55 import com.eviware.soapui.impl.wsdl.WsdlRequest;
56
57 /***
58 * Wsdl-related tools
59 *
60 * @author Ole.Matzura
61 */
62
63 public class WsdlUtils
64 {
65 private final static Logger log = Logger.getLogger( WsdlUtils.class );
66 private static WSDLReader wsdlReader;
67
68 public static <T extends ExtensibilityElement> T getExtensiblityElement(List list, Class<T> clazz )
69 {
70 List<T> elements = getExtensiblityElements( list, clazz );
71 return elements.isEmpty() ? null : elements.get( 0 );
72 }
73
74 public static <T extends ExtensibilityElement> List<T> getExtensiblityElements(List list, Class<T> clazz )
75 {
76 List<T> result = new ArrayList<T>();
77
78 for( Iterator<T> i = list.iterator(); i.hasNext(); )
79 {
80 T elm = (T) i.next();
81 if( clazz.isAssignableFrom( elm.getClass() ) )
82 {
83 result.add( elm );
84 }
85 }
86
87 return result;
88 }
89
90 public static String getSoapAction(BindingOperation operation)
91 {
92 List list = operation.getExtensibilityElements();
93 SOAPOperation soapOperation = (SOAPOperation) WsdlUtils.getExtensiblityElement( list, SOAPOperation.class );
94 if( soapOperation != null )
95 return soapOperation.getSoapActionURI();
96
97 SOAP12Operation soap12Operation = (SOAP12Operation) WsdlUtils.getExtensiblityElement( list, SOAP12Operation.class );
98 if( soap12Operation != null )
99 return soap12Operation.getSoapActionURI();
100
101 return null;
102 }
103
104 public static String[] getEndpointsForBinding(Definition definition, Binding binding)
105 {
106 List<String> result = new ArrayList<String>();
107 Map map = definition.getAllServices();
108 for( Iterator i = map.values().iterator(); i.hasNext(); )
109 {
110 Service service = (Service) i.next();
111 Map portMap = service.getPorts();
112 for( Iterator i2 = portMap.values().iterator(); i2.hasNext(); )
113 {
114 Port port = (Port) i2.next();
115 if( port.getBinding() == binding )
116 {
117 String endpoint = WsdlUtils.getSoapEndpoint( port );
118 if( endpoint != null )
119 result.add( endpoint );
120 }
121 }
122 }
123
124 return result.toArray( new String[result.size()]);
125 }
126
127 public static Binding findBindingForOperation(Definition definition, BindingOperation bindingOperation)
128 {
129 Map services = definition.getAllServices();
130 Iterator<Service> s = services.values().iterator();
131
132 while( s.hasNext())
133 {
134 Map ports = s.next().getPorts();
135 Iterator<Port> p = ports.values().iterator();
136 while( p.hasNext())
137 {
138 Binding binding = p.next().getBinding();
139 List bindingOperations = binding.getBindingOperations();
140 for (Iterator iter = bindingOperations.iterator(); iter.hasNext();)
141 {
142 BindingOperation op = (BindingOperation) iter.next();
143 if( op.getName().equals( bindingOperation.getName() ))
144 return binding;
145 }
146 }
147 }
148
149 Map bindings = definition.getAllBindings();
150 Iterator<QName> names = bindings.keySet().iterator();
151 while( names.hasNext() )
152 {
153 Binding binding = definition.getBinding( names.next() );
154 List bindingOperations = binding.getBindingOperations();
155 for (Iterator iter = bindingOperations.iterator(); iter.hasNext();)
156 {
157 BindingOperation op = (BindingOperation) iter.next();
158 if( op.getName().equals( bindingOperation.getName() ))
159 return binding;
160 }
161 }
162
163 return null;
164 }
165
166 public static boolean isInputSoapEncoded(BindingOperation bindingOperation)
167 {
168 SOAPBody soapBody = (SOAPBody) WsdlUtils.getExtensiblityElement(bindingOperation.getBindingInput()
169 .getExtensibilityElements(), SOAPBody.class);
170
171 if( soapBody != null )
172 {
173 return soapBody.getUse() != null && soapBody.getUse().equalsIgnoreCase( "encoded" ) &&
174 (soapBody.getEncodingStyles() == null || soapBody.getEncodingStyles().contains( "http://schemas.xmlsoap.org/soap/encoding/" ));
175 }
176
177 SOAP12Body soap12Body = (SOAP12Body) WsdlUtils.getExtensiblityElement(bindingOperation.getBindingInput()
178 .getExtensibilityElements(), SOAP12Body.class);
179
180 if( soap12Body != null )
181 {
182 return soap12Body.getUse() != null && soap12Body.getUse().equalsIgnoreCase( "encoded" ) &&
183 (soap12Body.getEncodingStyle() == null || soap12Body.getEncodingStyle().equals( "http://schemas.xmlsoap.org/soap/encoding/" ));
184 }
185
186 return false;
187 }
188
189 public static boolean isOutputSoapEncoded(BindingOperation bindingOperation)
190 {
191 BindingOutput bindingOutput = bindingOperation.getBindingOutput();
192 if( bindingOutput == null )
193 return false;
194
195 SOAPBody soapBody = (SOAPBody) WsdlUtils.getExtensiblityElement(bindingOutput
196 .getExtensibilityElements(), SOAPBody.class);
197
198 if( soapBody != null )
199 {
200 return soapBody.getUse() != null && soapBody.getUse().equalsIgnoreCase( "encoded" ) &&
201 (soapBody.getEncodingStyles() == null || soapBody.getEncodingStyles().contains( "http://schemas.xmlsoap.org/soap/encoding/" ));
202 }
203
204 SOAP12Body soap12Body = (SOAP12Body) WsdlUtils.getExtensiblityElement(bindingOutput
205 .getExtensibilityElements(), SOAP12Body.class);
206
207 if( soap12Body != null )
208 {
209 return soap12Body.getUse() != null && soap12Body.getUse().equalsIgnoreCase( "encoded" ) &&
210 (soap12Body.getEncodingStyle() == null || soap12Body.getEncodingStyle().equals( "http://schemas.xmlsoap.org/soap/encoding/" ));
211 }
212
213 return false;
214 }
215
216 public static boolean isRpc(Definition definition, BindingOperation bindingOperation)
217 {
218 SOAPOperation soapOperation = (SOAPOperation) WsdlUtils.getExtensiblityElement(
219 bindingOperation.getExtensibilityElements(), SOAPOperation.class );
220
221 if( soapOperation != null && soapOperation.getStyle() != null )
222 return soapOperation.getStyle().equalsIgnoreCase("rpc");
223
224 SOAP12Operation soap12Operation = (SOAP12Operation) WsdlUtils.getExtensiblityElement(
225 bindingOperation.getExtensibilityElements(), SOAP12Operation.class );
226
227 if( soap12Operation != null && soap12Operation.getStyle() != null )
228 return soap12Operation.getStyle().equalsIgnoreCase("rpc");
229
230 Binding binding = findBindingForOperation( definition, bindingOperation );
231 if( binding == null )
232 {
233 log.error( "Failed to find binding for operation [" + bindingOperation.getName() + "] in definition [" +
234 definition.getDocumentBaseURI() + "]" );
235 return false;
236 }
237
238 return isRpc(binding);
239 }
240
241 public static boolean isRpc(Binding binding)
242 {
243 SOAPBinding soapBinding = (SOAPBinding) WsdlUtils.getExtensiblityElement(
244 binding.getExtensibilityElements(), SOAPBinding.class );
245
246 if( soapBinding != null )
247 return "rpc".equalsIgnoreCase( soapBinding.getStyle());
248
249 SOAP12Binding soap12Binding = (SOAP12Binding) WsdlUtils.getExtensiblityElement(
250 binding.getExtensibilityElements(), SOAP12Binding.class );
251
252 if( soap12Binding != null )
253 return "rpc".equalsIgnoreCase( soap12Binding.getStyle());
254
255 return false;
256 }
257
258 /***
259 * Returns a list of parts for the specifed operation, either as specified in body or all
260 */
261
262 public static Part[] getInputParts(BindingOperation operation)
263 {
264 List<Part> result = new ArrayList<Part>();
265 Message msg = operation.getOperation().getInput().getMessage();
266 SOAPBody soapBody = (SOAPBody) WsdlUtils.getExtensiblityElement(operation.getBindingInput()
267 .getExtensibilityElements(), SOAPBody.class);
268
269 if (soapBody == null || soapBody.getParts() == null)
270 {
271 SOAP12Body soap12Body = (SOAP12Body) WsdlUtils.getExtensiblityElement(operation.getBindingInput()
272 .getExtensibilityElements(), SOAP12Body.class);
273
274 if (soap12Body == null || soap12Body.getParts() == null)
275 {
276 if( msg != null )
277 result.addAll( msg.getOrderedParts( null ));
278 }
279 else
280 {
281 Iterator i = soap12Body.getParts().iterator();
282 while (i.hasNext())
283 {
284 String partName = (String) i.next();
285 Part part = msg.getPart( partName );
286
287 result.add(part);
288 }
289 }
290 }
291 else
292 {
293 Iterator i = soapBody.getParts().iterator();
294 while (i.hasNext())
295 {
296 String partName = (String) i.next();
297 Part part = msg.getPart( partName );
298
299 result.add(part);
300 }
301 }
302
303 return result.toArray(new Part[result.size()]);
304 }
305
306 public static boolean isAttachmentInputPart( Part part, BindingOperation operation )
307 {
308 return getInputMultipartContent(part, operation).length > 0;
309 }
310
311 public static boolean isAttachmentOutputPart( Part part, BindingOperation operation )
312 {
313 return getOutputMultipartContent(part, operation).length > 0;
314 }
315
316 public static MIMEContent[] getOutputMultipartContent( Part part, BindingOperation operation )
317 {
318 MIMEMultipartRelated multipartOutput = (MIMEMultipartRelated) WsdlUtils.getExtensiblityElement(
319 operation.getBindingOutput().getExtensibilityElements(), MIMEMultipartRelated.class );
320
321 return getContentParts(part, multipartOutput);
322 }
323
324 public static MIMEContent[] getInputMultipartContent( Part part, BindingOperation operation )
325 {
326 MIMEMultipartRelated multipartInput = (MIMEMultipartRelated) WsdlUtils.getExtensiblityElement(
327 operation.getBindingInput().getExtensibilityElements(), MIMEMultipartRelated.class );
328
329 return getContentParts(part, multipartInput);
330 }
331
332 public static MIMEContent[] getContentParts(Part part, MIMEMultipartRelated multipart)
333 {
334 List<MIMEContent> result = new ArrayList<MIMEContent>();
335
336 if( multipart != null )
337 {
338 List<MIMEPart> parts = multipart.getMIMEParts();
339
340 for( int c = 0; c < parts.size(); c++ )
341 {
342 List<MIMEContent> contentParts = WsdlUtils.getExtensiblityElements( parts.get(c).getExtensibilityElements(), MIMEContent.class );
343
344 for( MIMEContent content : contentParts )
345 {
346 if( content.getPart().equals( part.getName() ))
347 result.add( content );
348 }
349 }
350 }
351
352 return result.toArray( new MIMEContent[result.size()] );
353 }
354
355 public static Part[] getFaultParts(BindingOperation bindingOperation, String faultName) throws Exception
356 {
357 List<Part> result = new ArrayList<Part>();
358
359 BindingFault bindingFault = bindingOperation.getBindingFault( faultName );
360 SOAPFault soapFault = (SOAPFault) WsdlUtils.getExtensiblityElement(bindingFault
361 .getExtensibilityElements(), SOAPFault.class);
362
363 Operation operation = bindingOperation.getOperation();
364 if (soapFault != null && soapFault.getName() != null )
365 {
366 Fault fault = operation.getFault( soapFault.getName() );
367 if( fault == null )
368 throw new Exception( "Missing Fault [" + soapFault.getName() + "] in operation [" + operation.getName() + "]" );
369 result.addAll( fault.getMessage().getOrderedParts( null ));
370 }
371 else
372 {
373 SOAP12Fault soap12Fault = (SOAP12Fault) WsdlUtils.getExtensiblityElement(bindingFault
374 .getExtensibilityElements(), SOAP12Fault.class);
375
376 if (soap12Fault != null && soap12Fault.getName() != null )
377 {
378 result.addAll( operation.getFault( soap12Fault.getName() ).getMessage().getOrderedParts( null ));
379 }
380 else
381 {
382 result.addAll( operation.getFault( faultName ).getMessage().getOrderedParts( null ));
383 }
384 }
385
386 return result.toArray(new Part[result.size()]);
387 }
388
389 public static Part[] getOutputParts(BindingOperation operation)
390 {
391 BindingOutput bindingOutput = operation.getBindingOutput();
392 if( bindingOutput == null )
393 return new Part[0];
394
395 List<Part> result = new ArrayList<Part>();
396 Message msg = operation.getOperation().getOutput().getMessage();
397 SOAPBody soapBody = (SOAPBody) WsdlUtils.getExtensiblityElement(bindingOutput
398 .getExtensibilityElements(), SOAPBody.class);
399
400 if (soapBody == null || soapBody.getParts() == null)
401 {
402 SOAP12Body soap12Body = (SOAP12Body) WsdlUtils.getExtensiblityElement(bindingOutput
403 .getExtensibilityElements(), SOAP12Body.class);
404
405 if(soap12Body == null || soap12Body.getParts() == null)
406 {
407 result.addAll( msg.getOrderedParts( null ));
408 }
409 else
410 {
411 Iterator i = soap12Body.getParts().iterator();
412 while (i.hasNext())
413 {
414 String partName = (String) i.next();
415 Part part = msg.getPart( partName );
416
417 result.add(part);
418 }
419 }
420 }
421 else
422 {
423 Iterator i = soapBody.getParts().iterator();
424 while (i.hasNext())
425 {
426 String partName = (String) i.next();
427 Part part = msg.getPart( partName );
428
429 result.add(part);
430 }
431 }
432
433 return result.toArray(new Part[result.size()]);
434 }
435
436 public static boolean isMultipartRequest(Definition definition, BindingOperation bindingOperation)
437 {
438 return (MIMEMultipartRelated) WsdlUtils.getExtensiblityElement(
439 bindingOperation.getBindingInput().getExtensibilityElements(), MIMEMultipartRelated.class ) != null;
440 }
441
442 public static String getSoapEndpoint( Port port )
443 {
444 SOAPAddress soapAddress = (SOAPAddress) WsdlUtils.getExtensiblityElement( port.getExtensibilityElements(), SOAPAddress.class );
445 if( soapAddress != null )
446 return soapAddress.getLocationURI();
447
448 SOAP12Address soap12Address = (SOAP12Address) WsdlUtils.getExtensiblityElement( port.getExtensibilityElements(), SOAP12Address.class );
449 if( soap12Address != null )
450 return soap12Address.getLocationURI();
451
452 return null;
453 }
454
455 public static String getSoapBodyNamespace( List list )
456 {
457 SOAPBody soapBody = (SOAPBody) WsdlUtils.getExtensiblityElement( list, SOAPBody.class);
458 if( soapBody != null )
459 return soapBody.getNamespaceURI();
460
461 SOAP12Body soap12Body = (SOAP12Body) WsdlUtils.getExtensiblityElement( list, SOAP12Body.class);
462 if( soap12Body != null )
463 return soap12Body.getNamespaceURI();
464
465 return null;
466 }
467
468 /***
469 * A SOAP-Header wrapper
470 *
471 * @author ole.matzura
472 */
473
474 public interface SoapHeader
475 {
476 public QName getMessage();
477
478 public String getPart();
479 }
480
481 /***
482 * SOAP 1.1 Header implementation
483 *
484 * @author ole.matzura
485 */
486
487 public static class Soap11Header implements SoapHeader
488 {
489 private final SOAPHeader soapHeader;
490
491 public Soap11Header( SOAPHeader soapHeader )
492 {
493 this.soapHeader = soapHeader;}
494
495 public QName getMessage()
496 {
497 return soapHeader.getMessage();
498 }
499
500 public String getPart()
501 {
502 return soapHeader.getPart();
503 }
504 }
505
506 /***
507 * SOAP 1.2 Header implementation
508 *
509 * @author ole.matzura
510 */
511
512 public static class Soap12Header implements SoapHeader
513 {
514 private final SOAP12Header soapHeader;
515
516 public Soap12Header( SOAP12Header soapHeader )
517 {
518 this.soapHeader = soapHeader;}
519
520 public QName getMessage()
521 {
522 return soapHeader.getMessage();
523 }
524
525 public String getPart()
526 {
527 return soapHeader.getPart();
528 }
529 }
530
531 public static List<SoapHeader> getSoapHeaders( List list )
532 {
533 List<SoapHeader> result = new ArrayList<SoapHeader>();
534
535 List<SOAPHeader> soapHeaders = WsdlUtils.getExtensiblityElements( list, SOAPHeader.class);
536 if( soapHeaders != null && !soapHeaders.isEmpty() )
537 {
538 for( SOAPHeader header : soapHeaders )
539 result.add( new Soap11Header( header ));
540 }
541 else
542 {
543 List<SOAP12Header> soap12Headers = WsdlUtils.getExtensiblityElements( list, SOAP12Header.class);
544 if( soap12Headers != null && !soap12Headers.isEmpty() )
545 {
546 for( SOAP12Header header : soap12Headers )
547 result.add( new Soap12Header( header ));
548 }
549 }
550
551 return result;
552 }
553
554 public static synchronized Definition readDefinition( String wsdlUrl ) throws Exception
555 {
556 if( wsdlReader == null )
557 {
558 WSDLFactory factory = WSDLFactory.newInstance();
559 wsdlReader = factory.newWSDLReader();
560 wsdlReader.setFeature("javax.wsdl.verbose", true);
561 wsdlReader.setFeature("javax.wsdl.importDocuments", true);
562 }
563
564 return wsdlReader.readWSDL( new UrlWsdlLoader( wsdlUrl ) );
565 }
566
567 public static SchemaType getSchemaTypeForPart( WsdlContext wsdlContext, javax.wsdl.Part part) throws Exception
568 {
569 SchemaType schemaType = null;
570 QName elementName = part.getElementName();
571
572 if( elementName != null )
573 {
574 SchemaGlobalElement elm = wsdlContext.getSchemaTypeLoader().findElement(elementName);
575 if( elm != null )
576 {
577 schemaType = elm.getType();
578 }
579 else WsdlRequest.log.error( "Could not find element [" + elementName + "] specified in part [" + part.getName() + "]" );
580 }
581 else
582 {
583 QName typeName = part.getTypeName();
584
585 if( typeName != null )
586 {
587 schemaType = wsdlContext.getSchemaTypeLoader().findType( typeName );
588
589 if( schemaType == null )
590 {
591 WsdlRequest.log.error( "Could not find type [" + typeName + "] specified in part [" + part.getName() + "]" );
592 }
593 }
594 }
595 return schemaType;
596 }
597 }