1
2
3
4
5
6
7
8
9
10
11 package org.mule.transport.cxf;
12
13 import org.mule.DefaultMuleMessage;
14 import org.mule.api.MuleEvent;
15 import org.mule.api.MuleMessage;
16 import org.mule.api.config.MuleProperties;
17 import org.mule.api.endpoint.EndpointURI;
18 import org.mule.api.endpoint.OutboundEndpoint;
19 import org.mule.api.transformer.TransformerException;
20 import org.mule.transport.AbstractMessageDispatcher;
21 import org.mule.transport.soap.SoapConstants;
22 import org.mule.util.TemplateParser;
23
24 import java.lang.reflect.Method;
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.HashMap;
28 import java.util.Iterator;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.Set;
32 import java.util.regex.Pattern;
33
34 import javax.activation.DataHandler;
35 import javax.xml.namespace.QName;
36 import javax.xml.ws.BindingProvider;
37
38 import org.apache.cxf.endpoint.Client;
39 import org.apache.cxf.endpoint.ClientImpl;
40 import org.apache.cxf.service.model.BindingOperationInfo;
41
42
43
44
45
46 public class CxfMessageDispatcher extends AbstractMessageDispatcher
47 {
48
49 private static final String URI_REGEX = "cxf:\\[(.+?)\\]:(.+?)/\\[(.+?)\\]:(.+?)";
50 Pattern URI_PATTERN = Pattern.compile(URI_REGEX);
51
52 protected final CxfConnector connector;
53 protected ClientWrapper wrapper;
54 private final TemplateParser soapActionTemplateParser = TemplateParser.createAntStyleParser();
55
56 public CxfMessageDispatcher(OutboundEndpoint endpoint)
57 {
58 super(endpoint);
59 this.connector = (CxfConnector) endpoint.getConnector();
60 }
61
62
63
64
65
66
67
68
69
70 protected void doConnect() throws Exception
71 {
72 wrapper = new ClientWrapper();
73 wrapper.setBus(connector.getCxfBus());
74 wrapper.setEndpoint(endpoint);
75 wrapper.initialize();
76 }
77
78 protected void doDisconnect() throws Exception
79 {
80 wrapper = null;
81 }
82
83 protected void doDispose()
84 {
85
86 }
87
88
89 protected Object[] getArgs(MuleEvent event) throws TransformerException
90 {
91 Object payload = event.transformMessage();
92 Object[] args;
93
94 if (payload instanceof Object[])
95 {
96 args = (Object[])payload;
97 }
98 else
99 {
100 args = new Object[]{payload};
101 }
102
103 MuleMessage message = event.getMessage();
104 Set<?> attachmentNames = message.getAttachmentNames();
105 if (attachmentNames != null && !attachmentNames.isEmpty())
106 {
107 List<DataHandler> attachments = new ArrayList<DataHandler>();
108 for (Iterator<?> i = attachmentNames.iterator(); i.hasNext();)
109 {
110 attachments.add(message.getAttachment((String)i.next()));
111 }
112 List<Object> temp = new ArrayList<Object>(Arrays.asList(args));
113 temp.add(attachments.toArray(new DataHandler[0]));
114 args = temp.toArray();
115 }
116
117 if (args.length == 0)
118 {
119 return null;
120 }
121 return args;
122 }
123
124 protected MuleMessage doSend(MuleEvent event) throws Exception
125 {
126 ((ClientImpl)wrapper.getClient()).setSynchronousTimeout(event.getTimeout());
127 if (!wrapper.isClientProxyAvailable())
128 {
129 return doSendWithClient(event);
130 }
131 else
132 {
133 return doSendWithProxy(event);
134 }
135 }
136
137 protected MuleMessage doSendWithProxy(MuleEvent event) throws Exception
138 {
139 Method method = wrapper.getMethod(event);
140
141 Map<String, Object> props = new HashMap<String, Object>();
142 props.put(MuleProperties.MULE_EVENT_PROPERTY, event);
143
144
145 String soapAction = (String)event.getMessage().getProperty(SoapConstants.SOAP_ACTION_PROPERTY);
146 if (soapAction != null)
147 {
148 soapAction = parseSoapAction(soapAction, new QName(method.getName()), event);
149 props.put(org.apache.cxf.binding.soap.SoapConstants.SOAP_ACTION, soapAction);
150 }
151
152 BindingProvider bp = wrapper.getClientProxy();
153 bp.getRequestContext().putAll(props);
154
155 Object response = method.invoke(wrapper.getClientProxy(), (Object[]) getArgs(event));
156
157
158
159 return buildResponseMessage(event, new Object[] { response });
160 }
161
162 protected MuleMessage doSendWithClient(MuleEvent event) throws Exception
163 {
164 BindingOperationInfo bop = wrapper.getOperation(event);
165
166 Map<String, Object> props = new HashMap<String, Object>();
167 props.put(MuleProperties.MULE_EVENT_PROPERTY, event);
168
169
170 String soapAction = (String)event.getMessage().getProperty(SoapConstants.SOAP_ACTION_PROPERTY);
171 if (soapAction != null)
172 {
173 soapAction = parseSoapAction(soapAction, bop.getName(), event);
174 props.put(org.apache.cxf.binding.soap.SoapConstants.SOAP_ACTION, soapAction);
175 event.getMessage().setProperty(SoapConstants.SOAP_ACTION_PROPERTY, soapAction);
176 }
177
178 Map<String, Object> ctx = new HashMap<String, Object>();
179 ctx.put(Client.REQUEST_CONTEXT, props);
180 ctx.put(Client.RESPONSE_CONTEXT, props);
181
182
183 Object[] arr = event.getMessage().getPropertyNames().toArray();
184 String head;
185
186 for (int i = 0; i < arr.length; i++)
187 {
188 head = (String) arr[i];
189 if ((head != null) && (!head.startsWith("MULE")))
190 {
191 props.put((String) arr[i], event.getMessage().getProperty((String) arr[i]));
192 }
193 }
194
195 Object[] response = wrapper.getClient().invoke(bop, getArgs(event), ctx);
196
197 return buildResponseMessage(event, response);
198 }
199
200 protected MuleMessage buildResponseMessage(MuleEvent event, Object[] response)
201 {
202 MuleMessage result = null;
203 if (response != null && response.length <= 1)
204 {
205 if (response.length == 1)
206 {
207 result = new DefaultMuleMessage(response[0], event.getMessage());
208 }
209 }
210 else
211 {
212 result = new DefaultMuleMessage(response, event.getMessage());
213 }
214
215 return result;
216 }
217 protected void doDispatch(MuleEvent event) throws Exception
218 {
219 doSend(event);
220 }
221
222 public String parseSoapAction(String soapAction, QName method, MuleEvent event)
223 {
224 EndpointURI endpointURI = event.getEndpoint().getEndpointURI();
225 Map<String, String> properties = new HashMap<String, String>();
226 MuleMessage msg = event.getMessage();
227 for (Iterator<?> iterator = msg.getPropertyNames().iterator(); iterator.hasNext();)
228 {
229 String propertyKey = (String)iterator.next();
230 properties.put(propertyKey, msg.getProperty(propertyKey).toString());
231 }
232 properties.put(MuleProperties.MULE_METHOD_PROPERTY, method.getLocalPart());
233 properties.put("methodNamespace", method.getNamespaceURI());
234 properties.put("address", endpointURI.getAddress());
235 properties.put("scheme", endpointURI.getScheme());
236 properties.put("host", endpointURI.getHost());
237 properties.put("port", String.valueOf(endpointURI.getPort()));
238 properties.put("path", endpointURI.getPath());
239 properties.put("hostInfo", endpointURI.getScheme()
240 + "://"
241 + endpointURI.getHost()
242 + (endpointURI.getPort() > -1
243 ? ":" + String.valueOf(endpointURI.getPort()) : ""));
244 if (event.getService() != null)
245 {
246 properties.put("serviceName", event.getService().getName());
247 }
248
249 soapAction = soapActionTemplateParser.parse(properties, soapAction);
250
251 if (logger.isDebugEnabled())
252 {
253 logger.debug("SoapAction for this call is: " + soapAction);
254 }
255
256 return soapAction;
257 }
258 }