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