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