Initial pass at JSR 223 pluggable scripting engne.
This commit is contained in:
@@ -0,0 +1 @@
|
||||
org.luaj.script.LuaScriptEngineFactory
|
||||
234
src/script/org/luaj/script/LuaScriptEngine.java
Normal file
234
src/script/org/luaj/script/LuaScriptEngine.java
Normal file
@@ -0,0 +1,234 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2008 LuaJ. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
package org.luaj.script;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.LineNumberInputStream;
|
||||
import java.io.Reader;
|
||||
import java.io.StringWriter;
|
||||
|
||||
import javax.script.Bindings;
|
||||
import javax.script.ScriptContext;
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptEngineFactory;
|
||||
import javax.script.ScriptException;
|
||||
import javax.script.SimpleBindings;
|
||||
import javax.script.SimpleScriptContext;
|
||||
|
||||
import org.luaj.compiler.LuaC;
|
||||
import org.luaj.platform.J2sePlatform;
|
||||
import org.luaj.vm.LClosure;
|
||||
import org.luaj.vm.LDouble;
|
||||
import org.luaj.vm.LFunction;
|
||||
import org.luaj.vm.LInteger;
|
||||
import org.luaj.vm.LPrototype;
|
||||
import org.luaj.vm.LString;
|
||||
import org.luaj.vm.LTable;
|
||||
import org.luaj.vm.LUserData;
|
||||
import org.luaj.vm.LValue;
|
||||
import org.luaj.vm.LoadState;
|
||||
import org.luaj.vm.Lua;
|
||||
import org.luaj.vm.LuaErrorException;
|
||||
import org.luaj.vm.LuaState;
|
||||
import org.luaj.vm.Platform;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jim_roseborough
|
||||
*/
|
||||
public class LuaScriptEngine extends LFunction implements ScriptEngine {
|
||||
|
||||
private static final String __ENGINE_VERSION__ = "V0.28";
|
||||
private static final String __NAME__ = "Luaj";
|
||||
private static final String __SHORT_NAME__ = "Luaj";
|
||||
private static final String __LANGUAGE__ = "lua";
|
||||
private static final String __LANGUAGE_VERSION__ = "5.1";
|
||||
private static final String __ARGV__ = "arg";
|
||||
private static final String __FILENAME__ = "?";
|
||||
|
||||
static {
|
||||
Platform.setInstance(new J2sePlatform());
|
||||
LuaC.install();
|
||||
}
|
||||
|
||||
private static final ScriptEngineFactory myFactory = new LuaScriptEngineFactory();
|
||||
|
||||
private ScriptContext defaultContext;
|
||||
|
||||
private final LuaState luaState;
|
||||
|
||||
public LuaScriptEngine() {
|
||||
setContext(new SimpleScriptContext());
|
||||
// set special values
|
||||
put(LANGUAGE_VERSION, __LANGUAGE_VERSION__);
|
||||
put(LANGUAGE, __LANGUAGE__);
|
||||
put(ENGINE, __NAME__);
|
||||
put(ENGINE_VERSION, __ENGINE_VERSION__);
|
||||
put(ARGV, __ARGV__);
|
||||
put(FILENAME, __FILENAME__);
|
||||
put(NAME, __SHORT_NAME__);
|
||||
put("THREADING", null);
|
||||
|
||||
// set lua state
|
||||
luaState = Platform.getInstance().newLuaState();
|
||||
|
||||
// connect up to bindings
|
||||
LTable metatable = new LTable();
|
||||
metatable.put("__index", this);
|
||||
metatable.put("__newindex", this);
|
||||
luaState._G.luaSetMetatable(metatable);
|
||||
}
|
||||
|
||||
|
||||
public Object eval(String script) throws ScriptException {
|
||||
return eval(script, getContext());
|
||||
}
|
||||
|
||||
public Object eval(String script, ScriptContext context) throws ScriptException {
|
||||
try {
|
||||
byte[] bytes = script.getBytes("UTF-8");
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream( bytes );
|
||||
LineNumberInputStream is = new LineNumberInputStream( bais );
|
||||
try {
|
||||
LPrototype p = LoadState.undump(luaState, is, "script");
|
||||
LClosure c = new LClosure( p, luaState._G );
|
||||
luaState.doCall( c, new LValue[0] );
|
||||
return luaState.topointer(1);
|
||||
} catch ( LuaErrorException lee ) {
|
||||
throw new ScriptException(lee.getMessage(), "script", is.getLineNumber() );
|
||||
} finally {
|
||||
is.close();
|
||||
}
|
||||
} catch ( Throwable t ) {
|
||||
throw new ScriptException("eval threw "+t.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public Object eval(String script, Bindings bindings) throws ScriptException {
|
||||
Bindings current = getContext().getBindings(ScriptContext.ENGINE_SCOPE);
|
||||
getContext().setBindings(bindings, ScriptContext.ENGINE_SCOPE);
|
||||
Object result = eval(script);
|
||||
getContext().setBindings(current, ScriptContext.ENGINE_SCOPE);
|
||||
return result;
|
||||
}
|
||||
|
||||
public Object eval(Reader reader) throws ScriptException {
|
||||
return eval(getScriptFromReader(reader));
|
||||
}
|
||||
|
||||
public Object eval(Reader reader, ScriptContext scriptContext) throws ScriptException {
|
||||
return eval(getScriptFromReader(reader), scriptContext);
|
||||
}
|
||||
|
||||
public Object eval(Reader reader, Bindings bindings) throws ScriptException {
|
||||
return eval(getScriptFromReader(reader), bindings);
|
||||
}
|
||||
|
||||
public void put(String key, Object value) {
|
||||
Bindings b = getBindings(ScriptContext.ENGINE_SCOPE);
|
||||
if ( value == null )
|
||||
b.remove(key);
|
||||
else {
|
||||
if ( value instanceof Number ) {
|
||||
double d = ((Number)value).doubleValue();
|
||||
int id = (int) d;
|
||||
value = (d==id? LInteger.valueOf(id): new LDouble(d));
|
||||
} else if ( value instanceof String ) {
|
||||
value = LString.valueOf(value.toString());
|
||||
} else {
|
||||
value = new LUserData(value);
|
||||
}
|
||||
b.put(key,value);
|
||||
}
|
||||
}
|
||||
|
||||
public Object get(String key) {
|
||||
Bindings b = getBindings(ScriptContext.ENGINE_SCOPE);
|
||||
Object o = b.get(key);
|
||||
if ( o == null )
|
||||
return null;
|
||||
LValue v = (LValue)o;
|
||||
switch ( v.luaGetType() ) {
|
||||
case Lua.LUA_TSTRING: return v.toJavaString();
|
||||
case Lua.LUA_TUSERDATA: return v.toJavaInstance();
|
||||
case Lua.LUA_TNUMBER: return v.isInteger()? (Object) v.toJavaBoxedInteger(): (Object) v.toJavaBoxedDouble();
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
public void luaSetTable(LuaState vm, LValue table, LValue key, LValue val) {
|
||||
Bindings b = getBindings(ScriptContext.ENGINE_SCOPE);
|
||||
String k = key.toJavaString();
|
||||
Object v = (val.isNil()? null: val);
|
||||
b.put(k,v);
|
||||
}
|
||||
|
||||
public void luaGetTable(LuaState vm, LValue table, LValue key) {
|
||||
Bindings b = getBindings(ScriptContext.ENGINE_SCOPE);
|
||||
String k = key.toJavaString();
|
||||
Object v = b.get(k);
|
||||
vm.pushlvalue((LValue)v);
|
||||
}
|
||||
|
||||
public Bindings getBindings(int scope) {
|
||||
return getContext().getBindings(scope);
|
||||
}
|
||||
|
||||
public void setBindings(Bindings bindings, int scope) {
|
||||
getContext().setBindings(bindings, scope);
|
||||
}
|
||||
|
||||
public Bindings createBindings() {
|
||||
return new SimpleBindings();
|
||||
}
|
||||
|
||||
public ScriptContext getContext() {
|
||||
return defaultContext;
|
||||
}
|
||||
|
||||
public void setContext(ScriptContext context) {
|
||||
defaultContext = context;
|
||||
}
|
||||
|
||||
public ScriptEngineFactory getFactory() {
|
||||
return myFactory;
|
||||
}
|
||||
|
||||
/*
|
||||
* private methods
|
||||
*/
|
||||
|
||||
private static String getScriptFromReader(Reader reader) {
|
||||
try {
|
||||
StringWriter script = new StringWriter();
|
||||
int data;
|
||||
while ((data = reader.read()) != -1) {
|
||||
script.write(data);
|
||||
}
|
||||
script.flush();
|
||||
return script.toString();
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
127
src/script/org/luaj/script/LuaScriptEngineFactory.java
Normal file
127
src/script/org/luaj/script/LuaScriptEngineFactory.java
Normal file
@@ -0,0 +1,127 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2008 LuaJ. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
package org.luaj.script;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptEngineFactory;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jim_roseborough
|
||||
*/
|
||||
public class LuaScriptEngineFactory implements ScriptEngineFactory {
|
||||
|
||||
private static final String FILEEXT = ".lua";
|
||||
|
||||
private static final String [] MIMETYPES = {
|
||||
"text/plain",
|
||||
"text/lua",
|
||||
"application/lua"
|
||||
};
|
||||
|
||||
private static final String [] NAMES = {
|
||||
"lua",
|
||||
"luaj",
|
||||
};
|
||||
|
||||
private ScriptEngine myScriptEngine;
|
||||
private List<String> extensions;
|
||||
private List<String> mimeTypes;
|
||||
private List<String> names;
|
||||
|
||||
public LuaScriptEngineFactory() {
|
||||
myScriptEngine = new LuaScriptEngine();
|
||||
extensions = Collections.nCopies(1, FILEEXT);
|
||||
mimeTypes = Arrays.asList(MIMETYPES);
|
||||
names = Arrays.asList(NAMES);
|
||||
}
|
||||
|
||||
public String getEngineName() {
|
||||
return getScriptEngine().get(ScriptEngine.ENGINE).toString();
|
||||
}
|
||||
|
||||
public String getEngineVersion() {
|
||||
return getScriptEngine().get(ScriptEngine.ENGINE_VERSION).toString();
|
||||
}
|
||||
|
||||
public List<String> getExtensions() {
|
||||
return extensions;
|
||||
}
|
||||
|
||||
public List<String> getMimeTypes() {
|
||||
return mimeTypes;
|
||||
}
|
||||
|
||||
public List<String> getNames() {
|
||||
return names;
|
||||
}
|
||||
|
||||
public String getLanguageName() {
|
||||
return getScriptEngine().get(ScriptEngine.LANGUAGE).toString();
|
||||
}
|
||||
|
||||
public String getLanguageVersion() {
|
||||
return getScriptEngine().get(ScriptEngine.LANGUAGE_VERSION).toString();
|
||||
}
|
||||
|
||||
public Object getParameter(String key) {
|
||||
return getScriptEngine().get(key).toString();
|
||||
}
|
||||
|
||||
public String getMethodCallSyntax(String obj, String m, String... args) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append(obj + ":" + m + "(");
|
||||
int len = args.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(',');
|
||||
}
|
||||
sb.append(args[i]);
|
||||
}
|
||||
sb.append(")");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String getOutputStatement(String toDisplay) {
|
||||
return "print(" + toDisplay + ")";
|
||||
}
|
||||
|
||||
public String getProgram(String ... statements) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
int len = statements.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (i > 0) {
|
||||
sb.append('\n');
|
||||
}
|
||||
sb.append(statements[i]);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public ScriptEngine getScriptEngine() {
|
||||
return myScriptEngine;
|
||||
}
|
||||
}
|
||||
62
src/script/org/luaj/script/ScriptEngineSample.java
Normal file
62
src/script/org/luaj/script/ScriptEngineSample.java
Normal file
@@ -0,0 +1,62 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2008 LuaJ. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
package org.luaj.script;
|
||||
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptEngineFactory;
|
||||
import javax.script.ScriptEngineManager;
|
||||
import javax.script.ScriptException;
|
||||
|
||||
public class ScriptEngineSample {
|
||||
|
||||
public static void main(String [] args) {
|
||||
ScriptEngineManager sem = new ScriptEngineManager();
|
||||
ScriptEngine e = sem.getEngineByExtension(".lua");
|
||||
ScriptEngineFactory f = e.getFactory();
|
||||
String engineName = f.getEngineName();
|
||||
String engineVersion = f.getEngineVersion();
|
||||
String langName = f.getLanguageName();
|
||||
String langVersion = f.getLanguageVersion();
|
||||
System.out.println(engineName + " " +
|
||||
engineVersion + " " +
|
||||
langName + " " +
|
||||
langVersion);
|
||||
String statement = f.getOutputStatement("\"hello, world\"");
|
||||
System.out.println(statement);
|
||||
try {
|
||||
e.eval(statement);
|
||||
|
||||
e.put("x", 25);
|
||||
e.eval("y = math.sqrt(x)");
|
||||
System.out.println( "y="+e.get("y") );
|
||||
|
||||
e.put("x", 2);
|
||||
e.eval("y = math.sqrt(x)");
|
||||
System.out.println( "y="+e.get("y") );
|
||||
|
||||
e.eval("\n\nbogus example\n\n");
|
||||
} catch (ScriptException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user