org.fit.cssbox.scriptbox.demo.tester.ConsoleInjector.java Source code

Java tutorial

Introduction

Here is the source code for org.fit.cssbox.scriptbox.demo.tester.ConsoleInjector.java

Source

/**
 * ConsoleInjector.java
 * (c) Radim Loskot and Radek Burget, 2013-2014
 *
 * ScriptBox is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *  
 * ScriptBox is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *  
 * You should have received a copy of the GNU Lesser General Public License
 * along with ScriptBox. If not, see <http://www.gnu.org/licenses/>.
 * 
 */

package org.fit.cssbox.scriptbox.demo.tester;

import java.awt.Color;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;

import org.apache.commons.lang3.StringUtils;
import org.fit.cssbox.scriptbox.script.annotation.ScriptFunction;
import org.fit.cssbox.scriptbox.script.javascript.JavaScriptInjector;
import org.mozilla.javascript.Undefined;

/**
 * Custom JavaScript injector which adds console support into JavaScript.
 *
 * @author Radim Loskot
 * @version 0.9
 * @since 0.9 - 21.4.2014
 */
public class ConsoleInjector extends JavaScriptInjector {

    /**
     * Class representing console object which will be visible inside JavaScript.
     *
     * @author Radim Loskot
     * @version 0.9
     * @since 0.9 - 21.4.2014
     */
    public static class Console {

        private StyledDocument doc;
        private JTextPane textPane;
        private Map<String, Date> namedStartTimes;
        private Map<String, Long> namedDiffs;

        private final static SimpleAttributeSet warningKeyword;
        private final static SimpleAttributeSet errorKeyword;
        private final static SimpleAttributeSet infoKeyword;

        static {
            warningKeyword = new SimpleAttributeSet();
            StyleConstants.setForeground(warningKeyword, Color.BLUE);
            StyleConstants.setBackground(warningKeyword, Color.YELLOW);
            StyleConstants.setBold(warningKeyword, true);

            errorKeyword = new SimpleAttributeSet();
            StyleConstants.setForeground(errorKeyword, Color.WHITE);
            StyleConstants.setBackground(errorKeyword, Color.RED);
            StyleConstants.setBold(errorKeyword, true);

            infoKeyword = new SimpleAttributeSet();
            StyleConstants.setForeground(infoKeyword, Color.WHITE);
            StyleConstants.setBackground(infoKeyword, Color.BLUE);
            StyleConstants.setBold(infoKeyword, true);
        }

        Console(JTextPane textPane) {
            this.doc = textPane.getStyledDocument();
            this.namedStartTimes = new HashMap<String, Date>();
            this.namedDiffs = new HashMap<String, Long>();
            this.textPane = textPane;
        }

        @ScriptFunction
        public void time(String name) {
            namedStartTimes.put(name, new Date());
        }

        @ScriptFunction
        public void timeEnd(String name) {
            Date previousDate = namedStartTimes.get(name);
            Date currentDate = new Date();

            if (previousDate != null) {
                long diffInMillies = currentDate.getTime() - previousDate.getTime();

                Long namedDiff = namedDiffs.get(name);
                if (namedDiff != null) {
                    diffInMillies += namedDiff;
                }

                log("Time for '" + name + "': " + Long.toString(diffInMillies) + " ms");
            } else {
                log("Time for '" + name + "': " + "undefined name");
            }
        }

        @ScriptFunction
        public void timeContinue(String name) {
            namedStartTimes.put(name, new Date());
        }

        @ScriptFunction
        public void timePause(String name) {
            Date previousDate = namedStartTimes.get(name);
            Date currentDate = new Date();
            long diff = 0;

            if (previousDate != null) {
                diff = currentDate.getTime() - previousDate.getTime();
            } else {
                return;
            }

            Long namedDiff = namedDiffs.get(name);
            if (namedDiff == null) {
                namedDiff = Long.valueOf(0);
            }

            namedDiff = namedDiff + diff;

            namedDiffs.put(name, namedDiff);
        }

        @ScriptFunction
        public void clear() {
            clearStyledDocument(doc);
        }

        @ScriptFunction
        public void warn(Object... args) {
            printArgs(args, "WARN", warningKeyword);
        }

        @ScriptFunction
        public void info(Object... args) {
            printArgs(args, "INFO", infoKeyword);
        }

        @ScriptFunction
        public void error(Object... args) {
            printArgs(args, "ERROR", errorKeyword);
        }

        @ScriptFunction
        public void log(Object... args) {
            printArgs(args, "LOG", null);
        }

        @ScriptFunction
        public void debug(Object... args) {
            log(args);
        }

        private void printArgs(Object[] args, final String header, final SimpleAttributeSet attr) {
            List<String> argsList = new ArrayList<String>();
            if (args != null) {
                for (Object arg : args) {
                    String printableString = printableString(arg);
                    argsList.add(printableString);
                }
            }

            final String joinedList = StringUtils.join(argsList, " ");

            if (SwingUtilities.isEventDispatchThread()) {
                consolePrint(header, joinedList, attr);
            } else {
                SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        consolePrint(header, joinedList, attr);
                    }
                });
            }
        }

        private void consolePrint(String header, String joinedList, SimpleAttributeSet attr) {
            try {
                doc.insertString(doc.getLength(), " " + header + " ", attr);
                doc.insertString(doc.getLength(), " - " + joinedList + "\n", null);

                if (textPane != null) {
                    Rectangle bottom = new Rectangle(0, textPane.getHeight() - 1, 1, 1);
                    textPane.scrollRectToVisible(bottom);
                    /*JScrollBar vertical = scrollPane.getVerticalScrollBar();
                    vertical.setValue(vertical.getMaximum());*/
                }

            } catch (BadLocationException e) {
                e.printStackTrace();
            }
        }

        private String printableString(Object arg) {
            String printString;
            if (arg == null) {
                printString = "null";
            } else if (arg instanceof Undefined) {
                printString = "undefined";
            } else {
                printString = arg.toString();
            }

            return printString;
        }
    }

    private JTextPane textPane;

    public ConsoleInjector(JTextPane textPane) {
        this.textPane = textPane;
    }

    @Override
    public boolean inject(ScriptContext context) {
        Console console = new Console(textPane);
        Bindings bindings = context.getBindings(ScriptContext.ENGINE_SCOPE);
        bindings.put("console", console);

        return true;
    }

    public void clearConsole() {
        StyledDocument doc = textPane.getStyledDocument();
        clearStyledDocument(doc);
    }

    private static void clearStyledDocument(final StyledDocument doc) {
        if (SwingUtilities.isEventDispatchThread()) {
            clearStyledDocumentImpl(doc);
        } else {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    clearStyledDocumentImpl(doc);
                }
            });
        }
    }

    private static void clearStyledDocumentImpl(final StyledDocument doc) {
        try {
            doc.remove(0, doc.getLength());
        } catch (BadLocationException e) {
            e.printStackTrace();
        }
    }
}