/*==========================================================================*\ | $Id: PrintWriterWithHistory.java,v 1.3 2010/02/23 17:06:36 stedwar2 Exp $ |*-------------------------------------------------------------------------*| | Copyright (C) 2007-2010 Virginia Tech | | This file is part of the Student-Library. | | The Student-Library is free software; you can redistribute it and/or | modify it under the terms of the GNU Lesser General Public License as | published by the Free Software Foundation; either version 3 of the | License, or (at your option) any later version. | | The Student-Library is distributed in the hope that it will be useful, | but WITHOUT ANY WARRANTY; without even the implied warranty of | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | GNU Lesser General Public License for more details. | | You should have received a copy of the GNU Lesser General Public License | along with the Student-Library; if not, see <http://www.gnu.org/licenses/>. \*==========================================================================*/ package student.testingsupport; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import java.io.StringWriter; import java.io.UnsupportedEncodingException; import java.io.Writer; //------------------------------------------------------------------------- /** * An enhanced version of {@link PrintWriter} that provides for a history * recall function and some other features making I/O testing a bit * easier to perform. See the documentation for {@link PrintWriter} for * more thorough details on what methods are provided. * * @author Stephen Edwards * @author Last changed by $Author: stedwar2 $ * @version $Revision: 1.3 $, $Date: 2010/02/23 17:06:36 $ */ public class PrintWriterWithHistory extends PrintWriter { //~ Instance/static variables ............................................. private StringWriter history = new StringWriter(); //~ Constructors .......................................................... // ---------------------------------------------------------- /** * Create a new PrintWriter with no destination--useful when you just * want to record the history (for testing, for example). If you want * to create a PrintWriter that points to {@link System#out} instead, * use this: * <pre> * new PrintWriterWithHistory(System.out); * </pre> */ public PrintWriterWithHistory() { super(new NullWriter()); } // ---------------------------------------------------------- /** * Create a new PrintWriter, without automatic line flushing. * * @param out A character-output stream */ public PrintWriterWithHistory(Writer out) { super(out, false); } // ---------------------------------------------------------- /** * Create a new PrintWriter. * * @param out A character-output stream * @param autoFlush A boolean; if true, the <tt>println</tt>, * <tt>printf</tt>, or <tt>format</tt> methods will * flush the output buffer */ public PrintWriterWithHistory(Writer out, boolean autoFlush) { super(out, autoFlush); } // ---------------------------------------------------------- /** * Create a new PrintWriter, <b>with</b> automatic line flushing, from an * existing OutputStream. This convenience constructor creates the * necessary intermediate OutputStreamWriter, which will convert characters * into bytes using the default character encoding. It differs from the * corresponding constructor in {@link PrintWriter} by forcing automatic * line flushing on instead of off, since students most often use it to * pass in something like {@link System#out}. * * @param out An output stream * * @see java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream) */ public PrintWriterWithHistory(OutputStream out) { super(out, true); } // ---------------------------------------------------------- /** * Create a new PrintWriter from an existing OutputStream. This * convenience constructor creates the necessary intermediate * OutputStreamWriter, which will convert characters into bytes using the * default character encoding. * * @param out An output stream * @param autoFlush A boolean; if true, the <tt>println</tt>, * <tt>printf</tt>, or <tt>format</tt> methods will * flush the output buffer * * @see java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream) */ public PrintWriterWithHistory(OutputStream out, boolean autoFlush) { super(out, autoFlush); } // ---------------------------------------------------------- /** * Creates a new PrintWriter, without automatic line flushing, with the * specified file name. This convenience constructor creates the necessary * intermediate {@link java.io.OutputStreamWriter OutputStreamWriter}, * which will encode characters using the {@linkplain * java.nio.charset.Charset#defaultCharset default charset} for this * instance of the Java virtual machine. * * @param fileName * The name of the file to use as the destination of this writer. * If the file exists then it will be truncated to zero size; * otherwise, a new file will be created. The output will be * written to the file and is buffered. * * @throws FileNotFoundException * If the given string does not denote an existing, writable * regular file and a new regular file of that name cannot be * created, or if some other error occurs while opening or * creating the file * * @throws SecurityException * If a security manager is present and {@link * SecurityManager#checkWrite checkWrite(fileName)} denies write * access to the file */ public PrintWriterWithHistory(String fileName) throws FileNotFoundException { super(fileName); } // ---------------------------------------------------------- /** * Creates a new PrintWriter, without automatic line flushing, with the * specified file name and charset. This convenience constructor creates * the necessary intermediate {@link java.io.OutputStreamWriter * OutputStreamWriter}, which will encode characters using the provided * charset. * * @param fileName * The name of the file to use as the destination of this writer. * If the file exists then it will be truncated to zero size; * otherwise, a new file will be created. The output will be * written to the file and is buffered. * * @param csn * The name of a supported {@linkplain java.nio.charset.Charset * charset} * * @throws FileNotFoundException * If the given string does not denote an existing, writable * regular file and a new regular file of that name cannot be * created, or if some other error occurs while opening or * creating the file * * @throws SecurityException * If a security manager is present and {@link * SecurityManager#checkWrite checkWrite(fileName)} denies write * access to the file * * @throws UnsupportedEncodingException * If the named charset is not supported */ public PrintWriterWithHistory(String fileName, String csn) throws FileNotFoundException, UnsupportedEncodingException { super(fileName, csn); } // ---------------------------------------------------------- /** * Creates a new PrintWriter, without automatic line flushing, with the * specified file. This convenience constructor creates the necessary * intermediate {@link java.io.OutputStreamWriter OutputStreamWriter}, * which will encode characters using the {@linkplain * java.nio.charset.Charset#defaultCharset default charset} for this * instance of the Java virtual machine. * * @param file * The file to use as the destination of this writer. If the file * exists then it will be truncated to zero size; otherwise, a new * file will be created. The output will be written to the file * and is buffered. * * @throws FileNotFoundException * If the given file object does not denote an existing, writable * regular file and a new regular file of that name cannot be * created, or if some other error occurs while opening or * creating the file * * @throws SecurityException * If a security manager is present and {@link * SecurityManager#checkWrite checkWrite(file.getPath())} * denies write access to the file */ public PrintWriterWithHistory(File file) throws FileNotFoundException { super(file); } // ---------------------------------------------------------- /** * Creates a new PrintWriter, without automatic line flushing, with the * specified file and charset. This convenience constructor creates the * necessary intermediate {@link java.io.OutputStreamWriter * OutputStreamWriter}, which will encode characters using the provided * charset. * * @param file * The file to use as the destination of this writer. If the file * exists then it will be truncated to zero size; otherwise, a new * file will be created. The output will be written to the file * and is buffered. * * @param csn * The name of a supported {@linkplain java.nio.charset.Charset * charset} * * @throws FileNotFoundException * If the given file object does not denote an existing, writable * regular file and a new regular file of that name cannot be * created, or if some other error occurs while opening or * creating the file * * @throws SecurityException * If a security manager is present and {@link * SecurityManager#checkWrite checkWrite(file.getPath())} * denies write access to the file * * @throws UnsupportedEncodingException * If the named charset is not supported */ public PrintWriterWithHistory(File file, String csn) throws FileNotFoundException, UnsupportedEncodingException { super(file, csn); } //~ Methods ............................................................... // ---------------------------------------------------------- /** * Retrieve the text history of what has been sent to this PrintWriter. * This will include all text printed through this object. The * {@link #clearHistory()} method resets the history to be empty, just * as when the object was first created. Note that newline characters * in the history are always represented by '\n', regardless of what * value the system <code>line.separator</code> property has. * @return all the text sent to this PrintWriter */ public String getHistory() { return history.toString(); } // ---------------------------------------------------------- /** * Reset this object's history to be empty, just as when the object was * first created. You can access the history using {@link #getHistory()}. */ public void clearHistory() { getHistoryBuffer().setLength(0); } // ---------------------------------------------------------- /** * Retrieve the StringBuffer object used to store this object's text * history. * @return The history as a string buffer */ public StringBuffer getHistoryBuffer() { return history.getBuffer(); } // ---------------------------------------------------------- /** * Write a single character. * @param c int specifying a character to be written. */ public void write(int c) { synchronized (history) { super.write(c); history.write(c); } } // ---------------------------------------------------------- /** * Write A Portion of an array of characters. * @param buf Array of characters * @param off Offset from which to start writing characters * @param len Number of characters to write */ public void write(char buf[], int off, int len) { synchronized (history) { super.write(buf, off, len); history.write(buf, off, len); } } // ---------------------------------------------------------- /** * Write a portion of a string. * @param s A String * @param off Offset from which to start writing characters * @param len Number of characters to write */ public void write(String s, int off, int len) { synchronized (history) { super.write(s, off, len); history.write(s, off, len); } } // ---------------------------------------------------------- /** * Terminate the current line by writing the line separator string. The * line separator string is defined by the system property * <code>line.separator</code>, and is not necessarily a single newline * character (<code>'\n'</code>). */ public void println() { synchronized (history) { super.println(); history.append('\n'); } } //~ Methods ............................................................... // ---------------------------------------------------------- /** * This is an inner class that is used for "null" destinations, such as * in the default constructor for PrintWriterWithHistory. */ protected static class NullWriter extends Writer { public void close() throws IOException { // Nothing to do } public void flush() throws IOException { // Nothing to do } public void write( char[] cbuf, int off, int len ) throws IOException { // Nothing to do } } }