001package jmri.script.swing;
002
003import java.io.IOException;
004import java.io.PipedReader;
005import java.io.PipedWriter;
006import javax.script.ScriptContext;
007import javax.swing.JTextArea;
008import jmri.InstanceManager;
009import jmri.script.JmriScriptEngineManager;
010import jmri.util.PipeListener;
011
012/**
013 *
014 * @author Randall Wood
015 */
016public class ScriptOutput {
017
018    /**
019     * JTextArea containing the output
020     */
021    private JTextArea output = null;
022
023    /**
024     * Provide access to the JTextArea containing all ScriptEngine output.
025     * <p>
026     * The output JTextArea is not created until this is invoked, so that code
027     * that doesn't use this feature can run on GUI-less machines.
028     * <p>
029     * This creates a "ScriptOutput PipeListener" thread which is not normally terminated.
030     * @return component containing script output
031     */
032    public JTextArea getOutputArea() {
033        if (output == null) {
034            // convert to stored output
035
036            try {
037                // create the output area
038                output = new JTextArea();
039
040                // Add the I/O pipes
041                PipedWriter pw = new PipedWriter();
042
043                ScriptContext context = JmriScriptEngineManager.getDefault().getDefaultContext();
044                context.setErrorWriter(pw);
045                context.setWriter(pw);
046
047                // ensure the output pipe is read and stored into a
048                // Swing TextArea data model
049                PipedReader pr = new PipedReader(pw);
050                PipeListener pl = new PipeListener(pr, output);
051                pl.setName("ScriptOutput PipeListener");
052                pl.setDaemon(true);
053                pl.start();
054            } catch (IOException e) {
055                log.error("Exception creating script output area", e);
056                return null;
057            }
058        }
059        return output;
060    }
061
062    public static ScriptOutput getDefault() {
063        if (InstanceManager.getNullableDefault(ScriptOutput.class) == null) {
064            InstanceManager.store(new ScriptOutput(), ScriptOutput.class);
065        }
066        return InstanceManager.getDefault(ScriptOutput.class);
067    }
068
069    /**
070     * Write a script to the output area. The output is prepended with a leading
071     * "&gt;&gt;&gt;" on the first line and a leading ellipsis on subsequent
072     * lines.
073     *
074     * @param script The script to write.
075     */
076    public static void writeScript(final String script) {
077        String output = ">>> " + script; // NOI18N
078        // Strip ending newlines
079        while (output.endsWith("\n")) { // NOI18N
080            output = output.substring(0, output.length() - 1);
081        }
082        output = output.replaceAll("\n", "\n... "); // NOI18N
083        output += "\n"; // NOI18N
084        ScriptOutput.getDefault().getOutputArea().append(output);
085    }
086
087    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ScriptOutput.class);
088
089}