/* If we want to support multiple commands in the command path we need to change this to not throw the exception. */ private BshMethod loadScriptedCommand( InputStream in, String name, Class[] argTypes, String resourcePath, Interpreter interpreter) throws UtilEvalError { try { interpreter.eval(new InputStreamReader(in), this, resourcePath); } catch (EvalError e) { /* Here we catch any EvalError from the interpreter because we are using it as a tool to load the command, not as part of the execution path. */ Interpreter.debug(e.toString()); throw new UtilEvalError("Error loading script: " + e.getMessage(), e); } // Look for the loaded command BshMethod meth = getMethod(name, argTypes); /* if ( meth == null ) throw new UtilEvalError("Loaded resource: " + resourcePath + "had an error or did not contain the correct method" ); */ return meth; }
/** * Execute Script Loads environment and saves result * * @return null or Exception */ public Exception execute() { m_result = null; if (m_variable == null || m_variable.length() == 0 || m_script == null || m_script.length() == 0) { IllegalArgumentException e = new IllegalArgumentException("No variable/script"); log.config(e.toString()); return e; } Interpreter i = new Interpreter(); loadEnvironment(i); try { log.config(m_script); i.eval(m_script); } catch (Exception e) { log.config(e.toString()); return e; } try { m_result = i.get(m_variable); log.config("Result (" + m_result.getClass().getName() + ") " + m_result); } catch (Exception e) { log.config("Result - " + e); if (e instanceof NullPointerException) e = new IllegalArgumentException("Result Variable not found - " + m_variable); return e; } return null; } // execute
/** * Runs a BeanShell script. Errors are passed to the caller. * * <p>If the <code>in</code> parameter is non-null, the script is read from that stream; otherwise * it is read from the file identified by <code>path</code> . * * <p>The <code>scriptPath</code> BeanShell variable is set to the path name of the script. * * @param path The script file's VFS path. * @param in The reader to read the script from, or <code>null</code> . * @param namespace The namespace to run the script in. * @exception Exception instances are thrown when various BeanShell errors occur * @since jEdit 4.2pre5 */ public void _runScript(String path, Reader in, NameSpace namespace) throws Exception { log.info("Running script " + path); Interpreter interp = createInterpreter(namespace); try { if (in == null) { in = res.getResourceAsReader(path); } setupDefaultVariables(namespace); interp.set("scriptPath", path); running = true; interp.eval(in, namespace, path); } catch (Exception e) { unwrapException(e); } finally { running = false; try { // no need to do this for macros! if (namespace == global) { resetDefaultVariables(namespace); interp.unset("scriptPath"); } } catch (EvalError e) { // do nothing } } } // }}}
private static void endInterpreter(String contextId) throws EvalError { Interpreter i = interpreters.get(contextId); if (i == null) return; i.eval("clear();"); // can't hurt to tell bsh to clean up internally interpreters.remove(contextId); // now wait for GC Log.log("Destroyed context: " + contextId + " (" + i + ")"); }
public String[][] exec(String[] befehle) { String[][] antworten = new String[befehle.length][1]; Object aktObj; for (int i = 0; i < befehle.length; i++) { try { aktObj = interpreter.eval(befehle[i]); if (aktObj != null) antworten[i][0] = aktObj.toString(); else antworten[i][0] = "null"; } catch (EvalError e) { System.err.println(e.getMessage()); antworten[i][0] = "ERROR"; } if (verbose) { assert !quiet; System.out.println("# " + i + ": " + befehle[i]); for (int j = 0; j < antworten[i].length; j++) { System.out.println("@ " + antworten[i][j]); } } else if (!quiet) for (int j = 0; j < antworten[i].length; j++) { System.out.print("#"); } } return antworten; }
private static Expr define(boolean isGlobal, Interpreter interpreter, Scope scope, Expr argExpr) { if (!(argExpr instanceof ListExpr)) return interpreter.error("def:is: needs more than one argument."); ListExpr args = (ListExpr) argExpr; if (args.getList().size() != 2) return interpreter.error("def:is: expects two arguments."); // get the list of names being defined Expr nameArg = args.getList().get(0); List<String> names = new ArrayList<String>(); if (nameArg.getType() == ExprType.NAME) { // defining a single name names.add(((NameExpr) nameArg).getName()); } else if (nameArg.getType() == ExprType.LIST) { // defining a list of names ListExpr namesList = (ListExpr) nameArg; for (Expr name : namesList.getList()) { if (name.getType() != ExprType.NAME) { return interpreter.error("First argument to def:is: must be a name, list, or call."); } names.add(((NameExpr) name).getName()); } } else { return interpreter.error("First argument to def:is: must be a name, list, or call."); } // evaluate the value(s) Expr body = args.getList().get(1); Expr value = interpreter.eval(scope, body); // make sure the body matches the names if (names.size() > 1) { if (value.getType() != ExprType.LIST) return interpreter.error("When defining multiple names, the value must be a list."); ListExpr valueList = (ListExpr) value; if (names.size() != valueList.getList().size()) return interpreter.error( "When defining multiple names, the number of names and values must match."); } // define the names in the correct scope if (names.size() == 1) { defineName(isGlobal, interpreter, scope, names.get(0), value); } else { ListExpr values = (ListExpr) value; for (int i = 0; i < names.size(); i++) { defineName(isGlobal, interpreter, scope, names.get(i), values.getList().get(i)); } } return Expr.unit(); }
static String getBshVersion() { if (bshVersion != null) return bshVersion; /* We have included a getVersion() command to detect the version of bsh. If bsh is packaged in the WAR file it could access it directly as a bsh command. But if bsh is in the app server's classpath it won't see it here, so we will source it directly. This command works around the lack of a coherent version number in the early versions. */ Interpreter bsh = new Interpreter(); try { bsh.eval(new InputStreamReader(BshServlet.class.getResource("getVersion.bsh").openStream())); bshVersion = (String) bsh.eval("getVersion()"); } catch (Exception e) { bshVersion = "BeanShell: unknown version"; } return bshVersion; }
Object evalScript( String script, StringBuffer scriptOutput, boolean captureOutErr, HttpServletRequest request, HttpServletResponse response) throws EvalError { // Create a PrintStream to capture output ByteArrayOutputStream baos = new ByteArrayOutputStream(); PrintStream pout = new PrintStream(baos); // Create an interpreter instance with a null inputstream, // the capture out/err stream, non-interactive Interpreter bsh = new Interpreter(null, pout, pout, false); // set up interpreter bsh.set("bsh.httpServletRequest", request); bsh.set("bsh.httpServletResponse", response); // Eval the text, gathering the return value or any error. Object result = null; String error = null; PrintStream sout = System.out; PrintStream serr = System.err; if (captureOutErr) { System.setOut(pout); System.setErr(pout); } try { // Eval the user text result = bsh.eval(script); } finally { if (captureOutErr) { System.setOut(sout); System.setErr(serr); } } pout.flush(); scriptOutput.append(baos.toString()); return result; }
public String[] exec(String befehl) { String[] antwort = new String[1]; Object aktObj; try { aktObj = interpreter.eval(befehl); if (aktObj != null) antwort[0] = aktObj.toString(); else antwort[0] = "null"; } catch (EvalError e) { System.err.println(e.getMessage()); antwort[0] = "ERROR"; } if (!quiet) System.out.print("#"); if (verbose) { assert !quiet; System.out.println(" " + befehl); System.out.println("@ " + antwort[0]); } return antwort; }
public static void main(String args[]) throws Exception { Yylex l = null; parser p; Interpreter I; try { if (args.length == 0) l = new Yylex(System.in); else l = new Yylex(new FileReader(args[0])); } catch (FileNotFoundException e) { System.err.println("Error: File not found: " + args[0]); System.exit(1); } p = new parser(l); /* The default parser is the first-defined entry point. */ /* You may want to change this. Other options are: */ /* */ try { calc.Absyn.Exp parse_tree = p.pExp(); I = new Interpreter(); // I.eval(parse_tree) ; System.out.println(I.eval(parse_tree)); /*System.out.println(); System.out.println("Parse Succesful!"); System.out.println(); System.out.println("[Abstract Syntax]"); System.out.println(); System.out.println(PrettyPrinter.show(parse_tree)); System.out.println(); System.out.println("[Linearized Tree]"); System.out.println(); System.out.println(PrettyPrinter.print(parse_tree)); */ } catch (Throwable e) { System.err.println( "At line " + String.valueOf(l.line_num()) + ", near \"" + l.buff() + "\" :"); System.err.println(" " + e.getMessage()); System.exit(1); } }
@Test public void misc_tests() throws Exception { Assert.assertEquals(true, TestUtil.eval("return true == true;")); Assert.assertEquals(true, TestUtil.eval("return false == false;")); Assert.assertEquals(false, TestUtil.eval("return true == false;")); Assert.assertEquals(false, TestUtil.eval("return false == true;")); try { TestUtil.eval("throw new RuntimeException();"); Assert.fail(); } catch (TargetError e) { Assert.assertTrue(e.getTarget().getClass() == RuntimeException.class); } Assert.assertEquals( "foobar", TestUtil.eval( "String a;", "try {", " a = \"foobar\";", "} catch (Exception e) {", " throw e;", "}", "return a;")); String script = "boolean fieldBool = false;\n" + "int fieldInt = 0;\n" + "Boolean fieldBool2 = false;\n" + "void run() {\n" + "fieldBool = ! fieldBool;\n" + "fieldBool2 = ! fieldBool2;\n" + "fieldInt++;\n" + "System.out.println(\"fieldBool: \"+fieldBool);\n" + "System.out.println(\"fieldBool2: \"+fieldBool2);\n" + "System.out.println(\"fieldInt: \"+fieldInt);\n" + "}\n"; Interpreter bsh = new Interpreter(); bsh.eval(script); Runnable runnable = (Runnable) bsh.getInterface(Runnable.class); runnable.run(); }
/** * Evaluates the specified BeanShell expression. Unlike <code>eval()</code> , this method passes * any exceptions to the caller. * * @param namespace The namespace * @param command The expression * @return Description of the Return Value * @exception Exception instances are thrown when various BeanShell errors occur * @since jEdit 3.2pre7 */ public Object _eval(NameSpace namespace, String command) throws Exception { Interpreter interp = createInterpreter(namespace); try { setupDefaultVariables(namespace); if (log.isDebugEnabled()) { log.debug("Running script: " + command); } return interp.eval(command); } catch (Exception e) { unwrapException(e); // never called return null; } finally { // try { resetDefaultVariables(namespace); // } // catch (UtilEvalError e) { // do nothing // } } } // }}}
private static Interpreter getInterpreter(String contextId) throws EvalError { // Get the appropriate interpreter Interpreter i = null; boolean createdInterp = false; synchronized (interpreters) { // serialize two gets of the same name i = interpreters.get(contextId); if (i == null) { i = new Interpreter(); interpreters.put(contextId, i); createdInterp = true; } } if (createdInterp) { Log.log("Created context: " + contextId + " (" + i + ")"); // Now configure stdin and stdout to capture 10k of content // Store references to the circular buffers within the interpreter itself. // This provides a nice place to store them plus theoretically allows // advanced use from within the bsh environment. // On Windows print() outputs \r\n but in XQuery that's normalized to \n // so the 10k of Java buffer may produce less than 10k of content in XQuery! OutputStream circularOutput = new CircularByteArrayOutputStream(10240); PrintStream printOutput = new PrintStream(circularOutput); i.setOut(printOutput); i.set("mljamout", circularOutput); OutputStream circularError = new CircularByteArrayOutputStream(10240); PrintStream printError = new PrintStream(circularError); i.setErr(printError); i.set("mljamerr", circularError); // Capture the built-in System.out and System.err also. // (Commented out since System appears global, can't do per interpreter.) // i.set("mljamprintout", printOutput); // i.set("mljamprinterr", printError); // i.eval("System.setOut(mljamprintout);"); // i.eval("System.setErr(mljamprinterr);"); // Need to expose hexdecode() and base64decode() built-in functions i.eval("hexdecode(String s) { return com.xqdev.jam.MLJAM.hexDecode(s); }"); i.eval("base64decode(String s) { return com.xqdev.jam.MLJAM.base64Decode(s); }"); // Let's tell the context what its id is i.set("mljamid", contextId); } // Update the last accessed time, used for cleaning i.set("mljamlast", System.currentTimeMillis()); // If it's been long enough, go snooping for stale contexts if (System.currentTimeMillis() > lastClean + CLEAN_INTERVAL) { Log.log("Initiated periodic scan for stale context objects"); lastClean = System.currentTimeMillis(); Iterator<Interpreter> itr = interpreters.values().iterator(); while (itr.hasNext()) { Interpreter interp = itr.next(); Long last = (Long) interp.get("mljamlast"); if (System.currentTimeMillis() > last + STALE_TIMEOUT) { itr.remove(); Log.log("Staled context: " + interp.get("mljamid") + " (" + interp + ")"); } else if ((System.currentTimeMillis() > last + TEMP_STALE_TIMEOUT) && ("" + interp.get("mljamid")).startsWith("temp:")) { itr.remove(); Log.log("Staled temp context: " + interp.get("mljamid") + " (" + interp + ")"); } } } return i; }
protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { try { // A good request looks like /mljam/contextid/verb?name=varname // The extra path info includes the context id and verb String extra = req.getPathInfo(); // "/contextid/verb" if (extra == null || extra.equals("")) { throw new ClientProblemException( "Request requires a context id and verb in its extra path info"); } String[] parts = extra.split("/"); // { "", "contextid", "verb" } if (parts.length < 2) { throw new ClientProblemException( "Request requires a context id and verb in its extra path info"); } else if (parts.length < 3) { throw new ClientProblemException("Request requires a verb in its extra path info"); } String contextId = parts[1]; String verb = parts[2]; String method = req.getMethod(); if (method.equalsIgnoreCase("get")) { // We have three GET verbs: get, get-stdout, get-stderr. // These are all idempotent, while the POST verbs aren't. The get // verb accept a "name" query string parameter. The get verb returns // either XQuery to evaluate (indicated by x-marklogic/xquery content type) // or a raw binary (indicated by an application/binary-encoded content type). if (verb.equalsIgnoreCase("get")) { String name = req.getParameter("name"); if (name == null || name.equals("")) { throw new ClientProblemException("The get verb requires a name parameter"); } Interpreter i = getInterpreter(contextId); Object o = i.get(name); if (o instanceof byte[]) { sendBinaryResponse(res, (byte[]) o); } else if (o instanceof String) { sendStringResponse(res, (String) o); } else { sendXQueryResponse(res, o); } } else if (verb.equalsIgnoreCase("get-stdout")) { Interpreter i = getInterpreter(contextId); i.getOut().flush(); CircularByteArrayOutputStream circ = (CircularByteArrayOutputStream) i.get("mljamout"); if (circ != null) { sendStringResponse(res, circ.toString()); circ.reset(); } else { throw new ServerProblemException("Could not fetch mljamout from interpreter context"); } } else if (verb.equalsIgnoreCase("get-stderr")) { Interpreter i = getInterpreter(contextId); i.getErr().flush(); CircularByteArrayOutputStream circ = (CircularByteArrayOutputStream) i.get("mljamerr"); if (circ != null) { sendStringResponse(res, circ.toString()); circ.reset(); } else { throw new ServerProblemException("Could not fetch mljamerr from interpreter context"); } } else { throw new ClientProblemException("Unrecognized GET verb: " + verb); } } else if (method.equalsIgnoreCase("post")) { // We have six POST verbs: eval, unset, end, source, set-string, and set-binary. // These are POST verbs because they aren't idempotent. // The set-string, set-binary, unset, and source verbs accept a "name" // query string parameter. The set-string and set-binary verbs accept // a value in their post body. The eval verb accepts code in its post body. if (verb.equalsIgnoreCase("set-string")) { String name = req.getParameter("name"); if (name == null || name.equals("")) { throw new ClientProblemException("The set-string verb requires a name parameter"); } String body = getBody(req); // a value of "" is legit Interpreter i = getInterpreter(contextId); i.unset(name); i.set(name, body); sendNoResponse(res); } else if (verb.equalsIgnoreCase("set-binary")) { String name = req.getParameter("name"); if (name == null || name.equals("")) { throw new ClientProblemException("The set-binary verb requires a name parameter"); } String body = getBody(req); // a value of "" is legit byte[] bodyBytes = hexDecode(body); // later could do this streaming for speed Interpreter i = getInterpreter(contextId); i.unset(name); i.set(name, bodyBytes); sendNoResponse(res); } else if (verb.equalsIgnoreCase("eval")) { String body = getBody(req); if (body == null || body.equals("")) { throw new ClientProblemException( "The eval verb requires a post body containing code to eval"); } Interpreter i = getInterpreter(contextId); i.eval(body); sendNoResponse(res); } else if (verb.equalsIgnoreCase("eval-get")) { String body = getBody(req); if (body == null || body.equals("")) { throw new ClientProblemException( "The eval-get verb requires a post body containing code to eval"); } Interpreter i = getInterpreter(contextId); Object o = i.eval(body); if (o instanceof byte[]) { sendBinaryResponse(res, (byte[]) o); } else if (o instanceof String) { sendStringResponse(res, (String) o); } else { sendXQueryResponse(res, o); } } else if (verb.equalsIgnoreCase("unset")) { String name = req.getParameter("name"); if (name == null || name.equals("")) { throw new ClientProblemException("The unset verb requires a name parameter"); } Interpreter i = getInterpreter(contextId); i.unset(name); sendNoResponse(res); } else if (verb.equalsIgnoreCase("end")) { endInterpreter(contextId); sendNoResponse(res); } else if (verb.equalsIgnoreCase("source")) { String name = req.getParameter("name"); if (name == null || name.equals("")) { throw new ClientProblemException("The source verb requires a name parameter"); } Interpreter i = getInterpreter(contextId); i.source(name); sendNoResponse(res); } else { throw new ClientProblemException("Unrecognized POST verb: " + verb); } } } catch (TargetError e) { Throwable target = e.getTarget(); Log.log(e); Log.log("Target: " + target); sendServerProblemResponse( res, target.getClass().getName() + ": " + target.getMessage() + " when executing Java code: " + e.getErrorText()); // include full trace? } catch (EvalError e) { Log.log(e); sendServerProblemResponse( res, e.getClass().getName() + ": " + e.getMessage()); // include full trace? } catch (ClientProblemException e) { Log.log(e); sendClientProblemResponse(res, e.getMessage()); } catch (ServerProblemException e) { Log.log(e); sendServerProblemResponse(res, e.getMessage()); } }