Coverage Report - org.mule.transport.soap.axis.AxisMessageReceiver
 
Classes in this File Line Coverage Branch Coverage Complexity
AxisMessageReceiver
93%
128/138
77%
43/56
4.667
 
 1  
 /*
 2  
  * $Id: AxisMessageReceiver.java 11373 2008-03-15 05:03:10Z dfeist $
 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.soap.axis;
 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.EndpointURI;
 17  
 import org.mule.api.endpoint.InboundEndpoint;
 18  
 import org.mule.api.lifecycle.CreateException;
 19  
 import org.mule.api.lifecycle.InitialisationException;
 20  
 import org.mule.api.service.Service;
 21  
 import org.mule.api.transport.Connector;
 22  
 import org.mule.component.AbstractJavaComponent;
 23  
 import org.mule.config.i18n.CoreMessages;
 24  
 import org.mule.transport.AbstractMessageReceiver;
 25  
 import org.mule.transport.soap.NamedParameter;
 26  
 import org.mule.transport.soap.SoapMethod;
 27  
 import org.mule.transport.soap.axis.extensions.MuleMsgProvider;
 28  
 import org.mule.transport.soap.axis.extensions.MuleRPCProvider;
 29  
 import org.mule.transport.soap.axis.i18n.AxisMessages;
 30  
 import org.mule.util.StringUtils;
 31  
 
 32  
 import java.util.HashMap;
 33  
 import java.util.Iterator;
 34  
 import java.util.List;
 35  
 import java.util.Map;
 36  
 
 37  
 import javax.xml.rpc.ParameterMode;
 38  
 
 39  
 import org.apache.axis.AxisProperties;
 40  
 import org.apache.axis.constants.Style;
 41  
 import org.apache.axis.constants.Use;
 42  
 import org.apache.axis.description.OperationDesc;
 43  
 import org.apache.axis.description.ParameterDesc;
 44  
 import org.apache.axis.handlers.soap.SOAPService;
 45  
 import org.apache.axis.providers.java.JavaProvider;
 46  
 import org.apache.axis.wsdl.fromJava.Namespaces;
 47  
 
 48  
 /**
 49  
  * <code>AxisMessageReceiver</code> is used to register a component as a service
 50  
  * with a Axis server.
 51  
  */
 52  
 
 53  
 public class AxisMessageReceiver extends AbstractMessageReceiver
 54  
 {
 55  
 
 56  
     public static final String AXIS_OPTIONS = "axisOptions";
 57  
     public static final String BEAN_TYPES = "beanTypes";
 58  
     public static final String SERVICE_NAMESPACE = "serviceNamespace";
 59  
 
 60  
     protected AxisConnector connector;
 61  
     protected SOAPService soapService;
 62  
 
 63  
     public AxisMessageReceiver(Connector connector, Service service, InboundEndpoint endpoint)
 64  
             throws CreateException
 65  
     {
 66  
 
 67  378
         super(connector, service, endpoint);
 68  
 
 69  378
         this.connector = (AxisConnector) connector;
 70  
         try
 71  
         {
 72  378
             AxisServiceProxy.setProperties(endpoint.getProperties());
 73  378
             create();
 74  
         }
 75  2
         catch (Exception e)
 76  
         {
 77  2
             throw new CreateException(e, this);
 78  376
         }
 79  376
     }
 80  
 
 81  
     protected void create() throws Exception
 82  
     {
 83  378
         AxisProperties.setProperty("axis.doAutoTypes", String.valueOf(connector.isDoAutoTypes()));
 84  
         // TODO RM: these are endpoint properties now
 85  
 //        String style = (String)descriptor.getProperties().get("style");
 86  
 //        String use = (String)descriptor.getProperties().get("use");
 87  
 //        String doc = (String)descriptor.getProperties().get("documentation");
 88  378
         String style = (String) endpoint.getProperties().get(AxisConnector.STYLE);
 89  378
         String use = (String) endpoint.getProperties().get(AxisConnector.USE);
 90  378
         String doc = (String) endpoint.getProperties().get("documentation");
 91  
 
 92  378
         EndpointURI uri = endpoint.getEndpointURI();
 93  378
         String serviceName = service.getName();
 94  
 
 95  378
         SOAPService existing = this.connector.getAxis().getService(serviceName);
 96  378
         if (existing != null)
 97  
         {
 98  0
             soapService = existing;
 99  0
             logger.debug("Using existing service for " + serviceName);
 100  
         }
 101  
         else
 102  
         {
 103  
             // Check if the style is message. If so, we need to create
 104  
             // a message oriented provider
 105  378
             if (style != null && style.equalsIgnoreCase("message"))
 106  
             {
 107  52
                 logger.debug("Creating Message Provider");
 108  52
                 soapService = new SOAPService(new MuleMsgProvider(connector));
 109  
                 // } else if (style != null && style.equalsIgnoreCase("document")) {
 110  
                 // logger.debug("Creating Doc Provider");
 111  
                 // service = new SOAPService(new MuleDocLitProvider(connector));
 112  
             }
 113  
             else
 114  
             {
 115  326
                 logger.debug("Creating RPC Provider");
 116  326
                 soapService = new SOAPService(new MuleRPCProvider(connector));
 117  
             }
 118  
 
 119  378
             soapService.setEngine(connector.getAxis());
 120  
         }
 121  
 
 122  378
         String servicePath = uri.getPath();
 123  378
         soapService.setOption(serviceName, this);
 124  378
         soapService.setOption(AxisConnector.SERVICE_PROPERTY_SERVCE_PATH, servicePath);
 125  378
         soapService.setOption(AxisConnector.SERVICE_PROPERTY_COMPONENT_NAME, serviceName);
 126  
 
 127  378
         soapService.setName(serviceName);
 128  
 
 129  
         // Add any custom options from the Descriptor config
 130  378
         Map options = (Map) endpoint.getProperties().get(AXIS_OPTIONS);
 131  
 
 132  
         // IF wsdl service name is not set, default to service name
 133  378
         if (options == null)
 134  
         {
 135  320
             options = new HashMap(2);
 136  
         }
 137  378
         if (options.get("wsdlServiceElement") == null)
 138  
         {
 139  320
             options.put("wsdlServiceElement", serviceName);
 140  
         }
 141  
 
 142  
         Map.Entry entry;
 143  378
         for (Iterator iterator = options.entrySet().iterator(); iterator.hasNext();)
 144  
         {
 145  390
             entry = (Map.Entry) iterator.next();
 146  390
             soapService.setOption(entry.getKey().toString(), entry.getValue());
 147  390
             logger.debug("Adding Axis option: " + entry);
 148  
         }
 149  
 
 150  
         // set method names
 151  378
         Class[] interfaces = AxisServiceProxy.getInterfacesForComponent(service);
 152  378
         if (interfaces.length == 0)
 153  
         {
 154  2
             throw new InitialisationException(
 155  
                     AxisMessages.objectMustImplementAnInterface(serviceName), service);
 156  
         }
 157  
         // You must supply a class name if you want to restrict methods
 158  
         // or specify the 'allowedMethods' property in the axisOptions property
 159  376
         String methodNames = "*";
 160  
 
 161  376
         Map methods = (Map) endpoint.getProperties().get(AxisConnector.SOAP_METHODS);
 162  376
         if (methods != null)
 163  
         {
 164  6
             Iterator i = methods.keySet().iterator();
 165  6
             StringBuffer buf = new StringBuffer(64);
 166  12
             while (i.hasNext())
 167  
             {
 168  6
                 String name = (String) i.next();
 169  6
                 Object m = methods.get(name);
 170  6
                 SoapMethod method = null;
 171  6
                 if (m instanceof List)
 172  
                 {
 173  6
                     method = new SoapMethod(name, (List) m);
 174  
                 }
 175  
                 else
 176  
                 {
 177  0
                     method = new SoapMethod(name, (String) m);
 178  
                 }
 179  
 
 180  6
                 List namedParameters = method.getNamedParameters();
 181  6
                 ParameterDesc[] parameters = new ParameterDesc[namedParameters.size()];
 182  18
                 for (int j = 0; j < namedParameters.size(); j++)
 183  
                 {
 184  12
                     NamedParameter parameter = (NamedParameter) namedParameters.get(j);
 185  12
                     byte mode = ParameterDesc.INOUT;
 186  12
                     if (parameter.getMode().equals(ParameterMode.IN))
 187  
                     {
 188  12
                         mode = ParameterDesc.IN;
 189  
                     }
 190  0
                     else if (parameter.getMode().equals(ParameterMode.OUT))
 191  
                     {
 192  0
                         mode = ParameterDesc.OUT;
 193  
                     }
 194  
 
 195  12
                     parameters[j] = new ParameterDesc(parameter.getName(), mode, parameter.getType());
 196  
                 }
 197  
 
 198  6
                 soapService.getServiceDescription().addOperationDesc(
 199  
                         new OperationDesc(method.getName().getLocalPart(), parameters, method.getReturnType()));
 200  6
                 buf.append(method.getName().getLocalPart() + ",");
 201  6
             }
 202  6
             methodNames = buf.toString();
 203  6
             methodNames = methodNames.substring(0, methodNames.length() - 1);
 204  6
         }
 205  
         else
 206  
         {
 207  370
             String[] methodNamesArray = AxisServiceProxy.getMethodNames(interfaces);
 208  370
             StringBuffer buf = new StringBuffer(64);
 209  2084
             for (int i = 0; i < methodNamesArray.length; i++)
 210  
             {
 211  1714
                 buf.append(methodNamesArray[i]).append(",");
 212  
             }
 213  370
             methodNames = buf.toString();
 214  370
             methodNames = methodNames.substring(0, methodNames.length() - 1);
 215  
         }
 216  
 
 217  376
         String className = interfaces[0].getName();
 218  
         // The namespace of the service.
 219  
         // Todo use the service qname in Mule 2.0
 220  376
         String namespace = (String) endpoint.getProperties().get(SERVICE_NAMESPACE);
 221  376
         if (namespace == null)
 222  
         {
 223  318
             namespace = Namespaces.makeNamespace(className);
 224  
         }
 225  
 
 226  
         // WSDL override
 227  
         // TODO RM: this is an endpoint property now?
 228  
         // String wsdlFile = (String)descriptor.getProperties().get("wsdlFile");
 229  376
         String wsdlFile = (String) endpoint.getProperties().get("wsdlFile");
 230  376
         if (wsdlFile != null)
 231  
         {
 232  6
             soapService.getServiceDescription().setWSDLFile(wsdlFile);
 233  
         }
 234  
         /*
 235  
          * Now we set up the various options for the SOAPService. We set:
 236  
          * RPCProvider.OPTION_WSDL_SERVICEPORT In essense, this is our service name
 237  
          * RPCProvider.OPTION_CLASSNAME This tells the serverProvider (whether it be
 238  
          * an AvalonProvider or just JavaProvider) what class to load via
 239  
          * "makeNewServiceObject". RPCProvider.OPTION_SCOPE How long the object
 240  
          * loaded via "makeNewServiceObject" will persist - either request, session,
 241  
          * or application. We use the default for now.
 242  
          * RPCProvider.OPTION_WSDL_TARGETNAMESPACE A namespace created from the
 243  
          * package name of the service. RPCProvider.OPTION_ALLOWEDMETHODS What
 244  
          * methods the service can execute on our class. We don't set:
 245  
          * RPCProvider.OPTION_WSDL_PORTTYPE RPCProvider.OPTION_WSDL_SERVICEELEMENT
 246  
          */
 247  376
         setOptionIfNotset(soapService, JavaProvider.OPTION_WSDL_SERVICEPORT, serviceName);
 248  376
         setOptionIfNotset(soapService, JavaProvider.OPTION_CLASSNAME, className);
 249  376
         setOptionIfNotset(soapService, JavaProvider.OPTION_SCOPE, "Request");
 250  376
         if (StringUtils.isNotBlank(namespace))
 251  
         {
 252  376
             setOptionIfNotset(soapService, JavaProvider.OPTION_WSDL_TARGETNAMESPACE, namespace);
 253  
         }
 254  
 
 255  
         // Set the allowed methods, allow all if there are none specified.
 256  376
         if (methodNames == null)
 257  
         {
 258  0
             setOptionIfNotset(soapService, JavaProvider.OPTION_ALLOWEDMETHODS, "*");
 259  
         }
 260  
         else
 261  
         {
 262  376
             setOptionIfNotset(soapService, JavaProvider.OPTION_ALLOWEDMETHODS, methodNames);
 263  
         }
 264  
 
 265  
         // Note that Axis has specific rules to how these two variables are
 266  
         // combined. This is handled for us
 267  
         // Set style: RPC/wrapped/Doc/Message
 268  
 
 269  376
         if (style != null)
 270  
         {
 271  64
             Style s = Style.getStyle(style);
 272  64
             if (s == null)
 273  
             {
 274  0
                 throw new CreateException(
 275  
                         CoreMessages.valueIsInvalidFor(style, AxisConnector.STYLE), this);
 276  
             }
 277  
             else
 278  
             {
 279  64
                 soapService.setStyle(s);
 280  
             }
 281  
         }
 282  
         // Set use: Endcoded/Literal
 283  376
         if (use != null)
 284  
         {
 285  12
             Use u = Use.getUse(use);
 286  12
             if (u == null)
 287  
             {
 288  0
                 throw new CreateException(CoreMessages.valueIsInvalidFor(use, AxisConnector.USE),
 289  
                         this);
 290  
             }
 291  
             else
 292  
             {
 293  12
                 soapService.setUse(u);
 294  
             }
 295  
         }
 296  
 
 297  376
         soapService.getServiceDescription().setDocumentation(doc);
 298  
 
 299  
         // Tell Axis to try and be intelligent about serialization.
 300  
         // TypeMappingRegistryImpl registry = (TypeMappingRegistryImpl)
 301  
         // service.getTypeMappingRegistry();
 302  
         // TypeMappingImpl tm = (TypeMappingImpl) registry.();
 303  
 
 304  
         // Handle complex bean type automatically
 305  
         // registry.setDoAutoTypes( true );
 306  
 
 307  
         // Axis 1.2 fix to handle autotypes properly
 308  
         // AxisProperties.setProperty("axis.doAutoTypes",
 309  
         // String.valueOf(connector.isDoAutoTypes()));
 310  
 
 311  
         // TODO Load any explicitly defined bean types
 312  
         // List types = (List) descriptor.getProperties().get(BEAN_TYPES);
 313  
         // connector.registerTypes(registry, types);
 314  
 
 315  376
         soapService.setName(serviceName);
 316  
 
 317  
         // Add initialisation callback for the Axis service
 318  376
         Component component = service.getComponent();
 319  376
         if (component instanceof JavaComponent)
 320  
         {
 321  376
             ((AbstractJavaComponent) component).getObjectFactory().addObjectInitialisationCallback(
 322  
                 new AxisInitialisationCallback(soapService));
 323  
         }
 324  
 
 325  376
         if (uri.getScheme().equalsIgnoreCase("servlet"))
 326  
         {
 327  2
             connector.addServletService(soapService);
 328  2
             String endpointUrl = uri.getAddress() + "/" + serviceName;
 329  2
             endpointUrl = endpointUrl.replaceFirst("servlet:", "http:");
 330  2
             soapService.getServiceDescription().setEndpointURL(endpointUrl);
 331  2
         }
 332  
         else
 333  
         {
 334  374
             soapService.getServiceDescription().setEndpointURL(uri.getAddress() + "/" + serviceName);
 335  
         }
 336  376
         if (StringUtils.isNotBlank(namespace))
 337  
         {
 338  376
             soapService.getServiceDescription().setDefaultNamespace(namespace);
 339  
         }
 340  376
         soapService.init();
 341  376
         soapService.stop();
 342  376
     }
 343  
 
 344  
     protected void doConnect() throws Exception
 345  
     {
 346  
         // Tell the axis configuration about our new service.
 347  374
         connector.getServerProvider().deployService(soapService.getName(), soapService);
 348  374
         connector.registerReceiverWithMuleService(this, endpoint.getEndpointURI());
 349  374
     }
 350  
 
 351  
     protected void doDisconnect() throws Exception
 352  
     {
 353  
         try
 354  
         {
 355  374
             doStop();
 356  
         }
 357  0
         catch (MuleException e)
 358  
         {
 359  0
             logger.error(e.getMessage(), e);
 360  374
         }
 361  
         // TODO: how do you undeploy an Axis service?
 362  
 
 363  
         // Unregister the mule part of the service
 364  374
         connector.unregisterReceiverWithMuleService(this, endpoint.getEndpointURI());
 365  374
     }
 366  
 
 367  
     protected void doStart() throws MuleException
 368  
     {
 369  374
         if (soapService != null)
 370  
         {
 371  374
             soapService.start();
 372  
         }
 373  374
     }
 374  
 
 375  
     protected void doStop() throws MuleException
 376  
     {
 377  748
         if (soapService != null)
 378  
         {
 379  748
             soapService.stop();
 380  
         }
 381  748
     }
 382  
 
 383  
     protected void doDispose()
 384  
     {
 385  
         // nothing to do               
 386  752
     }
 387  
 
 388  
     protected void setOptionIfNotset(SOAPService service, String option, Object value)
 389  
     {
 390  1880
         Object val = service.getOption(option);
 391  1880
         if (val == null)
 392  
         {
 393  1874
             service.setOption(option, value);
 394  
         }
 395  1880
     }
 396  
 
 397  
     public SOAPService getSoapService()
 398  
     {
 399  374
         return soapService;
 400  
     }
 401  
 }