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.StringWriter;
16 import java.io.UnsupportedEncodingException;
17 import java.net.URLDecoder;
18 import java.util.ArrayList;
19 import java.util.Iterator;
20 import java.util.List;
21 import java.util.Map;
22
23 import javax.wsdl.Binding;
24 import javax.wsdl.BindingFault;
25 import javax.wsdl.BindingInput;
26 import javax.wsdl.BindingOperation;
27 import javax.wsdl.BindingOutput;
28 import javax.wsdl.Definition;
29 import javax.wsdl.Fault;
30 import javax.wsdl.Input;
31 import javax.wsdl.Message;
32 import javax.wsdl.Operation;
33 import javax.wsdl.Output;
34 import javax.wsdl.Part;
35 import javax.wsdl.Port;
36 import javax.wsdl.Service;
37 import javax.wsdl.WSDLException;
38 import javax.wsdl.extensions.AttributeExtensible;
39 import javax.wsdl.extensions.ElementExtensible;
40 import javax.wsdl.extensions.ExtensibilityElement;
41 import javax.wsdl.extensions.ExtensionDeserializer;
42 import javax.wsdl.extensions.ExtensionRegistry;
43 import javax.wsdl.extensions.UnknownExtensibilityElement;
44 import javax.wsdl.extensions.mime.MIMEContent;
45 import javax.wsdl.extensions.mime.MIMEMultipartRelated;
46 import javax.wsdl.extensions.mime.MIMEPart;
47 import javax.wsdl.extensions.soap.SOAPAddress;
48 import javax.wsdl.extensions.soap.SOAPBinding;
49 import javax.wsdl.extensions.soap.SOAPBody;
50 import javax.wsdl.extensions.soap.SOAPFault;
51 import javax.wsdl.extensions.soap.SOAPHeader;
52 import javax.wsdl.extensions.soap.SOAPOperation;
53 import javax.wsdl.extensions.soap12.SOAP12Address;
54 import javax.wsdl.extensions.soap12.SOAP12Binding;
55 import javax.wsdl.extensions.soap12.SOAP12Body;
56 import javax.wsdl.extensions.soap12.SOAP12Fault;
57 import javax.wsdl.extensions.soap12.SOAP12Header;
58 import javax.wsdl.extensions.soap12.SOAP12Operation;
59 import javax.wsdl.factory.WSDLFactory;
60 import javax.wsdl.xml.WSDLReader;
61 import javax.xml.XMLConstants;
62 import javax.xml.namespace.QName;
63
64 import org.apache.log4j.Logger;
65 import org.apache.xmlbeans.SchemaGlobalElement;
66 import org.apache.xmlbeans.SchemaType;
67 import org.apache.xmlbeans.XmlException;
68 import org.apache.xmlbeans.XmlObject;
69 import org.w3c.dom.Document;
70 import org.w3c.dom.DocumentFragment;
71 import org.w3c.dom.Element;
72 import org.w3c.dom.Node;
73 import org.w3c.dom.NodeList;
74 import org.xml.sax.InputSource;
75
76 import com.eviware.soapui.SoapUI;
77 import com.eviware.soapui.config.AnonymousTypeConfig;
78 import com.eviware.soapui.config.DefinitionCacheConfig;
79 import com.eviware.soapui.config.DefinitionCacheTypeConfig;
80 import com.eviware.soapui.config.DefintionPartConfig;
81 import com.eviware.soapui.config.WsaVersionTypeConfig;
82 import com.eviware.soapui.impl.support.definition.DefinitionLoader;
83 import com.eviware.soapui.impl.wsdl.WsdlInterface;
84 import com.eviware.soapui.impl.wsdl.WsdlOperation;
85 import com.eviware.soapui.impl.wsdl.WsdlRequest;
86 import com.eviware.soapui.impl.wsdl.submit.WsdlMessageExchange;
87 import com.eviware.soapui.impl.wsdl.support.Constants;
88 import com.eviware.soapui.impl.wsdl.support.policy.PolicyUtils;
89 import com.eviware.soapui.impl.wsdl.support.soap.SoapUtils;
90 import com.eviware.soapui.impl.wsdl.support.soap.SoapVersion;
91 import com.eviware.soapui.impl.wsdl.support.wsa.WsaConfig;
92 import com.eviware.soapui.impl.wsdl.support.wsa.WsaUtils;
93 import com.eviware.soapui.impl.wsdl.support.xsd.SchemaUtils;
94 import com.eviware.soapui.settings.WsaSettings;
95 import com.eviware.soapui.support.StringUtils;
96 import com.eviware.soapui.support.types.StringList;
97 import com.eviware.soapui.support.xml.XmlUtils;
98 import com.ibm.wsdl.util.xml.QNameUtils;
99 import com.ibm.wsdl.xml.WSDLReaderImpl;
100 import com.ibm.wsdl.xml.WSDLWriterImpl;
101
102 /***
103 * Wsdl-related tools
104 *
105 * @author Ole.Matzura
106 */
107
108 public class WsdlUtils
109 {
110 private final static Logger log = Logger.getLogger( WsdlUtils.class );
111 private static WSDLReader wsdlReader;
112 private final static String WSDL_NAMESPACE = "http://schemas.xmlsoap.org/wsdl/";
113
114 public static <T extends ExtensibilityElement> T getExtensiblityElement( List<?> list, Class<T> clazz )
115 {
116 List<T> elements = getExtensiblityElements( list, clazz );
117 return elements.isEmpty() ? null : elements.get( 0 );
118 }
119
120 public static <T extends ExtensibilityElement> List<T> getExtensiblityElements( List list, Class<T> clazz )
121 {
122 List<T> result = new ArrayList<T>();
123
124 for( Iterator<T> i = list.iterator(); i.hasNext(); )
125 {
126 T elm = i.next();
127 if( clazz.isAssignableFrom( elm.getClass() ) )
128 {
129 result.add( elm );
130 }
131 }
132
133 return result;
134 }
135
136 public static Element[] getExentsibilityElements( ElementExtensible item, QName qname )
137 {
138 List<Element> result = new ArrayList<Element>();
139
140 List<?> list = item.getExtensibilityElements();
141 for( Iterator<?> i = list.iterator(); i.hasNext(); )
142 {
143 ExtensibilityElement elm = ( ExtensibilityElement )i.next();
144 if( elm.getElementType().equals( qname ) && elm instanceof UnknownExtensibilityElement )
145 {
146 result.add( ( ( UnknownExtensibilityElement )elm ).getElement() );
147 }
148 }
149
150 return result.toArray( new Element[result.size()] );
151 }
152
153 public static String[] getExentsibilityAttributes( AttributeExtensible item, QName qname )
154 {
155 StringList result = new StringList();
156
157 Map map = item.getExtensionAttributes();
158
159 for( Iterator<?> i = map.keySet().iterator(); i.hasNext(); )
160 {
161 QName name = ( QName )i.next();
162 if( name.equals( qname ) )
163 {
164 result.add( map.get( name ).toString() );
165 }
166 }
167
168 return result.toStringArray();
169 }
170
171 public static String getSoapAction( BindingOperation operation )
172 {
173 List list = operation.getExtensibilityElements();
174 SOAPOperation soapOperation = WsdlUtils.getExtensiblityElement( list, SOAPOperation.class );
175 if( soapOperation != null )
176 return soapOperation.getSoapActionURI();
177
178 SOAP12Operation soap12Operation = WsdlUtils.getExtensiblityElement( list, SOAP12Operation.class );
179 if( soap12Operation != null )
180 return soap12Operation.getSoapActionURI();
181
182 return null;
183 }
184
185 public static String[] getEndpointsForBinding( Definition definition, Binding binding )
186 {
187 List<String> result = new ArrayList<String>();
188 Map map = definition.getAllServices();
189 for( Iterator i = map.values().iterator(); i.hasNext(); )
190 {
191 Service service = ( Service )i.next();
192 Map portMap = service.getPorts();
193 for( Iterator i2 = portMap.values().iterator(); i2.hasNext(); )
194 {
195 Port port = ( Port )i2.next();
196 if( port.getBinding() == binding )
197 {
198 String endpoint = WsdlUtils.getSoapEndpoint( port );
199 if( endpoint != null )
200 result.add( endpoint );
201 }
202 }
203 }
204
205 return result.toArray( new String[result.size()] );
206 }
207
208 public static Binding findBindingForOperation( Definition definition, BindingOperation bindingOperation )
209 {
210 Map services = definition.getAllServices();
211 Iterator<Service> s = services.values().iterator();
212
213 while( s.hasNext() )
214 {
215 Map ports = s.next().getPorts();
216 Iterator<Port> p = ports.values().iterator();
217 while( p.hasNext() )
218 {
219 Binding binding = p.next().getBinding();
220 List bindingOperations = binding.getBindingOperations();
221 for( Iterator iter = bindingOperations.iterator(); iter.hasNext(); )
222 {
223 BindingOperation op = ( BindingOperation )iter.next();
224 if( op.getName().equals( bindingOperation.getName() ) )
225 return binding;
226 }
227 }
228 }
229
230 Map bindings = definition.getAllBindings();
231 Iterator<QName> names = bindings.keySet().iterator();
232 while( names.hasNext() )
233 {
234 Binding binding = definition.getBinding( names.next() );
235 List bindingOperations = binding.getBindingOperations();
236 for( Iterator iter = bindingOperations.iterator(); iter.hasNext(); )
237 {
238 BindingOperation op = ( BindingOperation )iter.next();
239 if( op.getName().equals( bindingOperation.getName() ) )
240 return binding;
241 }
242 }
243
244 return null;
245 }
246
247 public static BindingOperation findBindingOperation( Definition definition, String operationName )
248 {
249 Map services = definition.getAllServices();
250 for( Iterator i = services.keySet().iterator(); i.hasNext(); )
251 {
252 QName qName = ( QName )i.next();
253 Service service = definition.getService( qName );
254 Map ports = service.getPorts();
255
256 for( Iterator iterator = ports.keySet().iterator(); iterator.hasNext(); )
257 {
258 String key = ( String )iterator.next();
259 Port port = service.getPort( key );
260 BindingOperation bindingOperation = port.getBinding().getBindingOperation( operationName, null, null );
261 if( bindingOperation != null )
262 return bindingOperation;
263 }
264 }
265
266 Map bindings = definition.getAllBindings();
267 for( Iterator i = bindings.keySet().iterator(); i.hasNext(); )
268 {
269 Object key = i.next();
270 Binding binding = ( Binding )bindings.get( key );
271 BindingOperation bindingOperation = binding.getBindingOperation( operationName, null, null );
272 if( bindingOperation != null )
273 return bindingOperation;
274 }
275
276 return null;
277 }
278
279 public static boolean isInputSoapEncoded( BindingOperation bindingOperation )
280 {
281 if( bindingOperation == null )
282 return false;
283
284 BindingInput bindingInput = bindingOperation.getBindingInput();
285 if( bindingInput == null )
286 return false;
287
288 SOAPBody soapBody = WsdlUtils.getExtensiblityElement( bindingInput.getExtensibilityElements(), SOAPBody.class );
289
290 if( soapBody != null )
291 {
292 return soapBody.getUse() != null
293 && soapBody.getUse().equalsIgnoreCase( "encoded" )
294 && ( soapBody.getEncodingStyles() == null || soapBody.getEncodingStyles().contains(
295 "http://schemas.xmlsoap.org/soap/encoding/" ) );
296 }
297
298 SOAP12Body soap12Body = WsdlUtils.getExtensiblityElement( bindingInput.getExtensibilityElements(),
299 SOAP12Body.class );
300
301 if( soap12Body != null )
302 {
303 return soap12Body.getUse() != null
304 && soap12Body.getUse().equalsIgnoreCase( "encoded" )
305 && ( soap12Body.getEncodingStyle() == null || soap12Body.getEncodingStyle().equals(
306 "http://schemas.xmlsoap.org/soap/encoding/" ) );
307 }
308
309 return false;
310 }
311
312 public static boolean isOutputSoapEncoded( BindingOperation bindingOperation )
313 {
314 if( bindingOperation == null )
315 return false;
316
317 BindingOutput bindingOutput = bindingOperation.getBindingOutput();
318 if( bindingOutput == null )
319 return false;
320
321 SOAPBody soapBody = WsdlUtils.getExtensiblityElement( bindingOutput.getExtensibilityElements(), SOAPBody.class );
322
323 if( soapBody != null )
324 {
325 return soapBody.getUse() != null
326 && soapBody.getUse().equalsIgnoreCase( "encoded" )
327 && ( soapBody.getEncodingStyles() == null || soapBody.getEncodingStyles().contains(
328 "http://schemas.xmlsoap.org/soap/encoding/" ) );
329 }
330
331 SOAP12Body soap12Body = WsdlUtils.getExtensiblityElement( bindingOutput.getExtensibilityElements(),
332 SOAP12Body.class );
333
334 if( soap12Body != null )
335 {
336 return soap12Body.getUse() != null
337 && soap12Body.getUse().equalsIgnoreCase( "encoded" )
338 && ( soap12Body.getEncodingStyle() == null || soap12Body.getEncodingStyle().equals(
339 "http://schemas.xmlsoap.org/soap/encoding/" ) );
340 }
341
342 return false;
343 }
344
345 public static boolean isRpc( Definition definition, BindingOperation bindingOperation )
346 {
347 SOAPOperation soapOperation = WsdlUtils.getExtensiblityElement( bindingOperation.getExtensibilityElements(),
348 SOAPOperation.class );
349
350 if( soapOperation != null && soapOperation.getStyle() != null )
351 return soapOperation.getStyle().equalsIgnoreCase( "rpc" );
352
353 SOAP12Operation soap12Operation = WsdlUtils.getExtensiblityElement( bindingOperation.getExtensibilityElements(),
354 SOAP12Operation.class );
355
356 if( soap12Operation != null && soap12Operation.getStyle() != null )
357 return soap12Operation.getStyle().equalsIgnoreCase( "rpc" );
358
359 Binding binding = findBindingForOperation( definition, bindingOperation );
360 if( binding == null )
361 {
362 log.error( "Failed to find binding for operation [" + bindingOperation.getName() + "] in definition ["
363 + definition.getDocumentBaseURI() + "]" );
364 return false;
365 }
366
367 return isRpc( binding );
368 }
369
370 public static boolean isRpc( Binding binding )
371 {
372 SOAPBinding soapBinding = WsdlUtils
373 .getExtensiblityElement( binding.getExtensibilityElements(), SOAPBinding.class );
374
375 if( soapBinding != null )
376 return "rpc".equalsIgnoreCase( soapBinding.getStyle() );
377
378 SOAP12Binding soap12Binding = WsdlUtils.getExtensiblityElement( binding.getExtensibilityElements(),
379 SOAP12Binding.class );
380
381 if( soap12Binding != null )
382 return "rpc".equalsIgnoreCase( soap12Binding.getStyle() );
383
384 return false;
385 }
386
387 /***
388 * Returns a list of parts for the specifed operation, either as specified in
389 * body or all
390 */
391
392 public static Part[] getInputParts( BindingOperation operation )
393 {
394 List<Part> result = new ArrayList<Part>();
395 Input input = operation.getOperation().getInput();
396 if( input == null || operation.getBindingInput() == null )
397 return new Part[0];
398
399 Message msg = input.getMessage();
400
401 if( msg != null )
402 {
403 SOAPBody soapBody = WsdlUtils.getExtensiblityElement( operation.getBindingInput().getExtensibilityElements(),
404 SOAPBody.class );
405
406 if( soapBody == null || soapBody.getParts() == null )
407 {
408 SOAP12Body soap12Body = WsdlUtils.getExtensiblityElement( operation.getBindingInput()
409 .getExtensibilityElements(), SOAP12Body.class );
410
411 if( soap12Body == null || soap12Body.getParts() == null )
412 {
413 if( msg != null )
414 result.addAll( msg.getOrderedParts( null ) );
415 }
416 else
417 {
418 Iterator i = soap12Body.getParts().iterator();
419 while( i.hasNext() )
420 {
421 String partName = ( String )i.next();
422 Part part = msg.getPart( partName );
423
424 result.add( part );
425 }
426 }
427 }
428 else
429 {
430 Iterator i = soapBody.getParts().iterator();
431 while( i.hasNext() )
432 {
433 String partName = ( String )i.next();
434 Part part = msg.getPart( partName );
435
436 result.add( part );
437 }
438 }
439 }
440 else
441 {
442 }
443
444 return result.toArray( new Part[result.size()] );
445 }
446
447 public static boolean isAttachmentInputPart( Part part, BindingOperation operation )
448 {
449 return getInputMultipartContent( part, operation ).length > 0;
450 }
451
452 public static boolean isAttachmentOutputPart( Part part, BindingOperation operation )
453 {
454 return getOutputMultipartContent( part, operation ).length > 0;
455 }
456
457 public static MIMEContent[] getOutputMultipartContent( Part part, BindingOperation operation )
458 {
459 BindingOutput output = operation.getBindingOutput();
460 if( output == null )
461 return new MIMEContent[0];
462
463 MIMEMultipartRelated multipartOutput = WsdlUtils.getExtensiblityElement( output.getExtensibilityElements(),
464 MIMEMultipartRelated.class );
465
466 return getContentParts( part, multipartOutput );
467 }
468
469 public static MIMEContent[] getInputMultipartContent( Part part, BindingOperation operation )
470 {
471 BindingInput bindingInput = operation.getBindingInput();
472 if( bindingInput == null )
473 return new MIMEContent[0];
474
475 MIMEMultipartRelated multipartInput = WsdlUtils.getExtensiblityElement( bindingInput.getExtensibilityElements(),
476 MIMEMultipartRelated.class );
477
478 return getContentParts( part, multipartInput );
479 }
480
481 public static MIMEContent[] getContentParts( Part part, MIMEMultipartRelated multipart )
482 {
483 List<MIMEContent> result = new ArrayList<MIMEContent>();
484
485 if( multipart != null )
486 {
487 List<MIMEPart> parts = multipart.getMIMEParts();
488
489 for( int c = 0; c < parts.size(); c++ )
490 {
491 List<MIMEContent> contentParts = WsdlUtils.getExtensiblityElements( parts.get( c )
492 .getExtensibilityElements(), MIMEContent.class );
493
494 for( MIMEContent content : contentParts )
495 {
496 if( content.getPart().equals( part.getName() ) )
497 result.add( content );
498 }
499 }
500 }
501
502 return result.toArray( new MIMEContent[result.size()] );
503 }
504
505 public static Part[] getFaultParts( BindingOperation bindingOperation, String faultName ) throws Exception
506 {
507 List<Part> result = new ArrayList<Part>();
508
509 BindingFault bindingFault = bindingOperation.getBindingFault( faultName );
510 SOAPFault soapFault = WsdlUtils.getExtensiblityElement( bindingFault.getExtensibilityElements(), SOAPFault.class );
511
512 Operation operation = bindingOperation.getOperation();
513 if( soapFault != null && soapFault.getName() != null )
514 {
515 Fault fault = operation.getFault( soapFault.getName() );
516 if( fault == null )
517 throw new Exception( "Missing Fault [" + soapFault.getName() + "] in operation [" + operation.getName()
518 + "]" );
519 result.addAll( fault.getMessage().getOrderedParts( null ) );
520 }
521 else
522 {
523 SOAP12Fault soap12Fault = WsdlUtils.getExtensiblityElement( bindingFault.getExtensibilityElements(),
524 SOAP12Fault.class );
525
526 if( soap12Fault != null && soap12Fault.getName() != null )
527 {
528 result.addAll( operation.getFault( soap12Fault.getName() ).getMessage().getOrderedParts( null ) );
529 }
530 else
531 {
532 result.addAll( operation.getFault( faultName ).getMessage().getOrderedParts( null ) );
533 }
534 }
535
536 return result.toArray( new Part[result.size()] );
537 }
538
539 public static String findSoapFaultPartName( SoapVersion soapVersion, BindingOperation bindingOperation,
540 String message ) throws Exception
541 {
542 if( WsdlUtils.isOutputSoapEncoded( bindingOperation ) )
543 throw new Exception( "SOAP-Encoded messages not supported" );
544
545 XmlObject xml = XmlObject.Factory.parse( message );
546 XmlObject[] msgPaths = xml.selectPath( "declare namespace env='" + soapVersion.getEnvelopeNamespace() + "';"
547 + "$this/env:Envelope/env:Body/env:Fault" );
548 if( msgPaths.length == 0 )
549 return null;
550
551 XmlObject msgXml = msgPaths[0];
552
553 Map faults = bindingOperation.getBindingFaults();
554 for( Iterator<BindingFault> i = faults.values().iterator(); i.hasNext(); )
555 {
556 BindingFault bindingFault = i.next();
557 String faultName = bindingFault.getName();
558 Part[] faultParts = WsdlUtils.getFaultParts( bindingOperation, faultName );
559 Part part = faultParts[0];
560
561 QName elementName = part.getElementName();
562 if( elementName != null )
563 {
564 XmlObject[] faultPaths = msgXml.selectPath( "declare namespace env='" + soapVersion.getEnvelopeNamespace()
565 + "';" + "declare namespace ns='" + elementName.getNamespaceURI() + "';" + "//env:Fault/detail/ns:"
566 + elementName.getLocalPart() );
567
568 if( faultPaths.length == 1 )
569 return faultName;
570 }
571
572 else if( part.getTypeName() != null )
573 {
574 QName typeName = part.getTypeName();
575 XmlObject[] faultPaths = msgXml.selectPath( "declare namespace env='" + soapVersion.getEnvelopeNamespace()
576 + "';" + "declare namespace ns='" + typeName.getNamespaceURI() + "';" + "//env:Fault/detail/ns:"
577 + part.getName() );
578
579 if( faultPaths.length == 1 )
580 return faultName;
581 }
582 }
583
584 return null;
585 }
586
587 public static Part[] getOutputParts( BindingOperation operation )
588 {
589 BindingOutput bindingOutput = operation.getBindingOutput();
590 if( bindingOutput == null )
591 return new Part[0];
592
593 List<Part> result = new ArrayList<Part>();
594 Output output = operation.getOperation().getOutput();
595 if( output == null )
596 return new Part[0];
597
598 Message msg = output.getMessage();
599 if( msg != null )
600 {
601 SOAPBody soapBody = WsdlUtils
602 .getExtensiblityElement( bindingOutput.getExtensibilityElements(), SOAPBody.class );
603
604 if( soapBody == null || soapBody.getParts() == null )
605 {
606 SOAP12Body soap12Body = WsdlUtils.getExtensiblityElement( bindingOutput.getExtensibilityElements(),
607 SOAP12Body.class );
608
609 if( soap12Body == null || soap12Body.getParts() == null )
610 {
611 result.addAll( msg.getOrderedParts( null ) );
612 }
613 else
614 {
615 Iterator i = soap12Body.getParts().iterator();
616 while( i.hasNext() )
617 {
618 String partName = ( String )i.next();
619 Part part = msg.getPart( partName );
620
621 result.add( part );
622 }
623 }
624 }
625 else
626 {
627 Iterator i = soapBody.getParts().iterator();
628 while( i.hasNext() )
629 {
630 String partName = ( String )i.next();
631 Part part = msg.getPart( partName );
632
633 result.add( part );
634 }
635 }
636 }
637 else
638 {
639 log.warn( "Missing output message for binding operation [" + operation.getName() + "]" );
640 }
641
642 return result.toArray( new Part[result.size()] );
643 }
644
645 public static boolean isMultipartRequest( Definition definition, BindingOperation bindingOperation )
646 {
647 return WsdlUtils.getExtensiblityElement( bindingOperation.getBindingInput().getExtensibilityElements(),
648 MIMEMultipartRelated.class ) != null;
649 }
650
651 public static String getUsingAddressing( ElementExtensible item )
652 {
653 String version = WsaVersionTypeConfig.NONE.toString();
654
655 Element[] usingAddressingElements = WsdlUtils.getExentsibilityElements( item, new QName(
656 "http://www.w3.org/2006/05/addressing/wsdl", "UsingAddressing" ) );
657 if( usingAddressingElements.length == 0 )
658 {
659 usingAddressingElements = WsdlUtils.getExentsibilityElements( item, new QName(
660 "http://www.w3.org/2006/02/addressing/wsdl", "UsingAddressing" ) );
661 }
662
663 if( usingAddressingElements.length != 0 )
664 {
665
666
667 String addressingVersion = usingAddressingElements[0].getAttributeNS( WSDL_NAMESPACE, "required" );
668 if( addressingVersion != null && addressingVersion.equals( "true" ) )
669 {
670 version = WsaVersionTypeConfig.X_200508.toString();
671 }
672
673 }
674 return version;
675 }
676
677 private static String checkIfWsaPolicy( String version, Element policy )
678 {
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719 return version;
720 }
721
722 public static String getWsaPolicyAnonymous( Element policy )
723 {
724 String version = WsaVersionTypeConfig.NONE.toString();
725 String anonymous = AnonymousTypeConfig.OPTIONAL.toString();
726
727 Element wsAddressing = XmlUtils.getFirstChildElementNS( policy, WsaUtils.WS_A_NAMESPACE_200705, "Addressing" );
728 Element addressingPolicy = null;
729 if( wsAddressing != null )
730 {
731 String optional = wsAddressing.getAttributeNS( PolicyUtils.WS_W3_POLICY_NAMESPACE, "Optional" );
732 addressingPolicy = XmlUtils
733 .getFirstChildElementNS( wsAddressing, PolicyUtils.WS_W3_POLICY_NAMESPACE, "Policy" );
734 if( addressingPolicy != null )
735 {
736 if( StringUtils.isNullOrEmpty( optional ) || optional.equals( "false" )
737 || ( optional.equals( "true" ) && SoapUI.getSettings().getBoolean( WsaSettings.ENABLE_FOR_OPTIONAL ) ) )
738 {
739 version = WsaVersionTypeConfig.X_200508.toString();
740 }
741
742 Element anonymousElm = XmlUtils.getFirstChildElementNS( addressingPolicy, new QName(
743 WsaUtils.WS_A_NAMESPACE_200705, "AnonymousResponses" ) );
744 if( anonymousElm != null )
745 {
746 anonymous = AnonymousTypeConfig.REQUIRED.toString();
747 }
748 else
749 {
750 Element nonAnonymousElement = XmlUtils.getFirstChildElementNS( addressingPolicy, new QName(
751 WsaUtils.WS_A_NAMESPACE_200705, "NonAnonymousResponses" ) );
752 if( nonAnonymousElement != null )
753 {
754 anonymous = AnonymousTypeConfig.PROHIBITED.toString();
755 }
756 }
757 }
758 }
759 return anonymous;
760 }
761
762 public static String getSoapEndpoint( Port port )
763 {
764 SOAPAddress soapAddress = WsdlUtils.getExtensiblityElement( port.getExtensibilityElements(), SOAPAddress.class );
765 if( soapAddress != null && StringUtils.hasContent( soapAddress.getLocationURI() ) )
766 {
767 try
768 {
769 return URLDecoder.decode( soapAddress.getLocationURI(), "UTF-8" );
770 }
771 catch( UnsupportedEncodingException e )
772 {
773 e.printStackTrace();
774 return soapAddress.getLocationURI();
775 }
776 }
777
778 SOAP12Address soap12Address = WsdlUtils.getExtensiblityElement( port.getExtensibilityElements(),
779 SOAP12Address.class );
780 if( soap12Address != null && StringUtils.hasContent( soap12Address.getLocationURI() ) )
781 {
782 try
783 {
784 return URLDecoder.decode( soap12Address.getLocationURI(), "UTF-8" );
785 }
786 catch( UnsupportedEncodingException e )
787 {
788 e.printStackTrace();
789 return soap12Address.getLocationURI();
790 }
791 }
792
793 return null;
794 }
795
796 public static boolean replaceSoapEndpoint( Port port, String endpoint )
797 {
798 SOAPAddress soapAddress = WsdlUtils.getExtensiblityElement( port.getExtensibilityElements(), SOAPAddress.class );
799 if( soapAddress != null )
800 {
801 soapAddress.setLocationURI( endpoint );
802 return true;
803 }
804
805 SOAP12Address soap12Address = WsdlUtils.getExtensiblityElement( port.getExtensibilityElements(),
806 SOAP12Address.class );
807 if( soap12Address != null )
808 {
809 soap12Address.setLocationURI( endpoint );
810 return true;
811 }
812
813 return false;
814 }
815
816 public static String getSoapBodyNamespace( List<?> list )
817 {
818 SOAPBody soapBody = WsdlUtils.getExtensiblityElement( list, SOAPBody.class );
819 if( soapBody != null )
820 return soapBody.getNamespaceURI();
821
822 SOAP12Body soap12Body = WsdlUtils.getExtensiblityElement( list, SOAP12Body.class );
823 if( soap12Body != null )
824 return soap12Body.getNamespaceURI();
825
826 return null;
827 }
828
829 public static final class NonSchemaImportingWsdlReaderImpl extends WSDLReaderImpl
830 {
831 @SuppressWarnings( "unchecked" )
832 @Override
833 protected ExtensibilityElement parseSchema( Class parentType, Element el, Definition def, ExtensionRegistry extReg )
834 throws WSDLException
835 {
836 QName elementType = QNameUtils.newQName( el );
837
838 ExtensionDeserializer exDS = extReg.queryDeserializer( parentType, elementType );
839
840
841 ExtensibilityElement ee = exDS.unmarshall( parentType, elementType, el, def, extReg );
842
843 return ee;
844 }
845
846 }
847
848 /***
849 * A SOAP-Header wrapper
850 *
851 * @author ole.matzura
852 */
853
854 public interface SoapHeader
855 {
856 public QName getMessage();
857
858 public String getPart();
859 }
860
861 /***
862 * SOAP 1.1 Header implementation
863 *
864 * @author ole.matzura
865 */
866
867 public static class Soap11Header implements SoapHeader
868 {
869 private final SOAPHeader soapHeader;
870
871 public Soap11Header( SOAPHeader soapHeader )
872 {
873 this.soapHeader = soapHeader;
874 }
875
876 public QName getMessage()
877 {
878 return soapHeader.getMessage();
879 }
880
881 public String getPart()
882 {
883 return soapHeader.getPart();
884 }
885 }
886
887 /***
888 * SOAP 1.2 Header implementation
889 *
890 * @author ole.matzura
891 */
892
893 public static class Soap12Header implements SoapHeader
894 {
895 private final SOAP12Header soapHeader;
896
897 public Soap12Header( SOAP12Header soapHeader )
898 {
899 this.soapHeader = soapHeader;
900 }
901
902 public QName getMessage()
903 {
904 return soapHeader.getMessage();
905 }
906
907 public String getPart()
908 {
909 return soapHeader.getPart();
910 }
911 }
912
913 public static List<SoapHeader> getSoapHeaders( List list )
914 {
915 List<SoapHeader> result = new ArrayList<SoapHeader>();
916
917 List<SOAPHeader> soapHeaders = WsdlUtils.getExtensiblityElements( list, SOAPHeader.class );
918 if( soapHeaders != null && !soapHeaders.isEmpty() )
919 {
920 for( SOAPHeader header : soapHeaders )
921 result.add( new Soap11Header( header ) );
922 }
923 else
924 {
925 List<SOAP12Header> soap12Headers = WsdlUtils.getExtensiblityElements( list, SOAP12Header.class );
926 if( soap12Headers != null && !soap12Headers.isEmpty() )
927 {
928 for( SOAP12Header header : soap12Headers )
929 result.add( new Soap12Header( header ) );
930 }
931 }
932
933 return result;
934 }
935
936 public static synchronized Definition readDefinition( String wsdlUrl ) throws Exception
937 {
938 if( wsdlReader == null )
939 {
940 WSDLFactory factory = WSDLFactory.newInstance();
941 wsdlReader = factory.newWSDLReader();
942 wsdlReader.setFeature( "javax.wsdl.verbose", true );
943 wsdlReader.setFeature( "javax.wsdl.importDocuments", true );
944 }
945
946 return wsdlReader.readWSDL( new UrlWsdlLoader( wsdlUrl ) );
947 }
948
949 public static SchemaType getSchemaTypeForPart( WsdlContext wsdlContext, javax.wsdl.Part part ) throws Exception
950 {
951 SchemaType schemaType = null;
952 QName elementName = part.getElementName();
953
954 if( elementName != null )
955 {
956 SchemaGlobalElement elm = wsdlContext.getSchemaTypeLoader().findElement( elementName );
957 if( elm != null )
958 {
959 schemaType = elm.getType();
960 }
961 else
962 WsdlRequest.log.error( "Could not find element [" + elementName + "] specified in part [" + part.getName()
963 + "]" );
964 }
965 else
966 {
967 QName typeName = part.getTypeName();
968
969 if( typeName != null )
970 {
971 schemaType = wsdlContext.getSchemaTypeLoader().findType( typeName );
972
973 if( schemaType == null )
974 {
975 WsdlRequest.log.error( "Could not find type [" + typeName + "] specified in part [" + part.getName()
976 + "]" );
977 }
978 }
979 }
980 return schemaType;
981 }
982
983 public static SchemaGlobalElement getSchemaElementForPart( WsdlContext wsdlContext, javax.wsdl.Part part )
984 throws Exception
985 {
986 QName elementName = part.getElementName();
987
988 if( elementName != null )
989 {
990 return wsdlContext.getSchemaTypeLoader().findElement( elementName );
991 }
992
993 return null;
994 }
995
996 public static String replacePortEndpoint( WsdlInterface iface, InputSource inputSource, String endpoint )
997 throws WSDLException
998 {
999 WSDLReader wsdlReader = new NonSchemaImportingWsdlReaderImpl();
1000
1001 wsdlReader.setFeature( "javax.wsdl.verbose", true );
1002 wsdlReader.setFeature( "javax.wsdl.importDocuments", false );
1003
1004 Definition definition = wsdlReader.readWSDL( null, inputSource );
1005
1006 boolean updated = false;
1007 Map map = definition.getServices();
1008 for( Iterator i = map.values().iterator(); i.hasNext(); )
1009 {
1010 Service service = ( Service )i.next();
1011 Map portMap = service.getPorts();
1012 for( Iterator i2 = portMap.values().iterator(); i2.hasNext(); )
1013 {
1014 Port port = ( Port )i2.next();
1015 if( port.getBinding().getQName().equals( iface.getBindingName() ) )
1016 {
1017 if( replaceSoapEndpoint( port, endpoint ) )
1018 updated = true;
1019 }
1020 }
1021 }
1022
1023 if( updated )
1024 {
1025 StringWriter writer = new StringWriter();
1026
1027 Map nsMap = definition.getNamespaces();
1028 if( !nsMap.values().contains( Constants.SOAP_HTTP_BINDING_NS ) )
1029 definition.addNamespace( "soaphttp", Constants.SOAP_HTTP_BINDING_NS );
1030
1031 new WSDLWriterImpl().writeWSDL( definition, writer );
1032 return writer.toString();
1033 }
1034
1035 return null;
1036 }
1037
1038 public static BindingOperation findBindingOperation( Binding binding, String bindingOperationName, String inputName,
1039 String outputName )
1040 {
1041 if( binding == null )
1042 return null;
1043
1044 if( inputName == null )
1045 inputName = ":none";
1046
1047 if( outputName == null )
1048 outputName = ":none";
1049
1050 BindingOperation result = binding.getBindingOperation( bindingOperationName, inputName, outputName );
1051
1052 if( result == null && ( inputName.equals( ":none" ) || outputName.equals( ":none" ) ) )
1053 {
1054
1055 result = binding.getBindingOperation( bindingOperationName, inputName.equals( ":none" ) ? null : inputName,
1056 outputName.equals( ":none" ) ? null : outputName );
1057 }
1058 return result;
1059 }
1060
1061 public static boolean isHeaderInputPart( Part part, Message message, BindingOperation bindingOperation )
1062 {
1063 List<SOAPHeader> headers = WsdlUtils.getExtensiblityElements( bindingOperation.getBindingInput()
1064 .getExtensibilityElements(), SOAPHeader.class );
1065
1066 if( headers == null || headers.isEmpty() )
1067 return false;
1068
1069 for( SOAPHeader header : headers )
1070 {
1071 if( message.getQName().equals( header.getMessage() ) && part.getName().equals( header.getPart() ) )
1072 return true;
1073 }
1074
1075 return false;
1076 }
1077
1078 public static boolean isHeaderOutputPart( Part part, Message message, BindingOperation bindingOperation )
1079 {
1080 BindingOutput bindingOutput = bindingOperation.getBindingOutput();
1081 List<SOAPHeader> headers = bindingOutput == null ? null : WsdlUtils.getExtensiblityElements( bindingOutput
1082 .getExtensibilityElements(), SOAPHeader.class );
1083
1084 if( headers == null || headers.isEmpty() )
1085 return false;
1086
1087 for( SOAPHeader header : headers )
1088 {
1089 if( message.getQName().equals( header.getMessage() ) && part.getName().equals( header.getPart() ) )
1090 return true;
1091 }
1092
1093 return false;
1094 }
1095
1096 public static DefinitionCacheConfig cacheWsdl( DefinitionLoader loader ) throws Exception
1097 {
1098 DefinitionCacheConfig definitionCache = DefinitionCacheConfig.Factory.newInstance();
1099 definitionCache.setRootPart( loader.getBaseURI() );
1100 definitionCache.setType( DefinitionCacheTypeConfig.TEXT );
1101
1102 Map<String, XmlObject> urls = SchemaUtils.getDefinitionParts( loader );
1103
1104 for( Iterator<String> i = urls.keySet().iterator(); i.hasNext(); )
1105 {
1106 DefintionPartConfig definitionPart = definitionCache.addNewPart();
1107 String url = i.next();
1108 definitionPart.setUrl( url );
1109 XmlObject xmlObject = urls.get( url );
1110 Node domNode = xmlObject.getDomNode();
1111
1112 if( domNode.getNodeType() == Node.DOCUMENT_FRAGMENT_NODE )
1113 {
1114 Node node = ( ( DocumentFragment )domNode ).getFirstChild();
1115 if( node.getNodeType() == Node.TEXT_NODE )
1116 {
1117 domNode = XmlUtils.parseXml( node.getNodeValue() );
1118 xmlObject = XmlObject.Factory.parse( domNode );
1119 }
1120 }
1121
1122 Element contentElement = ( ( Document )domNode ).getDocumentElement();
1123
1124 Node newDomNode = definitionPart.addNewContent().getDomNode();
1125 newDomNode.appendChild( newDomNode.getOwnerDocument().createTextNode( xmlObject.toString() ) );
1126 definitionPart.setType( contentElement.getNamespaceURI() );
1127 }
1128
1129 return definitionCache;
1130 }
1131
1132 public static void getAnonymous( WsdlOperation wsdlOperation )
1133 {
1134 String anonymous = "";
1135
1136 Element[] anonymousElements = WsdlUtils.getExentsibilityElements( wsdlOperation.getBindingOperation(), new QName(
1137 "http://www.w3.org/2006/05/addressing/wsdl", "Anonymous" ) );
1138 if( anonymousElements.length == 0 )
1139 {
1140 anonymousElements = WsdlUtils.getExentsibilityElements( wsdlOperation.getBindingOperation(), new QName(
1141 "http://www.w3.org/2006/02/addressing/wsdl", "Anonymous" ) );
1142 }
1143
1144 if( anonymousElements != null && anonymousElements.length > 0 )
1145 {
1146 anonymous = XmlUtils.getElementText( anonymousElements[0] );
1147 }
1148 wsdlOperation.setAnonymous( anonymous );
1149 }
1150
1151 public static String getDefaultWsaAction( WsdlOperation operation, boolean output )
1152 {
1153
1154 if( operation.getInterface().getSoapVersion() == SoapVersion.Soap11
1155 && StringUtils.hasContent( operation.getAction() )
1156 && SoapUI.getSettings().getBoolean( WsaSettings.SOAP_ACTION_OVERRIDES_WSA_ACTION ) )
1157 return operation.getAction();
1158
1159 try
1160 {
1161 AttributeExtensible attributeExtensible = output ? operation.getBindingOperation().getOperation().getOutput()
1162 : operation.getBindingOperation().getOperation().getInput();
1163
1164 if( attributeExtensible == null )
1165 return null;
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178 String[] attrs;
1179 for( String namespace : WsaUtils.wsaNamespaces )
1180 {
1181 attrs = WsdlUtils.getExentsibilityAttributes( attributeExtensible, new QName( namespace, "Action" ) );
1182 if( attrs != null && attrs.length > 0 )
1183 {
1184 return attrs[0];
1185 }
1186 }
1187
1188 WsdlInterface iface = operation.getInterface();
1189
1190 Definition definition = iface.getWsdlContext().getDefinition();
1191 String targetNamespace = WsdlUtils.getTargetNamespace( definition );
1192 String portTypeName = iface.getBinding().getPortType().getQName().getLocalPart();
1193 String operationName = operation.getName();
1194 if( !StringUtils.isNullOrEmpty( operationName ) )
1195 {
1196 Operation op = iface.getBinding().getPortType().getOperation( operationName, null, null );
1197 if( op != null )
1198 {
1199 attributeExtensible = output ? op.getOutput() : op.getInput();
1200 attrs = WsdlUtils.getExentsibilityAttributes( attributeExtensible, new QName(
1201 WsaUtils.WS_A_NAMESPACE_200705, "Action" ) );
1202 if( attrs != null && attrs.length > 0 )
1203 {
1204 return attrs[0];
1205 }
1206 }
1207 }
1208 String operationInOutName = output ? operation.getOutputName() : operation.getInputName();
1209 if( operationInOutName == null )
1210 operationInOutName = operation.getName() + ( output ? "Response" : "Request" );
1211
1212 StringBuffer result = new StringBuffer( targetNamespace );
1213 if( targetNamespace.length() > 0 && targetNamespace.charAt( targetNamespace.length() - 1 ) != '/'
1214 && portTypeName.charAt( 0 ) != '/' )
1215 result.append( '/' );
1216 result.append( portTypeName );
1217 if( portTypeName.charAt( portTypeName.length() - 1 ) != '/' && operationInOutName.charAt( 0 ) != '/' )
1218 result.append( '/' );
1219 result.append( operationInOutName );
1220
1221 return result.toString();
1222 }
1223 catch( Exception e )
1224 {
1225 e.printStackTrace();
1226 log.warn( e.toString() );
1227 return null;
1228 }
1229 }
1230
1231 public static void setDefaultWsaAction( WsaConfig wsaConfig, boolean b )
1232 {
1233 String defaultAction = getDefaultWsaAction( wsaConfig.getWsaContainer().getOperation(), b );
1234 if( StringUtils.hasContent( defaultAction ) )
1235 wsaConfig.setAction( defaultAction );
1236 }
1237
1238 public static String getRequestWsaMessageId( WsdlMessageExchange messageExchange, String wsaVersionNameSpace )
1239 {
1240 String requestMessageId = null;
1241 try
1242 {
1243 XmlObject xmlObject = XmlObject.Factory.parse( messageExchange.getRequestContent() );
1244 SoapVersion soapVersion = messageExchange.getOperation().getInterface().getSoapVersion();
1245
1246 Element header = ( Element )SoapUtils.getHeaderElement( xmlObject, soapVersion, true ).getDomNode();
1247 Element msgNode = XmlUtils.getFirstChildElementNS( header, wsaVersionNameSpace, "MessageID" );
1248 if( msgNode != null )
1249 {
1250 requestMessageId = XmlUtils.getElementText( msgNode );
1251 }
1252 }
1253 catch( XmlException e )
1254 {
1255 e.printStackTrace();
1256 log.warn( e.toString() );
1257 return null;
1258 }
1259 return requestMessageId;
1260 }
1261
1262 public static NodeList getRequestReplyToRefProps( WsdlMessageExchange messageExchange, String wsaVersionNameSpace )
1263 {
1264 try
1265 {
1266 XmlObject xmlObject = XmlObject.Factory.parse( messageExchange.getRequestContent() );
1267 SoapVersion soapVersion = messageExchange.getOperation().getInterface().getSoapVersion();
1268
1269 Element header = ( Element )SoapUtils.getHeaderElement( xmlObject, soapVersion, true ).getDomNode();
1270 Element replyToNode = XmlUtils.getFirstChildElementNS( header, wsaVersionNameSpace, "ReplyTo" );
1271 Element replyRefParamsNode = XmlUtils.getFirstChildElementNS( replyToNode, wsaVersionNameSpace,
1272 "ReferenceParameters" );
1273 if( replyRefParamsNode != null )
1274 {
1275 return XmlUtils.getChildElements( replyRefParamsNode );
1276 }
1277 }
1278 catch( XmlException e )
1279 {
1280 e.printStackTrace();
1281 log.warn( e.toString() );
1282 }
1283 return null;
1284 }
1285
1286 public static NodeList getRequestFaultToRefProps( WsdlMessageExchange messageExchange, String wsaVersionNameSpace )
1287 {
1288 try
1289 {
1290 XmlObject xmlObject = XmlObject.Factory.parse( messageExchange.getRequestContent() );
1291 SoapVersion soapVersion = messageExchange.getOperation().getInterface().getSoapVersion();
1292
1293 Element header = ( Element )SoapUtils.getHeaderElement( xmlObject, soapVersion, true ).getDomNode();
1294 Element faultToNode = XmlUtils.getFirstChildElementNS( header, wsaVersionNameSpace, "FaultTo" );
1295 Element faultRefParamsNode = XmlUtils.getFirstChildElementNS( faultToNode, wsaVersionNameSpace,
1296 "ReferenceParameters" );
1297 if( faultRefParamsNode != null )
1298 {
1299 return XmlUtils.getChildElements( faultRefParamsNode );
1300 }
1301 }
1302 catch( XmlException e )
1303 {
1304 e.printStackTrace();
1305 log.warn( e.toString() );
1306 }
1307 return null;
1308 }
1309
1310 public static String getFaultCode( WsdlMessageExchange messageExchange )
1311 {
1312 try
1313 {
1314 XmlObject xmlObject = XmlObject.Factory.parse( messageExchange.getResponseContent() );
1315 SoapVersion soapVersion = messageExchange.getOperation().getInterface().getSoapVersion();
1316
1317 Element body = ( Element )SoapUtils.getBodyElement( xmlObject, soapVersion ).getDomNode();
1318 Element soapenvFault = XmlUtils.getFirstChildElementNS( body, "http://schemas.xmlsoap.org/soap/envelope/",
1319 "Fault" );
1320 Element faultCode = XmlUtils.getFirstChildElement( soapenvFault, "faultcode" );
1321 if( faultCode != null )
1322 {
1323 return XmlUtils.getElementText( faultCode );
1324 }
1325 }
1326 catch( XmlException e )
1327 {
1328 e.printStackTrace();
1329 log.warn( e.toString() );
1330 }
1331 return null;
1332 }
1333
1334 public static String getTargetNamespace( Definition definition )
1335 {
1336 return definition.getTargetNamespace() == null ? XMLConstants.NULL_NS_URI : definition.getTargetNamespace();
1337 }
1338 }