--- /dev/null
+package de.halbekunst.juplo.test;
+
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.util.Date;
+import java.util.Locale;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author kai
+ */
+public class LoggingHttpServletResponseWrapper implements HttpServletResponse {
+
+ private final static Logger log = LoggerFactory.getLogger(LoggingHttpServletResponseWrapper.class);
+
+ public final static int DEFAULT_BUFFER_SIZE = 1024;
+
+ private static long count = 0;
+
+ private final Long no;
+ private final HttpServletResponse response;
+ private CountingServletOutputStream out;
+ private ServletOutputStream stream;
+ private PrintWriter writer;
+ private int buffer = DEFAULT_BUFFER_SIZE;
+ private boolean committed = false;
+
+
+ LoggingHttpServletResponseWrapper(String name, HttpServletResponse response) {
+ no = ++count;
+ log.debug("New request {}: {}", no, name);
+ this.response = response;
+ }
+
+
+ public long close() throws IOException {
+ if (out == null) {
+ return -1l;
+ }
+ else {
+ if (writer != null)
+ writer.close();
+ else
+ stream.close();
+ long result = out.count;
+ out = null;
+ buffer = DEFAULT_BUFFER_SIZE;
+ return result;
+ }
+ }
+
+ @Override
+ public void flushBuffer() throws IOException {
+ log.debug("{} -- flushing buffer", no);
+ committed = true;
+ response.flushBuffer();
+ }
+
+ @Override
+ public int getBufferSize() {
+ log.trace("{} -- getting buffer size: {}", no, buffer);
+ return buffer;
+ }
+
+ @Override
+ public boolean isCommitted() {
+ Boolean result = committed || response.isCommitted();
+ log.trace("{} -- commited? {}", no, result);
+ return result;
+ }
+
+ @Override
+ public void reset() {
+ log.debug("{} -- reset!", no);
+ if (committed)
+ throw new IllegalStateException("call to reset() after response has been commited!");
+ if (out != null)
+ out.count = 0;
+ response.reset();
+ }
+
+ @Override
+ public void resetBuffer() {
+ log.debug("{} -- resetting buffer", no);
+ if (committed)
+ throw new IllegalStateException("call to resetBuffer() after response has been commited!");
+ if (out != null)
+ out.count = 0;
+ response.resetBuffer();
+ }
+
+ @Override
+ public void setBufferSize(int size) {
+ log.debug("{} -- setting buffer size to {}", no, size);
+ if (out != null && out.count > 0)
+ throw new IllegalStateException("call to setBuffer() after content has been written!");
+ response.setBufferSize(size);
+ buffer = size;
+ }
+
+ @Override
+ public ServletOutputStream getOutputStream() throws IOException {
+ log.debug("{} -- getting output stream", no);
+
+ if (writer != null)
+ throw new IllegalStateException("ServletOutputStream and PrintWriter cannot be requested both!");
+
+ if (stream == null) {
+ log.debug("{} -- creating new servlet output stream", no);
+ out = new CountingServletOutputStream(response.getOutputStream());
+ stream = out;
+ }
+
+ return stream;
+ }
+
+ @Override
+ public PrintWriter getWriter() throws IOException {
+ log.debug("{} -- getting print writer", no);
+
+ if (stream != null)
+ throw new IllegalStateException("ServletOutputStream and PrintWriter cannot be requested both!");
+
+ if (writer == null) {
+ log.debug("{} -- creating new print writer", no);
+ out = new CountingServletOutputStream(response.getOutputStream());
+ OutputStreamWriter streamWriter = new OutputStreamWriter(out, response.getCharacterEncoding());
+ writer = new PrintWriter(streamWriter);
+ }
+
+ return writer;
+ }
+
+ @Override
+ public void addCookie(Cookie cookie) {
+ log.debug("{} -- adding cookie: {}", no, cookie);
+ response.addCookie(cookie);
+ }
+
+ @Override
+ public boolean containsHeader(String name) {
+ Boolean result = response.containsHeader(name);
+ log.trace("{} -- contains header {}? {}", new Object[] { no, name, result });
+ return result;
+ }
+
+ @Override
+ public String encodeURL(String url) {
+ log.trace("{} -- encoding url {}", no, url);
+ return response.encodeURL(url);
+ }
+
+ @Override
+ public String encodeRedirectURL(String url) {
+ log.trace("{} -- encoding redirect url {}", no, url);
+ return response.encodeRedirectURL(url);
+ }
+
+ @Override
+ public String encodeUrl(String url) {
+ log.trace("{} -- encoding url {}", no, url);
+ return response.encodeUrl(url);
+ }
+
+ @Override
+ public String encodeRedirectUrl(String url) {
+ log.trace("{} -- encoding redirect url {}", no, url);
+ return response.encodeRedirectUrl(url);
+ }
+
+ @Override
+ public void sendError(int sc, String msg) throws IOException {
+ log.debug("{} -- sending error: {}. {}", new Object[] { no, sc, msg });
+ response.sendError(sc, msg);
+ }
+
+ @Override
+ public void sendError(int sc) throws IOException {
+ log.debug("{} -- sending error: {}", no, sc);
+ }
+
+ @Override
+ public void sendRedirect(String location) throws IOException {
+ log.debug("{} -- sending redirect: {}", no, location);
+ response.sendRedirect(location);
+ }
+
+ @Override
+ public void setDateHeader(String name, long date) {
+ log.debug("{} -- setting date header {} to {}", new Object[] { no, name, new Date(date) });
+ response.setDateHeader(name, date);
+ }
+
+ @Override
+ public void addDateHeader(String name, long date) {
+ log.debug("{} -- adding date header {}: {}", new Object[] { no, name, new Date(date) });
+ response.addDateHeader(name, date);
+ }
+
+ @Override
+ public void setHeader(String name, String value) {
+ log.debug("{} -- setting header {} to {}", new Object[] { no, name, value });
+ response.setHeader(name, value);
+ }
+
+ @Override
+ public void addHeader(String name, String value) {
+ log.debug("{} -- adding header {}: {}", new Object[] { no, name, value });
+ response.addHeader(name, value);
+ }
+
+ @Override
+ public void setIntHeader(String name, int value) {
+ log.debug("{} -- seting int header {} to {}", new Object[] { no, name, value });
+ response.setIntHeader(name, value);
+ }
+
+ @Override
+ public void addIntHeader(String name, int value) {
+ log.debug("{} -- adding int header {}: {}", new Object[] { no, name, value });
+ response.addIntHeader(name, value);
+ }
+
+ @Override
+ public void setStatus(int sc) {
+ log.debug("{} -- setting status to {}", no, sc);
+ response.setStatus(sc);
+ }
+
+ @Override
+ public void setStatus(int sc, String sm) {
+ log.debug("{} -- setting status to {} (message: {})", new Object[] { no, sc, sm });
+ response.setStatus(sc, sm);
+ }
+
+ @Override
+ public String getCharacterEncoding() {
+ String result = response.getCharacterEncoding();
+ log.trace("{} -- character encoding: {}", no, result);
+ return result;
+ }
+
+ @Override
+ public String getContentType() {
+ String result = response.getContentType();
+ log.trace("{} -- content type: {}", no, result);
+ return result;
+ }
+
+ @Override
+ public void setCharacterEncoding(String charset) {
+ log.debug("{} -- setting character encoding to {}", no, charset);
+ response.setCharacterEncoding(charset);
+ }
+
+ @Override
+ public void setContentLength(int len) {
+ log.debug("{} -- setting content length to {}", no, len);
+ response.setContentLength(len);
+ }
+
+ @Override
+ public void setContentType(String type) {
+ log.debug("{} -- setting content type to {}", no, type);
+ response.setContentType(type);
+ }
+
+ @Override
+ public void setLocale(Locale loc) {
+ log.debug("{} -- setting locale to {}", no, loc);
+ response.setLocale(loc);
+ }
+
+ @Override
+ public Locale getLocale() {
+ Locale locale = response.getLocale();
+ log.trace("{} -- locale: {}", no, locale);
+ return locale;
+ }
+
+
+ class CountingServletOutputStream extends ServletOutputStream {
+
+ private ServletOutputStream out;
+ long count = 0l;
+
+
+ CountingServletOutputStream(ServletOutputStream out) {
+ this.out = out;
+ }
+
+
+ @Override
+ public void write(int i) throws IOException {
+ count++;
+ /** Simulate commit, when count is getting bigger then buffer */
+ if (count == buffer + 1) {
+ log.info("{} -- simulating commit because buffer overflow! buffer: {}, count: {}", new Object[] { no, buffer, count });
+ committed = true;
+ }
+ log.trace("{} -- writing byte {}: {}", new Object[] { no, count, (char)i });
+ out.write(i);
+ }
+ }
+}