View Javadoc

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