001/*
002 * Stallion Core: A Modern Web Framework
003 *
004 * Copyright (C) 2015 - 2016 Stallion Software LLC.
005 *
006 * This program is free software: you can redistribute it and/or modify it under the terms of the
007 * GNU General Public License as published by the Free Software Foundation, either version 2 of
008 * the License, or (at your option) any later version. This program is distributed in the hope that
009 * it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
011 * License for more details. You should have received a copy of the GNU General Public License
012 * along with this program.  If not, see <http://www.gnu.org/licenses/gpl-2.0.html>.
013 *
014 *
015 *
016 */
017
018package io.stallion.plugins.javascript;
019
020import io.stallion.dataAccess.db.DB;
021import io.stallion.settings.Settings;
022import io.stallion.utils.json.JSON;
023import jdk.nashorn.internal.objects.Global;
024import jdk.nashorn.internal.runtime.*;
025import jdk.nashorn.internal.runtime.options.Options;
026import jline.console.ConsoleReader;
027import org.apache.commons.io.IOUtils;
028
029import javax.script.ScriptException;
030import java.io.*;
031import java.util.Locale;
032import java.util.ResourceBundle;
033
034import static io.stallion.utils.Literals.*;
035
036
037public class JavascriptShell {
038    private static final String MESSAGE_RESOURCE = "jdk.nashorn.tools.resources.Shell";
039    private static final ResourceBundle bundle = ResourceBundle.getBundle("jdk.nashorn.tools.resources.Shell", Locale.getDefault());
040    public static final int SUCCESS = 0;
041    public static final int COMMANDLINE_ERROR = 100;
042    public static final int COMPILATION_ERROR = 101;
043    public static final int RUNTIME_ERROR = 102;
044    public static final int IO_ERROR = 103;
045    public static final int INTERNAL_ERROR = 104;
046
047    public static void main(String[] args) {
048        try {
049            new JavascriptShell().runShell(args);
050        } catch (IOException e) {
051            throw new RuntimeException(e);
052        } catch (ScriptException e) {
053            throw new RuntimeException(e);
054        }
055    }
056
057    public int runShell(String[] args) throws IOException, ScriptException {
058        OutputStream out = System.out;
059        OutputStream err = System.err;
060        InputStream in = System.in;
061
062        Context context = makeContext(in, out, err, args);
063        Global global = context.createGlobal();
064        if(context == null) {
065            return 100;
066        } else {
067            return readEvalPrint(in, out, context, global);
068        }
069    }
070
071
072    private static Context makeContext(InputStream in, OutputStream out, OutputStream err, String[] args) {
073
074        PrintStream pout = out instanceof PrintStream?(PrintStream)out:new PrintStream(out);
075        PrintStream perr = err instanceof PrintStream?(PrintStream)err:new PrintStream(err);
076        PrintWriter wout = new PrintWriter(pout, true);
077        PrintWriter werr = new PrintWriter(perr, true);
078        ErrorManager errors = new ErrorManager(werr);
079        Options options = new Options("nashorn", werr);
080        if(args != null) {
081            try {
082                options.process(args);
083            } catch (IllegalArgumentException var27) {
084                werr.println(bundle.getString("shell.usage"));
085                options.displayHelp(var27);
086                return null;
087            }
088        }
089        return new Context(options, errors, wout, werr, Thread.currentThread().getContextClassLoader());
090    }
091
092
093    private static int readEvalPrint(InputStream input, OutputStream out, Context context, Global global) throws IOException, ScriptException {
094        JsPluginSettings pluginSettings = new JsPluginSettings();
095
096
097
098        //context.eval(global, "");
099
100        //Global global = context.createGlobal();
101        //ScriptEnvironment env = context.getEnv();
102
103        String prompt = bundle.getString("shell.prompt");
104        //BufferedReader in = new BufferedReader(new InputStreamReader(input));
105        ConsoleReader in = new ConsoleReader();
106        PrintWriter err = context.getErr();
107        Global oldGlobal = Context.getGlobal();
108        boolean globalChanged = oldGlobal != global;
109        ScriptEnvironment env = context.getEnv();
110
111        if (DB.available()) {
112            global.put("DB", DB.instance(), false);
113        }
114
115        try {
116            if(globalChanged) {
117                Context.setGlobal(global);
118            }
119
120            global.addShellBuiltins();
121
122            // Load builtins
123            global.put("javaToJsHelpers", new JavaToJsHelpers(Sandbox.allPermissions()), true);
124            SandboxedContext ctx = new SandboxedContext(Settings.instance().getTargetFolder() + "/js", Sandbox.allPermissions(), pluginSettings);
125            global.put("myContext", ctx, true);
126
127            String stallionSharedJs = IOUtils.toString(JavascriptShell.class.getResource("/jslib/stallion_shared.js"), UTF8);
128            context.eval(global, "load(" + JSON.stringify(map(val("script", stallionSharedJs), val("name", "stallion_shared.js"))) + ");", global, "<shellboot>");
129            global.put("stallionClassLoader", new UnrestrictedJsClassLoader(), true);
130
131
132            while(true) {
133                String source;
134                do {
135                    //err.print(prompt);
136                    //err.flush();
137                    source = "";
138
139                    try {
140                        source = in.readLine(prompt);
141                    } catch (IOException var14) {
142                        err.println(var14.toString());
143                    }
144
145                    if(source == null) {
146                        return 0;
147                    }
148                } while(source.isEmpty());
149
150                try {
151                    Object e = context.eval(global, source, global, "<shell>");
152                    if(e != ScriptRuntime.UNDEFINED) {
153                        err.println(JSType.toString(e));
154                    }
155                } catch (Exception var15) {
156                    err.println(var15);
157                    if(env._dump_on_error) {
158                        var15.printStackTrace(err);
159                    }
160                }
161            }
162        } finally {
163            if(globalChanged) {
164                Context.setGlobal(oldGlobal);
165            }
166
167        }
168    }
169}