下面列出了怎么用javax.script.SimpleBindings的API类实例代码及写法,或者点击链接到github查看源代码。
private void scriptCustomization(final List<String> customizers, final String ext, final Map<String, Object> customBindings) {
if (customizers == null || customizers.isEmpty()) {
return;
}
final ScriptEngine engine = new ScriptEngineManager().getEngineByExtension(ext);
if (engine == null) {
throw new IllegalStateException("No engine for " + ext + ". Maybe add the JSR223 implementation as plugin dependency.");
}
for (final String js : customizers) {
try {
final SimpleBindings bindings = new SimpleBindings();
bindings.put("project", project);
engine.eval(new StringReader(js), bindings);
bindings.putAll(customBindings);
} catch (final ScriptException e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
}
@Test
public void userEngineScopeBindingsRetentionTest() throws ScriptException {
final ScriptEngineManager m = new ScriptEngineManager();
final ScriptEngine e = m.getEngineByName("nashorn");
final ScriptContext newContext = new SimpleScriptContext();
newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE);
e.eval("function foo() {}", newContext);
// definition retained with user's ENGINE_SCOPE Binding
assertTrue(e.eval("typeof foo", newContext).equals("function"));
final Bindings oldBindings = newContext.getBindings(ScriptContext.ENGINE_SCOPE);
// but not in another ENGINE_SCOPE binding
newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE);
assertTrue(e.eval("typeof foo", newContext).equals("undefined"));
// restore ENGINE_SCOPE and check again
newContext.setBindings(oldBindings, ScriptContext.ENGINE_SCOPE);
assertTrue(e.eval("typeof foo", newContext).equals("function"));
}
@Test
public void userEngineScopeBindingsRetentionTest() throws ScriptException {
final ScriptEngineManager m = new ScriptEngineManager();
final ScriptEngine e = m.getEngineByName("nashorn");
final ScriptContext newContext = new SimpleScriptContext();
newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE);
e.eval("function foo() {}", newContext);
// definition retained with user's ENGINE_SCOPE Binding
assertTrue(e.eval("typeof foo", newContext).equals("function"));
final Bindings oldBindings = newContext.getBindings(ScriptContext.ENGINE_SCOPE);
// but not in another ENGINE_SCOPE binding
newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE);
assertTrue(e.eval("typeof foo", newContext).equals("undefined"));
// restore ENGINE_SCOPE and check again
newContext.setBindings(oldBindings, ScriptContext.ENGINE_SCOPE);
assertTrue(e.eval("typeof foo", newContext).equals("function"));
}
@Test
public void shouldHandleMaps() {
final TinkerGraph graph = TinkerFactory.createModern();
final GraphTraversalSource g = graph.traversal();
final Script script = GroovyTranslator.of("g", true).translate(g.V().id().is(new LinkedHashMap<Object,Object>() {{
put(3, "32");
put(Arrays.asList(1, 2, 3.1d), 4);
}}).asAdmin().getBytecode());
Bindings bindings = new SimpleBindings();
script.getParameters().ifPresent(bindings::putAll);
assertEquals(6, bindings.size());
assertEquals(Integer.valueOf(3), bindings.get("_args_0"));
assertEquals("32", bindings.get("_args_1"));
assertEquals(Integer.valueOf(1), bindings.get("_args_2"));
assertEquals(Integer.valueOf(2), bindings.get("_args_3"));
assertEquals(Double.valueOf(3.1), bindings.get("_args_4"));
assertEquals(Integer.valueOf(4), bindings.get("_args_5"));
assertEquals("g.V().id().is([(_args_0):(_args_1),([_args_2, _args_3, _args_4]):(_args_5)])", script.getScript());
final Script standard = GroovyTranslator.of("g").translate(g.V().id().is(new LinkedHashMap<Object,Object>() {{
put(3, "32");
put(Arrays.asList(1, 2, 3.1d), 4);
}}).asAdmin().getBytecode());
bindings.put("g", g);
assertParameterizedScriptOk(standard.getScript(), script.getScript(), bindings, true);
}
@Test
public void shouldIncludeCustomTypeTranslationForSomethingSilly() throws Exception {
final TinkerGraph graph = TinkerGraph.open();
final SillyClass notSillyEnough = SillyClass.from("not silly enough", 100);
final GraphTraversalSource g = graph.traversal();
// without type translation we get uglinesss
final String scriptBad = GroovyTranslator.of("g").
translate(g.inject(notSillyEnough).asAdmin().getBytecode()).getScript();
assertEquals(String.format("g.inject(%s)", "not silly enough:100"), scriptBad);
// with type translation we get valid gremlin
final String scriptGood = GroovyTranslator.of("g", new SillyClassTranslator(false)).
translate(g.inject(notSillyEnough).asAdmin().getBytecode()).getScript();
assertEquals(String.format("g.inject(org.apache.tinkerpop.gremlin.groovy.jsr223.GroovyTranslatorTest.SillyClass.from('%s', (int) %s))", notSillyEnough.getX(), notSillyEnough.getY()), scriptGood);
assertThatScriptOk(scriptGood, "g", g);
final GremlinGroovyScriptEngine customEngine = new GremlinGroovyScriptEngine(new SillyClassTranslatorCustomizer());
final Bindings b = new SimpleBindings();
b.put("g", g);
final Traversal t = customEngine.eval(g.inject(notSillyEnough).asAdmin().getBytecode(), b, "g");
final SillyClass sc = (SillyClass) t.next();
assertEquals(notSillyEnough.getX(), sc.getX());
assertEquals(notSillyEnough.getY(), sc.getY());
assertThat(t.hasNext(), is(false));
}
@Test
public void userEngineScopeBindingsRetentionTest() throws ScriptException {
final ScriptEngineManager m = new ScriptEngineManager();
final ScriptEngine e = m.getEngineByName("nashorn");
final ScriptContext newContext = new SimpleScriptContext();
newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE);
e.eval("function foo() {}", newContext);
// definition retained with user's ENGINE_SCOPE Binding
assertTrue(e.eval("typeof foo", newContext).equals("function"));
final Bindings oldBindings = newContext.getBindings(ScriptContext.ENGINE_SCOPE);
// but not in another ENGINE_SCOPE binding
newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE);
assertTrue(e.eval("typeof foo", newContext).equals("undefined"));
// restore ENGINE_SCOPE and check again
newContext.setBindings(oldBindings, ScriptContext.ENGINE_SCOPE);
assertTrue(e.eval("typeof foo", newContext).equals("function"));
}
@Test
public void userEngineScopeBindingsRetentionTest() throws ScriptException {
final ScriptEngineManager m = new ScriptEngineManager();
final ScriptEngine e = m.getEngineByName("nashorn");
final ScriptContext newContext = new SimpleScriptContext();
newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE);
e.eval("function foo() {}", newContext);
// definition retained with user's ENGINE_SCOPE Binding
assertTrue(e.eval("typeof foo", newContext).equals("function"));
final Bindings oldBindings = newContext.getBindings(ScriptContext.ENGINE_SCOPE);
// but not in another ENGINE_SCOPE binding
newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE);
assertTrue(e.eval("typeof foo", newContext).equals("undefined"));
// restore ENGINE_SCOPE and check again
newContext.setBindings(oldBindings, ScriptContext.ENGINE_SCOPE);
assertTrue(e.eval("typeof foo", newContext).equals("function"));
}
private void scriptCustomization(final List<String> customizers, final String ext, final String base) {
if (customizers == null || customizers.isEmpty()) {
return;
}
final ScriptEngine engine = new ScriptEngineManager().getEngineByExtension(ext);
if (engine == null) {
throw new IllegalStateException("No engine for " + ext + ". Maybe add the JSR223 implementation as plugin dependency.");
}
for (final String js : customizers) {
try {
final SimpleBindings bindings = new SimpleBindings();
bindings.put("catalinaBase", base);
engine.eval(new StringReader(js), bindings);
} catch (final ScriptException e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
}
@Test
public void shouldRegisterLongCompilation() throws Exception {
final GremlinGroovyScriptEngine engine = new GremlinGroovyScriptEngine(
CompilationOptionsCustomizer.build().setExpectedCompilationTime(10).create());
final int numberOfParameters = 3000;
final Bindings b = new SimpleBindings();
// generate a script that takes a long time to compile
String script = "x = 0";
for (int ix = 0; ix < numberOfParameters; ix++) {
if (ix > 0 && ix % 100 == 0) {
script = script + ";" + System.lineSeparator() + "x = x";
}
script = script + " + x" + ix;
b.put("x" + ix, ix);
}
assertEquals(0, engine.getClassCacheLongRunCompilationCount());
engine.eval(script, b);
assertEquals(1, engine.getClassCacheLongRunCompilationCount());
}
@Test
public void shouldPromoteDefinedVarsInInterpreterModeWithBindings() throws Exception {
final GremlinGroovyScriptEngine engine = new GremlinGroovyScriptEngine(new InterpreterModeGroovyCustomizer());
final Bindings b = new SimpleBindings();
b.put("x", 2);
engine.eval("def addItUp = { x, y -> x + y }", b);
assertEquals(3, engine.eval("int xxx = 1 + x", b));
assertEquals(4, engine.eval("yyy = xxx + 1", b));
assertEquals(7, engine.eval("def zzz = yyy + xxx", b));
assertEquals(4, engine.eval("zzz - xxx", b));
assertEquals("accessible-globally", engine.eval("if (yyy > 0) { def inner = 'should-stay-local'; outer = 'accessible-globally' }\n outer", b));
assertEquals("accessible-globally", engine.eval("outer", b));
try {
engine.eval("inner", b);
fail("Should not have been able to access 'inner'");
} catch (Exception ex) {
final Throwable root = ExceptionUtils.getRootCause(ex);
assertThat(root, instanceOf(MissingPropertyException.class));
}
assertEquals(10, engine.eval("addItUp(zzz,xxx)", b));
}
private void addScriptBindings(SlingScriptHelper scriptHelper, SlingHttpServletRequest request, SlingHttpServletResponse response)
throws IOException {
SimpleBindings bindings = new SimpleBindings();
bindings.put(SLING, scriptHelper);
bindings.put(RESOURCE, request.getResource());
bindings.put(SlingModelsScriptEngineFactory.RESOLVER, request.getResource().getResourceResolver());
bindings.put(REQUEST, request);
bindings.put(RESPONSE, response);
try {
bindings.put(READER, request.getReader());
} catch (Exception e) {
bindings.put(READER, new BufferedReader(new StringReader("")));
}
bindings.put(OUT, response.getWriter());
bindings.put(LOG, logger);
scriptEngineFactory.invokeBindingsValuesProviders(bindingsValuesProvidersByContext, bindings);
SlingBindings slingBindings = new SlingBindings();
slingBindings.putAll(bindings);
request.setAttribute(SlingBindings.class.getName(), slingBindings);
}
public void execute(DebugSessionImpl debugSession, SuspendedExecutionImpl suspendedExecution) {
CodeCompleterBuilder builder = new CodeCompleterBuilder();
if (scopeId != null) {
synchronized (suspendedExecution) {
if(!suspendedExecution.isResumed) {
ExecutionEntity executionEntity = suspendedExecution.getExecution();
ScriptBindingsFactory bindingsFactory = Context.getProcessEngineConfiguration()
.getScriptingEngines().getScriptBindingsFactory();
Bindings scopeBindings = bindingsFactory.createBindings(executionEntity, new SimpleBindings());
builder.bindings(scopeBindings);
}
}
}
List<CodeCompletionHint> hints = builder.buildCompleter().complete(prefix);
debugSession.fireCodeCompletion(hints);
}
@SuppressWarnings("unchecked")
private <T> T _eval(String scriptText, Map<String, Object> data)throws RuleException{
Bindings bindings = new SimpleBindings();
if(context != null){
bindings.put(Names.GLOBAL, context);
}
bindings.put(Names.LOCAL, data);
// execution
try {
Object o = scriptEngine.eval(scriptText, bindings);
if(o != null){
return (T)o;
}
return null;
} catch (ScriptException e) {
throw new RuleException("Execute the script error", e);
}
}
public static SimpleHttpResponse process(SimpleHttpRequest httpRequest)
throws NoSuchMethodException, ScriptException, IOException {
CompiledScript compiled;
Compilable engine;
String scriptFilePath = "./src/main/resources/templates/js/script.js";
engine = (Compilable) engineFactory.getScriptEngine();
compiled = ((Compilable) engine).compile(Files.newBufferedReader(Paths.get(scriptFilePath),StandardCharsets.UTF_8));
SimpleBindings global = new SimpleBindings();
global.put("theReq", httpRequest);
global.put("theResp", new SimpleHttpResponse());
Object result = compiled.eval(global);
SimpleHttpResponse resp = (SimpleHttpResponse) result;
return resp;
}
@Test
public void shouldRaiseExceptionInWithResultOfLifeCycle() throws Exception {
final GremlinExecutor gremlinExecutor = GremlinExecutor.build().create();
final GremlinExecutor.LifeCycle lc = GremlinExecutor.LifeCycle.build()
.withResult(r -> {
throw new RuntimeException("no worky");
}).create();
final AtomicBoolean exceptionRaised = new AtomicBoolean(false);
final CompletableFuture<Object> future = gremlinExecutor.eval("1+1", "gremlin-groovy", new SimpleBindings(), lc);
future.handle((r, t) -> {
exceptionRaised.set(t != null && t instanceof RuntimeException && t.getMessage().equals("no worky"));
return null;
}).get();
assertThat(exceptionRaised.get(), is(true));
gremlinExecutor.close();
}
@Test
public void shouldOverrideAfterFailure() throws Exception {
final AtomicInteger called = new AtomicInteger(0);
final GremlinExecutor gremlinExecutor = GremlinExecutor.build().afterFailure((b,t) -> called.set(1)).create();
try {
gremlinExecutor.eval("10/0", null, new SimpleBindings(),
GremlinExecutor.LifeCycle.build().afterFailure((b,t) -> called.set(200)).create()).get();
fail("Should have failed with division by zero");
} catch (Exception ignored) {
}
// need to wait long enough for the callback to register
Thread.sleep(500);
assertEquals(200, called.get());
}
@Test
public static void contextOverwriteTest() throws ScriptException {
final ScriptEngineManager m = new ScriptEngineManager();
final ScriptEngine e = m.getEngineByName("nashorn");
final Bindings b = new SimpleBindings();
b.put("context", "hello");
b.put("foo", 32);
final ScriptContext newCtxt = new SimpleScriptContext();
newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
e.setContext(newCtxt);
assertEquals(e.eval("context"), "hello");
assertEquals(((Number)e.eval("foo")).intValue(), 32);
}
@Override
public Bindings createBindings() {
if (_global_per_engine) {
// just create normal SimpleBindings.
// We use same 'global' for all Bindings.
return new SimpleBindings();
}
return createGlobalMirror(null);
}
/**
* 执行JS
*/
private Object evalJS(String jsStr, String baseUrl) throws Exception {
SimpleBindings bindings = new SimpleBindings();
bindings.put("java", new AnalyzeRule(null));
bindings.put("baseUrl", baseUrl);
return SCRIPT_ENGINE.eval(jsStr, bindings);
}
/**
* 执行JS
*/
private Object evalJS(String jsStr, String baseUrl) throws Exception {
SimpleBindings bindings = new SimpleBindings();
bindings.put("java", getAnalyzeRule());
bindings.put("baseUrl", baseUrl);
return SCRIPT_ENGINE.eval(jsStr, bindings);
}
public Object apply(final Object a) {
try {
final Bindings bindings = new SimpleBindings();
bindings.put(A, a);
return this.engine.eval(this.script, bindings);
} catch (final ScriptException e) {
throw new IllegalArgumentException(e.getMessage());
}
}
@Test
public void userEngineScopeBindingsTest() throws ScriptException {
final ScriptEngineManager m = new ScriptEngineManager();
final ScriptEngine e = m.getEngineByName("nashorn");
e.eval("function func() {}");
final ScriptContext newContext = new SimpleScriptContext();
newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE);
// we are using a new bindings - so it should have 'func' defined
final Object value = e.eval("typeof func", newContext);
assertTrue(value.equals("undefined"));
}
@Test
public static void contextOverwriteTest() throws ScriptException {
final ScriptEngineManager m = new ScriptEngineManager();
final ScriptEngine e = m.getEngineByName("nashorn");
final Bindings b = new SimpleBindings();
b.put("context", "hello");
b.put("foo", 32);
final ScriptContext newCtxt = new SimpleScriptContext();
newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
e.setContext(newCtxt);
assertEquals(e.eval("context"), "hello");
assertEquals(((Number)e.eval("foo")).intValue(), 32);
}
@Test
public static void testMegamorphicGetInGlobal() throws Exception {
final ScriptEngineManager m = new ScriptEngineManager();
final ScriptEngine engine = m.getEngineByName("nashorn");
final String script = "foo";
// "foo" is megamorphic because of different global scopes.
// Make sure ScriptContext variable search works even after
// it becomes megamorphic.
for (int index = 0; index < 25; index++) {
final Bindings bindings = new SimpleBindings();
bindings.put("foo", index);
final Number value = (Number)engine.eval(script, bindings);
assertEquals(index, value.intValue());
}
}
public void program() throws ScriptException {
ScriptContext sc = new SimpleScriptContext();
Bindings global = new SimpleBindings();
sc.setBindings(global, ScriptContext.GLOBAL_SCOPE);
sc.setBindings(engineBindings, ScriptContext.ENGINE_SCOPE);
global.put("text", "programText");
String value = engine.eval("text", sc).toString();
Assert.assertEquals(value, "programText");
engine.put("program", this);
engine.eval("program.method()");
// eval again from here!
value = engine.eval("text", sc).toString();
Assert.assertEquals(value, "programText");
}
public void method() throws ScriptException {
// a context with a new global bindings, same engine bindings
final ScriptContext sc = new SimpleScriptContext();
final Bindings global = new SimpleBindings();
sc.setBindings(global, ScriptContext.GLOBAL_SCOPE);
sc.setBindings(engineBindings, ScriptContext.ENGINE_SCOPE);
global.put("text", "methodText");
String value = engine.eval("text", sc).toString();
Assert.assertEquals(value, "methodText");
}
@Override
public Bindings createBindings() {
if (_global_per_engine) {
// just create normal SimpleBindings.
// We use same 'global' for all Bindings.
return new SimpleBindings();
}
return createGlobalMirror(null);
}
/**
* Get the {@link Graph} and {@link TraversalSource} list as a set of bindings.
*/
public final Bindings getAsBindings() {
final Bindings bindings = new SimpleBindings();
graphs.forEach(bindings::put);
traversalSources.forEach(bindings::put);
return bindings;
}
@Test
public void userEngineScopeBindingsNoLeakTest() throws ScriptException {
final ScriptEngineManager m = new ScriptEngineManager();
final ScriptEngine e = m.getEngineByName("nashorn");
final ScriptContext newContext = new SimpleScriptContext();
newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE);
e.eval("function foo() {}", newContext);
// in the default context's ENGINE_SCOPE, 'foo' shouldn't exist
assertTrue(e.eval("typeof foo").equals("undefined"));
}
@Test
public static void engineOverwriteTest() throws ScriptException {
final ScriptEngineManager m = new ScriptEngineManager();
final ScriptEngine e = m.getEngineByName("nashorn");
final Bindings b = new SimpleBindings();
b.put("engine", "hello");
b.put("foo", 32);
final ScriptContext newCtxt = new SimpleScriptContext();
newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
e.setContext(newCtxt);
assertEquals(e.eval("engine"), "hello");
assertEquals(((Number)e.eval("foo")).intValue(), 32);
}