1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
|
package ij.plugin;
import ij.*;
import ij.plugin.frame.Editor;
import javax.script.*;
/** Implements the text editor's Macros/Run command, and the
IJ.runMacroFile() method, when the file name ends with ".js". */
public class JavaScriptEvaluator implements PlugIn, Runnable {
private Thread thread;
private String script;
private Object result;
private String error;
private boolean evaluating;
ScriptEngine engine;
// run script in separate thread
public void run(String script) {
if (script.equals(""))
return;
this.script = script;
thread = new Thread(this, "JavaScript");
thread.setPriority(Math.max(thread.getPriority()-2, Thread.MIN_PRIORITY));
thread.start();
}
// Run script in current thread
public String run(String script, String arg) {
this.script = script;
run();
return null;
}
// Evaluates 'script' and returns any error messages as a String.
public String eval(String script) {
this.script = script;
evaluating = true;
run();
if (error!=null)
return error;
else
return result!=null?""+result:"";
}
public void run() {
result = null;
error = null;
Thread.currentThread().setContextClassLoader(IJ.getClassLoader());
if (IJ.isJava19())
System.setProperty("nashorn.args", "--language=es6"); // Use ECMAScript 6 on Java 9
try {
if (engine==null) {
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
engine = scriptEngineManager.getEngineByName("ECMAScript");
if (engine == null) {
IJ.error("Could not find JavaScript engine");
return;
}
if (!IJ.isJava18()) {
engine.eval("function load(path) {\n"
+ " importClass(Packages.sun.org.mozilla.javascript.internal.Context);\n"
+ " importClass(Packages.java.io.FileReader);\n"
+ " var cx = Context.getCurrentContext();\n"
+ " cx.evaluateReader(this, new FileReader(path), path, 1, null);\n"
+ "}");
}
}
result = engine.eval(script);
} catch(Throwable e) {
String msg = e.getMessage();
if (msg==null)
msg = "";
if (msg.startsWith("sun.org.mozilla.javascript.internal.EcmaError: "))
msg = msg.substring(47, msg.length());
if (msg.startsWith("sun.org.mozilla.javascript.internal.EvaluatorException"))
msg = "Error"+msg.substring(54, msg.length());
if (msg.length()>0 && !msg.contains("Macro canceled")) {
if (evaluating)
error = msg;
else
IJ.log(msg);
}
}
}
public String toString() {
return result!=null?""+result:"";
}
}
|