Update of /cvsroot/jtidy/jtidyservlet/src/java/org/w3c/tidy/servlet/filter In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2984/src/java/org/w3c/tidy/servlet/filter Modified Files: BufferedServletOutputStream.java BufferedServletResponse.java JTidyFilter.java Added Files: BufferedServletPrintWriter.java Log Message: New filter params isCommittedFix and defferedStreamClose --- NEW FILE --- /* * Java HTML Tidy - JTidy * HTML parser and pretty printer * * Copyright (c) 1998-2000 World Wide Web Consortium (Massachusetts * Institute of Technology, Institut National de Recherche en * Informatique et en Automatique, Keio University). All Rights * Reserved. * * Contributing Author(s): * * Dave Raggett <ds...@w3...> * Andy Quick <ac....@sy...> (translation to Java) * Gary L Peskin <ga...@fi...> (Java development) * Sami Lempinen <sa...@le...> (release management) * Fabrizio Giustina <fgiust at users.sourceforge.net> * Vlad Skarzhevskyy <vlads at users.sourceforge.net> (JTidy servlet development) * * The contributing author(s) would like to thank all those who * helped with testing, bug fixes, and patience. This wouldn't * have been possible without all of you. * * COPYRIGHT NOTICE: * * This software and documentation is provided "as is," and * the copyright holders and contributing author(s) make no * representations or warranties, express or implied, including * but not limited to, warranties of merchantability or fitness * for any particular purpose or that the use of the software or * documentation will not infringe any third party patents, * copyrights, trademarks or other rights. * * The copyright holders and contributing author(s) will not be * liable for any direct, indirect, special or consequential damages * arising out of any use of the software or documentation, even if * advised of the possibility of such damage. * * Permission is hereby granted to use, copy, modify, and distribute * this source code, or portions hereof, documentation and executables, * for any purpose, without fee, subject to the following restrictions: * * 1. The origin of this source code must not be misrepresented. * 2. Altered versions must be plainly marked as such and must * not be misrepresented as being the original source. * 3. This Copyright notice may not be removed or altered from any * source or altered source distribution. * * The copyright holders and contributing author(s) specifically * permit, without fee, and encourage the use of this source code * as a component for supporting the Hypertext Markup Language in * commercial products. If you use this source code in a product, * acknowledgment is not required but would be appreciated. * */ package org.w3c.tidy.servlet.filter; import java.io.OutputStream; import java.io.PrintWriter; import java.io.Writer; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** * Buffers the response. * * @author Vlad Skarzhevskyy <a href="mailto:ska...@gm...">ska...@gm...</a> * @version $Revision: 1.1 $ ($Author: vlads $) */ public class BufferedServletPrintWriter extends PrintWriter { private boolean defferedStreamClose; /** * Logger. */ private static Log log = LogFactory.getLog(BufferedServletPrintWriter.class); public BufferedServletPrintWriter(OutputStream out) { super(out); } public BufferedServletPrintWriter(Writer out) { super(out); } public void close() { if (log.isDebugEnabled()) { log.debug("called close() from", new Throwable()); } if (this.defferedStreamClose) { log.debug("PrintWriter close() deffered"); return; } super.close(); } protected void doClose() { super.close(); } public void setDefferedStreamClose(boolean defferedStreamClose) { this.defferedStreamClose = defferedStreamClose; } } Index: BufferedServletOutputStream.java =================================================================== RCS file: /cvsroot/jtidy/jtidyservlet/src/java/org/w3c/tidy/servlet/filter/BufferedServletOutputStream.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- BufferedServletOutputStream.java 29 Apr 2005 21:20:45 -0000 1.5 +++ BufferedServletOutputStream.java 2 Nov 2005 22:43:16 -0000 1.6 @@ -71,7 +71,7 @@ /** * Substitute ServletOutputStream. * - * @author Vlad Skarzhevskyy <a href="mailto:ska...@gm...">ska...@gm...</a> + * @author Vlad Skarzhevskyy <a href="mailto:ska...@gm...">ska...@gm...</a> * @version $Revision$ ($Author$) */ public class BufferedServletOutputStream extends ServletOutputStream @@ -90,11 +90,13 @@ * Disabe processing for binary output. */ protected boolean binary; - + private int originalContentLength = -1; + + private boolean defferedStreamClose; protected TidyProcessor processor; - + /** * Logger. */ @@ -104,14 +106,14 @@ * Has this stream been closed? */ protected boolean closed; - + /** * Original OutputStream. If in tee configuration */ private ServletOutputStream origOutputStream; - - /** + + /** * Create a regular buffer. */ BufferedServletOutputStream(HttpServletResponse httpServletResponse, TidyProcessor tidyProcessor) @@ -149,20 +151,37 @@ } /** - * Used by BufferedServletResponse.isCommitted + * Used by BufferedServletResponse.isCommitted * @return */ - public boolean hasNonemptyBuffer() + public boolean hasNonemptyBuffer() { return (this.buffer.size() != 0); } - + /** * Close this output stream, causing any buffered data to be flushed and * any further output data to throw an IOException. */ + public void close() throws IOException { + if (this.defferedStreamClose) + { + log.debug("stream close() deffered"); + return; + } + + doClose(); + } + + protected void doClose() throws IOException + { + + if (log.isDebugEnabled()) + { + log.debug("called close() from", new Throwable()); + } if (closed) { @@ -225,7 +244,7 @@ } /** * @param Intended size of the output. - */ + */ protected void setOriginalContentLength(int len) { this.originalContentLength = len; @@ -237,4 +256,9 @@ { return closed; } + + public void setDefferedStreamClose(boolean defferedStreamClose) + { + this.defferedStreamClose = defferedStreamClose; + } } Index: BufferedServletResponse.java =================================================================== RCS file: /cvsroot/jtidy/jtidyservlet/src/java/org/w3c/tidy/servlet/filter/BufferedServletResponse.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- BufferedServletResponse.java 29 Apr 2005 21:20:45 -0000 1.5 +++ BufferedServletResponse.java 2 Nov 2005 22:43:16 -0000 1.6 @@ -57,8 +57,8 @@ * Created on 02.10.2004 */ import java.io.IOException; -import java.io.PrintWriter; import java.io.OutputStreamWriter; +import java.io.PrintWriter; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; @@ -93,14 +93,20 @@ * any. */ - protected PrintWriter writer = null; + protected BufferedServletPrintWriter writer = null; /** * Do not buffer the output, Preform validation only */ private boolean tee = false; + protected boolean binary = false; + private int originalContentLength = -1; + + private boolean defferedStreamClose; + + private boolean isCommittedFix = true; protected TidyProcessor processor; @@ -138,6 +144,7 @@ } stream.setBinary(this.binary); stream.setOriginalContentLength(originalContentLength); + stream.setDefferedStreamClose(this.defferedStreamClose); return stream; } @@ -224,13 +231,15 @@ // according the spec, so feel free to remove that "if" if (charEnc != null) { - this.writer = new PrintWriter(new OutputStreamWriter(this.stream, charEnc)); + this.writer = new BufferedServletPrintWriter(new OutputStreamWriter(this.stream, charEnc)); } else { - this.writer = new PrintWriter(this.stream); + this.writer = new BufferedServletPrintWriter(this.stream); } - + + this.writer.setDefferedStreamClose(this.defferedStreamClose); + return (this.writer); } @@ -242,28 +251,41 @@ */ public boolean isCommitted() { - return /*(stream != null && stream.hasNonemptyBuffer()) ||*/ super.isCommitted(); + return (this.isCommittedFix && stream != null && stream.hasNonemptyBuffer()) || super.isCommitted(); } /** * Finish a response. */ - public void finishResponse() + protected void finishResponse() { try { log.debug("finishResponse"); if (this.writer != null) { - log.debug("close writer"); - this.writer.close(); + if (this.defferedStreamClose) { + log.debug("deffered close writer"); + this.writer.doClose(); + if (this.stream != null) { + log.debug("deffered close stream"); + this.stream.doClose(); + } + } else { + log.debug("close writer"); + this.writer.close(); + } } else if (this.stream != null) { - log.debug("close stream"); - this.stream.close(); + if (this.defferedStreamClose) { + log.debug("deffered close stream"); + this.stream.doClose(); + } else { + log.debug("close stream"); + this.stream.close(); + } } - } catch (IOException e) { @@ -278,4 +300,17 @@ { this.tee = tee; } + + /** + * @param defferedStreamClose The defferedStreamClose to set. + */ + public void setDefferedStreamClose(boolean defferedStreamClose) + { + this.defferedStreamClose = defferedStreamClose; + } + + public void setIsCommittedFix(boolean isCommittedFix) + { + this.isCommittedFix = isCommittedFix; + } } \ No newline at end of file Index: JTidyFilter.java =================================================================== RCS file: /cvsroot/jtidy/jtidyservlet/src/java/org/w3c/tidy/servlet/filter/JTidyFilter.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- JTidyFilter.java 1 Nov 2004 23:38:04 -0000 1.5 +++ JTidyFilter.java 2 Nov 2005 22:43:16 -0000 1.6 @@ -131,6 +131,24 @@ * */ public static final String CONFIG_COMMENTS_SUBST = "commentsSubst"; + + /** + * name of the parameter <code>defferedStreamClose</code>. + * + * Do not close BufferedServletOutputStream + * To avoid java.io.IOException: Stream closed after RequestProcessor.doForward + */ + public static final String CONFIG_DEFFERED_STREAM_CLOSE = "defferedStreamClose"; + + /** + * name of the parameter <code>isCommittedFix</code>. + * + * An exception is thrown when using JTidyFilter with a JSP that has a dynamic include which points to a Struts action that forwards to a Tiles definition. + * The fix is to override isCommitted() in BufferedServletResponse, to make sure this method correctly reports the "committed" status with our custom output stream + * + */ + public static final String CONFIG_IS_COMMITTED_FIX = "isCommittedFix"; + /** * Logger. */ @@ -160,6 +178,16 @@ * @see #CONFIG_COMMENTS_SUBST. */ private boolean commentsSubst; + + /** + * @see #CONFIG_DEFFERED_STREAM_CLOSE. + */ + private boolean defferedStreamClose; + + /** + * @see #CONFIG_IS_COMMITTED_FIX. + */ + private boolean isCommittedFix; /** * Convert String to beelean. @@ -188,11 +216,13 @@ JTidyServletProperties.getInstance().loadFile(filterConfig.getInitParameter(CONFIG_PROPERTIES_FILE_NAME)); - tee = getBoolean(filterConfig.getInitParameter(CONFIG_TEE), false); - doubleValidation = getBoolean(filterConfig.getInitParameter(CONFIG_DOUBLE_VALIDATION), false); - validateOnly = getBoolean(filterConfig.getInitParameter(CONFIG_VALIDATE_ONLY), false); - config = filterConfig.getInitParameter(CONFIG_CONFIG); - commentsSubst = getBoolean(filterConfig.getInitParameter(CONFIG_COMMENTS_SUBST), false); + this.tee = getBoolean(filterConfig.getInitParameter(CONFIG_TEE), false); + this.doubleValidation = getBoolean(filterConfig.getInitParameter(CONFIG_DOUBLE_VALIDATION), false); + this.validateOnly = getBoolean(filterConfig.getInitParameter(CONFIG_VALIDATE_ONLY), false); + this.config = filterConfig.getInitParameter(CONFIG_CONFIG); + this.commentsSubst = getBoolean(filterConfig.getInitParameter(CONFIG_COMMENTS_SUBST), false); + this.defferedStreamClose = getBoolean(filterConfig.getInitParameter(CONFIG_DEFFERED_STREAM_CLOSE), false); + this.isCommittedFix = getBoolean(filterConfig.getInitParameter(CONFIG_IS_COMMITTED_FIX), false); } /** @@ -232,7 +262,9 @@ BufferedServletResponse wrappedResponse = new BufferedServletResponse( (HttpServletResponse) servletResponse, tidyProcessor); - wrappedResponse.setTee(tee); + wrappedResponse.setTee(this.tee); + wrappedResponse.setDefferedStreamClose(this.defferedStreamClose); + wrappedResponse.setIsCommittedFix(this.isCommittedFix); try { |