Skip to content

Commit

Permalink
[core] javascript runner + test
Browse files Browse the repository at this point in the history
  • Loading branch information
JorisAerts committed Mar 16, 2024
1 parent ed78e5b commit 336deaa
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 50 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.xomda.core.script;

import java.util.Map;

@FunctionalInterface
public interface ScriptInvoker<T> {
T invoke(Map<String, Object> scope);

default T invoke() {
return invoke(null);
}
}

Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package org.xomda.core.script;

import static org.xomda.shared.util.ReflectionUtils.unchecked;

import java.util.Map;
import java.util.function.Supplier;
import javax.script.Bindings;
import javax.script.Compilable;
import javax.script.CompiledScript;
Expand All @@ -28,53 +29,34 @@ public class ScriptRunner {
engine = createEngine();
}

public static CompiledScript compile(final String script) throws ScriptException {
return ((Compilable) engine).compile(script);
}

public static <T> Supplier<T> callable(final String script) {
public static <T> ScriptInvoker<T> parse(final String script) {
final Logger logger = logger();
try {
final CompiledScript compiled = compile(script);
return (() -> {
final ScriptEngine engine = createEngine();
try {
@SuppressWarnings("unchecked")
T result = (T) compiled.eval(engine.getContext());
return result;
} catch (ScriptException e) {
logger.error("Failed to invoke script", e);
return null;
}
});
CompiledScript compiled = compile(script);
return ((final Map<String, Object> bindings) -> evaluate(compiled, bindings));
} catch (ScriptException e) {
logger.error("Failed to load script: %s".formatted(script), e);
return () -> null;
return null;
}
}

public static <T> Supplier<T> callable(final String script, final Map<String, Object> bindings) {
final Logger logger = logger();
private static CompiledScript compile(final String script) throws ScriptException {
return ((Compilable) engine).compile(script);
}

private static <T> T evaluate(CompiledScript compiled, final Map<String, Object> bindings) {
try {
CompiledScript compiled = compile(script);
return (() -> {
final ScriptEngine engine = createEngine();
final ScriptEngine engine = createEngine();
if (null == bindings) {
return unchecked(compiled.eval(engine.getContext()));
} else {
Bindings bindingContext = engine.getBindings(ScriptContext.ENGINE_SCOPE);
if (null != bindings) {
bindingContext.putAll(bindings);
}
try {
@SuppressWarnings("unchecked")
T result = (T) compiled.eval(bindingContext);
return result;
} catch (ScriptException e) {
logger.error("Failed to invoke script", e);
return null;
}
});
bindingContext.putAll(bindings);
return unchecked(compiled.eval(bindingContext));
}
} catch (ScriptException e) {
logger.error("Failed to load script: %s".formatted(script), e);
return () -> null;
logger().error("Failed to invoke script", e);
return null;
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.xomda.core.script;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

import java.util.Map;
import java.util.function.Function;
Expand All @@ -12,29 +13,35 @@ public class ScriptRunnerTest {

@Test
public void testScript() {
Supplier<String> supplier = ScriptRunner.callable("'Hello world!'");
assertEquals("Hello world!", supplier.get());
ScriptInvoker<String> invoker = ScriptRunner.parse("'Hello world!'");
assertNotNull(invoker);
assertEquals("Hello world!", invoker.invoke());
}

@Test
public void testScriptWithBindings() {
Supplier<String> test1 = ScriptRunner.callable("hello", Map.of("hello", "Hello world!"));
assertEquals("Hello world!", test1.get());
ScriptInvoker<String> test1 = ScriptRunner.parse("hello");
assertNotNull(test1);
assertEquals("Hello world!", test1.invoke(Map.of("hello", "Hello world!")));

Supplier<String> test2 = ScriptRunner.callable("test()", Map.of("test", (Supplier<String>) () -> "Hello world!"));
assertEquals("Hello world!", test2.get());
ScriptInvoker<String> test2 = ScriptRunner.parse("test()");
assertNotNull(test2);
assertEquals("Hello world!", test2.invoke(Map.of("test", (Supplier<String>) () -> "Hello world!")));

// single quote
Supplier<String> test3 = ScriptRunner.callable("test('Hello world!')", Map.of("test", Function.identity()));
assertEquals("Hello world!", test3.get());
ScriptInvoker<String> test3 = ScriptRunner.parse("test('Hello world!')");
assertNotNull(test3);
assertEquals("Hello world!", test3.invoke(Map.of("test", Function.identity())));

// double quote
Supplier<String> test4 = ScriptRunner.callable("test(\"Hello world!\")", Map.of("test", Function.identity()));
assertEquals("Hello world!", test4.get());
ScriptInvoker<String> test4 = ScriptRunner.parse("test(\"Hello world!\")");
assertNotNull(test4);
assertEquals("Hello world!", test4.invoke(Map.of("test", Function.identity())));

// backtick quote
Supplier<String> test5 = ScriptRunner.callable("test(`Hello world!`)", Map.of("test", Function.identity()));
assertEquals("Hello world!", test5.get());
ScriptInvoker<String> test5 = ScriptRunner.parse("test(`Hello world!`)");
assertNotNull(test5);
assertEquals("Hello world!", test5.invoke(Map.of("test", Function.identity())));
}

}

0 comments on commit 336deaa

Please sign in to comment.