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