View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2007 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of version 2.1 of the GNU Lesser General Public License as published by 
6    *  the Free Software Foundation.
7    *
8    *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
9    *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
10   *  See the GNU Lesser General Public License for more details at gnu.org.
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.BindingOperation;
26  import javax.wsdl.BindingOutput;
27  import javax.wsdl.Definition;
28  import javax.wsdl.Fault;
29  import javax.wsdl.Message;
30  import javax.wsdl.Operation;
31  import javax.wsdl.Part;
32  import javax.wsdl.Port;
33  import javax.wsdl.Service;
34  import javax.wsdl.WSDLException;
35  import javax.wsdl.extensions.ExtensibilityElement;
36  import javax.wsdl.extensions.ExtensionDeserializer;
37  import javax.wsdl.extensions.ExtensionRegistry;
38  import javax.wsdl.extensions.mime.MIMEContent;
39  import javax.wsdl.extensions.mime.MIMEMultipartRelated;
40  import javax.wsdl.extensions.mime.MIMEPart;
41  import javax.wsdl.extensions.soap.SOAPAddress;
42  import javax.wsdl.extensions.soap.SOAPBinding;
43  import javax.wsdl.extensions.soap.SOAPBody;
44  import javax.wsdl.extensions.soap.SOAPFault;
45  import javax.wsdl.extensions.soap.SOAPHeader;
46  import javax.wsdl.extensions.soap.SOAPOperation;
47  import javax.wsdl.extensions.soap12.SOAP12Address;
48  import javax.wsdl.extensions.soap12.SOAP12Binding;
49  import javax.wsdl.extensions.soap12.SOAP12Body;
50  import javax.wsdl.extensions.soap12.SOAP12Fault;
51  import javax.wsdl.extensions.soap12.SOAP12Header;
52  import javax.wsdl.extensions.soap12.SOAP12Operation;
53  import javax.wsdl.factory.WSDLFactory;
54  import javax.wsdl.xml.WSDLReader;
55  import javax.xml.namespace.QName;
56  
57  import org.apache.log4j.Logger;
58  import org.apache.xmlbeans.SchemaGlobalElement;
59  import org.apache.xmlbeans.SchemaType;
60  import org.apache.xmlbeans.XmlObject;
61  import org.w3c.dom.Element;
62  import org.xml.sax.InputSource;
63  
64  import com.eviware.soapui.impl.wsdl.WsdlRequest;
65  import com.eviware.soapui.model.iface.Interface;
66  import com.ibm.wsdl.util.xml.QNameUtils;
67  import com.ibm.wsdl.xml.WSDLReaderImpl;
68  import com.ibm.wsdl.xml.WSDLWriterImpl;
69  
70  /***
71   * Wsdl-related tools
72   * 
73   * @author Ole.Matzura
74   */
75  
76  public class WsdlUtils
77  {
78  	private final static Logger log = Logger.getLogger( WsdlUtils.class );
79  	private static WSDLReader wsdlReader;
80  
81  	public static <T extends ExtensibilityElement> T getExtensiblityElement( List list, Class<T> clazz )
82  	{
83  		List<T> elements = getExtensiblityElements( list, clazz );
84  		return elements.isEmpty() ? null : elements.get( 0 );
85  	}
86  
87  	public static <T extends ExtensibilityElement> List<T> getExtensiblityElements( List list, Class<T> clazz )
88  	{
89  		List<T> result = new ArrayList<T>();
90  
91  		for( Iterator<T> i = list.iterator(); i.hasNext(); )
92  		{
93  			T elm = i.next();
94  			if( clazz.isAssignableFrom( elm.getClass() ) )
95  			{
96  				result.add( elm );
97  			}
98  		}
99  
100 		return result;
101 	}
102 
103 	public static String getSoapAction( BindingOperation operation )
104 	{
105 		List list = operation.getExtensibilityElements();
106 		SOAPOperation soapOperation = WsdlUtils.getExtensiblityElement( list, SOAPOperation.class );
107 		if( soapOperation != null )
108 			return soapOperation.getSoapActionURI();
109 
110 		SOAP12Operation soap12Operation = WsdlUtils.getExtensiblityElement( list, SOAP12Operation.class );
111 		if( soap12Operation != null )
112 			return soap12Operation.getSoapActionURI();
113 
114 		return null;
115 	}
116 
117 	public static String[] getEndpointsForBinding( Definition definition, Binding binding )
118 	{
119 		List<String> result = new ArrayList<String>();
120 		Map map = definition.getAllServices();
121 		for( Iterator i = map.values().iterator(); i.hasNext(); )
122 		{
123 			Service service = ( Service ) i.next();
124 			Map portMap = service.getPorts();
125 			for( Iterator i2 = portMap.values().iterator(); i2.hasNext(); )
126 			{
127 				Port port = ( Port ) i2.next();
128 				if( port.getBinding() == binding )
129 				{
130 					String endpoint = WsdlUtils.getSoapEndpoint( port );
131 					if( endpoint != null )
132 						result.add( endpoint );
133 				}
134 			}
135 		}
136 
137 		return result.toArray( new String[result.size()] );
138 	}
139 
140 	public static Binding findBindingForOperation( Definition definition, BindingOperation bindingOperation )
141 	{
142 		Map services = definition.getAllServices();
143 		Iterator<Service> s = services.values().iterator();
144 
145 		while( s.hasNext() )
146 		{
147 			Map ports = s.next().getPorts();
148 			Iterator<Port> p = ports.values().iterator();
149 			while( p.hasNext() )
150 			{
151 				Binding binding = p.next().getBinding();
152 				List bindingOperations = binding.getBindingOperations();
153 				for( Iterator iter = bindingOperations.iterator(); iter.hasNext(); )
154 				{
155 					BindingOperation op = ( BindingOperation ) iter.next();
156 					if( op.getName().equals( bindingOperation.getName() ) )
157 						return binding;
158 				}
159 			}
160 		}
161 
162 		Map bindings = definition.getAllBindings();
163 		Iterator<QName> names = bindings.keySet().iterator();
164 		while( names.hasNext() )
165 		{
166 			Binding binding = definition.getBinding( names.next() );
167 			List bindingOperations = binding.getBindingOperations();
168 			for( Iterator iter = bindingOperations.iterator(); iter.hasNext(); )
169 			{
170 				BindingOperation op = ( BindingOperation ) iter.next();
171 				if( op.getName().equals( bindingOperation.getName() ) )
172 					return binding;
173 			}
174 		}
175 
176 		return null;
177 	}
178 
179 	public static BindingOperation findBindingOperation( Definition definition, String operationName )
180 	{
181 		Map services = definition.getAllServices();
182 		for( Iterator i = services.keySet().iterator(); i.hasNext(); )
183 		{
184 			QName qName = ( QName ) i.next();
185 			Service service = definition.getService( qName );
186 			Map ports = service.getPorts();
187 
188 			for( Iterator iterator = ports.keySet().iterator(); iterator.hasNext(); )
189 			{
190 				String key = ( String ) iterator.next();
191 				Port port = service.getPort( key );
192 				BindingOperation bindingOperation = port.getBinding().getBindingOperation( operationName, null, null );
193 				if( bindingOperation != null )
194 					return bindingOperation;
195 			}
196 		}
197 
198 		Map bindings = definition.getAllBindings();
199 		for( Iterator i = bindings.keySet().iterator(); i.hasNext(); )
200 		{
201 			Object key = i.next();
202 			Binding binding = ( Binding ) bindings.get( key );
203 			BindingOperation bindingOperation = binding.getBindingOperation( operationName, null, null );
204 			if( bindingOperation != null )
205 				return bindingOperation;
206 		}
207 
208 		return null;
209 	}
210 
211 	public static boolean isInputSoapEncoded( BindingOperation bindingOperation )
212 	{
213 		SOAPBody soapBody = WsdlUtils.getExtensiblityElement( bindingOperation.getBindingInput()
214 					.getExtensibilityElements(), SOAPBody.class );
215 
216 		if( soapBody != null )
217 		{
218 			return soapBody.getUse() != null
219 						&& soapBody.getUse().equalsIgnoreCase( "encoded" )
220 						&& ( soapBody.getEncodingStyles() == null || soapBody.getEncodingStyles().contains(
221 									"http://schemas.xmlsoap.org/soap/encoding/" ) );
222 		}
223 
224 		SOAP12Body soap12Body = WsdlUtils.getExtensiblityElement( bindingOperation.getBindingInput()
225 					.getExtensibilityElements(), SOAP12Body.class );
226 
227 		if( soap12Body != null )
228 		{
229 			return soap12Body.getUse() != null
230 						&& soap12Body.getUse().equalsIgnoreCase( "encoded" )
231 						&& ( soap12Body.getEncodingStyle() == null || soap12Body.getEncodingStyle().equals(
232 									"http://schemas.xmlsoap.org/soap/encoding/" ) );
233 		}
234 
235 		return false;
236 	}
237 
238 	public static boolean isOutputSoapEncoded( BindingOperation bindingOperation )
239 	{
240 		BindingOutput bindingOutput = bindingOperation.getBindingOutput();
241 		if( bindingOutput == null )
242 			return false;
243 
244 		SOAPBody soapBody = WsdlUtils.getExtensiblityElement( bindingOutput.getExtensibilityElements(), SOAPBody.class );
245 
246 		if( soapBody != null )
247 		{
248 			return soapBody.getUse() != null
249 						&& soapBody.getUse().equalsIgnoreCase( "encoded" )
250 						&& ( soapBody.getEncodingStyles() == null || soapBody.getEncodingStyles().contains(
251 									"http://schemas.xmlsoap.org/soap/encoding/" ) );
252 		}
253 
254 		SOAP12Body soap12Body = WsdlUtils.getExtensiblityElement( bindingOutput.getExtensibilityElements(),
255 					SOAP12Body.class );
256 
257 		if( soap12Body != null )
258 		{
259 			return soap12Body.getUse() != null
260 						&& soap12Body.getUse().equalsIgnoreCase( "encoded" )
261 						&& ( soap12Body.getEncodingStyle() == null || soap12Body.getEncodingStyle().equals(
262 									"http://schemas.xmlsoap.org/soap/encoding/" ) );
263 		}
264 
265 		return false;
266 	}
267 
268 	public static boolean isRpc( Definition definition, BindingOperation bindingOperation )
269 	{
270 		SOAPOperation soapOperation = WsdlUtils.getExtensiblityElement( bindingOperation.getExtensibilityElements(),
271 					SOAPOperation.class );
272 
273 		if( soapOperation != null && soapOperation.getStyle() != null )
274 			return soapOperation.getStyle().equalsIgnoreCase( "rpc" );
275 
276 		SOAP12Operation soap12Operation = WsdlUtils.getExtensiblityElement( bindingOperation.getExtensibilityElements(),
277 					SOAP12Operation.class );
278 
279 		if( soap12Operation != null && soap12Operation.getStyle() != null )
280 			return soap12Operation.getStyle().equalsIgnoreCase( "rpc" );
281 
282 		Binding binding = findBindingForOperation( definition, bindingOperation );
283 		if( binding == null )
284 		{
285 			log.error( "Failed to find binding for operation [" + bindingOperation.getName() + "] in definition ["
286 						+ definition.getDocumentBaseURI() + "]" );
287 			return false;
288 		}
289 
290 		return isRpc( binding );
291 	}
292 
293 	public static boolean isRpc( Binding binding )
294 	{
295 		SOAPBinding soapBinding = WsdlUtils
296 					.getExtensiblityElement( binding.getExtensibilityElements(), SOAPBinding.class );
297 
298 		if( soapBinding != null )
299 			return "rpc".equalsIgnoreCase( soapBinding.getStyle() );
300 
301 		SOAP12Binding soap12Binding = WsdlUtils.getExtensiblityElement( binding.getExtensibilityElements(),
302 					SOAP12Binding.class );
303 
304 		if( soap12Binding != null )
305 			return "rpc".equalsIgnoreCase( soap12Binding.getStyle() );
306 
307 		return false;
308 	}
309 
310 	/***
311 	 * Returns a list of parts for the specifed operation, either as specified in
312 	 * body or all
313 	 */
314 
315 	public static Part[] getInputParts( BindingOperation operation )
316 	{
317 		List<Part> result = new ArrayList<Part>();
318 		Message msg = operation.getOperation().getInput().getMessage();
319 		SOAPBody soapBody = WsdlUtils.getExtensiblityElement( operation.getBindingInput().getExtensibilityElements(),
320 					SOAPBody.class );
321 
322 		if( soapBody == null || soapBody.getParts() == null )
323 		{
324 			SOAP12Body soap12Body = WsdlUtils.getExtensiblityElement( operation.getBindingInput()
325 						.getExtensibilityElements(), SOAP12Body.class );
326 
327 			if( soap12Body == null || soap12Body.getParts() == null )
328 			{
329 				if( msg != null )
330 					result.addAll( msg.getOrderedParts( null ) );
331 			}
332 			else
333 			{
334 				Iterator i = soap12Body.getParts().iterator();
335 				while( i.hasNext() )
336 				{
337 					String partName = ( String ) i.next();
338 					Part part = msg.getPart( partName );
339 
340 					result.add( part );
341 				}
342 			}
343 		}
344 		else
345 		{
346 			Iterator i = soapBody.getParts().iterator();
347 			while( i.hasNext() )
348 			{
349 				String partName = ( String ) i.next();
350 				Part part = msg.getPart( partName );
351 
352 				result.add( part );
353 			}
354 		}
355 
356 		return result.toArray( new Part[result.size()] );
357 	}
358 
359 	public static boolean isAttachmentInputPart( Part part, BindingOperation operation )
360 	{
361 		return getInputMultipartContent( part, operation ).length > 0;
362 	}
363 
364 	public static boolean isAttachmentOutputPart( Part part, BindingOperation operation )
365 	{
366 		return getOutputMultipartContent( part, operation ).length > 0;
367 	}
368 
369 	public static MIMEContent[] getOutputMultipartContent( Part part, BindingOperation operation )
370 	{
371 		MIMEMultipartRelated multipartOutput = WsdlUtils.getExtensiblityElement( operation.getBindingOutput()
372 					.getExtensibilityElements(), MIMEMultipartRelated.class );
373 
374 		return getContentParts( part, multipartOutput );
375 	}
376 
377 	public static MIMEContent[] getInputMultipartContent( Part part, BindingOperation operation )
378 	{
379 		MIMEMultipartRelated multipartInput = WsdlUtils.getExtensiblityElement( operation.getBindingInput()
380 					.getExtensibilityElements(), MIMEMultipartRelated.class );
381 
382 		return getContentParts( part, multipartInput );
383 	}
384 
385 	public static MIMEContent[] getContentParts( Part part, MIMEMultipartRelated multipart )
386 	{
387 		List<MIMEContent> result = new ArrayList<MIMEContent>();
388 
389 		if( multipart != null )
390 		{
391 			List<MIMEPart> parts = multipart.getMIMEParts();
392 
393 			for( int c = 0; c < parts.size(); c++ )
394 			{
395 				List<MIMEContent> contentParts = WsdlUtils.getExtensiblityElements( parts.get( c )
396 							.getExtensibilityElements(), MIMEContent.class );
397 
398 				for( MIMEContent content : contentParts )
399 				{
400 					if( content.getPart().equals( part.getName() ) )
401 						result.add( content );
402 				}
403 			}
404 		}
405 
406 		return result.toArray( new MIMEContent[result.size()] );
407 	}
408 
409 	public static Part[] getFaultParts( BindingOperation bindingOperation, String faultName ) throws Exception
410 	{
411 		List<Part> result = new ArrayList<Part>();
412 
413 		BindingFault bindingFault = bindingOperation.getBindingFault( faultName );
414 		SOAPFault soapFault = WsdlUtils.getExtensiblityElement( bindingFault.getExtensibilityElements(), SOAPFault.class );
415 
416 		Operation operation = bindingOperation.getOperation();
417 		if( soapFault != null && soapFault.getName() != null )
418 		{
419 			Fault fault = operation.getFault( soapFault.getName() );
420 			if( fault == null )
421 				throw new Exception( "Missing Fault [" + soapFault.getName() + "] in operation [" + operation.getName()
422 							+ "]" );
423 			result.addAll( fault.getMessage().getOrderedParts( null ) );
424 		}
425 		else
426 		{
427 			SOAP12Fault soap12Fault = WsdlUtils.getExtensiblityElement( bindingFault.getExtensibilityElements(),
428 						SOAP12Fault.class );
429 
430 			if( soap12Fault != null && soap12Fault.getName() != null )
431 			{
432 				result.addAll( operation.getFault( soap12Fault.getName() ).getMessage().getOrderedParts( null ) );
433 			}
434 			else
435 			{
436 				result.addAll( operation.getFault( faultName ).getMessage().getOrderedParts( null ) );
437 			}
438 		}
439 
440 		return result.toArray( new Part[result.size()] );
441 	}
442 
443 	public static String findSoapFaultPartName( WsdlContext wsdlContext, BindingOperation bindingOperation,
444 				String message ) throws Exception
445 	{
446 		if( WsdlUtils.isOutputSoapEncoded( bindingOperation ) )
447 			throw new Exception( "SOAP-Encoded messages not supported" );
448 
449 		XmlObject xml = XmlObject.Factory.parse( message );
450 		XmlObject[] msgPaths = xml.selectPath( "declare namespace env='"
451 					+ wsdlContext.getSoapVersion().getEnvelopeNamespace() + "';" + "$this/env:Envelope/env:Body/env:Fault" );
452 		if( msgPaths.length == 0 )
453 			return null;
454 
455 		XmlObject msgXml = msgPaths[0];
456 
457 		Map faults = bindingOperation.getBindingFaults();
458 		for( Iterator<BindingFault> i = faults.values().iterator(); i.hasNext(); )
459 		{
460 			BindingFault bindingFault = i.next();
461 			String faultName = bindingFault.getName();
462 			Part[] faultParts = WsdlUtils.getFaultParts( bindingOperation, faultName );
463 			Part part = faultParts[0];
464 
465 			QName elementName = part.getElementName();
466 			if( elementName != null )
467 			{
468 				XmlObject[] faultPaths = msgXml.selectPath( "declare namespace env='"
469 							+ wsdlContext.getSoapVersion().getEnvelopeNamespace() + "';" + "declare namespace ns='"
470 							+ elementName.getNamespaceURI() + "';" + "//env:Fault/detail/ns:" + elementName.getLocalPart() );
471 
472 				if( faultPaths.length == 1 )
473 					return faultName;
474 			}
475 			// this is not allowed by Basic Profile.. remove?
476 			else if( part.getTypeName() != null )
477 			{
478 				QName typeName = part.getTypeName();
479 				XmlObject[] faultPaths = msgXml.selectPath( "declare namespace env='"
480 							+ wsdlContext.getSoapVersion().getEnvelopeNamespace() + "';" + "declare namespace ns='"
481 							+ typeName.getNamespaceURI() + "';" + "//env:Fault/detail/ns:" + part.getName() );
482 
483 				if( faultPaths.length == 1 )
484 					return faultName;
485 			}
486 		}
487 
488 		return null;
489 	}
490 
491 	public static Part[] getOutputParts( BindingOperation operation )
492 	{
493 		BindingOutput bindingOutput = operation.getBindingOutput();
494 		if( bindingOutput == null )
495 			return new Part[0];
496 
497 		List<Part> result = new ArrayList<Part>();
498 		Message msg = operation.getOperation().getOutput().getMessage();
499 		SOAPBody soapBody = WsdlUtils.getExtensiblityElement( bindingOutput.getExtensibilityElements(), SOAPBody.class );
500 
501 		if( soapBody == null || soapBody.getParts() == null )
502 		{
503 			SOAP12Body soap12Body = WsdlUtils.getExtensiblityElement( bindingOutput.getExtensibilityElements(),
504 						SOAP12Body.class );
505 
506 			if( soap12Body == null || soap12Body.getParts() == null )
507 			{
508 				result.addAll( msg.getOrderedParts( null ) );
509 			}
510 			else
511 			{
512 				Iterator i = soap12Body.getParts().iterator();
513 				while( i.hasNext() )
514 				{
515 					String partName = ( String ) i.next();
516 					Part part = msg.getPart( partName );
517 
518 					result.add( part );
519 				}
520 			}
521 		}
522 		else
523 		{
524 			Iterator i = soapBody.getParts().iterator();
525 			while( i.hasNext() )
526 			{
527 				String partName = ( String ) i.next();
528 				Part part = msg.getPart( partName );
529 
530 				result.add( part );
531 			}
532 		}
533 
534 		return result.toArray( new Part[result.size()] );
535 	}
536 
537 	public static boolean isMultipartRequest( Definition definition, BindingOperation bindingOperation )
538 	{
539 		return WsdlUtils.getExtensiblityElement( bindingOperation.getBindingInput().getExtensibilityElements(),
540 					MIMEMultipartRelated.class ) != null;
541 	}
542 
543 	public static String getSoapEndpoint( Port port )
544 	{
545 		SOAPAddress soapAddress = WsdlUtils.getExtensiblityElement( port.getExtensibilityElements(), SOAPAddress.class );
546 		if( soapAddress != null )
547 			try
548 			{
549 				return URLDecoder.decode( soapAddress.getLocationURI(), "UTF-8" );
550 			}
551 			catch( UnsupportedEncodingException e )
552 			{
553 				e.printStackTrace();
554 				return soapAddress.getLocationURI();
555 			}
556 
557 		SOAP12Address soap12Address = WsdlUtils.getExtensiblityElement( port.getExtensibilityElements(),
558 					SOAP12Address.class );
559 		if( soap12Address != null )
560 			try
561 			{
562 				return URLDecoder.decode( soap12Address.getLocationURI(), "UTF-8" );
563 			}
564 			catch( UnsupportedEncodingException e )
565 			{
566 				e.printStackTrace();
567 				return soap12Address.getLocationURI();
568 			}
569 
570 		return null;
571 	}
572 
573 	public static void setSoapEndpoint( Port port, String endpoint )
574 	{
575 		SOAPAddress soapAddress = WsdlUtils.getExtensiblityElement( port.getExtensibilityElements(), SOAPAddress.class );
576 		if( soapAddress != null )
577 			soapAddress.setLocationURI( endpoint );
578 
579 		SOAP12Address soap12Address = WsdlUtils.getExtensiblityElement( port.getExtensibilityElements(),
580 					SOAP12Address.class );
581 		if( soap12Address != null )
582 			soap12Address.setLocationURI( endpoint );
583 	}
584 
585 	public static String getSoapBodyNamespace( List list )
586 	{
587 		SOAPBody soapBody = WsdlUtils.getExtensiblityElement( list, SOAPBody.class );
588 		if( soapBody != null )
589 			return soapBody.getNamespaceURI();
590 
591 		SOAP12Body soap12Body = WsdlUtils.getExtensiblityElement( list, SOAP12Body.class );
592 		if( soap12Body != null )
593 			return soap12Body.getNamespaceURI();
594 
595 		return null;
596 	}
597 
598 	public static final class NonSchemaImportingWsdlReaderImpl extends WSDLReaderImpl
599 	{
600 		@Override
601 		protected ExtensibilityElement parseSchema( Class parentType, Element el, Definition def, ExtensionRegistry extReg )
602 					throws WSDLException
603 		{
604 			QName elementType = QNameUtils.newQName( el );
605 
606 			ExtensionDeserializer exDS = extReg.queryDeserializer( parentType, elementType );
607 
608 			// Now unmarshall the DOM element.
609 			ExtensibilityElement ee = exDS.unmarshall( parentType, elementType, el, def, extReg );
610 
611 			return ee;
612 		}
613 
614 	}
615 
616 	/***
617 	 * A SOAP-Header wrapper
618 	 * 
619 	 * @author ole.matzura
620 	 */
621 
622 	public interface SoapHeader
623 	{
624 		public QName getMessage();
625 
626 		public String getPart();
627 	}
628 
629 	/***
630 	 * SOAP 1.1 Header implementation
631 	 * 
632 	 * @author ole.matzura
633 	 */
634 
635 	public static class Soap11Header implements SoapHeader
636 	{
637 		private final SOAPHeader soapHeader;
638 
639 		public Soap11Header( SOAPHeader soapHeader )
640 		{
641 			this.soapHeader = soapHeader;
642 		}
643 
644 		public QName getMessage()
645 		{
646 			return soapHeader.getMessage();
647 		}
648 
649 		public String getPart()
650 		{
651 			return soapHeader.getPart();
652 		}
653 	}
654 
655 	/***
656 	 * SOAP 1.2 Header implementation
657 	 * 
658 	 * @author ole.matzura
659 	 */
660 
661 	public static class Soap12Header implements SoapHeader
662 	{
663 		private final SOAP12Header soapHeader;
664 
665 		public Soap12Header( SOAP12Header soapHeader )
666 		{
667 			this.soapHeader = soapHeader;
668 		}
669 
670 		public QName getMessage()
671 		{
672 			return soapHeader.getMessage();
673 		}
674 
675 		public String getPart()
676 		{
677 			return soapHeader.getPart();
678 		}
679 	}
680 
681 	public static List<SoapHeader> getSoapHeaders( List list )
682 	{
683 		List<SoapHeader> result = new ArrayList<SoapHeader>();
684 
685 		List<SOAPHeader> soapHeaders = WsdlUtils.getExtensiblityElements( list, SOAPHeader.class );
686 		if( soapHeaders != null && !soapHeaders.isEmpty() )
687 		{
688 			for( SOAPHeader header : soapHeaders )
689 				result.add( new Soap11Header( header ) );
690 		}
691 		else
692 		{
693 			List<SOAP12Header> soap12Headers = WsdlUtils.getExtensiblityElements( list, SOAP12Header.class );
694 			if( soap12Headers != null && !soap12Headers.isEmpty() )
695 			{
696 				for( SOAP12Header header : soap12Headers )
697 					result.add( new Soap12Header( header ) );
698 			}
699 		}
700 
701 		return result;
702 	}
703 
704 	public static synchronized Definition readDefinition( String wsdlUrl ) throws Exception
705 	{
706 		if( wsdlReader == null )
707 		{
708 			WSDLFactory factory = WSDLFactory.newInstance();
709 			wsdlReader = factory.newWSDLReader();
710 			wsdlReader.setFeature( "javax.wsdl.verbose", true );
711 			wsdlReader.setFeature( "javax.wsdl.importDocuments", true );
712 		}
713 
714 		return wsdlReader.readWSDL( new UrlWsdlLoader( wsdlUrl ) );
715 	}
716 
717 	public static SchemaType getSchemaTypeForPart( WsdlContext wsdlContext, javax.wsdl.Part part ) throws Exception
718 	{
719 		SchemaType schemaType = null;
720 		QName elementName = part.getElementName();
721 
722 		if( elementName != null )
723 		{
724 			SchemaGlobalElement elm = wsdlContext.getSchemaTypeLoader().findElement( elementName );
725 			if( elm != null )
726 			{
727 				schemaType = elm.getType();
728 			}
729 			else
730 				WsdlRequest.log.error( "Could not find element [" + elementName + "] specified in part [" + part.getName()
731 							+ "]" );
732 		}
733 		else
734 		{
735 			QName typeName = part.getTypeName();
736 
737 			if( typeName != null )
738 			{
739 				schemaType = wsdlContext.getSchemaTypeLoader().findType( typeName );
740 
741 				if( schemaType == null )
742 				{
743 					WsdlRequest.log.error( "Could not find type [" + typeName + "] specified in part [" + part.getName()
744 								+ "]" );
745 				}
746 			}
747 		}
748 		return schemaType;
749 	}
750 
751 	public static SchemaGlobalElement getSchemaElementForPart( WsdlContext wsdlContext, javax.wsdl.Part part )
752 				throws Exception
753 	{
754 		QName elementName = part.getElementName();
755 
756 		if( elementName != null )
757 		{
758 			return wsdlContext.getSchemaTypeLoader().findElement( elementName );
759 		}
760 
761 		return null;
762 	}
763 
764 	public static String replacePortEndpoint( Interface iface, InputSource inputSource, String endpoint )
765 				throws WSDLException
766 	{
767 		WSDLReader wsdlReader = new NonSchemaImportingWsdlReaderImpl();
768 
769 		wsdlReader.setFeature( "javax.wsdl.verbose", true );
770 		wsdlReader.setFeature( "javax.wsdl.importDocuments", false );
771 
772 		Definition definition = wsdlReader.readWSDL( null, inputSource );
773 
774 		boolean updated = false;
775 		Map map = definition.getServices();
776 		for( Iterator i = map.values().iterator(); i.hasNext(); )
777 		{
778 			Service service = ( Service ) i.next();
779 			Map portMap = service.getPorts();
780 			for( Iterator i2 = portMap.values().iterator(); i2.hasNext(); )
781 			{
782 				Port port = ( Port ) i2.next();
783 				if( port.getBinding().getQName().equals( iface.getBindingName() ) )
784 				{
785 					setSoapEndpoint( port, endpoint );
786 					updated = true;
787 				}
788 			}
789 		}
790 
791 		if( updated )
792 		{
793 			StringWriter writer = new StringWriter();
794 			new WSDLWriterImpl().writeWSDL( definition, writer );
795 			return writer.toString();
796 		}
797 
798 		return null;
799 	}
800 
801 	public static BindingOperation findBindingOperation( Binding binding, String bindingOperationName, String inputName, String outputName )
802 	{
803 		if( binding == null )
804 	      return null;
805 	   
806 	   if( inputName == null )
807 	      inputName = ":none";
808 	   
809 	   if( outputName == null )
810 	      outputName = ":none";
811 	   
812 	   BindingOperation result = binding.getBindingOperation( bindingOperationName, inputName, outputName );
813 	
814 	   if( result == null && (inputName.equals( ":none" ) || outputName.equals( ":none" )))
815 	   {
816 	      // fall back to this behaviour for WSDL4j 1.5.0 compatibility
817 	      result = binding.getBindingOperation( bindingOperationName, 
818 	               inputName.equals( ":none" ) ? null : inputName, outputName.equals( ":none" ) ? null : outputName ); 
819 	   }
820 	   return result;
821 	}
822 
823 	public static boolean isHeaderInputPart( Part part, Message message, BindingOperation bindingOperation )
824 	{
825 		List<SOAPHeader> headers = WsdlUtils.getExtensiblityElements( 
826 					bindingOperation.getBindingInput().getExtensibilityElements(), SOAPHeader.class );
827 		
828 		if( headers == null || headers.isEmpty() )
829 			return false;
830 		
831 		for( SOAPHeader header : headers )
832 		{
833 			if( message.getQName().equals( header.getMessage() ) &&
834 				 part.getName().equals( header.getPart() ))
835 				return true;
836 		}
837 		
838 		return false;
839 	}
840 }