/** * Licensed under the Artistic License; you may not use this file * except in compliance with the License. * You may obtain a copy of the License at * * http://displaytag.sourceforge.net/license.html * * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ package org.displaytag.filter; import java.io.CharArrayWriter; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.displaytag.tags.TableTagParameters; /** * J2ee 1.3 implementation of BufferedResponseWrapper. Need to extend HttpServletResponseWrapper for Weblogic * compatibility. * @author rapruitt * @author Fabrizio Giustina * @version $Revision: 917 $ ($Author: fgiust $) */ public class BufferedResponseWrapper13Impl extends HttpServletResponseWrapper implements BufferedResponseWrapper { /** * logger. */ private static Log log = LogFactory.getLog(BufferedResponseWrapper13Impl.class); /** * The buffered response. */ private CharArrayWriter outputWriter; /** * The outputWriter stream. */ private SimpleServletOutputStream servletOutputStream; /** * The contentType. */ private String contentType; /** * If state is set, allow getOutputStream() to return the "real" output stream, elsewhere returns a internal buffer. */ private boolean state; /** * Writer has been requested. */ private boolean outRequested; /** * @param httpServletResponse the response to wrap */ public BufferedResponseWrapper13Impl(HttpServletResponse httpServletResponse) { super(httpServletResponse); this.outputWriter = new CharArrayWriter(); this.servletOutputStream = new SimpleServletOutputStream(); } /** * @see org.displaytag.filter.BufferedResponseWrapper#getContentType() */ public String getContentType() { return this.contentType; } /** * The content type is NOT set on the wrapped response. You must set it manually. Overrides any previously set * value. * @param theContentType the content type. */ public void setContentType(String theContentType) { if (state) { log.debug("Allowing content type"); if (this.contentType != null && // content type has been set before this.contentType.indexOf("charset") > -1) // and it specified charset { // so copy the charset String charset = this.contentType.substring(this.contentType.indexOf("charset")); if (log.isDebugEnabled()) { log.debug("Adding charset: [" + charset + "]"); } getResponse().setContentType(StringUtils.substringBefore(theContentType, "charset") + '=' + charset); } else { getResponse().setContentType(theContentType); } } this.contentType = theContentType; } /** * @see javax.servlet.ServletResponse#getWriter() */ public PrintWriter getWriter() throws IOException { if (state && !outRequested) { log.debug("getWriter() returned"); // ok, exporting in progress, discard old data and go on streaming this.servletOutputStream.reset(); this.outputWriter.reset(); this.outRequested = true; return ((HttpServletResponse) getResponse()).getWriter(); } return new PrintWriter(this.outputWriter); } /** * Flush the buffer, not the response. * @throws IOException if encountered when flushing */ public void flushBuffer() throws IOException { if (outputWriter != null) { this.outputWriter.flush(); this.servletOutputStream.outputStream.reset(); } } /** * @see javax.servlet.ServletResponse#getOutputStream() */ public ServletOutputStream getOutputStream() throws IOException { if (state && !outRequested) { log.debug("getOutputStream() returned"); // ok, exporting in progress, discard old data and go on streaming this.servletOutputStream.reset(); this.outputWriter.reset(); this.outRequested = true; return ((HttpServletResponse) getResponse()).getOutputStream(); } return this.servletOutputStream; } /** * @see javax.servlet.http.HttpServletResponse#addHeader(java.lang.String, java.lang.String) */ public void addHeader(String name, String value) { // if the "magic parameter" is set, a table tag is going to call getOutputStream() if (TableTagParameters.PARAMETER_EXPORTING.equals(name)) { log.debug("Magic header received, real response is now accessible"); state = true; } else { if (!ArrayUtils.contains(FILTERED_HEADERS, StringUtils.lowerCase(name))) { ((HttpServletResponse) getResponse()).addHeader(name, value); } } } /** * @see org.displaytag.filter.BufferedResponseWrapper#isOutRequested() */ public boolean isOutRequested() { return this.outRequested; } /** * @see org.displaytag.filter.BufferedResponseWrapper#getContentAsString() */ public String getContentAsString() { return this.outputWriter.toString() + this.servletOutputStream.toString(); } /** * @see javax.servlet.http.HttpServletResponse#setDateHeader(java.lang.String, long) */ public void setDateHeader(String name, long date) { if (!ArrayUtils.contains(FILTERED_HEADERS, StringUtils.lowerCase(name))) { ((HttpServletResponse) getResponse()).setDateHeader(name, date); } } /** * @see javax.servlet.http.HttpServletResponse#addDateHeader(java.lang.String, long) */ public void addDateHeader(String name, long date) { if (!ArrayUtils.contains(FILTERED_HEADERS, StringUtils.lowerCase(name))) { ((HttpServletResponse) getResponse()).addDateHeader(name, date); } } /** * @see javax.servlet.http.HttpServletResponse#setHeader(java.lang.String, java.lang.String) */ public void setHeader(String name, String value) { if (!ArrayUtils.contains(FILTERED_HEADERS, StringUtils.lowerCase(name))) { ((HttpServletResponse) getResponse()).setHeader(name, value); } } /** * @see javax.servlet.http.HttpServletResponse#setIntHeader(java.lang.String, int) */ public void setIntHeader(String name, int value) { if (!ArrayUtils.contains(FILTERED_HEADERS, StringUtils.lowerCase(name))) { ((HttpServletResponse) getResponse()).setIntHeader(name, value); } } /** * @see javax.servlet.http.HttpServletResponse#addIntHeader(java.lang.String, int) */ public void addIntHeader(String name, int value) { if (!ArrayUtils.contains(FILTERED_HEADERS, StringUtils.lowerCase(name))) { ((HttpServletResponse) getResponse()).addIntHeader(name, value); } } }