//============================================================================== // tribble/io/DebugWriter.java //------------------------------------------------------------------------------ package tribble.io; // System imports import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.Writer; import java.lang.String; import java.lang.System; // Local imports import tribble.io.DebugWriterI; import tribble.io.SuspendableWriterI; /******************************************************************************* * Debugging (tracing) message output stream. * *
* Provides an output stream suitable for writing debug or trace * text messages to. * *
* A debugging output stream is used to provide debugging trace information, * which is typically needed during program development to identify bugs. * Such a stream is capable of printing text string messages. The underlying * output stream is some kind of output stream derived from * java.io.Writer or @link java.io.OutputStream. * *
* This debugging output stream implements {@link tribble.io.SuspendableWriterI},
* which means that its output can be selectively suspended and resumed
* (i.e., turned off and on).
*
* @version $Revision: 1.1 $ $Date: 2003/02/25 20:27:23 $
* @since 2003-02-25
* @author
* David R. Tribble,
* david@tribble.com.
*
* Copyright
* ©2003 by David R. Tribble all rights reserved.
*
* Permission is granted to freely use and distribute this source code
* provided that the original copyright and authorship notices remain
* intact.
*/
public class DebugWriter
implements DebugWriterI, SuspendableWriterI
{
// Identification
/** Revision information. */
static final String REV =
"@(#)tribble/io/DebugWriter.java $Revision: 1.1 $ $Date: 2003/02/25 20:27:23 $\n";
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Public constants
// (None)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Protected constants
/** Native operating system newline character sequence. */
protected static final String NEWLINE =
System.getProperty("line.separator");
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Static methods
// (None)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Protected variables
/** Underlying output stream. */
protected Writer m_out;
/** Saved (suspended) output stream. */
protected Writer m_sus;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Public constructors
/***************************************************************************
* Constructor.
*
* @param out
* The underlying output stream for this debugging output stream.
*
* @since 1.1, 2003-02-25
*/
public DebugWriter(Writer out)
{
// Establish the underlying output stream
m_out = out;
m_sus = m_out;
}
/***************************************************************************
* Constructor.
*
* @param out
* The underlying output stream for this debugging output stream.
*
* @since 1.1, 2003-02-25
*/
public DebugWriter(OutputStream out)
{
// Establish the underlying output stream
m_out = new OutputStreamWriter(out);
m_sus = m_out;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Public methods
/***************************************************************************
* Close this debugging output stream.
*
*
* Note that this method flushes any pending output to the underlying output * stream of this stream, regardless of whether or not this stream is * currently suspended. The underlying output stream is then closed (by * calling its close() method). (This is probably not be a wise * thing to do if the underlying output stream is System.out.) * *
* Note that this method does not throw any checked exceptions (such as * java.io.IOException). * * @since 1.1, 2003-02-25 */ public synchronized void close() //implements tribble.io.SuspendableWriterI { try { // Flush and close the underlying output stream if (m_sus != null) { synchronized (m_sus) { m_sus.flush(); m_sus.close(); } } } catch (IOException ex) { // Ignore } finally { // Disassociate the underlying output stream m_sus = null; m_out = null; } } /*************************************************************************** * Write a text message to this debugging output stream. * *
* Note that this method does not throw any checked exceptions (such as * java.io.IOException). * * @param msg * The message text. * Note that the message text should not contain a terminating newline. * * @return * This debugging output stream. * *
* This allows several debugging calls to be chained together. * For example: *
* DebugWriter dbg = ...;
*
* dbg.print("length=")
* .print(len+"")
* .print(", width=")
* .print(wid+"")
* .println();
*
* @since 1.1, 2003-02-01
*/
public DebugWriterI print(String msg)
//implements tribble.io.DebugWriterI
{
// Check if the output stream is suspended
if (m_out == null)
return (this);
// Check args
if (msg == null)
return (this);
// Write the message string
try
{
synchronized (m_out)
{
m_out.write(msg);
}
}
catch (IOException ex)
{
// Ignore
}
return (this);
}
/***************************************************************************
* Write a text message to this debugging output stream, followed by a
* newline.
*
* * Note that the means of writing a "newline" are dependent upon the * implementation of the underlying output stream as well as the underlying * operating system, and might involve something other than simply writing a * single '\n' character. The exact character sequence is specified * by the "line.separator" Java system property. * *
* Note that this method does not throw any checked exceptions (such as * java.io.IOException). * * @param msg * The message text. * Note that the message text should not contain a terminating newline. * * @return * This debugging output stream. * *
* This allows several debugging calls to be chained together. * For example: *
* DebugWriter dbg = ...;
*
* dbg.println("Customer: ")
* .println(" name: " + cust.name)
* .println(" addr: " + cust.addr)
* .println(" balance: " + cust.balance);
*
* @since 1.1, 2003-02-01
*/
public DebugWriterI println(String msg)
//implements tribble.io.DebugWriterI
{
// Check if the output stream is suspended
if (m_out == null)
return (this);
// Check args
if (msg == null)
return (this);
// Write the message string and a newline
try
{
synchronized (m_out)
{
m_out.write(msg);
m_out.write(NEWLINE);
m_out.flush();
}
}
catch (IOException ex)
{
// Ignore
}
return (this);
}
/***************************************************************************
* Write a newline to this debugging output stream.
* This also flushes any pending output to the underlying output stream.
*
* * Note that the means of writing a "newline" are dependent upon the * implementation of the underlying output stream as well as the underlying * operating system, and might involve something other than simply writing a * single '\n' character. The exact character sequence is specified * by the "line.separator" Java system property. * *
* Note that this method does not throw any checked exceptions (such as * java.io.IOException). * * @return * This debugging output stream. * *
* This allows several debugging calls to be chained together. * For example: *
* DebugWriter dbg = ...;
*
* dbg.print("x=" + x).print(", y=" + y).println();
*
* @since 1.1, 2003-02-01
*/
public DebugWriterI println()
//implements tribble.io.DebugWriterI
{
// Check if the output stream is suspended
if (m_out == null)
return (this);
// Write a newline to the output stream
try
{
synchronized (m_out)
{
m_out.write(NEWLINE);
m_out.flush();
}
}
catch (IOException ex)
{
// Ignore
}
return (this);
}
/***************************************************************************
* Suspend subsequent output written to this debugging output stream.
*
* * Subsequent calls to any of the print() or println() * methods will not write any output to the underlying stream. * *
* Output to this stream can be resumed by calling {@link #resume}. * *
* This method may be called multiple times without any intervening call to * {@link #resume} without any ill effects. * * @since 1.1, 2002-03-25 * * @see #resume */ public synchronized void suspend() //implements tribble.io.SuspendableWriterI { // Suspend subsequent output to this stream m_out = null; } /*************************************************************************** * Resume subsequent output written to this debugging output stream. * *
* Subsequent calls to any of the print() or println() * methods will cause output to be written to the underlying stream. * *
* Output to this stream can be suspended by calling {@link #suspend}. * *
* This method may be called multiple times without any previous or * intervening call to {@link #suspend} without any ill effects. * * @since 1.1, 2003-02-25 * * @see #suspend */ public synchronized void resume() //implements tribble.io.SuspendableWriterI { // Resume subsequent output to this stream m_out = m_sus; } /*************************************************************************** * Determine if this debugging output stream is suspended or not. * * @return * True if this output stream is currently suspended, otherwise false. * * @since 1.1, 2003-02-25 * * @see #suspend */ public boolean isSuspended() //implements tribble.io.SuspendableWriterI { // Determine if this output stream is suspended return (m_out == null); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Private constructors /*************************************************************************** * Default constructor. * Do not use this constructor. * * @since 1.1, 2003-02-25 */ private DebugWriter() { // Do nothing } } // End DebugWriter.java