package org.marketcetera.util.file; import java.io.Closeable; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.Reader; import org.marketcetera.util.misc.ClassVersion; import org.marketcetera.util.unicode.DecodingStrategy; import org.marketcetera.util.unicode.UnicodeFileReader; import org.marketcetera.util.unicode.UnicodeInputStreamReader; import static org.marketcetera.util.file.SpecialNames.*; /** * A wrapped reader. It may wrap a regular file, the standard input * stream, or any other {@link Reader} instance. This wrapper is * intended to wrap {@link Reader} 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: ReaderWrapper.java 16154 2012-07-14 16:34:05Z colin $ */ /* $License$ */ @ClassVersion("$Id: ReaderWrapper.java 16154 2012-07-14 16:34:05Z colin $") public class ReaderWrapper implements Closeable { // INSTANCE DATA. private Reader mReader; private boolean mSkipClose; // CONSTRUCTORS. /** * Creates a new wrapped reader that wraps the regular file with * the given name, or the standard input stream (if the name is * {@link SpecialNames#STANDARD_INPUT}). A reader that recognizes * unicode BOMs is used as a proxy; that reader uses the given * decoding strategy. * * @param name The file name. * @param decodingStrategy The decoding strategy. It may be null * to use the default JVM charset. * * @throws FileNotFoundException Thrown if the name represents a * regular file, and it cannot be opened for reading. */ public ReaderWrapper (String name, DecodingStrategy decodingStrategy) throws FileNotFoundException { if (name.equals(STANDARD_INPUT)) { mReader=new UnicodeInputStreamReader(System.in,decodingStrategy); mSkipClose=true; return; } mReader=new UnicodeFileReader(name,decodingStrategy); } /** * Creates a new wrapped reader that wraps the regular file with * the given name, or the standard input stream (if the name is * {@link SpecialNames#STANDARD_INPUT}). The default JVM charset * is used to convert bytes into characters. * * @param name The file name. * * @throws FileNotFoundException Thrown if the name represents a * regular file, and it cannot be opened for reading. */ public ReaderWrapper (String name) throws FileNotFoundException { this(name,null); } /** * Creates a new wrapped reader that wraps the given regular * file. A reader that recognizes unicode BOMs is used as a proxy; * that reader uses the given decoding strategy. * * @param file The file. * @param decodingStrategy The decoding strategy. It may be null * to use the default JVM charset. * * @throws FileNotFoundException Thrown if the file cannot be * opened for reading. */ public ReaderWrapper (File file, DecodingStrategy decodingStrategy) throws FileNotFoundException { mReader=new UnicodeFileReader(file,decodingStrategy); } /** * Creates a new wrapped reader that wraps the given regular file. * The default JVM charset is used to convert bytes into * characters. * * @param file The file. * * @throws FileNotFoundException Thrown if the file cannot be * opened for reading. */ public ReaderWrapper (File file) throws FileNotFoundException { this(file,null); } /** * Creates a new wrapped reader that wraps the given reader. The * reader may or may not be closed when {@link #close()} is * called depending on the given flag. * * @param reader The reader. * @param skipClose True if the underlying reader should not be * closed. */ public ReaderWrapper (Reader reader, boolean skipClose) { mReader=reader; mSkipClose=skipClose; } /** * Creates a new wrapped reader that wraps the given reader. The * underlying reader will be closed when {@link #close()} is * called; hence the given reader should not wrap the standard * input stream. * * @param reader The reader. */ public ReaderWrapper (Reader reader) { this(reader,false); } // Closeable. @Override public void close() throws IOException { if ((getReader()==null) || getSkipClose()) { return; } getReader().close(); // Prevent future closures per {@link Closeable}. mReader=null; } // INSTANCE METHODS. /** * Returns the receiver's underlying reader. * * @return The reader. */ public Reader getReader() { return mReader; } /** * Returns true if the receiver's underlying reader will not be * closed when {@link #close()} is called. * * @return True if so. */ public boolean getSkipClose() { return mSkipClose; } }