1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package io.wcm.caravan.io.http.impl.servletclient;
21
22 import java.io.ByteArrayOutputStream;
23 import java.io.IOException;
24 import java.io.PrintWriter;
25 import java.text.SimpleDateFormat;
26 import java.util.Collection;
27 import java.util.Collections;
28 import java.util.Date;
29 import java.util.List;
30 import java.util.Locale;
31 import java.util.TimeZone;
32
33 import javax.servlet.ServletOutputStream;
34 import javax.servlet.http.Cookie;
35 import javax.servlet.http.HttpServletResponse;
36
37 import com.google.common.base.Charsets;
38 import com.google.common.collect.HashMultimap;
39 import com.google.common.collect.Lists;
40 import com.google.common.collect.Multimap;
41
42 import io.wcm.caravan.io.http.response.CaravanHttpResponse;
43 import io.wcm.caravan.io.http.response.CaravanHttpResponseBuilder;
44
45
46
47
48 public class HttpServletResponseMapper implements HttpServletResponse {
49
50 private String characterEncoding = Charsets.UTF_8.toString();
51 private String contentType;
52 private ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
53 private int bufferSize = 4096;
54 private Locale locale;
55 private final List<Cookie> cookies = Lists.newArrayList();
56 private final Multimap<String, String> headers = HashMultimap.create();
57 private int status = HttpServletResponse.SC_OK;
58 private String reason = "OK";
59
60 @Override
61 public String getCharacterEncoding() {
62 return characterEncoding;
63 }
64
65 @Override
66 public String getContentType() {
67 return contentType;
68 }
69
70 @Override
71 public ServletOutputStream getOutputStream() throws IOException {
72
73 return new ServletOutputStream() {
74
75 @Override
76 public void write(int b) throws IOException {
77 outputStream.write(b);
78 }
79 };
80 }
81
82 @Override
83 public PrintWriter getWriter() throws IOException {
84 return new PrintWriter(outputStream);
85 }
86
87 @Override
88 public void setCharacterEncoding(String charset) {
89 characterEncoding = charset;
90 }
91
92 @Override
93 public void setContentLength(int len) {
94 setIntHeader("Content-Length", len);
95
96
97
98 if (len > 0 && outputStream.size() == 0) {
99 outputStream = new ByteArrayOutputStream(len);
100 }
101 }
102
103 @Override
104 public void setContentType(String type) {
105 contentType = type;
106 }
107
108 @Override
109 public void setBufferSize(int size) {
110 bufferSize = size;
111 }
112
113 @Override
114 public int getBufferSize() {
115 return bufferSize;
116 }
117
118 @Override
119 public void flushBuffer() throws IOException {
120 outputStream.flush();
121 }
122
123 @Override
124 public void resetBuffer() {
125 outputStream.reset();
126 }
127
128 @Override
129 public boolean isCommitted() {
130 return false;
131 }
132
133 @Override
134 public void reset() {
135 resetBuffer();
136 this.characterEncoding = null;
137 this.contentType = null;
138 this.locale = null;
139 this.cookies.clear();
140 this.headers.clear();
141 this.status = HttpServletResponse.SC_OK;
142 this.reason = null;
143 }
144
145 @Override
146 public void setLocale(Locale loc) {
147 locale = loc;
148 }
149
150 @Override
151 public Locale getLocale() {
152 return locale;
153 }
154
155 @Override
156 public void addCookie(Cookie cookie) {
157 cookies.add(cookie);
158 }
159
160 @Override
161 public boolean containsHeader(String name) {
162 return headers.containsKey(name);
163 }
164
165 @Override
166 public String encodeURL(String url) {
167 return url;
168 }
169
170 @Override
171 public String encodeRedirectURL(String url) {
172 return encodeURL(url);
173 }
174
175 @Override
176 public String encodeUrl(String url) {
177 return encodeURL(url);
178 }
179
180 @Override
181 public String encodeRedirectUrl(String url) {
182 return encodeRedirectURL(url);
183 }
184
185 @Override
186 public void sendError(int sc, String msg) throws IOException {
187 status = sc;
188 reason = msg;
189 }
190
191 @Override
192 public void sendError(int sc) throws IOException {
193 status = sc;
194 }
195
196 @Override
197 public void sendRedirect(String location) throws IOException {
198 setHeader("Location", location);
199 setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
200 }
201
202 @Override
203 public void setDateHeader(String name, long date) {
204 String value = formatDate(date);
205 setHeader(name, value);
206 }
207
208 private String formatDate(long date) {
209 SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US);
210 dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
211 return dateFormat.format(new Date(date));
212 }
213
214 @Override
215 public void addDateHeader(String name, long date) {
216 String value = formatDate(date);
217 addHeader(name, value);
218 }
219
220 @Override
221 public void setHeader(String name, String value) {
222 headers.replaceValues(name, Collections.singletonList(value));
223 }
224
225 @Override
226 public void addHeader(String name, String value) {
227 headers.put(name, value);
228 }
229
230 @Override
231 public void setIntHeader(String name, int value) {
232 setHeader(name, String.valueOf(value));
233 }
234
235 @Override
236 public void addIntHeader(String name, int value) {
237 addHeader(name, String.valueOf(value));
238 }
239
240 @Override
241 public void setStatus(int sc) {
242 status = sc;
243 }
244
245 @Override
246 public void setStatus(int sc, String sm) {
247 setStatus(sc);
248 reason = sm;
249 }
250
251 @Override
252 public int getStatus() {
253 return status;
254 }
255
256 @Override
257 public String getHeader(String name) {
258 Collection<String> values = headers.get(name);
259 return values.isEmpty() ? null : values.iterator().next();
260 }
261
262 @Override
263 public Collection<String> getHeaders(String name) {
264 return headers.get(name);
265 }
266
267 @Override
268 public Collection<String> getHeaderNames() {
269 return headers.keySet();
270 }
271
272 public CaravanHttpResponse getResponse() {
273 return new CaravanHttpResponseBuilder()
274 .body(outputStream.toByteArray())
275 .headers(headers)
276 .reason(reason)
277 .status(status)
278 .build();
279 }
280
281 }