1
2
3
4
5
6
7
8
9
10
11 package org.mule.providers.soap.axis;
12
13 import org.mule.config.MuleProperties;
14 import org.mule.config.i18n.CoreMessages;
15 import org.mule.impl.MuleMessage;
16 import org.mule.impl.endpoint.MuleEndpointURI;
17 import org.mule.providers.AbstractMessageDispatcher;
18 import org.mule.providers.NullPayload;
19 import org.mule.providers.soap.NamedParameter;
20 import org.mule.providers.soap.SoapConstants;
21 import org.mule.providers.soap.SoapMethod;
22 import org.mule.providers.soap.i18n.SoapMessages;
23 import org.mule.umo.UMOEvent;
24 import org.mule.umo.UMOMessage;
25 import org.mule.umo.endpoint.UMOEndpointURI;
26 import org.mule.umo.endpoint.UMOImmutableEndpoint;
27 import org.mule.umo.provider.DispatchException;
28 import org.mule.umo.transformer.TransformerException;
29 import org.mule.util.BeanUtils;
30 import org.mule.util.StringUtils;
31 import org.mule.util.TemplateParser;
32
33 import java.util.ArrayList;
34 import java.util.Arrays;
35 import java.util.HashMap;
36 import java.util.Iterator;
37 import java.util.List;
38 import java.util.Map;
39 import java.util.Properties;
40
41 import javax.activation.DataHandler;
42 import javax.xml.namespace.QName;
43 import javax.xml.soap.SOAPEnvelope;
44
45 import org.apache.axis.AxisProperties;
46 import org.apache.axis.EngineConfiguration;
47 import org.apache.axis.Message;
48 import org.apache.axis.MessageContext;
49 import org.apache.axis.attachments.AttachmentPart;
50 import org.apache.axis.client.Call;
51 import org.apache.axis.client.Service;
52 import org.apache.axis.configuration.FileProvider;
53 import org.apache.axis.constants.Style;
54 import org.apache.axis.constants.Use;
55 import org.apache.axis.wsdl.fromJava.Namespaces;
56 import org.apache.axis.wsdl.fromJava.Types;
57
58
59
60
61
62 public class AxisMessageDispatcher extends AbstractMessageDispatcher
63 {
64
65 protected EngineConfiguration clientConfig;
66 protected AxisConnector connector;
67 protected Service service;
68 private Map callParameters;
69
70 public AxisMessageDispatcher(UMOImmutableEndpoint endpoint)
71 {
72 super(endpoint);
73 this.connector = (AxisConnector)endpoint.getConnector();
74 AxisProperties.setProperty("axis.doAutoTypes", Boolean.toString(connector.isDoAutoTypes()));
75 }
76
77 protected void doConnect() throws Exception
78 {
79 if (service == null)
80 {
81 service = createService(endpoint);
82 }
83 }
84
85 protected void doDisconnect() throws Exception
86 {
87 if (service != null)
88 {
89 service = null;
90 }
91 }
92
93 protected void doDispose()
94 {
95
96 }
97
98 protected synchronized EngineConfiguration getClientConfig(UMOImmutableEndpoint endpoint)
99 {
100 if (clientConfig == null)
101 {
102
103 String config;
104 config = (String)endpoint.getProperty(AxisConnector.AXIS_CLIENT_CONFIG_PROPERTY);
105
106 if (config != null)
107 {
108 clientConfig = new FileProvider(config);
109 }
110 else
111 {
112 clientConfig = connector.getClientProvider();
113 }
114 }
115 return clientConfig;
116 }
117
118 protected Service createService(UMOImmutableEndpoint endpoint) throws Exception
119 {
120
121 EngineConfiguration config = getClientConfig(endpoint);
122 return new Service(config);
123 }
124
125 protected void doDispatch(UMOEvent event) throws Exception
126 {
127 Object[] args = getArgs(event);
128 Call call = getCall(event, args);
129
130
131
132
133 call.setProperty("axis.one.way", Boolean.TRUE);
134 call.setProperty(MuleProperties.MULE_EVENT_PROPERTY, event);
135 call.invoke(args);
136 }
137
138 protected UMOMessage doSend(UMOEvent event) throws Exception
139 {
140 Call call;
141 Object result;
142 Object[] args = getArgs(event);
143 call = getCall(event, args);
144 result = call.invoke(args);
145 if (result == null)
146 {
147 return null;
148 }
149 else
150 {
151 UMOMessage resultMessage = new MuleMessage(result, event.getMessage());
152 setMessageContextProperties(resultMessage, call.getMessageContext());
153 return resultMessage;
154 }
155 }
156
157 protected Call getCall(UMOEvent event, Object[] args) throws Exception
158 {
159 UMOEndpointURI endpointUri = event.getEndpoint().getEndpointURI();
160 Object method = getInitialMethod(event);
161 Call call = (Call) service.createCall();
162 parseStyle(event, call);
163 parseUse(event, call);
164
165
166 BeanUtils.populateWithoutFail(call, event.getEndpoint().getProperties(), false);
167 call.setTargetEndpointAddress(endpointUri.getAddress());
168
169 method = refineMethod(event, call, method);
170 String methodNamespace = call.getOperationName().getNamespaceURI();
171
172
173 call.setProperty(MuleProperties.MULE_EVENT_PROPERTY, event);
174 call.setProperty(MuleProperties.MULE_ENDPOINT_PROPERTY, event.getEndpoint());
175
176 setCustomProperties(event, call);
177 call.setTimeout(new Integer(event.getTimeout()));
178 setUserCredentials(endpointUri, call);
179
180 Map methodCalls = (Map)event.getMessage().getProperty("soapMethods");
181 if (methodCalls == null && !(method instanceof SoapMethod))
182 {
183 buildSoapMethods(event, call, method, methodNamespace, args);
184 }
185
186 setCallParams(call, event, call.getOperationName());
187 setSoapAction(event, endpointUri, call);
188 addAttachments(event, call);
189 return call;
190 }
191
192 protected void addAttachments(UMOEvent event, Call call)
193 {
194
195 for (Iterator iterator = event.getMessage().getAttachmentNames().iterator(); iterator.hasNext();)
196 {
197 String name = (String)iterator.next();
198 DataHandler dh = event.getMessage().getAttachment(name);
199 AttachmentPart part = new AttachmentPart(dh);
200 call.addAttachmentPart(part);
201 }
202 }
203
204 protected void setSoapAction(UMOEvent event, UMOEndpointURI endpointUri, Call call)
205 {
206
207 String soapAction = (String)event.getMessage().getProperty(SoapConstants.SOAP_ACTION_PROPERTY);
208 if (soapAction != null)
209 {
210 soapAction = parseSoapAction(soapAction, call.getOperationName(), event);
211 call.setSOAPActionURI(soapAction);
212 call.setUseSOAPAction(Boolean.TRUE.booleanValue());
213 }
214 else
215 {
216 call.setSOAPActionURI(endpointUri.getAddress());
217 }
218 }
219
220 protected void buildSoapMethods(UMOEvent event, Call call, Object method, String methodNamespace, Object[] args)
221 {
222 List params = new ArrayList();
223 for (int i = 0; i < args.length; i++)
224 {
225 if (args[i] == null)
226 {
227 QName qname = call.getTypeMapping().getTypeQName(Object.class);
228 params.add("value" + i + ";qname{" + qname.getPrefix() + ":" + qname.getLocalPart() + ":"
229 + qname.getNamespaceURI() + "};in");
230 }
231 else if (args[i] instanceof DataHandler[])
232 {
233 params.add("attachments;qname{DataHandler:http://xml.apache.org/xml-soap};in");
234
235 }
236 else if (args[i] instanceof Map && connector.isTreatMapAsNamedParams())
237 {
238 for (Iterator iterator = ((Map)args[i]).entrySet().iterator(); iterator.hasNext();)
239 {
240 Map.Entry entry = (Map.Entry)iterator.next();
241 if (call.getTypeMapping().getTypeQName(entry.getValue().getClass()) != null)
242 {
243 QName type = call.getTypeMapping().getTypeQName(entry.getValue().getClass());
244 params.add("qname{" + entry.getKey().toString()
245 + (methodNamespace == null ? "" : ":" + methodNamespace) + "};qname{"
246 + type.getPrefix() + ":" + type.getLocalPart() + ":"
247 + type.getNamespaceURI() + "};in");
248 }
249 else
250 {
251 params.add("value" + i + ";qname{"
252 + Types.getLocalNameFromFullName(args[i].getClass().getName()) + ":"
253 + Namespaces.makeNamespace(args[i].getClass().getName()) + "};in");
254 params.add("qname{" + entry.getKey().toString()
255 + (methodNamespace == null ? "" : ":" + methodNamespace) + "};qname{"
256 + Types.getLocalNameFromFullName(args[i].getClass().getName()) + ":"
257 + Namespaces.makeNamespace(args[i].getClass().getName()) + "};in");
258 }
259
260 }
261 }
262 else if (call.getTypeMapping().getTypeQName(args[i].getClass()) != null)
263 {
264 QName qname = call.getTypeMapping().getTypeQName(args[i].getClass());
265 params.add("value" + i + ";qname{" + qname.getPrefix() + ":" + qname.getLocalPart() + ":"
266 + qname.getNamespaceURI() + "};in");
267 }
268 else
269 {
270 params.add("value" + i + ";qname{"
271 + Types.getLocalNameFromFullName(args[i].getClass().getName()) + ":"
272 + Namespaces.makeNamespace(args[i].getClass().getName()) + "};in");
273 }
274 }
275
276 HashMap map = new HashMap();
277 map.put(method, params);
278 event.getMessage().setProperty("soapMethods", map);
279 }
280
281 protected void setUserCredentials(UMOEndpointURI endpointUri, Call call)
282 {
283 if (endpointUri.getUserInfo() != null)
284 {
285 call.setUsername(endpointUri.getUsername());
286 call.setPassword(endpointUri.getPassword());
287 }
288 }
289
290 protected void setCustomProperties(UMOEvent event, Call call)
291 {
292 for (Iterator iter = event.getMessage().getPropertyNames().iterator(); iter.hasNext();)
293 {
294 String key = (String)iter.next();
295 if (!(key.startsWith(MuleProperties.PROPERTY_PREFIX)))
296 {
297 Object value = event.getMessage().getProperty(key);
298 if (value != null)
299 {
300 call.setProperty(key, value);
301 }
302 }
303 }
304 }
305
306 protected Object refineMethod(UMOEvent event, Call call, Object method)
307 {
308 if (method instanceof String)
309 {
310
311
312 String methodNamespace = (String)event.getMessage().getProperty(SoapConstants.METHOD_NAMESPACE_PROPERTY);
313 if (methodNamespace != null)
314 {
315 call.setOperationName(new QName(methodNamespace, method.toString()));
316 }
317 else
318 {
319 call.setOperationName(new QName(method.toString()));
320 }
321 }
322 else if (method instanceof QName)
323 {
324 call.setOperationName((QName)method);
325 method = ((QName)method).getLocalPart();
326 }
327 else
328 {
329 call.setOperationName(((SoapMethod)method).getName());
330 }
331 return method;
332 }
333
334 protected void parseUse(UMOEvent event, Call call)
335 {
336
337 String use = event.getMessage().getStringProperty("use", null);
338 if (use != null)
339 {
340 Use u = Use.getUse(use);
341 if (u == null)
342 {
343 throw new IllegalArgumentException(
344 CoreMessages.valueIsInvalidFor(use, "use").toString());
345 }
346 else
347 {
348 call.setOperationUse(u);
349 }
350 }
351 }
352
353 protected void parseStyle(UMOEvent event, Call call)
354 {
355
356
357
358 String style = event.getMessage().getStringProperty("style", null);
359 if (style != null)
360 {
361 Style s = Style.getStyle(style);
362 if (s == null)
363 {
364 throw new IllegalArgumentException(
365 CoreMessages.valueIsInvalidFor(style, "style").toString());
366 }
367 else
368 {
369 call.setOperationStyle(s);
370 }
371 }
372 }
373
374 protected Object getInitialMethod(UMOEvent event) throws DispatchException
375 {
376 Object method = event.getMessage().getProperty(MuleProperties.MULE_METHOD_PROPERTY);
377 if (method == null)
378 {
379 method = event.getEndpoint().getEndpointURI().getParams().getProperty(MuleProperties.MULE_METHOD_PROPERTY);
380 }
381 if (method == null)
382 {
383 throw new DispatchException(
384 SoapMessages.cannotInvokeCallWithoutOperation(), event.getMessage(),
385 event.getEndpoint());
386 }
387 else if (method instanceof SoapMethod)
388 {
389 synchronized (this)
390 {
391 if (callParameters == null)
392 {
393 callParameters = new HashMap();
394 }
395 callParameters.put(((SoapMethod)method).getName().getLocalPart(), method);
396 }
397 }
398 return method;
399 }
400
401 private Object[] getArgs(UMOEvent event) throws TransformerException
402 {
403 Object payload = event.getTransformedMessage();
404 Object[] args;
405 if (payload instanceof Object[])
406 {
407 args = (Object[])payload;
408 }
409 else
410 {
411 args = new Object[]{payload};
412 }
413 if (event.getMessage().getAttachmentNames() != null
414 && event.getMessage().getAttachmentNames().size() > 0)
415 {
416 ArrayList attachments = new ArrayList();
417 Iterator i = event.getMessage().getAttachmentNames().iterator();
418 while (i.hasNext())
419 {
420 attachments.add(event.getMessage().getAttachment((String)i.next()));
421 }
422 ArrayList temp = new ArrayList(Arrays.asList(args));
423 temp.add(attachments.toArray(new DataHandler[0]));
424 args = temp.toArray();
425 }
426 return args;
427 }
428
429 protected void setMessageContextProperties(UMOMessage message, MessageContext ctx)
430 {
431 String temp = ctx.getStrProp(MuleProperties.MULE_CORRELATION_ID_PROPERTY);
432 if (StringUtils.isNotBlank(temp))
433 {
434 message.setCorrelationId(temp);
435 }
436 temp = ctx.getStrProp(MuleProperties.MULE_CORRELATION_GROUP_SIZE_PROPERTY);
437 if (StringUtils.isNotBlank(temp))
438 {
439 message.setCorrelationGroupSize(Integer.parseInt(temp));
440 }
441 temp = ctx.getStrProp(MuleProperties.MULE_CORRELATION_SEQUENCE_PROPERTY);
442 if (StringUtils.isNotBlank(temp))
443 {
444 message.setCorrelationSequence(Integer.parseInt(temp));
445 }
446 temp = ctx.getStrProp(MuleProperties.MULE_REPLY_TO_PROPERTY);
447 if (StringUtils.isNotBlank(temp))
448 {
449 message.setReplyTo(temp);
450 }
451 }
452
453 protected void setMessageContextAttachments(UMOMessage message, MessageContext ctx) throws Exception
454 {
455 int x = 0;
456 for (Iterator iterator = ctx.getMessage().getAttachments(); iterator.hasNext(); x++)
457 {
458 message.addAttachment(String.valueOf(x),
459 ((AttachmentPart)iterator.next()).getActivationDataHandler());
460 }
461 }
462
463
464
465
466
467
468
469
470
471
472
473
474 protected UMOMessage doReceive(long timeout) throws Exception
475 {
476 Call call = new Call(service);
477 String uri = endpoint.getEndpointURI().toString();
478 call.setSOAPActionURI(uri);
479 call.setTargetEndpointAddress(uri);
480
481 Properties params = endpoint.getEndpointURI().getUserParams();
482 String method = (String)params.remove(MuleProperties.MULE_METHOD_PROPERTY);
483 call.setOperationName(method);
484
485 String args[] = new String[params.size()];
486 int i = 0;
487 for (Iterator iterator = params.values().iterator(); iterator.hasNext(); i++)
488 {
489 args[i] = iterator.next().toString();
490 }
491
492 call.setOperationName(method);
493 call.setProperty(MuleProperties.MULE_ENDPOINT_PROPERTY, endpoint);
494 Object result = call.invoke(method, args);
495 return createMessage(result, call);
496 }
497
498 public UMOMessage receive(String endpoint, Object[] args) throws Exception
499 {
500 Call call = new Call(service);
501
502 call.setSOAPActionURI(endpoint);
503 call.setTargetEndpointAddress(endpoint);
504
505 if (!endpoint.startsWith("axis:"))
506 {
507 endpoint = "axis:" + endpoint;
508 }
509 UMOEndpointURI ep = new MuleEndpointURI(endpoint);
510 String method = (String)ep.getParams().remove(MuleProperties.MULE_METHOD_PROPERTY);
511 call.setOperationName(method);
512
513 call.setOperationName(method);
514 Object result = call.invoke(method, args);
515 return createMessage(result, call);
516 }
517
518 public UMOMessage receive(String endpoint, SOAPEnvelope envelope) throws Exception
519 {
520 Call call = new Call(service);
521
522 call.setSOAPActionURI(endpoint);
523 call.setTargetEndpointAddress(endpoint);
524 Object result = call.invoke(new Message(envelope));
525 return createMessage(result, call);
526 }
527
528 protected UMOMessage createMessage(Object result, Call call)
529 {
530 if (result == null)
531 {
532 result = NullPayload.getInstance();
533 }
534 Map props = new HashMap();
535 Iterator iter = call.getMessageContext().getPropertyNames();
536 Object key;
537 while (iter.hasNext())
538 {
539 key = iter.next();
540 props.put(key, call.getMessageContext().getProperty(key.toString()));
541 }
542 props.put("soap.message", call.getMessageContext().getMessage());
543 call.clearHeaders();
544 call.clearOperation();
545 return new MuleMessage(result, props);
546 }
547
548 public String parseSoapAction(String soapAction, QName method, UMOEvent event)
549 {
550 UMOEndpointURI endpointURI = event.getEndpoint().getEndpointURI();
551 Map properties = new HashMap();
552 UMOMessage msg = event.getMessage();
553 for (Iterator iterator = msg.getPropertyNames().iterator(); iterator.hasNext();)
554 {
555 String propertyKey = (String)iterator.next();
556 properties.put(propertyKey, msg.getProperty(propertyKey));
557 }
558 properties.put(MuleProperties.MULE_METHOD_PROPERTY, method.getLocalPart());
559 properties.put("methodNamespace", method.getNamespaceURI());
560 properties.put("address", endpointURI.getAddress());
561 properties.put("scheme", endpointURI.getScheme());
562 properties.put("host", endpointURI.getHost());
563 properties.put("port", String.valueOf(endpointURI.getPort()));
564 properties.put("path", endpointURI.getPath());
565 properties.put("hostInfo", endpointURI.getScheme()
566 + "://"
567 + endpointURI.getHost()
568 + (endpointURI.getPort() > -1
569 ? ":" + String.valueOf(endpointURI.getPort()) : ""));
570 if (event.getComponent() != null)
571 {
572 properties.put("serviceName", event.getComponent().getDescriptor().getName());
573 }
574
575 TemplateParser tp = TemplateParser.createAntStyleParser();
576 soapAction = tp.parse(properties, soapAction);
577
578 if (logger.isDebugEnabled())
579 {
580 logger.debug("SoapAction for this call is: " + soapAction);
581 }
582 return soapAction;
583 }
584
585 private void setCallParams(Call call, UMOEvent event, QName method) throws ClassNotFoundException
586 {
587 synchronized (this)
588 {
589 if (callParameters == null)
590 {
591 loadCallParams(event, method.getNamespaceURI());
592 }
593 }
594
595 SoapMethod soapMethod = (SoapMethod)event.getMessage()
596 .removeProperty(MuleProperties.MULE_SOAP_METHOD);
597 if (soapMethod == null)
598 {
599 soapMethod = (SoapMethod)callParameters.get(method.getLocalPart());
600 }
601
602 if (soapMethod != null)
603 {
604 for (Iterator iterator = soapMethod.getNamedParameters().iterator(); iterator.hasNext();)
605 {
606 NamedParameter parameter = (NamedParameter)iterator.next();
607 call.addParameter(parameter.getName(), parameter.getType(), parameter.getMode());
608 }
609
610 if (soapMethod.getReturnType() != null)
611 {
612 call.setReturnType(soapMethod.getReturnType());
613 }
614 else if (soapMethod.getReturnClass() != null)
615 {
616 call.setReturnClass(soapMethod.getReturnClass());
617 }
618
619 call.setOperationName(soapMethod.getName());
620 }
621 }
622
623 private void loadCallParams(UMOEvent event, String namespace) throws ClassNotFoundException
624 {
625 Map methodCalls = (Map)event.getMessage().getProperty("soapMethods");
626 if (methodCalls == null)
627 {
628 return;
629 }
630
631 Map.Entry entry;
632 SoapMethod soapMethod;
633 callParameters = new HashMap();
634
635 for (Iterator iterator = methodCalls.entrySet().iterator(); iterator.hasNext();)
636 {
637 entry = (Map.Entry)iterator.next();
638 if (StringUtils.isEmpty(namespace))
639 {
640 if (entry.getValue() instanceof List)
641 {
642 soapMethod = new SoapMethod(entry.getKey().toString(), (List)entry.getValue());
643 }
644 else
645 {
646 soapMethod = new SoapMethod(entry.getKey().toString(), entry.getValue().toString());
647 }
648 }
649 else
650 {
651 if (entry.getValue() instanceof List)
652 {
653 soapMethod = new SoapMethod(new QName(namespace, entry.getKey().toString()),
654 (List)entry.getValue());
655 }
656 else
657 {
658 soapMethod = new SoapMethod(new QName(namespace, entry.getKey().toString()),
659 entry.getValue().toString());
660 }
661 }
662 callParameters.put(soapMethod.getName().getLocalPart(), soapMethod);
663 }
664 }
665
666 }