package org.marketcetera.util.file;
import java.io.Closeable;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import org.marketcetera.util.misc.ClassVersion;
import static org.marketcetera.util.file.SpecialNames.*;
/**
* A wrapped output stream. It may wrap a regular file, the standard
* output or error stream, or any other {@link OutputStream}
* instance. This wrapper is intended to wrap {@link OutputStream}
* instances for use with {@link CloseableRegistry}, hence such
* instances should not be closed directly, that is, without going
* through the wrapper's {@link #close()} method.
*
* @author tlerios@marketcetera.com
* @since 0.5.0
* @version $Id: OutputStreamWrapper.java 16154 2012-07-14 16:34:05Z colin $
*/
/* $License$ */
@ClassVersion("$Id: OutputStreamWrapper.java 16154 2012-07-14 16:34:05Z colin $")
public class OutputStreamWrapper
implements Closeable
{
// INSTANCE DATA.
private OutputStream mStream;
private boolean mSkipClose;
// CONSTRUCTORS.
/**
* Creates a new wrapped stream that wraps:
*
* <ul>
* <li>the regular file with the given name (data is appended to the
* file if the name is prefixed by {@link SpecialNames#PREFIX_APPEND}),
* or</li>
* <li>the standard output stream (if the name is {@link
* SpecialNames#STANDARD_OUTPUT}), or</li>
* <li>the standard error stream (if the name is {@link
* SpecialNames#STANDARD_ERROR}).</li>
* </ul>
*
* @param name The file name.
*
* @throws FileNotFoundException Thrown if the name represents a
* regular file, and it cannot be opened for writing.
*/
public OutputStreamWrapper
(String name)
throws FileNotFoundException
{
if (name.equals(STANDARD_OUTPUT)) {
mStream=System.out;
mSkipClose=true;
return;
}
if (name.equals(STANDARD_ERROR)) {
mStream=System.err;
mSkipClose=true;
return;
}
if (!name.startsWith(PREFIX_APPEND)) {
mStream=new FileOutputStream(name);
return;
}
mStream=new FileOutputStream
(name.substring(PREFIX_APPEND.length()),true);
}
/**
* Creates a new wrapped stream that wraps the given regular file.
*
* @param file The file.
*
* @throws FileNotFoundException Thrown if the file cannot be
* opened for writing.
*/
public OutputStreamWrapper
(File file)
throws FileNotFoundException
{
mStream=new FileOutputStream(file);
}
/**
* Creates a new wrapped stream that wraps the given stream. The
* stream may or may not be closed when {@link #close()} is called
* depending on the given flag.
*
* @param stream The stream.
* @param skipClose True if the underlying stream should not be
* closed.
*/
public OutputStreamWrapper
(OutputStream stream,
boolean skipClose)
{
mStream=stream;
mSkipClose=skipClose;
}
/**
* Creates a new wrapped stream that wraps the given stream. The
* underlying stream will be closed when {@link #close()} is
* called; hence the given stream should not wrap (or be) the
* standard output or error stream.
*
* @param stream The stream.
*/
public OutputStreamWrapper
(OutputStream stream)
{
this(stream,false);
}
// Closeable.
@Override
public void close()
throws IOException
{
if (getStream()==null) {
return;
}
// All streams (closeable or not) are flushed.
getStream().flush();
if (getSkipClose()) {
return;
}
getStream().close();
// Prevent future closures per {@link Closeable}.
mStream=null;
}
// INSTANCE METHODS.
/**
* Returns the receiver's underlying stream.
*
* @return The stream.
*/
public OutputStream getStream()
{
return mStream;
}
/**
* Returns true if the receiver's underlying stream will not be
* closed when {@link #close()} is called.
*
* @return True if so.
*/
public boolean getSkipClose()
{
return mSkipClose;
}
}