Package henplus.commands

Source Code of henplus.commands.SpoolCommand$StackedDevice

/*
* This is free software, licensed under the Gnu Public License (GPL) get a copy from <http://www.gnu.org/licenses/gpl.html> $Id:
* SpoolCommand.java,v 1.6 2005-06-18 04:58:13 hzeller Exp $ author: Henner Zeller <H.Zeller@acm.org>
*/
package henplus.commands;

import henplus.AbstractCommand;
import henplus.HenPlus;
import henplus.OutputDevice;
import henplus.PrintStreamOutputDevice;
import henplus.SQLSession;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Date;
import java.util.Stack;

/**
* prepared ..
*/
public final class SpoolCommand extends AbstractCommand {

    private final Stack<OutputDevice> _outStack;
    private final Stack<OutputDevice> _msgStack;

    /**
     * returns the command-strings this command can handle.
     */
    @Override
    public String[] getCommandList() {
        return new String[] { "spool" };
    }

    public SpoolCommand(final HenPlus hp) {
        _outStack = new Stack<OutputDevice>();
        _msgStack = new Stack<OutputDevice>();
        _outStack.push(hp.getOutputDevice());
        _msgStack.push(hp.getMessageDevice());
    }

    @Override
    public boolean requiresValidSession(final String cmd) {
        return false;
    }

    /**
     * execute the command given.
     */
    @Override
    public int execute(final SQLSession currentSession, final String cmd, String param) {
        param = param.trim();
        try {
            if ("off".equals(param.toLowerCase())) {
                closeSpool();
            } else if (param.length() > 0) {
                openSpool(param);
            } else {
                return SYNTAX_ERROR;
            }
        } catch (final Exception e) {
            e.printStackTrace();
            return EXEC_FAILED;
        }
        return SUCCESS;
    }

    /**
     * combine the current output from the stack with the given output, use this as current output and return it.
     */
    private OutputDevice openStackedDevice(final Stack<OutputDevice> stack, final OutputDevice newOut) {
        final OutputDevice origOut = stack.peek();
        final OutputDevice outDevice = new StackedDevice(origOut, newOut);
        stack.push(outDevice);
        return outDevice;
    }

    /**
     * close the top device on the stack and return the previous.
     */
    private OutputDevice closeStackedDevice(final Stack<OutputDevice> stack) {
        final OutputDevice out = stack.pop();
        out.close();
        return stack.peek();
    }

    private void openSpool(final String filename) throws IOException {
        // open file
        final OutputDevice spool = new PrintStreamOutputDevice(new PrintStream(new FileOutputStream(filename)));
        HenPlus.getInstance().setOutput(openStackedDevice(_outStack, spool), openStackedDevice(_msgStack, spool));
        HenPlus.msg().println("-- open spool at " + new Date());
    }

    private boolean closeSpool() throws IOException {
        if (_outStack.size() == 1) {
            HenPlus.msg().println("no open spool.");
            return false;
        }
        HenPlus.msg().println("-- close spool at " + new Date());
        HenPlus.getInstance().setOutput(closeStackedDevice(_outStack), closeStackedDevice(_msgStack));
        return true;
    }

    @Override
    public String getShortDescription() {
        return "log output to a file";
    }

    @Override
    public String getSynopsis(final String cmd) {
        return "spool <filename>|off";
    }

    @Override
    public String getLongDescription(final String cmd) {
        String dsc;
        dsc = "\tIf command is followed by a filename, opens a file\n"
                + "\tand writes all subsequent output not only to the terminal\n" + "\tbut as well to this file. With\n"
                + "\t spool off\n" + "\tspooling is stopped and the file is closed. The spool\n"
                + "\tcommand works recursivly, i.e. you can open more than one \n"
                + "\tfile, and you have to close each of them with 'spool off'\n";
        return dsc;
    }

    /**
     * A stream that writes to two output streams. On close, only the second, stacked stream is closed.
     */
    private static class StackedDevice implements OutputDevice {

        private final OutputDevice _a;
        private final OutputDevice _b;

        public StackedDevice(final OutputDevice a, final OutputDevice b) {
            _a = a;
            _b = b;
        }

        @Override
        public void flush() {
            _a.flush();
            _b.flush();
        }

        @Override
        public void write(final byte[] buffer, final int off, final int len) {
            _a.write(buffer, off, len);
            _b.write(buffer, off, len);
        }

        @Override
        public void print(final String s) {
            _a.print(s);
            _b.print(s);
        }

        @Override
        public void println(final String s) {
            _a.println(s);
            _b.println(s);
        }

        @Override
        public void println() {
            _a.println();
            _b.println();
        }

        @Override
        public void attributeBold() {
            _a.attributeBold();
            _b.attributeBold();
        }

        @Override
        public void attributeGrey() {
            _a.attributeGrey();
            _b.attributeGrey();
        }

        @Override
        public void attributeReset() {
            _a.attributeReset();
            _b.attributeReset();
        }

        /** closes _only_ the (stacked) second stream */
        @Override
        public void close() {
            _b.close();
        }

        @Override
        public boolean isTerminal() {
            return _a.isTerminal() && _b.isTerminal();
        }
    }
}

/*
* Local variables: c-basic-offset: 4 compile-command:
* "ant -emacs -find build.xml" End:
*/ 
TOP

Related Classes of henplus.commands.SpoolCommand$StackedDevice

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.