View Javadoc

1   /*
2    *  soapUI, copyright (C) 2006 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of the GNU Lesser General Public License as published by the Free Software Foundation; 
6    *  either version 2.1 of the License, or (at your option) any later version.
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.util.ArrayList;
16  import java.util.Iterator;
17  import java.util.List;
18  import java.util.Map;
19  
20  import javax.wsdl.Binding;
21  import javax.wsdl.BindingFault;
22  import javax.wsdl.BindingOperation;
23  import javax.wsdl.BindingOutput;
24  import javax.wsdl.Definition;
25  import javax.wsdl.Message;
26  import javax.wsdl.Part;
27  import javax.wsdl.Port;
28  import javax.wsdl.Service;
29  import javax.wsdl.extensions.ExtensibilityElement;
30  import javax.wsdl.extensions.mime.MIMEContent;
31  import javax.wsdl.extensions.mime.MIMEMultipartRelated;
32  import javax.wsdl.extensions.mime.MIMEPart;
33  import javax.wsdl.extensions.soap.SOAPAddress;
34  import javax.wsdl.extensions.soap.SOAPBinding;
35  import javax.wsdl.extensions.soap.SOAPBody;
36  import javax.wsdl.extensions.soap.SOAPFault;
37  import javax.wsdl.extensions.soap.SOAPHeader;
38  import javax.wsdl.extensions.soap.SOAPOperation;
39  import javax.wsdl.extensions.soap12.SOAP12Address;
40  import javax.wsdl.extensions.soap12.SOAP12Binding;
41  import javax.wsdl.extensions.soap12.SOAP12Body;
42  import javax.wsdl.extensions.soap12.SOAP12Fault;
43  import javax.wsdl.extensions.soap12.SOAP12Header;
44  import javax.wsdl.extensions.soap12.SOAP12Operation;
45  import javax.xml.namespace.QName;
46  
47  import org.apache.log4j.Logger;
48  
49  /***
50   * Wsdl-related tools
51   * 
52   * @author Ole.Matzura
53   */
54  
55  public class WsdlUtils
56  {
57     private final static Logger log = Logger.getLogger( WsdlUtils.class );
58     
59     public static <T extends ExtensibilityElement> T getExtensiblityElement(List list, Class<T> clazz )
60     {
61        List<T> elements = getExtensiblityElements( list, clazz );
62        return elements.isEmpty() ? null : elements.get( 0 );
63     }
64     
65     public static <T extends ExtensibilityElement> List<T> getExtensiblityElements(List list, Class<T> clazz )
66     {
67        List<T> result = new ArrayList<T>();
68        
69        for( Iterator<T> i = list.iterator(); i.hasNext(); )
70        {
71           T elm = (T) i.next();
72           if( clazz.isAssignableFrom( elm.getClass() ) )
73           {
74              result.add( elm );
75           }
76        }
77  
78        return result;
79     }
80     
81     public static String getSoapAction(BindingOperation operation)
82     {
83        List list = operation.getExtensibilityElements();
84        SOAPOperation soapOperation = (SOAPOperation) WsdlUtils.getExtensiblityElement( list, SOAPOperation.class );
85        if( soapOperation != null )
86        	return soapOperation.getSoapActionURI();
87        
88        SOAP12Operation soap12Operation = (SOAP12Operation) WsdlUtils.getExtensiblityElement( list, SOAP12Operation.class );
89        if( soap12Operation != null )
90        	return soap12Operation.getSoapActionURI();
91        
92        return null;
93     }
94     
95     public static String[] getEndpointsForBinding(Definition definition, Binding binding)
96     {
97        List<String> result = new ArrayList<String>(); 
98        Map map = definition.getAllServices();
99        for( Iterator i = map.values().iterator(); i.hasNext(); )
100       {
101          Service service = (Service) i.next();
102          Map portMap = service.getPorts();
103          for( Iterator i2 = portMap.values().iterator(); i2.hasNext(); )
104          {
105             Port port = (Port) i2.next();
106             if( port.getBinding() == binding )
107             {
108             	String endpoint = WsdlUtils.getSoapEndpoint( port );
109             	if( endpoint != null )
110             		result.add( endpoint );
111             }
112          }
113       }
114       
115       return result.toArray( new String[result.size()]);
116    }
117    
118    public static Binding findBindingForOperation(Definition definition, BindingOperation bindingOperation)
119    {
120       Map services = definition.getAllServices();
121       Iterator<Service> s = services.values().iterator();
122       
123       while( s.hasNext())
124       {
125          Map ports = s.next().getPorts();
126          Iterator<Port> p = ports.values().iterator();
127          while( p.hasNext())
128          {
129             Binding binding = p.next().getBinding();
130             List bindingOperations = binding.getBindingOperations();
131             for (Iterator iter = bindingOperations.iterator(); iter.hasNext();)
132             {
133                BindingOperation op = (BindingOperation) iter.next();
134                if( op.getName().equals( bindingOperation.getName() ))
135                   return binding;
136             }
137          }
138       }
139       
140       Map bindings = definition.getAllBindings();
141       Iterator<QName> names = bindings.keySet().iterator();
142       while( names.hasNext() ) 
143       {
144       	Binding binding = definition.getBinding( names.next() );
145       	List bindingOperations = binding.getBindingOperations();
146          for (Iterator iter = bindingOperations.iterator(); iter.hasNext();)
147          {
148             BindingOperation op = (BindingOperation) iter.next();
149             if( op.getName().equals( bindingOperation.getName() ))
150                return binding;
151          }
152       }
153       
154       return null;
155    }
156    
157    public static boolean isInputSoapEncoded(BindingOperation bindingOperation)
158    {
159       SOAPBody soapBody = (SOAPBody) WsdlUtils.getExtensiblityElement(bindingOperation.getBindingInput()
160             .getExtensibilityElements(), SOAPBody.class);
161       
162       if( soapBody != null )
163       {
164       	return soapBody.getUse() != null && soapBody.getUse().equalsIgnoreCase( "encoded" ) &&
165       		(soapBody.getEncodingStyles() == null || soapBody.getEncodingStyles().contains( "http://schemas.xmlsoap.org/soap/encoding/" ));
166       }
167       
168       SOAP12Body soap12Body = (SOAP12Body) WsdlUtils.getExtensiblityElement(bindingOperation.getBindingInput()
169                .getExtensibilityElements(), SOAP12Body.class);
170          
171       if( soap12Body != null )
172       {
173       	return soap12Body.getUse() != null && soap12Body.getUse().equalsIgnoreCase( "encoded" ) &&
174       		(soap12Body.getEncodingStyle() == null || soap12Body.getEncodingStyle().equals( "http://schemas.xmlsoap.org/soap/encoding/" ));
175       }
176       
177       return false;
178    }
179    
180    public static boolean isOutputSoapEncoded(BindingOperation bindingOperation)
181    {
182       BindingOutput bindingOutput = bindingOperation.getBindingOutput();
183       if( bindingOutput == null )
184       	return false;
185       
186 		SOAPBody soapBody = (SOAPBody) WsdlUtils.getExtensiblityElement(bindingOutput
187             .getExtensibilityElements(), SOAPBody.class);
188       
189 		if( soapBody != null )
190 		{
191 			return soapBody.getUse() != null && soapBody.getUse().equalsIgnoreCase( "encoded" ) &&
192       		(soapBody.getEncodingStyles() == null || soapBody.getEncodingStyles().contains( "http://schemas.xmlsoap.org/soap/encoding/" ));
193 		}
194 		
195 		SOAP12Body soap12Body = (SOAP12Body) WsdlUtils.getExtensiblityElement(bindingOutput
196 	            .getExtensibilityElements(), SOAP12Body.class);
197 	      
198 		if( soap12Body != null )
199 		{
200 			return soap12Body.getUse() != null && soap12Body.getUse().equalsIgnoreCase( "encoded" ) &&
201       		(soap12Body.getEncodingStyle() == null || soap12Body.getEncodingStyle().equals( "http://schemas.xmlsoap.org/soap/encoding/" ));
202 		}
203 		
204 		return false;
205    }
206    
207    public static boolean isRpc(Definition definition, BindingOperation bindingOperation)
208    {
209       SOAPOperation soapOperation = (SOAPOperation) WsdlUtils.getExtensiblityElement( 
210             bindingOperation.getExtensibilityElements(), SOAPOperation.class );
211       
212       if( soapOperation != null && soapOperation.getStyle() != null )
213          return soapOperation.getStyle().equalsIgnoreCase("rpc");
214       
215       SOAP12Operation soap12Operation = (SOAP12Operation) WsdlUtils.getExtensiblityElement( 
216                bindingOperation.getExtensibilityElements(), SOAP12Operation.class );
217          
218       if( soap12Operation != null && soap12Operation.getStyle() != null )
219          return soap12Operation.getStyle().equalsIgnoreCase("rpc");
220       
221       Binding binding = findBindingForOperation( definition, bindingOperation );
222       if( binding == null ) 
223       {
224          log.error( "Failed to find binding for operation [" + bindingOperation.getName() + "] in definition [" + 
225                definition.getDocumentBaseURI() + "]" );
226          return false;
227       }
228       
229       return isRpc(binding);
230    }
231 
232 	public static boolean isRpc(Binding binding)
233 	{
234 		SOAPBinding soapBinding = (SOAPBinding) WsdlUtils.getExtensiblityElement( 
235             binding.getExtensibilityElements(), SOAPBinding.class );
236       
237 		if( soapBinding != null )
238 			return "rpc".equalsIgnoreCase( soapBinding.getStyle());
239 		
240 		SOAP12Binding soap12Binding = (SOAP12Binding) WsdlUtils.getExtensiblityElement( 
241 	            binding.getExtensibilityElements(), SOAP12Binding.class );
242 	      
243 		if( soap12Binding != null )
244 			return "rpc".equalsIgnoreCase( soap12Binding.getStyle());
245 		
246 		return false;
247 	}
248    
249    /***
250     * Returns a list of parts for the specifed operation, either as specified in body or all
251     */
252    
253    public static Part[] getInputParts(BindingOperation operation)
254    {
255       List<Part> result = new ArrayList<Part>();
256       Message msg = operation.getOperation().getInput().getMessage();
257       SOAPBody soapBody = (SOAPBody) WsdlUtils.getExtensiblityElement(operation.getBindingInput()
258             .getExtensibilityElements(), SOAPBody.class);
259 
260       if (soapBody == null || soapBody.getParts() == null)
261       {
262       	SOAP12Body soap12Body = (SOAP12Body) WsdlUtils.getExtensiblityElement(operation.getBindingInput()
263       	            .getExtensibilityElements(), SOAP12Body.class);
264       	
265       	if (soap12Body == null || soap12Body.getParts() == null)
266          {
267       		if( msg != null )
268       			result.addAll( msg.getOrderedParts( null ));
269          }
270       	else
271       	{
272       		Iterator i = soap12Body.getParts().iterator();
273             while (i.hasNext())
274             {
275                String partName = (String) i.next();
276                Part part = msg.getPart( partName );
277                
278                result.add(part);
279             }
280       	}
281       }
282       else
283       {
284          Iterator i = soapBody.getParts().iterator();
285          while (i.hasNext())
286          {
287             String partName = (String) i.next();
288             Part part = msg.getPart( partName );
289             
290             result.add(part);
291          }
292       }
293 
294       return result.toArray(new Part[result.size()]);
295    }
296    
297    public static boolean isAttachmentInputPart( Part part, BindingOperation operation )
298    {
299    	return getInputMultipartContent(part, operation).length > 0;
300    }
301    
302    public static boolean isAttachmentOutputPart( Part part, BindingOperation operation )
303    {
304    	return getOutputMultipartContent(part, operation).length > 0;
305    }
306 
307    public static MIMEContent[] getOutputMultipartContent( Part part, BindingOperation operation )
308    {
309    	MIMEMultipartRelated multipartOutput = (MIMEMultipartRelated) WsdlUtils.getExtensiblityElement( 
310       		operation.getBindingOutput().getExtensibilityElements(), MIMEMultipartRelated.class );
311    	
312    	return getContentParts(part, multipartOutput);
313    }
314    
315    public static MIMEContent[] getInputMultipartContent( Part part, BindingOperation operation )
316    {
317    	MIMEMultipartRelated multipartInput = (MIMEMultipartRelated) WsdlUtils.getExtensiblityElement( 
318       		operation.getBindingInput().getExtensibilityElements(), MIMEMultipartRelated.class );
319    	
320    	return getContentParts(part, multipartInput);
321    }
322    
323 	public static MIMEContent[] getContentParts(Part part, MIMEMultipartRelated multipart)
324 	{
325 		List<MIMEContent> result = new ArrayList<MIMEContent>();
326 		
327 		if( multipart != null )
328    	{
329    		List<MIMEPart> parts = multipart.getMIMEParts();
330 
331       	for( int c = 0; c < parts.size(); c++ )
332       	{
333 	      	List<MIMEContent> contentParts = WsdlUtils.getExtensiblityElements( parts.get(c).getExtensibilityElements(), MIMEContent.class );
334 	      	
335 	      	for( MIMEContent content : contentParts )
336 	      	{
337 	      		if( content.getPart().equals( part.getName() ))
338 	      		  result.add( content );
339 	      	}
340       	}
341    	}
342    	
343    	return result.toArray( new MIMEContent[result.size()] );
344 	}
345    
346    public static Part[] getFaultParts(BindingOperation bindingOperation, String faultName)
347    {
348       List<Part> result = new ArrayList<Part>();
349       
350       BindingFault bindingFault = bindingOperation.getBindingFault( faultName );
351       SOAPFault soapFault = (SOAPFault) WsdlUtils.getExtensiblityElement(bindingFault
352             .getExtensibilityElements(), SOAPFault.class);
353 
354       if (soapFault != null && soapFault.getName() != null )
355       {
356          result.addAll( bindingOperation.getOperation().getFault( soapFault.getName() ).getMessage().getOrderedParts( null ));
357       }
358       else
359       {
360       	SOAP12Fault soap12Fault = (SOAP12Fault) WsdlUtils.getExtensiblityElement(bindingFault
361                   .getExtensibilityElements(), SOAP12Fault.class);
362       	
363       	 if (soap12Fault != null && soap12Fault.getName() != null )
364           {
365              result.addAll( bindingOperation.getOperation().getFault( soap12Fault.getName() ).getMessage().getOrderedParts( null ));
366           }
367           else
368           {
369          	 result.addAll( bindingOperation.getOperation().getFault( faultName ).getMessage().getOrderedParts( null ));
370           }
371       }
372       
373       return result.toArray(new Part[result.size()]);
374    }
375    
376    public static Part[] getOutputParts(BindingOperation operation)
377    {
378    	BindingOutput bindingOutput = operation.getBindingOutput();
379    	if( bindingOutput == null )
380    		return new Part[0];
381    	
382       List<Part> result = new ArrayList<Part>();
383       Message msg = operation.getOperation().getOutput().getMessage();
384 		SOAPBody soapBody = (SOAPBody) WsdlUtils.getExtensiblityElement(bindingOutput
385             .getExtensibilityElements(), SOAPBody.class);
386 
387       if (soapBody == null || soapBody.getParts() == null)
388       {
389       	SOAP12Body soap12Body = (SOAP12Body) WsdlUtils.getExtensiblityElement(bindingOutput
390                   .getExtensibilityElements(), SOAP12Body.class);
391       	
392       	if(soap12Body == null || soap12Body.getParts() == null)
393       	{
394       		result.addAll( msg.getOrderedParts( null ));
395       	}
396       	else
397       	{
398       		Iterator i = soap12Body.getParts().iterator();
399             while (i.hasNext())
400             {
401                String partName = (String) i.next();
402                Part part = msg.getPart( partName );
403                
404                result.add(part);
405             }
406       	}
407       }
408       else
409       {
410          Iterator i = soapBody.getParts().iterator();
411          while (i.hasNext())
412          {
413             String partName = (String) i.next();
414             Part part = msg.getPart( partName );
415             
416             result.add(part);
417          }
418       }
419 
420       return result.toArray(new Part[result.size()]);
421    }
422 
423 	public static boolean isMultipartRequest(Definition definition, BindingOperation bindingOperation)
424 	{
425 		return (MIMEMultipartRelated) WsdlUtils.getExtensiblityElement(
426 					bindingOperation.getBindingInput().getExtensibilityElements(), MIMEMultipartRelated.class ) != null;
427 	}
428 
429 	public static String getSoapEndpoint( Port port )
430 	{
431 		SOAPAddress soapAddress = (SOAPAddress) WsdlUtils.getExtensiblityElement( port.getExtensibilityElements(), SOAPAddress.class );
432       if( soapAddress != null )
433       	return soapAddress.getLocationURI();
434       
435       SOAP12Address soap12Address = (SOAP12Address) WsdlUtils.getExtensiblityElement( port.getExtensibilityElements(), SOAP12Address.class );
436       if( soap12Address != null )
437       	return soap12Address.getLocationURI();
438       
439       return null;
440 	}
441 
442 	public static String getSoapBodyNamespace( List list )
443 	{
444 		SOAPBody soapBody = (SOAPBody) WsdlUtils.getExtensiblityElement( list, SOAPBody.class);
445 		if( soapBody != null )
446 			return soapBody.getNamespaceURI();
447 		
448 		SOAP12Body soap12Body = (SOAP12Body) WsdlUtils.getExtensiblityElement( list, SOAP12Body.class);
449 		if( soap12Body != null )
450 			return soap12Body.getNamespaceURI();
451 	      
452 		return null;
453 	}
454 	
455 	public interface SoapHeader
456 	{
457 		public QName getMessage();
458 		
459 		public String getPart();
460 	}
461 	
462 	public static class Soap11Header implements SoapHeader
463 	{
464 		private final SOAPHeader soapHeader;
465 
466 		public Soap11Header( SOAPHeader soapHeader )
467 		{
468 			this.soapHeader = soapHeader;}
469 		
470 		public QName getMessage()
471 		{
472 			return soapHeader.getMessage();
473 		}
474 
475 		public String getPart()
476 		{
477 			return soapHeader.getPart();
478 		}
479 	}
480 	
481 	public static class Soap12Header implements SoapHeader
482 	{
483 		private final SOAP12Header soapHeader;
484 
485 		public Soap12Header( SOAP12Header soapHeader )
486 		{
487 			this.soapHeader = soapHeader;}
488 		
489 		public QName getMessage()
490 		{
491 			return soapHeader.getMessage();
492 		}
493 
494 		public String getPart()
495 		{
496 			return soapHeader.getPart();
497 		}
498 	}
499 
500 	public static List<SoapHeader> getSoapHeaders( List list )
501 	{
502 		List<SoapHeader> result = new ArrayList<SoapHeader>();
503 		
504 		List<SOAPHeader> soapHeaders = WsdlUtils.getExtensiblityElements( list, SOAPHeader.class);
505 		if( soapHeaders != null && !soapHeaders.isEmpty() )
506 		{
507 			for( SOAPHeader header : soapHeaders )
508 				result.add( new Soap11Header( header ));
509 		}
510 		else
511 		{
512 			List<SOAP12Header> soap12Headers = WsdlUtils.getExtensiblityElements( list, SOAP12Header.class);
513 			if( soap12Headers != null && !soap12Headers.isEmpty() )
514 			{
515 				for( SOAP12Header header : soap12Headers )
516 					result.add( new Soap12Header( header ));
517 			}
518 		}
519 		
520 		return result;
521 	}
522 }