1
2
3
4
5
6
7
8
9
10
11 package org.mule.providers.http.transformers;
12
13 import org.mule.config.MuleManifest;
14 import org.mule.config.MuleProperties;
15 import org.mule.providers.NullPayload;
16 import org.mule.providers.http.HttpConnector;
17 import org.mule.providers.http.HttpConstants;
18 import org.mule.providers.http.HttpResponse;
19 import org.mule.transformers.AbstractEventAwareTransformer;
20 import org.mule.transformers.simple.SerializableToByteArray;
21 import org.mule.umo.UMOEventContext;
22 import org.mule.umo.UMOMessage;
23 import org.mule.umo.transformer.TransformerException;
24 import org.mule.util.StringUtils;
25
26 import java.io.ByteArrayInputStream;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.text.SimpleDateFormat;
30 import java.util.Collection;
31 import java.util.Date;
32 import java.util.Iterator;
33 import java.util.Locale;
34 import java.util.Map;
35
36 import org.apache.commons.httpclient.Header;
37 import org.apache.commons.httpclient.HttpVersion;
38
39
40
41
42
43
44 public class UMOMessageToHttpResponse extends AbstractEventAwareTransformer
45 {
46 public static final String CUSTOM_HEADER_PREFIX = "";
47
48
49 private SimpleDateFormat format;
50 private String server;
51 private SerializableToByteArray serializableToByteArray;
52
53 public UMOMessageToHttpResponse()
54 {
55 registerSourceType(Object.class);
56 setReturnClass(Object.class);
57
58 format = new SimpleDateFormat(HttpConstants.DATE_FORMAT, Locale.US);
59
60
61
62 String productName = MuleManifest.getProductName();
63 if (productName == null)
64 {
65 server = "Mule/SNAPSHOT";
66 }
67 else
68 {
69 server = productName + "/" + MuleManifest.getProductVersion();
70 }
71
72 serializableToByteArray = new SerializableToByteArray();
73 }
74
75 public Object transform(Object src, String encoding, UMOEventContext context) throws TransformerException
76 {
77
78 if (context.getMessage().getExceptionPayload() != null)
79 {
80
81 }
82
83
84
85
86 if (src instanceof NullPayload)
87 {
88 src = StringUtils.EMPTY;
89 }
90
91 try
92 {
93 HttpResponse response;
94 if (src instanceof HttpResponse)
95 {
96 response = (HttpResponse)src;
97 }
98 else
99 {
100 response = createResponse(src, encoding, context);
101 }
102
103
104 if (!response.containsHeader(HttpConstants.HEADER_CONTENT_TYPE))
105 {
106 response.addHeader(new Header(HttpConstants.HEADER_CONTENT_TYPE,
107 HttpConstants.DEFAULT_CONTENT_TYPE));
108 }
109
110
111 if (!response.containsHeader(HttpConstants.HEADER_CONTENT_LENGTH)
112 && !response.containsHeader(HttpConstants.HEADER_TRANSFER_ENCODING))
113 {
114 InputStream content = response.getBody();
115 if (content != null)
116 {
117 long len = response.getContentLength();
118 if (len < 0)
119 {
120 if (response.getHttpVersion().lessEquals(HttpVersion.HTTP_1_0))
121 {
122 throw new IOException("Chunked encoding not supported for HTTP version "
123 + response.getHttpVersion());
124 }
125 Header header = new Header(HttpConstants.HEADER_TRANSFER_ENCODING, "chunked");
126 response.addHeader(header);
127 }
128 else
129 {
130 Header header = new Header(HttpConstants.HEADER_CONTENT_LENGTH, Long.toString(len));
131 response.setHeader(header);
132 }
133 }
134 else
135 {
136 Header header = new Header(HttpConstants.HEADER_CONTENT_LENGTH, "0");
137 response.addHeader(header);
138 }
139 }
140
141 UMOMessage msg = context.getMessage();
142
143 if (!response.containsHeader(HttpConstants.HEADER_CONNECTION))
144 {
145
146 String connHeader = msg.getStringProperty(HttpConstants.HEADER_CONNECTION, null);
147 if (connHeader != null)
148 {
149 if (connHeader.equalsIgnoreCase("keep-alive"))
150 {
151 Header header = new Header(HttpConstants.HEADER_CONNECTION, "keep-alive");
152 response.addHeader(header);
153 response.setKeepAlive(true);
154 }
155 if (connHeader.equalsIgnoreCase("close"))
156 {
157 Header header = new Header(HttpConstants.HEADER_CONNECTION, "close");
158 response.addHeader(header);
159 response.setKeepAlive(false);
160 }
161 }
162 else
163 {
164
165 if (response.getHttpVersion().greaterEquals(HttpVersion.HTTP_1_1))
166 {
167 response.setKeepAlive(true);
168 }
169 else
170 {
171 response.setKeepAlive(false);
172 }
173 }
174 }
175 if ("HEAD".equalsIgnoreCase(msg.getStringProperty(HttpConnector.HTTP_METHOD_PROPERTY, null)))
176 {
177
178 response.setBody(null);
179 }
180 return response;
181 }
182 catch (IOException e)
183 {
184 throw new TransformerException(this, e);
185 }
186
187 }
188
189 protected HttpResponse createResponse(Object src, String encoding, UMOEventContext context)
190 throws IOException, TransformerException
191 {
192 HttpResponse response = new HttpResponse();
193 UMOMessage msg = context.getMessage();
194
195 int status = msg.getIntProperty(HttpConnector.HTTP_STATUS_PROPERTY, HttpConstants.SC_OK);
196 String version = msg.getStringProperty(HttpConnector.HTTP_VERSION_PROPERTY, HttpConstants.HTTP11);
197
198 String date;
199 synchronized (format)
200 {
201 date = format.format(new Date());
202 }
203
204 String contentType = msg.getStringProperty(HttpConstants.HEADER_CONTENT_TYPE,
205 HttpConstants.DEFAULT_CONTENT_TYPE);
206
207 response.setStatusLine(HttpVersion.parse(version), status);
208 response.setHeader(new Header(HttpConstants.HEADER_CONTENT_TYPE, contentType));
209 response.setHeader(new Header(HttpConstants.HEADER_DATE, date));
210 response.setHeader(new Header(HttpConstants.HEADER_SERVER, server));
211 if (msg.getProperty(HttpConstants.HEADER_EXPIRES) == null)
212 {
213 response.setHeader(new Header(HttpConstants.HEADER_EXPIRES, date));
214 }
215 response.setFallbackCharset(encoding);
216
217 Collection headerNames = HttpConstants.RESPONSE_HEADER_NAMES.values();
218 String headerName, value;
219 for (Iterator iterator = headerNames.iterator(); iterator.hasNext();)
220 {
221 headerName = (String)iterator.next();
222 value = msg.getStringProperty(headerName, null);
223 if (value != null)
224 {
225 response.setHeader(new Header(headerName, value));
226 }
227 }
228
229
230 Map customHeaders = (Map)msg.getProperty(HttpConnector.HTTP_CUSTOM_HEADERS_MAP_PROPERTY);
231 if (customHeaders != null)
232 {
233 Map.Entry entry;
234 for (Iterator iterator = customHeaders.entrySet().iterator(); iterator.hasNext();)
235 {
236 entry = (Map.Entry)iterator.next();
237 if (entry.getValue() != null)
238 {
239 response.setHeader(new Header(entry.getKey().toString(), entry.getValue().toString()));
240 }
241 }
242 }
243
244
245 String user = msg.getStringProperty(MuleProperties.MULE_USER_PROPERTY, null);
246 if (user != null)
247 {
248 response.setHeader(new Header(CUSTOM_HEADER_PREFIX + MuleProperties.MULE_USER_PROPERTY, user));
249 }
250 if (msg.getCorrelationId() != null)
251 {
252 response.setHeader(new Header(CUSTOM_HEADER_PREFIX + MuleProperties.MULE_CORRELATION_ID_PROPERTY,
253 msg.getCorrelationId()));
254 response.setHeader(new Header(CUSTOM_HEADER_PREFIX
255 + MuleProperties.MULE_CORRELATION_GROUP_SIZE_PROPERTY,
256 String.valueOf(msg.getCorrelationGroupSize())));
257 response.setHeader(new Header(CUSTOM_HEADER_PREFIX
258 + MuleProperties.MULE_CORRELATION_SEQUENCE_PROPERTY,
259 String.valueOf(msg.getCorrelationSequence())));
260 }
261 if (msg.getReplyTo() != null)
262 {
263 response.setHeader(new Header(CUSTOM_HEADER_PREFIX + MuleProperties.MULE_REPLY_TO_PROPERTY,
264 msg.getReplyTo().toString()));
265 }
266 if (src instanceof InputStream)
267 {
268 response.setBody((InputStream)src);
269 }
270 else if (src instanceof String)
271 {
272 response.setBodyString(src.toString());
273 }
274 else
275 {
276 response.setBody(new ByteArrayInputStream((byte[])serializableToByteArray.doTransform(src,
277 encoding)));
278 }
279 return response;
280 }
281
282 public boolean isAcceptNull()
283 {
284 return true;
285 }
286 }