Created
December 3, 2018 03:10
-
-
Save jacaetevha/48fb85397e4ff5fa0d20815e165a4254 to your computer and use it in GitHub Desktop.
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
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