1 | |
|
2 | |
|
3 | |
|
4 | |
|
5 | |
|
6 | |
|
7 | |
|
8 | |
|
9 | |
|
10 | |
|
11 | |
package org.mule.transport.http.transformers; |
12 | |
|
13 | |
import org.mule.RequestContext; |
14 | |
import org.mule.api.MuleEvent; |
15 | |
import org.mule.api.MuleMessage; |
16 | |
import org.mule.api.config.MuleProperties; |
17 | |
import org.mule.api.transformer.TransformerException; |
18 | |
import org.mule.api.transport.OutputHandler; |
19 | |
import org.mule.api.transport.PropertyScope; |
20 | |
import org.mule.message.ds.StringDataSource; |
21 | |
import org.mule.transformer.AbstractMessageTransformer; |
22 | |
import org.mule.transformer.types.DataTypeFactory; |
23 | |
import org.mule.transport.NullPayload; |
24 | |
import org.mule.transport.http.HttpConnector; |
25 | |
import org.mule.transport.http.HttpConstants; |
26 | |
import org.mule.transport.http.StreamPayloadRequestEntity; |
27 | |
import org.mule.transport.http.i18n.HttpMessages; |
28 | |
import org.mule.util.IOUtils; |
29 | |
import org.mule.util.ObjectUtils; |
30 | |
import org.mule.util.StringUtils; |
31 | |
|
32 | |
import java.io.InputStream; |
33 | |
import java.io.Serializable; |
34 | |
import java.io.UnsupportedEncodingException; |
35 | |
import java.net.URI; |
36 | |
import java.net.URISyntaxException; |
37 | |
import java.net.URLEncoder; |
38 | |
import java.util.Iterator; |
39 | |
import java.util.Map; |
40 | |
|
41 | |
import javax.activation.DataHandler; |
42 | |
import javax.activation.FileDataSource; |
43 | |
import javax.activation.URLDataSource; |
44 | |
|
45 | |
import org.apache.commons.httpclient.HttpMethod; |
46 | |
import org.apache.commons.httpclient.HttpVersion; |
47 | |
import org.apache.commons.httpclient.methods.ByteArrayRequestEntity; |
48 | |
import org.apache.commons.httpclient.methods.DeleteMethod; |
49 | |
import org.apache.commons.httpclient.methods.EntityEnclosingMethod; |
50 | |
import org.apache.commons.httpclient.methods.GetMethod; |
51 | |
import org.apache.commons.httpclient.methods.HeadMethod; |
52 | |
import org.apache.commons.httpclient.methods.InputStreamRequestEntity; |
53 | |
import org.apache.commons.httpclient.methods.OptionsMethod; |
54 | |
import org.apache.commons.httpclient.methods.PostMethod; |
55 | |
import org.apache.commons.httpclient.methods.PutMethod; |
56 | |
import org.apache.commons.httpclient.methods.StringRequestEntity; |
57 | |
import org.apache.commons.httpclient.methods.TraceMethod; |
58 | |
import org.apache.commons.httpclient.methods.multipart.ByteArrayPartSource; |
59 | |
import org.apache.commons.httpclient.methods.multipart.FilePart; |
60 | |
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity; |
61 | |
import org.apache.commons.httpclient.methods.multipart.Part; |
62 | |
import org.apache.commons.httpclient.methods.multipart.StringPart; |
63 | |
import org.apache.commons.httpclient.params.HttpMethodParams; |
64 | |
import org.apache.commons.lang.SerializationUtils; |
65 | |
|
66 | |
|
67 | |
|
68 | |
|
69 | |
|
70 | |
public class ObjectToHttpClientMethodRequest extends AbstractMessageTransformer |
71 | |
{ |
72 | |
public ObjectToHttpClientMethodRequest() |
73 | 0 | { |
74 | 0 | setReturnDataType(DataTypeFactory.create(HttpMethod.class)); |
75 | 0 | registerSourceType(DataTypeFactory.MULE_MESSAGE); |
76 | 0 | registerSourceType(DataTypeFactory.BYTE_ARRAY); |
77 | 0 | registerSourceType(DataTypeFactory.STRING); |
78 | 0 | registerSourceType(DataTypeFactory.INPUT_STREAM); |
79 | 0 | registerSourceType(DataTypeFactory.create(OutputHandler.class)); |
80 | 0 | registerSourceType(DataTypeFactory.create(NullPayload.class)); |
81 | 0 | } |
82 | |
|
83 | |
@Override |
84 | |
public Object transformMessage(MuleMessage msg, String outputEncoding) throws TransformerException |
85 | |
{ |
86 | 0 | String method = detectHttpMethod(msg); |
87 | |
try |
88 | |
{ |
89 | |
HttpMethod httpMethod; |
90 | |
|
91 | 0 | if (HttpConstants.METHOD_GET.equals(method)) |
92 | |
{ |
93 | 0 | httpMethod = createGetMethod(msg, outputEncoding); |
94 | |
} |
95 | 0 | else if (HttpConstants.METHOD_POST.equalsIgnoreCase(method)) |
96 | |
{ |
97 | 0 | httpMethod = createPostMethod(msg, outputEncoding); |
98 | |
} |
99 | 0 | else if (HttpConstants.METHOD_PUT.equalsIgnoreCase(method)) |
100 | |
{ |
101 | 0 | httpMethod = createPutMethod(msg, outputEncoding); |
102 | |
} |
103 | 0 | else if (HttpConstants.METHOD_DELETE.equalsIgnoreCase(method)) |
104 | |
{ |
105 | 0 | httpMethod = createDeleteMethod(msg); |
106 | |
} |
107 | 0 | else if (HttpConstants.METHOD_HEAD.equalsIgnoreCase(method)) |
108 | |
{ |
109 | 0 | httpMethod = createHeadMethod(msg); |
110 | |
} |
111 | 0 | else if (HttpConstants.METHOD_OPTIONS.equalsIgnoreCase(method)) |
112 | |
{ |
113 | 0 | httpMethod = createOptionsMethod(msg); |
114 | |
} |
115 | 0 | else if (HttpConstants.METHOD_TRACE.equalsIgnoreCase(method)) |
116 | |
{ |
117 | 0 | httpMethod = createTraceMethod(msg); |
118 | |
} |
119 | |
else |
120 | |
{ |
121 | 0 | throw new TransformerException(HttpMessages.unsupportedMethod(method)); |
122 | |
} |
123 | |
|
124 | |
|
125 | 0 | final HttpMethodParams params = (HttpMethodParams) msg.removeProperty( |
126 | |
HttpConnector.HTTP_PARAMS_PROPERTY, PropertyScope.OUTBOUND); |
127 | 0 | if (params != null) |
128 | |
{ |
129 | 0 | httpMethod.setParams(params); |
130 | |
} |
131 | |
else |
132 | |
{ |
133 | |
|
134 | 0 | final String httpVersion = msg.getOutboundProperty(HttpConnector.HTTP_VERSION_PROPERTY, |
135 | |
HttpConstants.HTTP11); |
136 | 0 | if (HttpConstants.HTTP10.equals(httpVersion)) |
137 | |
{ |
138 | 0 | httpMethod.getParams().setVersion(HttpVersion.HTTP_1_0); |
139 | |
} |
140 | |
else |
141 | |
{ |
142 | 0 | httpMethod.getParams().setVersion(HttpVersion.HTTP_1_1); |
143 | |
} |
144 | |
} |
145 | |
|
146 | 0 | setHeaders(httpMethod, msg); |
147 | |
|
148 | 0 | return httpMethod; |
149 | |
} |
150 | 0 | catch (final Exception e) |
151 | |
{ |
152 | 0 | throw new TransformerException(this, e); |
153 | |
} |
154 | |
} |
155 | |
|
156 | |
protected String detectHttpMethod(MuleMessage msg) |
157 | |
{ |
158 | 0 | String method = msg.getOutboundProperty(HttpConnector.HTTP_METHOD_PROPERTY, null); |
159 | 0 | if (method == null) |
160 | |
{ |
161 | 0 | method = msg.getInvocationProperty(HttpConnector.HTTP_METHOD_PROPERTY, HttpConstants.METHOD_POST); |
162 | |
} |
163 | 0 | return method; |
164 | |
} |
165 | |
|
166 | |
protected HttpMethod createGetMethod(MuleMessage msg, String outputEncoding) throws Exception |
167 | |
{ |
168 | 0 | final Object src = msg.getPayload(); |
169 | |
|
170 | |
|
171 | |
|
172 | 0 | final URI uri = getURI(msg); |
173 | |
HttpMethod httpMethod; |
174 | 0 | String query = uri.getRawQuery(); |
175 | |
|
176 | 0 | httpMethod = new GetMethod(uri.toString()); |
177 | 0 | String paramName = msg.getOutboundProperty(HttpConnector.HTTP_GET_BODY_PARAM_PROPERTY, null); |
178 | 0 | if (paramName != null) |
179 | |
{ |
180 | 0 | paramName = URLEncoder.encode(paramName, outputEncoding); |
181 | |
|
182 | |
String paramValue; |
183 | 0 | Boolean encode = msg.getInvocationProperty(HttpConnector.HTTP_ENCODE_PARAMVALUE); |
184 | 0 | if (encode == null) |
185 | |
{ |
186 | 0 | encode = msg.getOutboundProperty(HttpConnector.HTTP_ENCODE_PARAMVALUE, true); |
187 | |
} |
188 | |
|
189 | 0 | if (encode) |
190 | |
{ |
191 | 0 | paramValue = URLEncoder.encode(src.toString(), outputEncoding); |
192 | |
} |
193 | |
else |
194 | |
{ |
195 | 0 | paramValue = src.toString(); |
196 | |
} |
197 | |
|
198 | 0 | if (!(src instanceof NullPayload) && !StringUtils.EMPTY.equals(src)) |
199 | |
{ |
200 | 0 | if (query == null) |
201 | |
{ |
202 | 0 | query = paramName + "=" + paramValue; |
203 | |
} |
204 | |
else |
205 | |
{ |
206 | 0 | query += "&" + paramName + "=" + paramValue; |
207 | |
} |
208 | |
} |
209 | |
} |
210 | |
|
211 | 0 | httpMethod.setQueryString(query); |
212 | 0 | return httpMethod; |
213 | |
} |
214 | |
|
215 | |
protected HttpMethod createPostMethod(MuleMessage msg, String outputEncoding) throws Exception |
216 | |
{ |
217 | 0 | URI uri = getURI(msg); |
218 | 0 | PostMethod postMethod = new PostMethod(uri.toString()); |
219 | |
|
220 | 0 | String bodyParameterName = getBodyParameterName(msg); |
221 | 0 | Object src = msg.getPayload(); |
222 | 0 | if (src instanceof Map) |
223 | |
{ |
224 | 0 | for (Map.Entry<?, ?> entry : ((Map<?, ?>) src).entrySet()) |
225 | |
{ |
226 | 0 | postMethod.addParameter(entry.getKey().toString(), entry.getValue().toString()); |
227 | |
} |
228 | |
} |
229 | 0 | else if (bodyParameterName != null) |
230 | |
{ |
231 | 0 | postMethod.addParameter(bodyParameterName, src.toString()); |
232 | |
|
233 | |
} |
234 | |
else |
235 | |
{ |
236 | 0 | setupEntityMethod(src, outputEncoding, msg, postMethod); |
237 | |
} |
238 | |
|
239 | |
|
240 | 0 | String outgoingContentType = msg.getInvocationProperty(HttpConstants.HEADER_CONTENT_TYPE); |
241 | 0 | if (outgoingContentType != null) |
242 | |
{ |
243 | 0 | postMethod.setRequestHeader(HttpConstants.HEADER_CONTENT_TYPE, outgoingContentType); |
244 | |
} |
245 | |
|
246 | 0 | return postMethod; |
247 | |
} |
248 | |
|
249 | |
protected String getBodyParameterName(MuleMessage message) |
250 | |
{ |
251 | 0 | String bodyParameter = message.getOutboundProperty(HttpConnector.HTTP_POST_BODY_PARAM_PROPERTY); |
252 | 0 | if (bodyParameter == null) |
253 | |
{ |
254 | 0 | bodyParameter = message.getInvocationProperty(HttpConnector.HTTP_POST_BODY_PARAM_PROPERTY); |
255 | |
} |
256 | 0 | return bodyParameter; |
257 | |
} |
258 | |
|
259 | |
protected HttpMethod createPutMethod(MuleMessage msg, String outputEncoding) throws Exception |
260 | |
{ |
261 | 0 | URI uri = getURI(msg); |
262 | 0 | PutMethod putMethod = new PutMethod(uri.toString()); |
263 | |
|
264 | 0 | Object payload = msg.getPayload(); |
265 | 0 | setupEntityMethod(payload, outputEncoding, msg, putMethod); |
266 | |
|
267 | 0 | return putMethod; |
268 | |
} |
269 | |
|
270 | |
protected HttpMethod createDeleteMethod(MuleMessage message) throws Exception |
271 | |
{ |
272 | 0 | URI uri = getURI(message); |
273 | 0 | return new DeleteMethod(uri.toString()); |
274 | |
} |
275 | |
|
276 | |
protected HttpMethod createHeadMethod(MuleMessage message) throws Exception |
277 | |
{ |
278 | 0 | URI uri = getURI(message); |
279 | 0 | return new HeadMethod(uri.toString()); |
280 | |
} |
281 | |
|
282 | |
protected HttpMethod createOptionsMethod(MuleMessage message) throws Exception |
283 | |
{ |
284 | 0 | URI uri = getURI(message); |
285 | 0 | return new OptionsMethod(uri.toString()); |
286 | |
} |
287 | |
|
288 | |
protected HttpMethod createTraceMethod(MuleMessage message) throws Exception |
289 | |
{ |
290 | 0 | URI uri = getURI(message); |
291 | 0 | return new TraceMethod(uri.toString()); |
292 | |
} |
293 | |
|
294 | |
protected URI getURI(MuleMessage message) throws URISyntaxException, TransformerException |
295 | |
{ |
296 | 0 | String endpointAddress = message.getOutboundProperty(MuleProperties.MULE_ENDPOINT_PROPERTY, null); |
297 | 0 | if (endpointAddress == null) |
298 | |
{ |
299 | 0 | throw new TransformerException( |
300 | |
HttpMessages.eventPropertyNotSetCannotProcessRequest(MuleProperties.MULE_ENDPOINT_PROPERTY), |
301 | |
this); |
302 | |
} |
303 | 0 | return new URI(endpointAddress); |
304 | |
} |
305 | |
|
306 | |
protected void setupEntityMethod(Object src, String encoding, MuleMessage msg, |
307 | |
EntityEnclosingMethod postMethod) throws UnsupportedEncodingException, TransformerException |
308 | |
{ |
309 | |
|
310 | |
|
311 | 0 | if (!(msg.getPayload() instanceof NullPayload)) |
312 | |
{ |
313 | 0 | String outboundMimeType = (String) msg.getProperty(HttpConstants.HEADER_CONTENT_TYPE, |
314 | |
PropertyScope.OUTBOUND); |
315 | 0 | if (outboundMimeType == null) |
316 | |
{ |
317 | 0 | outboundMimeType = (getEndpoint() != null ? getEndpoint().getMimeType() : null); |
318 | |
} |
319 | 0 | if (outboundMimeType == null) |
320 | |
{ |
321 | 0 | logger.info("Content-Type not set on outgoing request, defaulting to: " + outboundMimeType); |
322 | 0 | outboundMimeType = HttpConstants.DEFAULT_CONTENT_TYPE; |
323 | |
} |
324 | |
|
325 | 0 | if (encoding != null && !"UTF-8".equals(encoding.toUpperCase()) |
326 | |
&& outboundMimeType.indexOf("charset") == -1) |
327 | |
{ |
328 | 0 | outboundMimeType += "; charset=" + encoding; |
329 | |
} |
330 | |
|
331 | |
|
332 | |
|
333 | 0 | final String httpVersion = msg.getOutboundProperty(HttpConnector.HTTP_VERSION_PROPERTY, |
334 | |
HttpConstants.HTTP11); |
335 | 0 | if (HttpConstants.HTTP10.equals(httpVersion)) |
336 | |
{ |
337 | |
try |
338 | |
{ |
339 | 0 | src = msg.getPayloadAsBytes(); |
340 | |
} |
341 | 0 | catch (final Exception e) |
342 | |
{ |
343 | 0 | throw new TransformerException(this, e); |
344 | 0 | } |
345 | |
} |
346 | |
|
347 | 0 | if (msg.getOutboundAttachmentNames() != null && msg.getOutboundAttachmentNames().size() > 0) |
348 | |
{ |
349 | |
try |
350 | |
{ |
351 | 0 | postMethod.setRequestEntity(createMultiPart(msg, postMethod)); |
352 | 0 | return; |
353 | |
} |
354 | 0 | catch (final Exception e) |
355 | |
{ |
356 | 0 | throw new TransformerException(this, e); |
357 | |
} |
358 | |
} |
359 | 0 | if (src instanceof String) |
360 | |
{ |
361 | 0 | postMethod.setRequestEntity(new StringRequestEntity(src.toString(), outboundMimeType, encoding)); |
362 | 0 | return; |
363 | |
} |
364 | |
|
365 | 0 | if (src instanceof InputStream) |
366 | |
{ |
367 | 0 | postMethod.setRequestEntity(new InputStreamRequestEntity((InputStream) src, outboundMimeType)); |
368 | |
} |
369 | 0 | else if (src instanceof byte[]) |
370 | |
{ |
371 | 0 | postMethod.setRequestEntity(new ByteArrayRequestEntity((byte[]) src, outboundMimeType)); |
372 | |
} |
373 | 0 | else if (src instanceof OutputHandler) |
374 | |
{ |
375 | 0 | final MuleEvent event = RequestContext.getEvent(); |
376 | 0 | postMethod.setRequestEntity(new StreamPayloadRequestEntity((OutputHandler) src, event)); |
377 | 0 | } |
378 | |
else |
379 | |
{ |
380 | 0 | final byte[] buffer = SerializationUtils.serialize((Serializable) src); |
381 | 0 | postMethod.setRequestEntity(new ByteArrayRequestEntity(buffer, outboundMimeType)); |
382 | |
} |
383 | 0 | } |
384 | 0 | else if (msg.getOutboundAttachmentNames() != null && msg.getOutboundAttachmentNames().size() > 0) |
385 | |
{ |
386 | |
try |
387 | |
{ |
388 | 0 | postMethod.setRequestEntity(createMultiPart(msg, postMethod)); |
389 | |
} |
390 | 0 | catch (Exception e) |
391 | |
{ |
392 | 0 | throw new TransformerException(this, e); |
393 | 0 | } |
394 | |
} |
395 | 0 | } |
396 | |
|
397 | |
protected void setHeaders(HttpMethod httpMethod, MuleMessage msg) throws TransformerException |
398 | |
{ |
399 | 0 | for (String headerName : msg.getOutboundPropertyNames()) |
400 | |
{ |
401 | 0 | String headerValue = ObjectUtils.getString(msg.getOutboundProperty(headerName), null); |
402 | |
|
403 | 0 | if (headerName.startsWith(MuleProperties.PROPERTY_PREFIX)) |
404 | |
{ |
405 | |
|
406 | 0 | headerName = new StringBuffer(30).append("X-").append(headerName).toString(); |
407 | 0 | httpMethod.addRequestHeader(headerName, headerValue); |
408 | |
|
409 | |
} |
410 | 0 | else if (!HttpConstants.RESPONSE_HEADER_NAMES.containsKey(headerName) |
411 | |
&& !HttpConnector.HTTP_INBOUND_PROPERTIES.contains(headerName) |
412 | |
&& !HttpConnector.HTTP_COOKIES_PROPERTY.equals(headerName)) |
413 | |
{ |
414 | |
|
415 | 0 | httpMethod.addRequestHeader(headerName, headerValue); |
416 | |
} |
417 | 0 | } |
418 | 0 | } |
419 | |
|
420 | |
protected MultipartRequestEntity createMultiPart(MuleMessage msg, EntityEnclosingMethod method) |
421 | |
throws Exception |
422 | |
{ |
423 | |
Part[] parts; |
424 | 0 | int i = 0; |
425 | 0 | if (msg.getPayload() instanceof NullPayload) |
426 | |
{ |
427 | 0 | parts = new Part[msg.getOutboundAttachmentNames().size()]; |
428 | |
} |
429 | |
else |
430 | |
{ |
431 | 0 | parts = new Part[msg.getOutboundAttachmentNames().size() + 1]; |
432 | 0 | parts[i++] = new FilePart("payload", new ByteArrayPartSource("payload", msg.getPayloadAsBytes())); |
433 | |
} |
434 | |
|
435 | 0 | for (final Iterator<String> iterator = msg.getOutboundAttachmentNames().iterator(); iterator.hasNext(); i++) |
436 | |
{ |
437 | 0 | final String name = iterator.next(); |
438 | 0 | String fileName = name; |
439 | 0 | final DataHandler dh = msg.getOutboundAttachment(name); |
440 | 0 | if (dh.getDataSource() instanceof StringDataSource) |
441 | |
{ |
442 | 0 | final StringDataSource ds = (StringDataSource) dh.getDataSource(); |
443 | 0 | parts[i] = new StringPart(ds.getName(), IOUtils.toString(ds.getInputStream())); |
444 | 0 | } |
445 | |
else |
446 | |
{ |
447 | 0 | if (dh.getDataSource() instanceof FileDataSource) |
448 | |
{ |
449 | 0 | fileName = ((FileDataSource) dh.getDataSource()).getFile().getName(); |
450 | |
} |
451 | 0 | else if (dh.getDataSource() instanceof URLDataSource) |
452 | |
{ |
453 | 0 | fileName = ((URLDataSource) dh.getDataSource()).getURL().getFile(); |
454 | |
|
455 | 0 | final int x = fileName.lastIndexOf("/"); |
456 | 0 | if (x > -1) |
457 | |
{ |
458 | 0 | fileName = fileName.substring(x + 1); |
459 | |
} |
460 | |
} |
461 | 0 | parts[i] = new FilePart(dh.getName(), new ByteArrayPartSource(fileName, |
462 | |
IOUtils.toByteArray(dh.getInputStream())), dh.getContentType(), null); |
463 | |
} |
464 | |
} |
465 | |
|
466 | 0 | return new MultipartRequestEntity(parts, method.getParams()); |
467 | |
} |
468 | |
} |