View Javadoc

1    /****************************************************************************
2    * Copyright (c) 2005, 2006, 2007, 2008, 2009 Imola Informatica.
3    * All rights reserved. This program and the accompanying materials
4    * are made available under the terms of the LGPL License v2.1
5    * which accompanies this distribution, and is available at
6    * http://www.gnu.org/licenses/lgpl.html
7    ****************************************************************************/
8   package it.imolinfo.jbi4corba.jbi.cxf;
9   
10  import it.imolinfo.jbi4corba.Logger;
11  import it.imolinfo.jbi4corba.LoggerFactory;
12  import it.imolinfo.jbi4corba.exception.Jbi4CorbaException;
13  import it.imolinfo.jbi4corba.jbi.Messages;
14  
15  import java.io.IOException;
16  import java.io.OutputStream;
17  import java.util.ArrayList;
18  import java.util.Collection;
19  import java.util.List;
20  
21  import java.util.Map;
22  import javax.wsdl.Definition;
23  import javax.wsdl.WSDLException;
24  import javax.wsdl.factory.WSDLFactory;
25  import javax.wsdl.xml.WSDLWriter;
26  import javax.xml.namespace.QName;
27  
28  import org.apache.cxf.Bus;
29  import org.apache.cxf.BusException;
30  import org.apache.cxf.BusFactory;
31  import org.apache.cxf.binding.soap.SoapBindingConstants;
32  import org.apache.cxf.binding.soap.interceptor.RPCInInterceptor;
33  import org.apache.cxf.endpoint.Endpoint;
34  import org.apache.cxf.interceptor.BareInInterceptor;
35  import org.apache.cxf.interceptor.BareOutInterceptor;
36  import org.apache.cxf.interceptor.DocLiteralInInterceptor;
37  import org.apache.cxf.interceptor.FaultOutInterceptor;
38  import org.apache.cxf.interceptor.StaxInInterceptor;
39  import org.apache.cxf.interceptor.StaxOutInterceptor;
40  import org.apache.cxf.interceptor.WrappedInInterceptor;
41  import org.apache.cxf.interceptor.WrappedOutInterceptor;
42  import org.apache.cxf.jaxws.JaxWsClientFactoryBean;
43  import org.apache.cxf.jaxws.interceptors.HolderInInterceptor;
44  import org.apache.cxf.jaxws.interceptors.HolderOutInterceptor;
45  import org.apache.cxf.jaxws.interceptors.WrapperClassInInterceptor;
46  import org.apache.cxf.jaxws.interceptors.WrapperClassOutInterceptor;
47  import org.apache.cxf.phase.PhaseInterceptorChain;
48  import org.apache.cxf.service.Service;
49  import org.apache.cxf.service.factory.AbstractServiceConfiguration;
50  import org.apache.cxf.service.model.BindingOperationInfo;
51  import org.apache.cxf.service.model.EndpointInfo;
52  import org.apache.cxf.service.model.MessageInfo;
53  import org.apache.cxf.service.model.MessagePartInfo;
54  import org.apache.cxf.wsdl11.ServiceWSDLBuilder;
55  import org.w3c.dom.Document;
56  
57  /**
58   * Utility methods to manage CXF classes.
59   * @author <a href="mailto:mpiraccini@imolinfo.it">Marco Piraccini</a>s
60   */
61  public final class CXFUtils {
62      
63      private static Bus bus;
64     
65      /** The logger. */
66      private static final Logger LOG = 
67      	LoggerFactory.getLogger(CXFUtils.class);
68      
69      /** The messages. */
70      private static final Messages MESSAGES = 
71      	Messages.getMessages(CXFUtils.class);
72  
73            
74      public  static Bus setupBus() throws BusException {
75          
76          if (bus == null) {            
77              bus = createBus();
78          }
79          
80          return bus;
81      }
82      
83      /**
84       * The Bus can be null...
85       * @return
86       * @throws BusException
87       */
88      public static Bus getBus() {        
89          return bus;
90      }
91      
92      /**
93       * Creates the CXF "Bus".
94       */
95      protected static Bus createBus() throws BusException {     
96          Bus _bus = null;
97          // Get the classloader (to avoid OpenESB classloading problems)
98          ClassLoader threadClassLoader = Thread.currentThread().getContextClassLoader();
99          ClassLoader componentClassLoader = new CXFUtils().getClass().getClassLoader();
100                        
101         try {            
102             Thread.currentThread().setContextClassLoader(componentClassLoader);            
103             _bus = BusFactory.newInstance().createBus();
104             
105         } finally {
106             // Sets the thread classloader
107             Thread.currentThread().setContextClassLoader(threadClassLoader);
108         }
109               
110         return _bus;
111     }
112     /**
113      * Creates the CXF Service factory.
114      */
115     public static JaxWsClientFactoryBean getJaxWsClientFactoryBean() throws Jbi4CorbaException {        
116         if (bus == null) {
117             try {
118                 setupBus();
119             } catch (BusException bex) {
120             	String msg=MESSAGES.getString("CRB000900_Error_in_CXF_Bus_init");
121                 LOG.error(msg,bex);
122                 throw new Jbi4CorbaException(msg,bex);
123             }
124         }
125         JaxWsClientFactoryBean factory = new JaxWsClientFactoryBean();    
126         factory.setBus(bus);
127         
128         // Sets the configuration to force message part minOccurs/maxOccurs to 1
129         List<AbstractServiceConfiguration> customServiceConfigurations = 
130             new ArrayList<AbstractServiceConfiguration>();
131         customServiceConfigurations.add(new Jbi4CorbaServiceConfiguration());
132         factory.getServiceFactory().setServiceConfigurations(customServiceConfigurations);
133         
134         return factory;
135     }        
136                    
137     /**
138      * Gets the WSDL document.
139      * 
140      * @param service
141      * 
142      * @return the WSDL document
143      * 
144      * @throws WSDLException
145      */
146     protected static Document getWSDLDocument(Service service) throws WSDLException {                
147         ServiceWSDLBuilder wsdlBuilder = 
148             new ServiceWSDLBuilder(bus, service.getServiceInfos().get(0));
149         wsdlBuilder.setUseSchemaImports(true);
150         Definition definition = wsdlBuilder.build();
151         WSDLWriter writer = WSDLFactory.newInstance().newWSDLWriter();        
152         return writer.getDocument(definition);
153     }
154     
155     /**
156      * Gets the WSDL definition.
157      * 
158      * @param service
159      * 
160      * @return the WSDL definition
161      * 
162      * @throws WSDLException
163      */
164     public static Definition getWSDLDefinition(Service service) throws WSDLException {
165         LOG.debug("BUS: " + bus);
166         
167         ServiceWSDLBuilder wsdlBuilder = new ServiceWSDLBuilder(bus, service.getServiceInfos());
168         
169         Definition def = wsdlBuilder.build(); 
170         return def;
171     }
172 
173     /**
174      * Gets the Abstract WSDL Documents starting from Definition
175      *
176      * @param def
177      *
178      * @return the WSDL Document
179      *
180      * @throws WSDLException
181      */
182     public static Document  getAbstractWSDLDocument(Definition def) throws WSDLException {
183         WSDLWriter writer = WSDLFactory.newInstance().newWSDLWriter();
184 
185         Map services=def.getServices();
186         Map bindings=def.getBindings();
187         for (Object o:services.keySet()){
188             def.removeService((QName) o);
189         }
190 
191         for (Object o:bindings.keySet()){
192             def.removeBinding((QName)o);
193         }
194         return writer.getDocument(def);
195     }
196 
197     /**
198      * Gets the Abstract WSDL Documents starting from Service
199      *
200      * @param service
201      *
202      * @return the WSDL Document
203      *
204      * @throws WSDLException
205      */
206     public static Document getAbstractWSDLDocument(Service service) throws WSDLException {
207         
208         Definition def = getWSDLDefinition(service);
209         
210         return getAbstractWSDLDocument(def);
211 
212     }
213 
214     /**
215      * Writes out the service definition on the output stream 
216      * @param out
217      * @throws WSDLException 
218      */
219     public static void writeDefinitionOnOutputStream(Service service, OutputStream out) throws WSDLException {        
220         Definition def = getWSDLDefinition(service);
221         WSDLWriter wsdlWriter = WSDLFactory.newInstance().newWSDLWriter();
222         wsdlWriter.writeWSDL(def, out);        
223     }
224         
225     /**
226      * Gets THE FIRST ENDPOINT interface name.
227      * @param service
228      * @return
229      */
230     public static QName getInterfaceNameFromFirstEndpoint(Service service) {
231         Collection<Endpoint> serviceEndpoints = (service.getEndpoints()).values();
232         Endpoint endpoint = (Endpoint)serviceEndpoints.iterator().next();
233         QName interfaceName = endpoint.getEndpointInfo().getBinding().getInterface().getName();
234         return interfaceName;
235     }
236         
237     /**
238      * Gets the EndpointInfo for the FIRST (should be the only...) Endpoint.
239      * @param service
240      * @return
241      * @throws IOException
242      */
243     public static EndpointInfo getEndpointInfo(Service service) throws IOException {        
244         Collection<Endpoint> serviceEndpoints = (service.getEndpoints()).values();
245         LOG.debug("Endpoints of service: " + serviceEndpoints.size());
246         Endpoint endpoint = (Endpoint)serviceEndpoints.iterator().next();
247         EndpointInfo ei = endpoint.getEndpointInfo();        
248         return ei;
249     }       
250             
251     /**
252      * Gets the endpoint from service endpoint.
253      */
254     public static Endpoint getEndpoint(Service service, EndpointInfo ei) {
255         for(int i=0;i<service.getEndpoints().size();i++){
256             LOG.debug("ENP ==> "+service.getEndpoints().keySet().toArray()[i].toString());
257         }
258         return service.getEndpoints().get(ei.getName());        
259     }
260     
261     /**
262      * Return the correct binding style for the binding, Document o RPC.
263      * We don'thave  SOAP binding extensions, so we have to calculate that 
264      * from the message part. See Section 7 of the SOAP 1.1 specification.
265      * (notice that the WSDL is always Document/literal).
266      * @param bio
267      * @return <code>SoapBindingConstants.PARAMETER_STYLE_WRAPPED</code> or <code>SoapBindingConstants.PARAMETER_STYLE_BARE</code>
268      */
269     public static String getBindingStyle(BindingOperationInfo bio) {                	
270         String bindingStyle = SoapBindingConstants.BINDING_STYLE_DOC;     
271         if (bio.getOperationInfo() != null) {
272            MessageInfo mi = bio.getOperationInfo().getInput();
273             MessagePartInfo mpi = mi.getMessagePart(0);
274             // There
275             if ((mi.getMessageParts().size() != 1)  || 
276             	(!mpi.isElement()) ) {
277             	bindingStyle = SoapBindingConstants.BINDING_STYLE_RPC;        	
278             } 
279         }
280         return bindingStyle;
281     }    
282   	
283     /**
284      * This method creates the CXF OUT Interceptors chain and process the message.
285      * 
286      * @param parameterStyle
287      * @param bindingStyle
288      * @param isProviderOrConsumerFromIDL
289      */
290   	public static void populateOutInterceptors(PhaseInterceptorChain outInterceptorChain, 
291   			String parameterStyle, String bindingStyle, boolean isProviderOrConsumerFromIDL) {
292   	  		
293           outInterceptorChain.add(new StaxOutInterceptor());                                 
294           outInterceptorChain.add(new HolderOutInterceptor());
295        
296           if (isProviderOrConsumerFromIDL) {
297     		  // In the "from IDL" case the WSDL is always wrapped
298               // For Jax-ws
299               outInterceptorChain.add(new WrapperClassOutInterceptor());        	  
300         	  outInterceptorChain.add(new Jbi4CorbaWrappedOutInterceptor());
301         	  outInterceptorChain.add(new Jbi4CorbaBareOutInterceptor());
302           } else {         
303         	  // Must check if the WDSL is wrapped
304               outInterceptorChain.add(new BareOutInterceptor());              
305               if (parameterStyle.equals(SoapBindingConstants.PARAMETER_STYLE_WRAPPED)) {            
306                   outInterceptorChain.add(new WrappedOutInterceptor());
307               }	
308           }
309            		
310   	} 
311   	
312     /**
313      * This method creates the CXF OUT Interceptors chain and process the message.
314      * 
315      * @param parameterStyle
316      * @param message
317      */
318 	public static void populateFaultInterceptors(PhaseInterceptorChain faultInterceptorChain, 
319 			String parameterStyle, String bindingStyle) {
320 		
321         // The FaultOutInterceptor creates and fills the XML details from the cause Exception                 
322         faultInterceptorChain.add(new StaxOutInterceptor());
323         // faultInterceptorChain.add(new Soap12FaultOutInterceptor());
324         faultInterceptorChain.add(new FaultOutInterceptor());						
325 	}     
326   	
327 
328 	
329     /**
330      * This method creates the CXF OUT Interceptors chain and process the message.
331      * The interceptor order is important! First the Stream is created, than the message is unwrapped 
332      * and then 
333      * converted into objects. Notice that with a custom binding, we could fix the interceptor 
334      * execution order statically
335      * 
336      * @param parameterStyle
337      * @param bindingStyle
338      * @param message
339      */
340   	public static void populateInInterceptorsForConsumer(PhaseInterceptorChain inInterceptorChain, 
341   			String parameterStyle, String bindingStyle, boolean isFromIDL) {
342   		
343   		/**
344   		 * DON'T CHANGE THE INTERCEPTORE DECLARATION ORDER (IS A CXF ISSUE!)
345   		 */
346   		inInterceptorChain.add(new StaxInInterceptor());          				
347   		
348   		inInterceptorChain.add(new HolderInInterceptor());
349  
350   		if (parameterStyle.equals(SoapBindingConstants.PARAMETER_STYLE_WRAPPED)) {
351   			inInterceptorChain.add(new WrapperClassInInterceptor());  	    	
352   	    } 
353   		// If it's from IDL, we generate the WSDL (is't doc-literal).
354   		if (isFromIDL) {
355   			inInterceptorChain.add(new WrappedInInterceptor());	
356   			inInterceptorChain.add(new DocLiteralInInterceptor());
357   		} else {
358   	      if (parameterStyle.equals(SoapBindingConstants.PARAMETER_STYLE_WRAPPED)) {
359   	          inInterceptorChain.add(new WrappedInInterceptor());
360   	      }
361   	      inInterceptorChain.add(new BareInInterceptor());
362   		}
363 
364   	} 	
365   	
366     /**
367      * This method creates the CXF Interceptors chain and process the message.
368      *                
369      * @param parameterStyle
370      * @param message
371      */
372 	public static void populateInInterceptorsForProvider(PhaseInterceptorChain inInterceptorChain, 
373 			String parameterStyle, String bindingStyle) { 
374 		
375 		inInterceptorChain.add(new StaxInInterceptor());
376 		// For jax-ws
377 		inInterceptorChain.add(new WrapperClassInInterceptor());			
378 		
379 		inInterceptorChain.add(new HolderInInterceptor());
380 		inInterceptorChain.add(new Jbi4CorbaServiceInvokerInterceptor());
381 		
382 		if (bindingStyle.equals(SoapBindingConstants.BINDING_STYLE_RPC)) {
383 			inInterceptorChain.add(new RPCInInterceptor());
384 		} else {            	
385 		    inInterceptorChain.add(new DocLiteralInInterceptor());
386 		} 		
387 	}  
388   	
389   	/**
390      * Return the correct parameter style for the binding, Wrapped or Bare 
391      * (notice that the WSDL is always Document/literal).
392      * @param bio
393      * @return <code>SoapBindingConstants.PARAMETER_STYLE_WRAPPED</code> or <code>SoapBindingConstants.PARAMETER_STYLE_BARE</code>
394      */
395     public static String getParameterStyle(BindingOperationInfo bio) {
396             
397         String parameterStyle = SoapBindingConstants.PARAMETER_STYLE_WRAPPED;
398         if (bio!= null) {
399             if (bio.getUnwrappedOperation() == null) {
400                 parameterStyle = SoapBindingConstants.PARAMETER_STYLE_BARE;
401             }
402         }        
403         return parameterStyle;
404     }
405 
406     
407 }