package org.oddjob; import java.io.PrintStream; import org.apache.log4j.Logger; import org.oddjob.logging.LogArchive; import org.oddjob.logging.LogArchiver; import org.oddjob.logging.LogEventSink; import org.oddjob.logging.LogLevel; import org.oddjob.logging.LoggingPrintStream; import org.oddjob.logging.cache.LogArchiveImpl; /** * Manage capture of console output to ensure original stream is replaced. * <p> * Oddjob used to set the console capture once but this didn't play well * with Ant JUnit running in fork once mode as that replaces stdout and stderr * at the beginning of each test. * * @since 1.5 * * @author rob * */ public class OddjobConsole { private static final Logger logger = Logger.getLogger(OddjobConsole.class); /** The archiver to which all console output will be captured. */ private static volatile LogArchive console; private static volatile PrintStream stdoutLoggingPrintStream; private static volatile PrintStream stderrloggingPrintStream; public static Close initialise() { if (System.out == stdoutLoggingPrintStream) { return new Close() { @Override public void close() { // Nothing to restore } }; } final PrintStream originalStdOut = System.out; final PrintStream originalStdErr = System.err; // Force logger class to load first so that console appender attaches // to original not to ours. logger.debug("Replacing sdterr and stdout."); console = new LogArchiveImpl("CONSOLE_MAIN", LogArchiver.MAX_HISTORY); stdoutLoggingPrintStream = new LoggingPrintStream(System.out, LogLevel.INFO, (LogEventSink) console); stderrloggingPrintStream = new LoggingPrintStream(System.err, LogLevel.ERROR, (LogEventSink) console); System.setOut(stdoutLoggingPrintStream); System.setErr(stderrloggingPrintStream); return new Close() { @Override public void close() { stdoutLoggingPrintStream.flush(); stderrloggingPrintStream.flush(); System.setOut(originalStdOut); System.setErr(originalStdErr); console = null; } }; } public static LogArchive console() { if (console == null) { throw new IllegalStateException("OddjobConsole not initialised."); } return console; } public interface Close extends AutoCloseable { @Override public void close(); } }