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