View Javadoc

1   /*
2    * $Id: MuleRPCProvider.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.extensions;
12  
13  import org.mule.impl.RequestContext;
14  import org.mule.impl.model.ModelHelper;
15  import org.mule.providers.soap.ServiceProxy;
16  import org.mule.providers.soap.axis.AxisConnector;
17  import org.mule.providers.soap.axis.AxisMessageReceiver;
18  import org.mule.providers.soap.axis.AxisServiceProxy;
19  import org.mule.umo.UMOComponent;
20  
21  import java.lang.reflect.Proxy;
22  import java.util.ArrayList;
23  import java.util.Iterator;
24  
25  import javax.xml.namespace.QName;
26  import javax.xml.rpc.holders.Holder;
27  
28  import org.apache.axis.AxisFault;
29  import org.apache.axis.Constants;
30  import org.apache.axis.MessageContext;
31  import org.apache.axis.constants.Style;
32  import org.apache.axis.description.OperationDesc;
33  import org.apache.axis.description.ParameterDesc;
34  import org.apache.axis.description.ServiceDesc;
35  import org.apache.axis.handlers.soap.SOAPService;
36  import org.apache.axis.message.RPCElement;
37  import org.apache.axis.message.RPCHeaderParam;
38  import org.apache.axis.message.RPCParam;
39  import org.apache.axis.message.SOAPEnvelope;
40  import org.apache.axis.providers.java.RPCProvider;
41  import org.apache.axis.soap.SOAPConstants;
42  import org.apache.axis.utils.JavaUtils;
43  
44  /**
45   * <code>MuleProvider</code> is an Axis service endpoint that builds services from
46   * Mule managed components.
47   */
48  public class MuleRPCProvider extends RPCProvider
49  {
50      /**
51       * Serial version
52       */
53      private static final long serialVersionUID = -4987111047650933518L;
54  
55      private AxisConnector connector;
56  
57      public MuleRPCProvider(AxisConnector connector)
58      {
59          this.connector = connector;
60      }
61  
62      protected Object makeNewServiceObject(MessageContext messageContext, String s) throws Exception
63      {
64          String transUrl = (String)messageContext.getProperty("transport.url");
65          int i = transUrl.indexOf("?");
66          if (i > -1)
67          {
68              transUrl = transUrl.substring(0, i);
69          }
70          AxisMessageReceiver receiver = (AxisMessageReceiver)connector.lookupReceiver(transUrl);
71          if (receiver == null)
72          {
73              receiver = (AxisMessageReceiver)connector.lookupReceiver(messageContext.getTargetService());
74          }
75          if (receiver == null)
76          {
77              throw new AxisFault("Could not find Mule registered service: " + s);
78          }
79          Class[] classes = ServiceProxy.getInterfacesForComponent(receiver.getComponent());
80          return AxisServiceProxy.createProxy(receiver, true, classes);
81      }
82  
83      protected Class getServiceClass(String s, SOAPService soapService, MessageContext messageContext)
84          throws AxisFault
85      {
86          UMOComponent component = ModelHelper.getComponent(soapService.getName());
87          try
88          {
89              Class[] classes = ServiceProxy.getInterfacesForComponent(component);
90              return Proxy.getProxyClass(Thread.currentThread().getContextClassLoader(), classes);
91          }
92          catch (Exception e)
93          {
94              throw new AxisFault("Failed to implementation class for component: " + e.getMessage(), e);
95          }
96      }
97  
98      public void invoke(MessageContext msgContext) throws AxisFault
99      {
100         super.invoke(msgContext);
101         if (RequestContext.getExceptionPayload() != null)
102         {
103             Throwable t = RequestContext.getExceptionPayload().getException();
104             if (t instanceof Exception)
105             {
106                 AxisFault fault = AxisFault.makeFault((Exception)t);
107                 if (t instanceof RuntimeException)
108                 {
109                     fault.addFaultDetail(Constants.QNAME_FAULTDETAIL_RUNTIMEEXCEPTION, "true");
110                 }
111                 throw fault;
112             }
113             else
114             {
115                 throw (Error)t;
116             }
117         }
118     }
119 
120     protected RPCElement createResponseBody(RPCElement body,
121                                             MessageContext msgContext,
122                                             OperationDesc operation,
123                                             ServiceDesc serviceDesc,
124                                             Object objRes,
125                                             SOAPEnvelope resEnv,
126                                             ArrayList outs) throws Exception
127     {
128         String methodName = operation.getName();
129 
130         /* Now put the result in the result SOAPEnvelope */
131         RPCElement resBody = new RPCElement(methodName + "Response");
132         resBody.setPrefix(body.getPrefix());
133         resBody.setNamespaceURI(body.getNamespaceURI());
134         resBody.setEncodingStyle(msgContext.getEncodingStyle());
135         try
136         {
137             // Return first
138             if (operation.getMethod().getReturnType() != Void.TYPE)
139             {
140                 QName returnQName = operation.getReturnQName();
141                 if (returnQName == null)
142                 {
143                     String nsp = body.getNamespaceURI();
144                     if (nsp == null || nsp.length() == 0)
145                     {
146                         nsp = serviceDesc.getDefaultNamespace();
147                     }
148                     returnQName = new QName(msgContext.isEncoded() ? "" : nsp, methodName + "Return");
149                 }
150 
151                 RPCParam param = new RPCParam(returnQName, objRes);
152                 param.setParamDesc(operation.getReturnParamDesc());
153 
154                 if (!operation.isReturnHeader())
155                 {
156                     // For SOAP 1.2 rpc style, add a result
157                     if (msgContext.getSOAPConstants() == SOAPConstants.SOAP12_CONSTANTS
158                         && (serviceDesc.getStyle().equals(Style.RPC)))
159                     {
160                         RPCParam resultParam = new RPCParam(Constants.QNAME_RPC_RESULT, returnQName);
161                         resultParam.setXSITypeGeneration(Boolean.FALSE);
162                         resBody.addParam(resultParam);
163                     }
164                     resBody.addParam(param);
165                 }
166                 else
167                 {
168                     resEnv.addHeader(new RPCHeaderParam(param));
169                 }
170 
171             }
172 
173             // Then any other out params
174             if (!outs.isEmpty())
175             {
176                 for (Iterator i = outs.iterator(); i.hasNext();)
177                 {
178                     // We know this has a holder, so just unwrap the value
179                     RPCParam param = (RPCParam)i.next();
180                     Holder holder = (Holder)param.getObjectValue();
181                     Object value = JavaUtils.getHolderValue(holder);
182                     ParameterDesc paramDesc = param.getParamDesc();
183 
184                     param.setObjectValue(value);
185                     if (paramDesc != null && paramDesc.isOutHeader())
186                     {
187                         resEnv.addHeader(new RPCHeaderParam(param));
188                     }
189                     else
190                     {
191                         resBody.addParam(param);
192                     }
193                 }
194             }
195         }
196         catch (Exception e)
197         {
198             throw e;
199         }
200         return resBody;
201     }
202 }