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