1
2
3
4
5
6
7
8
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
49
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 super(connector, flowConstruct, endpoint);
67
68 this.connector = (AxisConnector) connector;
69 try
70 {
71 AxisServiceProxy.setProperties(endpoint.getProperties());
72 create();
73 }
74 catch (Exception e)
75 {
76 throw new CreateException(e, this);
77 }
78 }
79
80 protected void create() throws Exception
81 {
82 if (!(flowConstruct instanceof Service))
83 {
84 throw new IllegalArgumentException(
85 "Only the Service flow constuct is supported by the axis transport");
86 }
87 Service service = (Service) flowConstruct;
88
89
90 AxisProperties.setProperty("axis.doAutoTypes", String.valueOf(connector.isDoAutoTypes()));
91 String style = (String) endpoint.getProperties().get(AxisConnector.STYLE);
92 String use = (String) endpoint.getProperties().get(AxisConnector.USE);
93 String doc = (String) endpoint.getProperties().get("documentation");
94
95 EndpointURI uri = endpoint.getEndpointURI();
96 String serviceName = flowConstruct.getName();
97
98 SOAPService existing = this.connector.getAxis().getService(serviceName);
99 if (existing != null)
100 {
101 soapService = existing;
102 logger.debug("Using existing service for " + serviceName);
103 }
104 else
105 {
106
107
108 if (style != null && style.equalsIgnoreCase("message"))
109 {
110 logger.debug("Creating Message Provider");
111 soapService = new SOAPService(new MuleMsgProvider(connector));
112
113
114
115 }
116 else
117 {
118 logger.debug("Creating RPC Provider");
119 soapService = new SOAPService(new MuleRPCProvider(connector));
120 }
121
122 soapService.setEngine(connector.getAxis());
123 }
124
125 String servicePath = uri.getPath();
126 soapService.setOption(serviceName, this);
127 soapService.setOption(AxisConnector.SERVICE_PROPERTY_SERVCE_PATH, servicePath);
128 soapService.setOption(AxisConnector.SERVICE_PROPERTY_COMPONENT_NAME, serviceName);
129
130 soapService.setName(serviceName);
131
132
133 Map options = (Map) endpoint.getProperties().get(AXIS_OPTIONS);
134
135
136 if (options == null)
137 {
138 options = new HashMap(2);
139 }
140 if (options.get("wsdlServiceElement") == null)
141 {
142 options.put("wsdlServiceElement", serviceName);
143 }
144
145 Map.Entry entry;
146 for (Iterator iterator = options.entrySet().iterator(); iterator.hasNext();)
147 {
148 entry = (Map.Entry) iterator.next();
149 soapService.setOption(entry.getKey().toString(), entry.getValue());
150 logger.debug("Adding Axis option: " + entry);
151 }
152
153
154 Class[] interfaces = AxisServiceProxy.getInterfacesForComponent(service);
155 if (interfaces.length == 0)
156 {
157 throw new InitialisationException(
158 AxisMessages.objectMustImplementAnInterface(serviceName), service);
159 }
160
161
162 String methodNames = "*";
163
164 Map methods = (Map) endpoint.getProperties().get(AxisConnector.SOAP_METHODS);
165 if (methods != null)
166 {
167 Iterator i = methods.keySet().iterator();
168 StringBuffer buf = new StringBuffer(64);
169 while (i.hasNext())
170 {
171 String name = (String) i.next();
172 Object m = methods.get(name);
173 SoapMethod method;
174 if (m instanceof List)
175 {
176 method = new SoapMethod(name, (List) m);
177 }
178 else
179 {
180 method = new SoapMethod(name, (String) m);
181 }
182
183 List namedParameters = method.getNamedParameters();
184 ParameterDesc[] parameters = new ParameterDesc[namedParameters.size()];
185 for (int j = 0; j < namedParameters.size(); j++)
186 {
187 NamedParameter parameter = (NamedParameter) namedParameters.get(j);
188 byte mode = ParameterDesc.INOUT;
189 if (parameter.getMode().equals(ParameterMode.IN))
190 {
191 mode = ParameterDesc.IN;
192 }
193 else if (parameter.getMode().equals(ParameterMode.OUT))
194 {
195 mode = ParameterDesc.OUT;
196 }
197
198 parameters[j] = new ParameterDesc(parameter.getName(), mode, parameter.getType());
199 }
200
201 soapService.getServiceDescription().addOperationDesc(
202 new OperationDesc(method.getName().getLocalPart(), parameters, method.getReturnType()));
203 buf.append(method.getName().getLocalPart() + ",");
204 }
205 methodNames = buf.toString();
206 methodNames = methodNames.substring(0, methodNames.length() - 1);
207 }
208 else
209 {
210 String[] methodNamesArray = AxisServiceProxy.getMethodNames(interfaces);
211 StringBuffer buf = new StringBuffer(64);
212 for (int i = 0; i < methodNamesArray.length; i++)
213 {
214 buf.append(methodNamesArray[i]).append(",");
215 }
216 methodNames = buf.toString();
217 methodNames = methodNames.substring(0, methodNames.length() - 1);
218 }
219
220 String className = interfaces[0].getName();
221
222
223 String namespace = (String) endpoint.getProperties().get(SERVICE_NAMESPACE);
224 if (namespace == null)
225 {
226 namespace = Namespaces.makeNamespace(className);
227 }
228
229
230 String wsdlFile = (String) endpoint.getProperties().get("wsdlFile");
231 if (wsdlFile != null)
232 {
233 soapService.getServiceDescription().setWSDLFile(wsdlFile);
234 }
235
236
237
238
239
240
241
242
243
244
245
246
247
248 setOptionIfNotset(soapService, JavaProvider.OPTION_WSDL_SERVICEPORT, serviceName);
249 setOptionIfNotset(soapService, JavaProvider.OPTION_CLASSNAME, className);
250 setOptionIfNotset(soapService, JavaProvider.OPTION_SCOPE, "Request");
251 if (StringUtils.isNotBlank(namespace))
252 {
253 setOptionIfNotset(soapService, JavaProvider.OPTION_WSDL_TARGETNAMESPACE, namespace);
254 }
255
256
257 if (methodNames == null)
258 {
259 setOptionIfNotset(soapService, JavaProvider.OPTION_ALLOWEDMETHODS, "*");
260 }
261 else
262 {
263 setOptionIfNotset(soapService, JavaProvider.OPTION_ALLOWEDMETHODS, methodNames);
264 }
265
266
267
268
269
270 if (style != null)
271 {
272 Style s = Style.getStyle(style);
273 if (s == null)
274 {
275 throw new CreateException(
276 CoreMessages.valueIsInvalidFor(style, AxisConnector.STYLE), this);
277 }
278 else
279 {
280 soapService.setStyle(s);
281 }
282 }
283
284 if (use != null)
285 {
286 Use u = Use.getUse(use);
287 if (u == null)
288 {
289 throw new CreateException(CoreMessages.valueIsInvalidFor(use, AxisConnector.USE),
290 this);
291 }
292 else
293 {
294 soapService.setUse(u);
295 }
296 }
297
298 soapService.getServiceDescription().setDocumentation(doc);
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316 soapService.setName(serviceName);
317
318
319 Component component = service.getComponent();
320 if (component instanceof JavaComponent)
321 {
322 ((AbstractJavaComponent) component).getObjectFactory().addObjectInitialisationCallback(
323 new AxisInitialisationCallback(soapService));
324 }
325
326 if (uri.getScheme().equalsIgnoreCase("servlet"))
327 {
328 connector.addServletService(soapService);
329 String endpointUrl = uri.getAddress() + "/" + serviceName;
330 endpointUrl = endpointUrl.replaceFirst("servlet:", "http:");
331 soapService.getServiceDescription().setEndpointURL(endpointUrl);
332 }
333 else
334 {
335 soapService.getServiceDescription().setEndpointURL(uri.getAddress() + "/" + serviceName);
336 }
337 if (StringUtils.isNotBlank(namespace))
338 {
339 soapService.getServiceDescription().setDefaultNamespace(namespace);
340 }
341 soapService.init();
342 soapService.stop();
343 }
344
345 @Override
346 protected void doConnect() throws Exception
347 {
348
349 connector.getServerProvider().deployService(soapService.getName(), soapService);
350 connector.registerReceiverWithMuleService(this, endpoint.getEndpointURI());
351 }
352
353 @Override
354 protected void doDisconnect() throws Exception
355 {
356 try
357 {
358 doStop();
359 }
360 catch (MuleException e)
361 {
362 logger.error(e.getMessage(), e);
363 }
364
365
366
367 connector.unregisterReceiverWithMuleService(this, endpoint.getEndpointURI());
368 }
369
370 @Override
371 protected void doStart() throws MuleException
372 {
373 if (soapService != null)
374 {
375 soapService.start();
376 }
377 }
378
379 @Override
380 protected void doStop() throws MuleException
381 {
382 if (soapService != null)
383 {
384 soapService.stop();
385 }
386 }
387
388 @Override
389 protected void doDispose()
390 {
391
392 }
393
394 protected void setOptionIfNotset(SOAPService service, String option, Object value)
395 {
396 Object val = service.getOption(option);
397 if (val == null)
398 {
399 service.setOption(option, value);
400 }
401 }
402
403 public SOAPService getSoapService()
404 {
405 return soapService;
406 }
407 }