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