f654f2a7d05327dc217cf3a9d43b1f4d77bfa8ac
[percentcodec] / test / src / main / java / de / halbekunst / juplo / test / LoggingHttpServletResponseWrapper.java
1 package de.halbekunst.juplo.test;
2
3 import java.io.IOException;
4 import java.io.OutputStreamWriter;
5 import java.io.PrintWriter;
6 import java.util.Date;
7 import java.util.Locale;
8 import javax.servlet.ServletOutputStream;
9 import javax.servlet.http.Cookie;
10 import javax.servlet.http.HttpServletResponse;
11 import org.slf4j.Logger;
12 import org.slf4j.LoggerFactory;
13
14 /**
15  * @author kai
16  */
17 public class LoggingHttpServletResponseWrapper implements HttpServletResponse {
18
19   private final static Logger log = LoggerFactory.getLogger(LoggingHttpServletResponseWrapper.class);
20
21   public final static int DEFAULT_BUFFER_SIZE = 1024;
22
23   private static long count = 0;
24
25   private final Long no;
26   private final HttpServletResponse response;
27   private CountingServletOutputStream out;
28   private ServletOutputStream stream;
29   private PrintWriter writer;
30   private int buffer = DEFAULT_BUFFER_SIZE;
31   private boolean committed = false;
32
33
34   LoggingHttpServletResponseWrapper(String name, HttpServletResponse response) {
35     no = ++count;
36     log.debug("New request {}: {}", no, name);
37     this.response = response;
38   }
39
40
41   public long close() throws IOException {
42     if (out == null) {
43       return -1l;
44     }
45     else {
46       if (writer != null)
47         writer.close();
48       else
49         stream.close();
50       long result = out.count;
51       out = null;
52       buffer = DEFAULT_BUFFER_SIZE;
53       return result;
54     }
55   }
56
57   @Override
58   public void flushBuffer() throws IOException {
59     log.debug("{} -- flushing buffer", no);
60     committed = true;
61     response.flushBuffer();
62   }
63
64   @Override
65   public int getBufferSize() {
66     log.trace("{} -- getting buffer size: {}", no, buffer);
67     return buffer;
68   }
69
70   @Override
71   public boolean isCommitted() {
72     Boolean result = committed || response.isCommitted();
73     log.trace("{} -- commited? {}", no, result);
74     return result;
75   }
76
77   @Override
78   public void reset() {
79     log.debug("{} -- reset!", no);
80     if (committed)
81       throw new IllegalStateException("call to reset() after response has been commited!");
82     if (out != null)
83       out.count = 0;
84     response.reset();
85   }
86
87   @Override
88   public void resetBuffer() {
89     log.debug("{} -- resetting buffer", no);
90     if (committed)
91       throw new IllegalStateException("call to resetBuffer() after response has been commited!");
92     if (out != null)
93       out.count = 0;
94     response.resetBuffer();
95   }
96
97   @Override
98   public void setBufferSize(int size) {
99     log.debug("{} -- setting buffer size to {}", no, size);
100     if (out != null && out.count > 0)
101       throw new IllegalStateException("call to setBuffer() after content has been written!");
102     response.setBufferSize(size);
103     buffer = size;
104   }
105
106   @Override
107   public ServletOutputStream getOutputStream() throws IOException {
108     log.debug("{} -- getting output stream", no);
109
110     if (writer != null)
111       throw new IllegalStateException("ServletOutputStream and PrintWriter cannot be requested both!");
112
113     if (stream == null) {
114       log.debug("{} -- creating new servlet output stream", no);
115       out = new CountingServletOutputStream(response.getOutputStream());
116       stream = out;
117     }
118
119     return stream;
120   }
121
122   @Override
123   public PrintWriter getWriter() throws IOException {
124     log.debug("{} -- getting print writer", no);
125
126     if (stream != null)
127       throw new IllegalStateException("ServletOutputStream and PrintWriter cannot be requested both!");
128
129     if (writer == null) {
130       log.debug("{} -- creating new print writer", no);
131       out = new CountingServletOutputStream(response.getOutputStream());
132       OutputStreamWriter streamWriter = new OutputStreamWriter(out, response.getCharacterEncoding());
133       writer = new PrintWriter(streamWriter);
134     }
135
136     return writer;
137   }
138
139   @Override
140   public void addCookie(Cookie cookie) {
141     log.debug("{} -- adding cookie: {}", no, cookie);
142     response.addCookie(cookie);
143   }
144
145   @Override
146   public boolean containsHeader(String name) {
147     Boolean result = response.containsHeader(name);
148     log.trace("{} -- contains header {}? {}", new Object[] { no, name, result });
149     return result;
150   }
151
152   @Override
153   public String encodeURL(String url) {
154     log.trace("{} -- encoding url {}", no, url);
155     return response.encodeURL(url);
156   }
157
158   @Override
159   public String encodeRedirectURL(String url) {
160     log.trace("{} -- encoding redirect url {}", no, url);
161     return response.encodeRedirectURL(url);
162   }
163
164   @Override
165   public String encodeUrl(String url) {
166     log.trace("{} -- encoding url {}", no, url);
167     return response.encodeUrl(url);
168   }
169
170   @Override
171   public String encodeRedirectUrl(String url) {
172     log.trace("{} -- encoding redirect url {}", no, url);
173     return response.encodeRedirectUrl(url);
174   }
175
176   @Override
177   public void sendError(int sc, String msg) throws IOException {
178     log.debug("{} -- sending error: {}. {}", new Object[] { no, sc, msg });
179     response.sendError(sc, msg);
180   }
181
182   @Override
183   public void sendError(int sc) throws IOException {
184     log.debug("{} -- sending error: {}", no, sc);
185   }
186
187   @Override
188   public void sendRedirect(String location) throws IOException {
189     log.debug("{} -- sending redirect: {}", no, location);
190     response.sendRedirect(location);
191   }
192
193   @Override
194   public void setDateHeader(String name, long date) {
195     log.debug("{} -- setting date header {} to {}", new Object[] { no, name, new Date(date) });
196     response.setDateHeader(name, date);
197   }
198
199   @Override
200   public void addDateHeader(String name, long date) {
201     log.debug("{} -- adding date header {}: {}", new Object[] { no, name, new Date(date) });
202     response.addDateHeader(name, date);
203   }
204
205   @Override
206   public void setHeader(String name, String value) {
207     log.debug("{} -- setting header {} to {}", new Object[] { no, name, value });
208     response.setHeader(name, value);
209   }
210
211   @Override
212   public void addHeader(String name, String value) {
213     log.debug("{} -- adding header {}: {}", new Object[] { no, name, value });
214     response.addHeader(name, value);
215   }
216
217   @Override
218   public void setIntHeader(String name, int value) {
219     log.debug("{} -- seting int header {} to {}", new Object[] { no, name, value });
220     response.setIntHeader(name, value);
221   }
222
223   @Override
224   public void addIntHeader(String name, int value) {
225     log.debug("{} -- adding int header {}: {}", new Object[] { no, name, value });
226     response.addIntHeader(name, value);
227   }
228
229   @Override
230   public void setStatus(int sc) {
231     log.debug("{} -- setting status to {}", no, sc);
232     response.setStatus(sc);
233   }
234
235   @Override
236   public void setStatus(int sc, String sm) {
237     log.debug("{} -- setting status to {} (message: {})", new Object[] { no, sc, sm });
238     response.setStatus(sc, sm);
239   }
240
241   @Override
242   public String getCharacterEncoding() {
243     String result = response.getCharacterEncoding();
244     log.trace("{} -- character encoding: {}", no, result);
245     return result;
246   }
247
248   @Override
249   public String getContentType() {
250     String result = response.getContentType();
251     log.trace("{} -- content type: {}", no, result);
252     return result;
253   }
254
255   @Override
256   public void setCharacterEncoding(String charset) {
257     log.debug("{} -- setting character encoding to {}", no, charset);
258     response.setCharacterEncoding(charset);
259   }
260
261   @Override
262   public void setContentLength(int len) {
263     log.debug("{} -- setting content length to {}", no, len);
264     response.setContentLength(len);
265   }
266
267   @Override
268   public void setContentType(String type) {
269     log.debug("{} -- setting content type to {}", no, type);
270     response.setContentType(type);
271   }
272
273   @Override
274   public void setLocale(Locale loc) {
275     log.debug("{} -- setting locale to {}", no, loc);
276     response.setLocale(loc);
277   }
278
279   @Override
280   public Locale getLocale() {
281     Locale locale = response.getLocale();
282     log.trace("{} -- locale: {}", no, locale);
283     return locale;
284   }
285
286
287   class CountingServletOutputStream extends ServletOutputStream {
288
289     private ServletOutputStream out;
290     long count = 0l;
291
292
293     CountingServletOutputStream(ServletOutputStream out) {
294       this.out = out;
295     }
296
297
298     @Override
299     public void write(int i) throws IOException {
300       count++;
301       /** Simulate commit, when count is getting bigger then buffer */
302       if (count == buffer + 1) {
303         log.info("{} -- simulating commit because buffer overflow! buffer: {}, count: {}", new Object[] { no, buffer, count });
304         committed = true;
305       }
306       log.trace("{} -- writing byte {}: {}", new Object[] { no, count, (char)i });
307       out.write(i);
308     }
309   }
310 }