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