diff --git a/build.xml b/build.xml
index 73e31cf21..b43470ff4 100644
--- a/build.xml
+++ b/build.xml
@@ -16,6 +16,7 @@
+
@@ -38,7 +39,7 @@
-
+
diff --git a/src/com/sk89q/worldedit/LocalConfiguration.java b/src/com/sk89q/worldedit/LocalConfiguration.java
index ca65fa785..12f3be51b 100644
--- a/src/com/sk89q/worldedit/LocalConfiguration.java
+++ b/src/com/sk89q/worldedit/LocalConfiguration.java
@@ -19,6 +19,7 @@
package com.sk89q.worldedit;
+import java.util.HashSet;
import java.util.Set;
import com.sk89q.worldedit.snapshots.SnapshotRepository;
@@ -36,7 +37,7 @@ public abstract class LocalConfiguration {
};
public boolean profile = false;
- public Set disallowedBlocks = null;
+ public Set disallowedBlocks = new HashSet();
public int defaultChangeLimit = -1;
public int maxChangeLimit = -1;
public String shellSaveType = null;
@@ -54,6 +55,7 @@ public abstract class LocalConfiguration {
public boolean useInventoryOverride = false;
public int navigationWand = 345;
public int navigationWandMaxDistance = 50;
+ public int scriptTimeout = 3000;
/**
* Loads the configuration.
diff --git a/src/com/sk89q/worldedit/WorldEditController.java b/src/com/sk89q/worldedit/WorldEditController.java
index 3599f99c8..84ff44bc3 100644
--- a/src/com/sk89q/worldedit/WorldEditController.java
+++ b/src/com/sk89q/worldedit/WorldEditController.java
@@ -22,20 +22,19 @@ package com.sk89q.worldedit;
import java.util.List;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Map;
import java.util.Set;
import java.util.HashSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.io.*;
-import javax.script.ScriptEngine;
-import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import com.sk89q.util.StringUtil;
import com.sk89q.worldedit.bags.BlockBag;
import com.sk89q.worldedit.blocks.*;
import com.sk89q.worldedit.data.*;
import com.sk89q.worldedit.filters.*;
-import com.sk89q.worldedit.scripting.ScriptContext;
+import com.sk89q.worldedit.scripting.*;
import com.sk89q.worldedit.snapshots.*;
import com.sk89q.worldedit.superpickaxe.*;
import com.sk89q.worldedit.regions.*;
@@ -2149,44 +2148,61 @@ public class WorldEditController {
String script;
try {
- FileInputStream file = new FileInputStream(f);
- DataInputStream in = new DataInputStream (file);
+ InputStream file;
+
+ if (!f.exists()) {
+ file = WorldEditController.class.getResourceAsStream(
+ "craftscripts/" + filename);
+
+ if (file == null) {
+ player.printError("Script does not exist: " + filename);
+ return;
+ }
+ } else {
+ file = new FileInputStream(f);
+ }
+
+ DataInputStream in = new DataInputStream(file);
byte[] data = new byte[in.available()];
in.readFully(data);
- in.close ();
+ in.close();
script = new String(data, 0, data.length, "utf-8");
- } catch (FileNotFoundException e) {
- player.printError("Script does not exist: " + filename);
- return;
} catch (IOException e) {
player.printError("Script read error: " + e.getMessage());
return;
}
-
- ScriptEngineManager manager = new ScriptEngineManager();
- ScriptEngine engine = manager.getEngineByExtension(ext);
-
- if (engine == null) {
- player.printError("Failed to load the scripting engine.");
- return;
- }
LocalSession session = getSession(player);
- ScriptContext context = new ScriptContext(this, server, config, session, player);
+ CraftScriptContext scriptContext =
+ new CraftScriptContext(this, server, config, session, player);
- engine.put("argv", args);
- engine.put("ctx", context);
- engine.put("player", player);
- engine.put("BaseBlock", BaseBlock.class);
+ CraftScriptEngine engine = null;
try {
- engine.eval(script);
+ engine = new RhinoCraftScriptEngine();
+ } catch (NoClassDefFoundError e) {
+ try {
+ engine = new SunRhinoCraftScriptEngine();
+ } catch (NoClassDefFoundError e2) {
+ player.printError("Failed to find an installed script engine.");
+ return;
+ }
+ }
+
+ engine.setTimeLimit(3000);
+
+ Map vars = new HashMap();
+ vars.put("argv", args);
+ vars.put("context", scriptContext);
+ vars.put("player", player);
+
+ try {
+ engine.evaluate(script, filename, vars);
} catch (ScriptException e) {
- e.printStackTrace();
- player.printError("Script encountered an error: " + e.getMessage());
- return;
+ player.printError("Failed to execute:");
+ player.printRaw(e.getMessage());
} finally {
- for (EditSession editSession : context._getEditSessions()) {
+ for (EditSession editSession : scriptContext._getEditSessions()) {
session.remember(editSession);
}
}
diff --git a/src/com/sk89q/worldedit/bukkit/BukkitConfiguration.java b/src/com/sk89q/worldedit/bukkit/BukkitConfiguration.java
index 4a4fa3551..d15ca4ed1 100644
--- a/src/com/sk89q/worldedit/bukkit/BukkitConfiguration.java
+++ b/src/com/sk89q/worldedit/bukkit/BukkitConfiguration.java
@@ -65,6 +65,8 @@ public class BukkitConfiguration extends LocalConfiguration {
navigationWand = config.getInt("navigation-wand.item", navigationWand);
navigationWandMaxDistance = config.getInt("navigation-wand.max-distance", navigationWandMaxDistance);
+ scriptTimeout = config.getInt("scripting.timeout", scriptTimeout);
+
disallowedBlocks = new HashSet(config.getIntList("limits.disallowed-blocks", null));
String snapshotsDir = config.getString("snapshots.directory", "");
diff --git a/src/com/sk89q/worldedit/scripting/ScriptContext.java b/src/com/sk89q/worldedit/scripting/CraftScriptContext.java
similarity index 92%
rename from src/com/sk89q/worldedit/scripting/ScriptContext.java
rename to src/com/sk89q/worldedit/scripting/CraftScriptContext.java
index bba38a21e..8d2da49ea 100644
--- a/src/com/sk89q/worldedit/scripting/ScriptContext.java
+++ b/src/com/sk89q/worldedit/scripting/CraftScriptContext.java
@@ -31,10 +31,10 @@ import com.sk89q.worldedit.UnknownItemException;
import com.sk89q.worldedit.WorldEditController;
import com.sk89q.worldedit.blocks.BaseBlock;
-public class ScriptContext extends ScriptEnvironment {
+public class CraftScriptContext extends CraftScriptEnvironment {
private List editSessions = new ArrayList();
- public ScriptContext(WorldEditController controller,
+ public CraftScriptContext(WorldEditController controller,
ServerInterface server, LocalConfiguration config,
LocalSession session, LocalPlayer player) {
super(controller, server, config, session, player);
diff --git a/src/com/sk89q/worldedit/scripting/CraftScriptEngine.java b/src/com/sk89q/worldedit/scripting/CraftScriptEngine.java
new file mode 100644
index 000000000..32ac9c41d
--- /dev/null
+++ b/src/com/sk89q/worldedit/scripting/CraftScriptEngine.java
@@ -0,0 +1,30 @@
+// $Id$
+/*
+ * WorldEdit
+ * Copyright (C) 2010 sk89q
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+*/
+
+package com.sk89q.worldedit.scripting;
+
+import java.util.Map;
+import javax.script.ScriptException;
+
+public interface CraftScriptEngine {
+ public void setTimeLimit(int milliseconds);
+ public int getTimeLimit();
+ public Object evaluate(String script, String filename, Map args)
+ throws ScriptException;
+}
diff --git a/src/com/sk89q/worldedit/scripting/ScriptEnvironment.java b/src/com/sk89q/worldedit/scripting/CraftScriptEnvironment.java
similarity index 88%
rename from src/com/sk89q/worldedit/scripting/ScriptEnvironment.java
rename to src/com/sk89q/worldedit/scripting/CraftScriptEnvironment.java
index 30d7a1b27..06a83b600 100644
--- a/src/com/sk89q/worldedit/scripting/ScriptEnvironment.java
+++ b/src/com/sk89q/worldedit/scripting/CraftScriptEnvironment.java
@@ -25,14 +25,14 @@ import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.ServerInterface;
import com.sk89q.worldedit.WorldEditController;
-public abstract class ScriptEnvironment {
+public abstract class CraftScriptEnvironment {
protected WorldEditController controller;
protected LocalPlayer player;
protected LocalConfiguration config;
protected LocalSession session;
protected ServerInterface server;
- public ScriptEnvironment(WorldEditController controller, ServerInterface server,
+ public CraftScriptEnvironment(WorldEditController controller, ServerInterface server,
LocalConfiguration config, LocalSession session, LocalPlayer player) {
this.controller = controller;
this.player = player;
diff --git a/src/com/sk89q/worldedit/scripting/RhinoContextFactory.java b/src/com/sk89q/worldedit/scripting/RhinoContextFactory.java
new file mode 100644
index 000000000..381b6c5f8
--- /dev/null
+++ b/src/com/sk89q/worldedit/scripting/RhinoContextFactory.java
@@ -0,0 +1,61 @@
+// $Id$
+/*
+ * WorldEdit
+ * Copyright (C) 2010 sk89q
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldedit.scripting;
+
+import org.mozilla.javascript.*;
+
+public class RhinoContextFactory extends ContextFactory {
+ protected int timeLimit;
+
+ public RhinoContextFactory(int timeLimit) {
+ this.timeLimit = timeLimit;
+ }
+
+ protected Context makeContext() {
+ RhinoContext cx = new RhinoContext(this);
+ cx.setInstructionObserverThreshold(10000);
+ return cx;
+ }
+
+ protected void observeInstructionCount(Context cx, int instructionCount) {
+ RhinoContext mcx = (RhinoContext)cx;
+ long currentTime = System.currentTimeMillis();
+
+ if (currentTime - mcx.startTime > timeLimit) {
+ throw new Error("Script timed out (" + timeLimit + "ms)");
+ }
+ }
+
+ protected Object doTopCall(Callable callable, Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args) {
+ RhinoContext mcx = (RhinoContext)cx;
+ mcx.startTime = System.currentTimeMillis();
+
+ return super.doTopCall(callable, cx, scope, thisObj, args);
+ }
+
+ private static class RhinoContext extends Context {
+ long startTime;
+
+ public RhinoContext(ContextFactory factory) {
+ super(factory);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/com/sk89q/worldedit/scripting/RhinoCraftScriptEngine.java b/src/com/sk89q/worldedit/scripting/RhinoCraftScriptEngine.java
new file mode 100644
index 000000000..c872b4874
--- /dev/null
+++ b/src/com/sk89q/worldedit/scripting/RhinoCraftScriptEngine.java
@@ -0,0 +1,75 @@
+// $Id$
+/*
+ * WorldEdit
+ * Copyright (C) 2010 sk89q
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+*/
+
+package com.sk89q.worldedit.scripting;
+
+import java.util.Map;
+import javax.script.ScriptException;
+import org.mozilla.javascript.*;
+
+public class RhinoCraftScriptEngine implements CraftScriptEngine {
+ private int timeLimit;
+
+ @Override
+ public void setTimeLimit(int milliseconds) {
+ timeLimit = milliseconds;
+ }
+
+ @Override
+ public int getTimeLimit() {
+ return timeLimit;
+ }
+
+ @Override
+ public Object evaluate(String script, String filename, Map args)
+ throws ScriptException {
+ RhinoContextFactory factory = new RhinoContextFactory(timeLimit);
+ Context cx = factory.enterContext();
+ ScriptableObject scriptable = new ImporterTopLevel(cx);
+ Scriptable scope = cx.initStandardObjects(scriptable);
+
+ for (Map.Entry entry : args.entrySet()) {
+ ScriptableObject.putProperty(scope, entry.getKey(),
+ Context.javaToJS(entry.getValue(), scope));
+ }
+ try {
+ return cx.evaluateString(scope, script, filename, 1, null);
+ } catch (Error e) {
+ throw new ScriptException(e.getMessage());
+ } catch (RhinoException e) {
+ String msg;
+ int line = (line = e.lineNumber()) == 0 ? -1 : line;
+
+ if (e instanceof JavaScriptException) {
+ msg = String.valueOf(((JavaScriptException)e).getValue());
+ } else {
+ msg = e.getMessage();
+ }
+
+ ScriptException scriptException =
+ new ScriptException(msg, e.sourceName(), line);
+ scriptException.initCause(e);
+
+ throw scriptException;
+ } finally {
+ Context.exit();
+ }
+ }
+
+}
diff --git a/src/com/sk89q/worldedit/scripting/SunRhinoContextFactory.java b/src/com/sk89q/worldedit/scripting/SunRhinoContextFactory.java
new file mode 100644
index 000000000..aad0fa2ae
--- /dev/null
+++ b/src/com/sk89q/worldedit/scripting/SunRhinoContextFactory.java
@@ -0,0 +1,61 @@
+// $Id$
+/*
+ * WorldEdit
+ * Copyright (C) 2010 sk89q
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldedit.scripting;
+
+import sun.org.mozilla.javascript.internal.*;
+
+public class SunRhinoContextFactory extends ContextFactory {
+ protected int timeLimit;
+
+ public SunRhinoContextFactory(int timeLimit) {
+ this.timeLimit = timeLimit;
+ }
+
+ protected Context makeContext() {
+ RhinoContext cx = new RhinoContext(this);
+ cx.setInstructionObserverThreshold(10000);
+ return cx;
+ }
+
+ protected void observeInstructionCount(Context cx, int instructionCount) {
+ RhinoContext mcx = (RhinoContext)cx;
+ long currentTime = System.currentTimeMillis();
+
+ if (currentTime - mcx.startTime > timeLimit) {
+ throw new Error("Script timed out (" + timeLimit + "ms)");
+ }
+ }
+
+ protected Object doTopCall(Callable callable, Context cx, Scriptable scope,
+ Scriptable thisObj, Object[] args) {
+ RhinoContext mcx = (RhinoContext)cx;
+ mcx.startTime = System.currentTimeMillis();
+
+ return super.doTopCall(callable, cx, scope, thisObj, args);
+ }
+
+ private static class RhinoContext extends Context {
+ long startTime;
+
+ public RhinoContext(ContextFactory factory) {
+ super();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/com/sk89q/worldedit/scripting/SunRhinoCraftScriptEngine.java b/src/com/sk89q/worldedit/scripting/SunRhinoCraftScriptEngine.java
new file mode 100644
index 000000000..10726fcf7
--- /dev/null
+++ b/src/com/sk89q/worldedit/scripting/SunRhinoCraftScriptEngine.java
@@ -0,0 +1,82 @@
+// $Id$
+/*
+ * WorldEdit
+ * Copyright (C) 2010 sk89q
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+*/
+
+package com.sk89q.worldedit.scripting;
+
+import java.util.Map;
+import javax.script.ScriptException;
+import com.sk89q.worldedit.WorldEditController;
+import sun.org.mozilla.javascript.internal.*;
+
+public class SunRhinoCraftScriptEngine implements CraftScriptEngine {
+ private int timeLimit;
+
+ @Override
+ public void setTimeLimit(int milliseconds) {
+ timeLimit = milliseconds;
+ }
+
+ @Override
+ public int getTimeLimit() {
+ return timeLimit;
+ }
+
+ @Override
+ public Object evaluate(final String script, final String filename,
+ final Map args)
+ throws ScriptException {
+ SunRhinoContextFactory factory = new SunRhinoContextFactory(timeLimit);
+ factory.initApplicationClassLoader(WorldEditController.class.getClassLoader());
+
+ try {
+ return factory.call(new ContextAction() {
+ public Object run(Context cx) {
+ Scriptable topLevel = new ImporterTopLevel(cx);
+ Scriptable scope = cx.initStandardObjects();
+ topLevel.setParentScope(scope);
+
+ for (Map.Entry entry : args.entrySet()) {
+ ScriptableObject.putProperty(scope, entry.getKey(),
+ Context.javaToJS(entry.getValue(), scope));
+ }
+
+ return cx.evaluateString(topLevel, script, filename, 1, null);
+ }
+ });
+ } catch (Error e) {
+ throw new ScriptException(e.getMessage());
+ } catch (RhinoException e) {
+ String msg;
+ int line = (line = e.lineNumber()) == 0 ? -1 : line;
+
+ if (e instanceof JavaScriptException) {
+ msg = String.valueOf(((JavaScriptException)e).getValue());
+ } else {
+ msg = e.getMessage();
+ }
+
+ ScriptException scriptException =
+ new ScriptException(msg, e.sourceName(), line);
+ scriptException.initCause(e);
+
+ throw scriptException;
+ }
+ }
+
+}
diff --git a/src/com/sk89q/worldedit/scripting/java/RhinoScriptEngine.java b/src/com/sk89q/worldedit/scripting/java/RhinoScriptEngine.java
new file mode 100644
index 000000000..4fd93000e
--- /dev/null
+++ b/src/com/sk89q/worldedit/scripting/java/RhinoScriptEngine.java
@@ -0,0 +1,119 @@
+// $Id$
+/*
+ * WorldEdit
+ * Copyright (C) 2010 sk89q
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldedit.scripting.java;
+
+import java.io.*;
+import javax.script.*;
+import org.mozilla.javascript.*;
+import com.sk89q.worldedit.scripting.RhinoContextFactory;
+
+public class RhinoScriptEngine extends AbstractScriptEngine {
+ private ScriptEngineFactory factory;
+ private Context cx;
+
+ public RhinoScriptEngine() {
+ RhinoContextFactory factory = new RhinoContextFactory(3000);
+ factory.enterContext();
+ }
+
+ public Bindings createBindings() {
+ return new SimpleBindings();
+ }
+
+ @Override
+ public Object eval(String script, ScriptContext context)
+ throws ScriptException {
+
+ Scriptable scope = setupScope(cx, context);
+
+ String filename = (filename = (String)get(ScriptEngine.FILENAME)) == null
+ ? "" : filename;
+
+ try {
+ return cx.evaluateString(scope, script, filename, 1, null);
+ } catch (RhinoException e) {
+ String msg;
+ int line = (line = e.lineNumber()) == 0 ? -1 : line;
+
+ if (e instanceof JavaScriptException) {
+ msg = String.valueOf(((JavaScriptException)e).getValue());
+ } else {
+ msg = e.getMessage();
+ }
+
+ ScriptException scriptException =
+ new ScriptException(msg, e.sourceName(), line);
+ scriptException.initCause(e);
+
+ throw scriptException;
+ } finally {
+ Context.exit();
+ }
+ }
+
+ @Override
+ public Object eval(Reader reader, ScriptContext context)
+ throws ScriptException {
+
+ Scriptable scope = setupScope(cx, context);
+
+ String filename = (filename = (String)get(ScriptEngine.FILENAME)) == null
+ ? "" : filename;
+
+ try {
+ return cx.evaluateReader(scope, reader, filename, 1, null);
+ } catch (RhinoException e) {
+ String msg;
+ int line = (line = e.lineNumber()) == 0 ? -1 : line;
+
+ if (e instanceof JavaScriptException) {
+ msg = String.valueOf(((JavaScriptException)e).getValue());
+ } else {
+ msg = e.getMessage();
+ }
+
+ ScriptException scriptException =
+ new ScriptException(msg, e.sourceName(), line);
+ scriptException.initCause(e);
+
+ throw scriptException;
+ } catch (IOException e) {
+ throw new ScriptException(e);
+ } finally {
+ Context.exit();
+ }
+ }
+
+ @Override
+ public ScriptEngineFactory getFactory() {
+ if (factory != null) {
+ return factory;
+ } else {
+ return new RhinoScriptEngineFactory();
+ }
+ }
+
+ private Scriptable setupScope(Context cx, ScriptContext context) {
+ ScriptableObject scriptable = new ImporterTopLevel(cx);
+ Scriptable scope = cx.initStandardObjects(scriptable);
+ //ScriptableObject.putProperty(scope, "argv", Context.javaToJS(args, scope));
+ return scope;
+ }
+}
diff --git a/src/com/sk89q/worldedit/scripting/java/RhinoScriptEngineFactory.java b/src/com/sk89q/worldedit/scripting/java/RhinoScriptEngineFactory.java
new file mode 100644
index 000000000..0dd82acaf
--- /dev/null
+++ b/src/com/sk89q/worldedit/scripting/java/RhinoScriptEngineFactory.java
@@ -0,0 +1,151 @@
+// $Id$
+/*
+ * WorldEdit
+ * Copyright (C) 2010 sk89q
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.sk89q.worldedit.scripting.java;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineFactory;
+
+public class RhinoScriptEngineFactory implements ScriptEngineFactory {
+ private static List names;
+ private static List mimeTypes;
+ private static List extensions;
+
+ static {
+ names = new ArrayList(5);
+ names.add("ECMAScript");
+ names.add("ecmascript");
+ names.add("JavaScript");
+ names.add("javascript");
+ names.add("js");
+ names = Collections.unmodifiableList(names);
+
+ mimeTypes = new ArrayList(4);
+ mimeTypes.add("application/ecmascript");
+ mimeTypes.add("text/ecmascript");
+ mimeTypes.add("application/javascript");
+ mimeTypes.add("text/javascript");
+ mimeTypes = Collections.unmodifiableList(mimeTypes);
+
+ extensions = new ArrayList(2);
+ extensions.add("emcascript");
+ extensions.add("js");
+ extensions = Collections.unmodifiableList(extensions);
+ }
+
+ @Override
+ public String getEngineName() {
+ return "Rhino JavaScript Engine (SK)";
+ }
+
+ @Override
+ public String getEngineVersion() {
+ return "unknown";
+ }
+
+ @Override
+ public List getExtensions() {
+ return extensions;
+ }
+
+ @Override
+ public String getLanguageName() {
+ return "EMCAScript";
+ }
+
+ @Override
+ public String getLanguageVersion() {
+ return "1.8";
+ }
+
+ @Override
+ public String getMethodCallSyntax(String obj, String m, String ... args) {
+ StringBuilder s = new StringBuilder();
+ s.append(obj);
+ s.append(".");
+ s.append(m);
+ s.append("(");
+
+ for (int i = 0; i < args.length; i++) {
+ s.append(args[i]);
+ if (i < args.length - 1) {
+ s.append(",");
+ }
+ }
+
+ s.append(")");
+
+ return s.toString();
+ }
+
+ @Override
+ public List getMimeTypes() {
+ return mimeTypes;
+ }
+
+ @Override
+ public List getNames() {
+ return names;
+ }
+
+ @Override
+ public String getOutputStatement(String str) {
+ return "print(" + str.replace("\\", "\\\\")
+ .replace("\"", "\\\\\"")
+ .replace(";", "\\\\;") + ")";
+ }
+
+ @Override
+ public Object getParameter(String key) {
+ if (key.equals(ScriptEngine.ENGINE)) {
+ return getEngineName();
+ } else if (key.equals(ScriptEngine.ENGINE_VERSION)) {
+ return getEngineVersion();
+ } else if (key.equals(ScriptEngine.NAME)) {
+ return getEngineName();
+ } else if (key.equals(ScriptEngine.LANGUAGE)) {
+ return getLanguageName();
+ } else if (key.equals(ScriptEngine.LANGUAGE_VERSION)) {
+ return getLanguageVersion();
+ } else if (key.equals("THREADING")) {
+ return "MULTITHREADED";
+ } else {
+ throw new IllegalArgumentException("Invalid key");
+ }
+ }
+
+ @Override
+ public String getProgram(String ... statements) {
+ StringBuilder s = new StringBuilder();
+ for (String stmt : statements) {
+ s.append(stmt);
+ s.append(";");
+ }
+ return s.toString();
+ }
+
+ @Override
+ public ScriptEngine getScriptEngine() {
+ return new RhinoScriptEngine();
+ }
+
+}