/* * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package org.aitools.programd.interfaces; import java.io.OutputStreamWriter; import java.io.PrintStream; import org.aitools.programd.Core; import org.aitools.programd.Core.Status; import org.aitools.programd.interfaces.shell.Shell; import org.apache.log4j.Logger; /** * Creating a Console essentially means that loggers (as configured) will (may) also print output to the console. * * @author <a href="mailto:noel@aitools.org">Noel Bush</a> */ public class Console { /** The Core to which this console is (may be) attached. */ private Core _core; /** The stdout handler. */ private ConsoleStreamAppender stdOutAppender; /** The stderr handler. */ private ConsoleStreamAppender stdErrAppender; /** The Shell that will (may) be activated for this console. */ private Shell _shell; /** * Creates a <code>Console</code> with default output streams. */ public Console() { this.initialize(System.out, System.err); } /** * Creates a <code>Console</code> with specified input, output and prompt streams (this implies that a shell will be * enabled). * * @param out the stream to use for normal messages * @param err the stream to use for error messages */ public Console(PrintStream out, PrintStream err) { this.initialize(out, err); } /** * Adds the given Shell to the Console * * @param shell the Shell to add * @param core the core to which to attach the Shell */ public void addShell(Shell shell, Core core) { this._shell = shell; this._shell.attachTo(core); if (this.stdOutAppender != null) { this.stdOutAppender.watch(this._shell); } if (this.stdErrAppender != null) { this.stdErrAppender.watch(this._shell); } } /** * Attaches the console to the given core. * * @param core the core to which to attach */ public void attachTo(Core core) { this._core = core; if (this._core.getSettings().useShell()) { this.addShell(new Shell(), this._core); } else { Logger.getLogger("programd").info("Interactive shell disabled. Awaiting SIGHUP to shut down."); } } /** * Sets up the stdout and stderr appenders (if they are defined in the log4j configuration). * * @param out the stream to use for normal output messages * @param err the stream to use for error messages */ protected void initialize(PrintStream out, PrintStream err) { this.stdOutAppender = (ConsoleStreamAppender) Logger.getLogger("programd").getAppender("stdout"); if (this.stdOutAppender != null) { this.stdOutAppender.setWriter(new OutputStreamWriter(out)); } this.stdErrAppender = (ConsoleStreamAppender) Logger.getLogger("programd").getAppender("stderr"); if (this.stdErrAppender != null) { this.stdErrAppender.setWriter(new OutputStreamWriter(err)); } } /** * Starts the attached shell (if one exists and the shell is enabled). */ public void startShell() { if (this._core.getSettings().useShell()) { this._shell.start(); } // Now just run as long as the core status stays at READY. while (this._core.getStatus() == Status.READY) { try { Thread.sleep(1000); } catch (InterruptedException e) { this._core.getLogger().warn("Console was interrupted; shell will not run anymore."); } } } }