Skip to content

Instantly share code, notes, and snippets.

@jacaetevha
Created December 3, 2018 03:10
Show Gist options
  • Save jacaetevha/48fb85397e4ff5fa0d20815e165a4254 to your computer and use it in GitHub Desktop.
Save jacaetevha/48fb85397e4ff5fa0d20815e165a4254 to your computer and use it in GitHub Desktop.
package com.xyz;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.script.SimpleBindings;
import javax.script.SimpleScriptContext;
import org.jruby.embed.EvalFailedException;
public class RubyScripting {
private static ScriptEngineManager FACTORY;
private static ScriptEngine ENGINE;
static {
System.setProperty("org.jruby.embed.localcontext.scope", "concurrent");
System.setProperty("org.jruby.embed.localvariable.behavior", "transient");
FACTORY = new ScriptEngineManager();
ENGINE = FACTORY.getEngineByName("jruby");
ENGINE.eval(loadFile("some_bootstrap_script_that_defines_your_constants.rb"));
System.out.println("Initialed Ruby scripting engine");
}
public static Bindings defaultBindings() {
return ENGINE.createBindings();
}
public static Bindings emptyBindings() {
return new SimpleBindings();
}
public static ScriptEngine engine() {
return ENGINE;
}
public static Bindings evalResource(String resourceName) throws ScriptException {
ScriptContext newContext = new SimpleScriptContext();
newContext.setBindings(defaultBindings(), ScriptContext.ENGINE_SCOPE);
Bindings engineScope = newContext.getBindings(ScriptContext.ENGINE_SCOPE);
return evalResource(resourceName, engineScope);
}
public static Bindings evalResource(String resourceName, Bindings bindings)
throws ScriptException {
return evalScript(loadFile(resourceName), bindings);
}
public static Bindings evalScript(String script) throws ScriptException {
ScriptContext newContext = new SimpleScriptContext();
newContext.setBindings(defaultBindings(), ScriptContext.ENGINE_SCOPE);
Bindings engineScope = newContext.getBindings(ScriptContext.ENGINE_SCOPE);
return evalScript(script, engineScope);
}
public static Bindings evalScript(String script, Bindings bindings) throws ScriptException {
try {
Object result = ENGINE.eval(script, bindings);
bindings.put("result", result);
return bindings;
} catch (EvalFailedException e) {
Bindings b = emptyBindings();
b.put("error", e.getMessage());
return b;
}
}
@SuppressWarnings("unchecked")
public static <T> T eval(String script) throws ScriptException {
try {
return (T) ENGINE.eval(script, emptyBindings());
} catch (EvalFailedException e) {
throw new RuntimeException(e);
}
}
public static void init() {
// ... for now this method is just a way to enforce the static initialization block to run
}
public static String loadFile(String resourceName) {
if (ObjectUtils.isBlank(resourceName)) {
return "# oops ... this is just a comment";
}
ClassLoader classloader = Thread.currentThread().getContextClassLoader();
InputStream is = classloader.getResourceAsStream(resourceName);
StringBuilder builder = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(is))) {
String line;
while ((line = reader.readLine()) != null) {
builder.append(line);
builder.append("\n");
}
} catch (IOException e) {
LoggingManager.error("Failed to load Ruby resource: " + resourceName);
}
return builder.append("\n").toString();
}
private RubyScripting() {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment