Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
JSR-223 support added directly into dynjs.jar.
- Loading branch information
1 parent
b250c9d
commit f8cc6c1
Showing
10 changed files
with
658 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
package org.dynjs.jsr223; | ||
|
||
import org.dynjs.Config; | ||
import org.dynjs.runtime.DynJS; | ||
|
||
import javax.script.Bindings; | ||
import javax.script.ScriptContext; | ||
import javax.script.ScriptEngine; | ||
import javax.script.SimpleBindings; | ||
import java.io.InputStreamReader; | ||
import java.io.OutputStreamWriter; | ||
import java.io.Reader; | ||
import java.io.Writer; | ||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.List; | ||
|
||
/** | ||
* @author Bob McWhirter | ||
*/ | ||
public class DynJSScriptContext implements ScriptContext { | ||
|
||
private final static List<Integer> SCOPES; | ||
|
||
static { | ||
SCOPES = Collections.unmodifiableList(new ArrayList<Integer>() {{ | ||
add( ScriptContext.ENGINE_SCOPE ); | ||
add( ScriptContext.GLOBAL_SCOPE ); | ||
}}); | ||
} | ||
|
||
private final DynJSScriptEngine engine; | ||
private final ScriptEngineGlobalObject global; | ||
private Writer writer; | ||
private Writer errorWriter; | ||
private Reader reader; | ||
|
||
public DynJSScriptContext(DynJSScriptEngine engine) { | ||
this.engine = engine; | ||
this.writer = new OutputStreamWriter(System.out); | ||
this.errorWriter = new OutputStreamWriter(System.err); | ||
this.reader = new InputStreamReader(System.in); | ||
|
||
this.global = new ScriptEngineGlobalObject( this ); | ||
} | ||
|
||
ScriptEngineGlobalObject getGlobalObject() { | ||
return this.global; | ||
} | ||
|
||
DynJSScriptEngine getEngine() { | ||
return engine; | ||
} | ||
|
||
@Override | ||
public void setBindings(Bindings bindings, int scope) { | ||
if (scope == ScriptContext.GLOBAL_SCOPE) { | ||
this.engine.getFactory().setGlobalBindings(bindings); | ||
return; | ||
} else if (scope == ScriptContext.ENGINE_SCOPE) { | ||
this.global.setBindings( bindings ); | ||
return; | ||
} | ||
|
||
throw new IllegalArgumentException("Invalid scope: " + scope); | ||
} | ||
|
||
@Override | ||
public Bindings getBindings(int scope) { | ||
if (scope == ScriptContext.GLOBAL_SCOPE) { | ||
return this.engine.getFactory().getGlobalBindings(); | ||
} else if (scope == ScriptContext.ENGINE_SCOPE) { | ||
return this.global.getBindings(); | ||
} | ||
|
||
throw new IllegalArgumentException("Invalid scope: " + scope); | ||
} | ||
|
||
@Override | ||
public void setAttribute(String name, Object value, int scope) { | ||
if (scope == ScriptContext.GLOBAL_SCOPE) { | ||
this.engine.getFactory().getGlobalBindings().put(name, value); | ||
return; | ||
} else if (scope == ScriptContext.ENGINE_SCOPE) { | ||
this.global.getBindings().put(name, value); | ||
return; | ||
} | ||
|
||
throw new IllegalArgumentException("Invalid scope: " + scope); | ||
} | ||
|
||
@Override | ||
public Object getAttribute(String name, int scope) { | ||
if (scope == ScriptContext.GLOBAL_SCOPE) { | ||
return this.engine.getFactory().getGlobalBindings().get(name); | ||
} else if (scope == ScriptContext.ENGINE_SCOPE) { | ||
return this.global.getBindings().get(name); | ||
} | ||
throw new IllegalArgumentException("Invalid scope: " + scope); | ||
} | ||
|
||
@Override | ||
public Object removeAttribute(String name, int scope) { | ||
if (scope == ScriptContext.GLOBAL_SCOPE) { | ||
return this.engine.getFactory().getGlobalBindings().remove(name); | ||
} else if (scope == ScriptContext.ENGINE_SCOPE) { | ||
return this.global.getBindings().remove(name); | ||
} | ||
|
||
throw new IllegalArgumentException("Invalid scope: " + scope); | ||
} | ||
|
||
@Override | ||
public Object getAttribute(String name) { | ||
Object value = getAttribute(name, ScriptContext.ENGINE_SCOPE); | ||
if (value == null) { | ||
value = getAttribute(name, ScriptContext.GLOBAL_SCOPE); | ||
} | ||
return value; | ||
} | ||
|
||
@Override | ||
public int getAttributesScope(String name) { | ||
if (getAttribute(name, ScriptContext.ENGINE_SCOPE) != null) { | ||
return ScriptContext.ENGINE_SCOPE; | ||
} | ||
|
||
if (getAttribute(name, ScriptContext.GLOBAL_SCOPE) != null) { | ||
return ScriptContext.GLOBAL_SCOPE; | ||
} | ||
|
||
return -1; | ||
} | ||
|
||
@Override | ||
public Writer getWriter() { | ||
return this.writer; | ||
} | ||
|
||
@Override | ||
public Writer getErrorWriter() { | ||
return this.errorWriter; | ||
} | ||
|
||
@Override | ||
public void setWriter(Writer writer) { | ||
this.writer = writer; | ||
} | ||
|
||
@Override | ||
public void setErrorWriter(Writer writer) { | ||
this.errorWriter = writer; | ||
} | ||
|
||
@Override | ||
public Reader getReader() { | ||
return this.reader; | ||
} | ||
|
||
@Override | ||
public void setReader(Reader reader) { | ||
this.reader = reader; | ||
} | ||
|
||
@Override | ||
public List<Integer> getScopes() { | ||
return SCOPES; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
package org.dynjs.jsr223; | ||
|
||
import org.dynjs.Config; | ||
import org.dynjs.runtime.DynJS; | ||
import org.dynjs.runtime.Types; | ||
import org.dynjs.runtime.builtins.DynJSBuiltin; | ||
|
||
import javax.script.*; | ||
import java.io.Reader; | ||
|
||
/** | ||
* @author Bob McWhirter | ||
*/ | ||
public class DynJSScriptEngine implements ScriptEngine { | ||
|
||
private final DynJSScriptEngineFactory factory; | ||
private DynJSScriptContext context; | ||
|
||
public DynJSScriptEngine(DynJSScriptEngineFactory factory) { | ||
this.factory = factory; | ||
this.context = new DynJSScriptContext(this); | ||
} | ||
|
||
@Override | ||
public Object eval(String script, ScriptContext context) throws ScriptException { | ||
return eval( script, context, null ); | ||
} | ||
|
||
@Override | ||
public Object eval(Reader reader, ScriptContext context) throws ScriptException { | ||
return eval( reader, context, null ); | ||
} | ||
|
||
@Override | ||
public Object eval(String script) throws ScriptException { | ||
return eval( script, this.context, null ); | ||
} | ||
|
||
@Override | ||
public Object eval(Reader reader) throws ScriptException { | ||
return eval( reader, this.context, null ); | ||
} | ||
|
||
@Override | ||
public Object eval(String script, Bindings n) throws ScriptException { | ||
return eval( script, this.context, n ); | ||
} | ||
|
||
@Override | ||
public Object eval(Reader reader, Bindings n) throws ScriptException { | ||
return eval( reader, this.context, n ); | ||
} | ||
|
||
protected Object eval(String script, ScriptContext context, Bindings bindings) throws ScriptException { | ||
if ( ! ( context instanceof DynJSScriptContext ) ) { | ||
throw new IllegalArgumentException( "context must be an instance of " + DynJSScriptContext.class.getName() ); | ||
} | ||
|
||
DynJSScriptContext dynjsContext = (DynJSScriptContext) context; | ||
ScriptEngineGlobalObject global = getGlobalObject(dynjsContext, bindings); | ||
DynJS runtime = getRuntime( global, dynjsContext ); | ||
|
||
try { | ||
return runtime.newRunner().withSource(script).execute(); | ||
} catch (Exception t) { | ||
throw new ScriptException(t); | ||
} | ||
} | ||
|
||
protected Object eval(Reader reader, ScriptContext context, Bindings bindings) throws ScriptException { | ||
if ( ! ( context instanceof DynJSScriptContext ) ) { | ||
throw new IllegalArgumentException( "context must be an instance of " + DynJSScriptContext.class.getName() ); | ||
} | ||
|
||
DynJSScriptContext dynjsContext = (DynJSScriptContext) context; | ||
ScriptEngineGlobalObject global = getGlobalObject(dynjsContext, bindings); | ||
DynJS runtime = getRuntime( global, dynjsContext ); | ||
|
||
try { | ||
return runtime.newRunner().withSource(reader).execute(); | ||
} catch (Exception t) { | ||
throw new ScriptException(t); | ||
} | ||
} | ||
|
||
private ScriptEngineGlobalObject getGlobalObject(DynJSScriptContext context, Bindings localBindings) { | ||
if ( localBindings == null ) { | ||
return context.getGlobalObject(); | ||
} | ||
|
||
return new ScriptEngineGlobalObject( context.getGlobalObject(), localBindings ); | ||
} | ||
|
||
private DynJS getRuntime(ScriptEngineGlobalObject global, DynJSScriptContext context) { | ||
Object builtin = global.get(null, "dynjs"); | ||
|
||
DynJS runtime = null; | ||
|
||
if ( builtin != Types.UNDEFINED ) { | ||
runtime = ((DynJSBuiltin) builtin).getRuntime(); | ||
} | ||
|
||
runtime = new DynJS( new Config(), global ); | ||
|
||
Object argv = context.getAttribute( ScriptEngine.ARGV ); | ||
if ( argv != null ) { | ||
if ( ! argv.getClass().isArray() ) { | ||
throw new IllegalArgumentException( "ARGV must be an array" ); | ||
} | ||
runtime.getConfig().setArgv((Object[]) argv); | ||
} | ||
|
||
return runtime; | ||
} | ||
|
||
@Override | ||
public void put(String key, Object value) { | ||
getBindings( ScriptContext.ENGINE_SCOPE ).put( key, value ); | ||
} | ||
|
||
@Override | ||
public Object get(String key) { | ||
return getBindings( ScriptContext.ENGINE_SCOPE ).get( key ); | ||
} | ||
|
||
@Override | ||
public Bindings getBindings(int scope) { | ||
return this.context.getBindings( scope ); | ||
} | ||
|
||
@Override | ||
public void setBindings(Bindings bindings, int scope) { | ||
this.context.setBindings( bindings, scope ); | ||
} | ||
|
||
@Override | ||
public Bindings createBindings() { | ||
return new SimpleBindings(); | ||
} | ||
|
||
@Override | ||
public ScriptContext getContext() { | ||
return this.context; | ||
} | ||
|
||
@Override | ||
public void setContext(ScriptContext context) { | ||
if ( ! ( context instanceof DynJSScriptContext ) ) { | ||
throw new IllegalArgumentException( "Context must be " + DynJSScriptContext.class.getName() ); | ||
} | ||
this.context = (DynJSScriptContext) context; | ||
} | ||
|
||
@Override | ||
public DynJSScriptEngineFactory getFactory() { | ||
return this.factory; | ||
} | ||
|
||
} |
Oops, something went wrong.