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