Coverage Report - org.mule.transport.cxf.CxfMessageReceiver
 
Classes in this File Line Coverage Branch Coverage Complexity
CxfMessageReceiver
88%
125/142
75%
48/64
0
 
 1  
 /*
 2  
  * $Id: CxfMessageReceiver.java 12283 2008-07-10 18:16:53Z dandiep $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
 5  
  *
 6  
  * The software in this package is published under the terms of the CPAL v1.0
 7  
  * license, a copy of which has been included with this distribution in the
 8  
  * LICENSE.txt file.
 9  
  */
 10  
 
 11  
 package org.mule.transport.cxf;
 12  
 
 13  
 import org.mule.api.MuleException;
 14  
 import org.mule.api.component.Component;
 15  
 import org.mule.api.component.JavaComponent;
 16  
 import org.mule.api.endpoint.InboundEndpoint;
 17  
 import org.mule.api.lifecycle.Callable;
 18  
 import org.mule.api.lifecycle.CreateException;
 19  
 import org.mule.api.lifecycle.Disposable;
 20  
 import org.mule.api.lifecycle.Initialisable;
 21  
 import org.mule.api.lifecycle.InitialisationException;
 22  
 import org.mule.api.service.Service;
 23  
 import org.mule.api.service.ServiceAware;
 24  
 import org.mule.api.transport.Connector;
 25  
 import org.mule.transport.AbstractMessageReceiver;
 26  
 import org.mule.transport.cxf.i18n.CxfMessages;
 27  
 import org.mule.transport.cxf.support.MuleHeadersInInterceptor;
 28  
 import org.mule.transport.cxf.support.MuleProtocolHeadersOutInterceptor;
 29  
 import org.mule.transport.cxf.support.OutputPayloadInterceptor;
 30  
 import org.mule.transport.cxf.support.ProxyService;
 31  
 import org.mule.util.ClassUtils;
 32  
 import org.mule.util.StringUtils;
 33  
 
 34  
 import java.util.ArrayList;
 35  
 import java.util.HashMap;
 36  
 import java.util.List;
 37  
 import java.util.Map;
 38  
 
 39  
 import javax.xml.namespace.QName;
 40  
 
 41  
 import org.apache.commons.lang.BooleanUtils;
 42  
 import org.apache.cxf.Bus;
 43  
 import org.apache.cxf.aegis.databinding.AegisDatabinding;
 44  
 import org.apache.cxf.configuration.Configurer;
 45  
 import org.apache.cxf.databinding.DataBinding;
 46  
 import org.apache.cxf.databinding.stax.StaxDataBinding;
 47  
 import org.apache.cxf.databinding.stax.StaxDataBindingFeature;
 48  
 import org.apache.cxf.endpoint.Server;
 49  
 import org.apache.cxf.feature.AbstractFeature;
 50  
 import org.apache.cxf.frontend.ServerFactoryBean;
 51  
 import org.apache.cxf.interceptor.Interceptor;
 52  
 import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
 53  
 import org.apache.cxf.service.factory.AbstractServiceConfiguration;
 54  
 import org.apache.cxf.service.factory.ReflectionServiceFactoryBean;
 55  
 
 56  
 /**
 57  
  * Create a CXF service. All messages for the service will be sent to the Mule bus a
 58  
  * la the MuleInvoker.
 59  
  */
 60  
 public class CxfMessageReceiver extends AbstractMessageReceiver
 61  
 {
 62  
 
 63  
     protected CxfConnector connector;
 64  
     private Server server;
 65  
     private boolean proxy;
 66  
     private boolean applySecurityToProtocol;
 67  
     private boolean applyTransformersToProtocol;
 68  
     private boolean applyFiltersToProtocol;
 69  
     
 70  
     public CxfMessageReceiver(Connector connector, Service service, InboundEndpoint Endpoint)
 71  
         throws CreateException
 72  
     {
 73  290
         super(connector, service, Endpoint);
 74  290
         this.connector = (CxfConnector) connector;
 75  290
     }
 76  
 
 77  
     @SuppressWarnings("unchecked")
 78  
     @Override
 79  
     protected void doInitialise() throws InitialisationException
 80  
     {
 81  
         try
 82  
         {
 83  290
             Map endpointProps = getEndpoint().getProperties();
 84  290
             String wsdlUrl = (String) endpointProps.get(CxfConstants.WSDL_LOCATION);
 85  290
             String bindingId = (String) endpointProps.get(CxfConstants.BINDING_ID);
 86  290
             String frontend = (String) endpointProps.get(CxfConstants.FRONTEND);
 87  290
             String serviceClassName = (String) endpointProps.get(CxfConstants.SERVICE_CLASS);
 88  290
             String mtomEnabled = (String) endpointProps.get(CxfConstants.MTOM_ENABLED);
 89  290
             List<DataBinding> databinding = (List<DataBinding>) endpointProps.get(CxfConstants.DATA_BINDING);
 90  290
             List<AbstractFeature> features = (List<AbstractFeature>) endpointProps.get(CxfConstants.FEATURES);
 91  290
             String proxyStr = (String) endpointProps.get(CxfConstants.PROXY);
 92  
 
 93  290
             applyFiltersToProtocol = BooleanUtils.toBoolean((String) endpointProps.get(CxfConstants.APPLY_FILTERS_TO_PROTOCOL));
 94  290
             applySecurityToProtocol = BooleanUtils.toBoolean((String) endpointProps.get(CxfConstants.APPLY_SECURITY_TO_PROTOCOL));
 95  290
             applyTransformersToProtocol = BooleanUtils.toBoolean((String) endpointProps.get(CxfConstants.APPLY_TRANSFORMERS_TO_PROTOCOL));
 96  
             
 97  290
             Class<?> svcCls = null;
 98  
             Class<?> targetCls;
 99  
             
 100  290
             proxy = BooleanUtils.toBoolean(proxyStr);
 101  
             
 102  290
             if (proxy)
 103  
             {
 104  40
                 svcCls = ProxyService.class;
 105  40
                 targetCls = svcCls;
 106  40
                 frontend = "simple";
 107  
             }
 108  
             else 
 109  
             {
 110  250
                 if (StringUtils.isEmpty(frontend))
 111  
                 {
 112  204
                     frontend = connector.getDefaultFrontend();
 113  
                 }
 114  
                 
 115  250
                 if (!StringUtils.isEmpty(serviceClassName)) 
 116  
                 {
 117  10
                     svcCls = ClassUtils.loadClass(serviceClassName, getClass());
 118  
                 } 
 119  
                 
 120  250
                 targetCls = getTargetClass(svcCls);
 121  
                 
 122  250
                 if (svcCls == null)
 123  
                 {
 124  240
                     svcCls = targetCls;
 125  
                 }
 126  
             }
 127  
 
 128  290
             ServerFactoryBean sfb = null;
 129  290
             if (CxfConstants.SIMPLE_FRONTEND.equals(frontend))
 130  
             {
 131  256
                 sfb = new ServerFactoryBean();
 132  256
                 sfb.setDataBinding(new AegisDatabinding());
 133  
             }
 134  34
             else if (CxfConstants.JAX_WS_FRONTEND.equals(frontend))
 135  
             {
 136  34
                 sfb = new JaxWsServerFactoryBean();
 137  
             }
 138  
             else
 139  
             {
 140  0
                 throw new CreateException(CxfMessages.invalidFrontend(frontend), this);
 141  
             }
 142  
 
 143  290
             if (!proxy)
 144  
             {
 145  250
                 if (databinding != null && databinding.size() > 0)
 146  
                 {
 147  
                     // TODO: find a way to make this not a list
 148  2
                     sfb.setDataBinding(databinding.get(0));
 149  
                 }
 150  
                 
 151  250
                 if (service.getComponent() instanceof JavaComponent)
 152  
                 {
 153  240
                     sfb.setServiceBean(((JavaComponent) service.getComponent()).getObjectFactory().getInstance());
 154  
                 }
 155  
             }
 156  
             else
 157  
             {
 158  40
                 sfb.setDataBinding(new StaxDataBinding());
 159  40
                 sfb.getFeatures().add(new StaxDataBindingFeature());
 160  
             }
 161  
            
 162  
             // The binding - i.e. SOAP, XML, HTTP Binding, etc
 163  290
             if (bindingId != null)
 164  
             {
 165  0
                 sfb.setBindingId(bindingId);
 166  
             }
 167  
             
 168  290
             if (features != null) 
 169  
             {
 170  26
                 sfb.getFeatures().addAll(features);
 171  
             }
 172  
             
 173  290
             if (mtomEnabled != null)
 174  
             {
 175  2
                 Map<String, Object> properties = sfb.getProperties();
 176  2
                 if (properties == null)
 177  
                 {
 178  2
                     properties = new HashMap<String, Object>();
 179  2
                     sfb.setProperties(properties);
 180  
                 }
 181  2
                 properties.put("mtom-enabled", mtomEnabled);
 182  
             }
 183  
             
 184  290
             sfb.setInInterceptors((List<Interceptor>) endpointProps.get("inInterceptors"));
 185  290
             sfb.setInFaultInterceptors((List<Interceptor>) endpointProps.get("inFaultInterceptors"));
 186  290
             sfb.setOutInterceptors((List<Interceptor>) endpointProps.get("outInterceptors"));
 187  290
             sfb.setOutFaultInterceptors((List<Interceptor>) endpointProps.get("outFaultInterceptors"));
 188  
 
 189  290
             if (sfb.getInInterceptors() == null)
 190  
             {
 191  288
                 sfb.setInInterceptors(new ArrayList<Interceptor>());
 192  
             }
 193  
             
 194  290
             sfb.getInInterceptors().add(new MuleHeadersInInterceptor());
 195  
             
 196  290
             if (sfb.getOutInterceptors() == null)
 197  
             {
 198  290
                 sfb.setOutInterceptors(new ArrayList<Interceptor>());
 199  
             }
 200  290
             sfb.getOutInterceptors().add(new MuleProtocolHeadersOutInterceptor());
 201  
             
 202  290
             if (sfb.getOutFaultInterceptors() == null)
 203  
             {
 204  290
                 sfb.setOutFaultInterceptors(new ArrayList<Interceptor>());
 205  
             }
 206  290
             sfb.getOutFaultInterceptors().add(new MuleProtocolHeadersOutInterceptor());
 207  
             
 208  290
             if (proxy)
 209  
             {
 210  40
                 sfb.getOutInterceptors().add(new OutputPayloadInterceptor());
 211  
             }
 212  
             
 213  290
             sfb.setServiceClass(svcCls);
 214  290
             sfb.setAddress(getAddressWithoutQuery());
 215  
 
 216  290
             if (wsdlUrl != null)
 217  
             {
 218  0
                 sfb.setWsdlURL(wsdlUrl);
 219  
             }
 220  
 
 221  290
             ReflectionServiceFactoryBean svcFac = sfb.getServiceFactory();
 222  
 
 223  290
             addIgnoredMethods(svcFac, Callable.class.getName());
 224  290
             addIgnoredMethods(svcFac, Initialisable.class.getName());
 225  290
             addIgnoredMethods(svcFac, Disposable.class.getName());
 226  290
             addIgnoredMethods(svcFac, ServiceAware.class.getName());
 227  
 
 228  290
             String name = (String) endpointProps.get(CxfConstants.NAME);
 229  
             // check if there is the namespace property on the service
 230  290
             String namespace = (String) endpointProps.get(CxfConstants.NAMESPACE);
 231  
 
 232  
             // HACK because CXF expects a QName for the service
 233  290
             initServiceName(svcCls, name, namespace, svcFac);
 234  
 
 235  290
             boolean sync = endpoint.isSynchronous();
 236  
             // default to synchronous if using http
 237  290
             if (endpoint.getEndpointURI().getScheme().startsWith("http")
 238  
                 || endpoint.getEndpointURI().getScheme().startsWith("servlet"))
 239  
             {
 240  204
                 sync = true;
 241  
             }
 242  
 
 243  290
             sfb.setInvoker(new MuleInvoker(this, targetCls, sync));
 244  290
             sfb.setStart(false);
 245  
 
 246  290
             Bus bus = connector.getCxfBus();
 247  290
             sfb.setBus(bus);
 248  
 
 249  290
             initializeServerFactory(sfb);
 250  
             
 251  290
             Configurer configurer = bus.getExtension(Configurer.class);
 252  290
             if (null != configurer)
 253  
             {
 254  290
                 configurer.configureBean(sfb.getServiceFactory().getEndpointName().toString(), sfb);
 255  
             }
 256  
 
 257  290
             server = sfb.create();
 258  
         }
 259  0
         catch (MuleException e)
 260  
         {
 261  0
             throw new InitialisationException(e, this);
 262  
         }
 263  0
         catch (ClassNotFoundException e)
 264  
         {
 265  
             // will be thrown in the case that the ClassUtils.loadClass() does
 266  
             // not find the class to load
 267  0
             throw new InitialisationException(e, this);
 268  
         }
 269  0
         catch (Exception e)
 270  
         {
 271  0
             throw new InitialisationException(e, this);
 272  290
         }
 273  290
     }
 274  
 
 275  
     /**
 276  
      * If any custom initialization logic needs to be done, it can
 277  
      * be done by overriding this method.
 278  
      * @param sfb
 279  
      */
 280  
     protected void initializeServerFactory(ServerFactoryBean sfb)
 281  
     {
 282  290
     }
 283  
 
 284  
     private String getAddressWithoutQuery()
 285  
     {
 286  290
         String a = getEndpointURI().getAddress();
 287  290
         int idx = a.lastIndexOf('?');
 288  290
         if (idx > -1) {
 289  0
             a = a.substring(0, idx);
 290  
         }
 291  290
         return a;
 292  
     }
 293  
 
 294  
     /**
 295  
      * Gross hack to support getting the service namespace from CXF if one wasn't
 296  
      * supplied.
 297  
      */
 298  
     private void initServiceName(Class<?> exposedInterface,
 299  
                                  String name,
 300  
                                  String namespace,
 301  
                                  ReflectionServiceFactoryBean svcFac)
 302  
     {
 303  290
         svcFac.setServiceClass(exposedInterface);
 304  290
         for (AbstractServiceConfiguration c : svcFac.getServiceConfigurations())
 305  
         {
 306  324
             c.setServiceFactory(svcFac);
 307  
         }
 308  
 
 309  290
         if (name != null && namespace == null)
 310  
         {
 311  0
             namespace = svcFac.getServiceQName().getNamespaceURI();
 312  
         }
 313  290
         else if (name == null && namespace != null)
 314  
         {
 315  0
             name = svcFac.getServiceQName().getLocalPart();
 316  
         }
 317  
 
 318  290
         if (name != null)
 319  
         {
 320  0
             svcFac.setServiceName(new QName(namespace, name));
 321  
         }
 322  290
     }
 323  
 
 324  
     public void addIgnoredMethods(ReflectionServiceFactoryBean svcFac, String className)
 325  
     {
 326  
         try
 327  
         {
 328  1160
             Class<?> c = ClassUtils.loadClass(className, getClass());
 329  2320
             for (int i = 0; i < c.getMethods().length; i++)
 330  
             {
 331  1160
                 svcFac.getIgnoredMethods().add(c.getMethods()[i]);
 332  
             }
 333  
         }
 334  0
         catch (ClassNotFoundException e)
 335  
         {
 336  
             // can be ignored.
 337  1160
         }
 338  1160
     }
 339  
 
 340  
     private Class<?> getTargetClass(Class<?> svcCls) throws MuleException, ClassNotFoundException
 341  
     {
 342  250
         Component component = service.getComponent();
 343  250
         if (!(component instanceof JavaComponent)) 
 344  
         {
 345  10
             if (svcCls == null)
 346  
             {
 347  0
                 throw new InitialisationException(CxfMessages.serviceClassRequiredWithPassThrough(), this);
 348  
             }
 349  
             else
 350  
             {
 351  10
                 return svcCls;
 352  
             }
 353  
         }
 354  
         
 355  
         try
 356  
         {
 357  240
             return ((JavaComponent) component).getObjectType();
 358  
         }
 359  0
         catch (Exception e)
 360  
         {
 361  0
             throw new CreateException(e, this);
 362  
         }
 363  
     }
 364  
 
 365  
     protected void doDispose()
 366  
     {
 367  
         // template method
 368  580
     }
 369  
 
 370  
     public void doConnect() throws Exception
 371  
     {
 372  
         // Start the CXF Server
 373  288
         server.start();
 374  288
         connector.registerReceiverWithMuleService(this, endpoint.getEndpointURI());
 375  288
     }
 376  
 
 377  
     public void doDisconnect() throws Exception
 378  
     {
 379  288
         server.stop();
 380  288
     }
 381  
 
 382  
     public void doStart() throws MuleException
 383  
     {
 384  
         // nothing to do
 385  288
     }
 386  
 
 387  
     public void doStop() throws MuleException
 388  
     {
 389  
         // nothing to do
 390  288
     }
 391  
 
 392  
     public Server getServer()
 393  
     {
 394  300
         return server;
 395  
     }
 396  
 
 397  
     public boolean isProxy()
 398  
     {
 399  106
         return proxy;
 400  
     }
 401  
 
 402  
     public boolean isApplySecurityToProtocol()
 403  
     {
 404  288
         return applySecurityToProtocol;
 405  
     }
 406  
 
 407  
     public boolean isApplyTransformersToProtocol()
 408  
     {
 409  288
         return applyTransformersToProtocol;
 410  
     }
 411  
 
 412  
     public boolean isApplyFiltersToProtocol()
 413  
     {
 414  288
         return applyFiltersToProtocol;
 415  
     }
 416  
 
 417  
 }