package com.plexobject.rbac.eval.js; import java.util.Map; import javax.script.Bindings; import javax.script.ScriptContext; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; import javax.script.SimpleScriptContext; import org.springframework.stereotype.Component; import com.plexobject.rbac.eval.PredicateEvaluator; @Component("evaluator") public class JavascriptEvaluator implements PredicateEvaluator { private ScriptEngineManager manager = new ScriptEngineManager(); @Override public boolean evaluate(String expression, Map<String, Object> args) { ScriptEngine engine = manager.getEngineByName("JavaScript"); ScriptContext newContext = new SimpleScriptContext(); Bindings engineScope = newContext .getBindings(ScriptContext.ENGINE_SCOPE); for (Map.Entry<String, Object> e : args.entrySet()) { engineScope.put(e.getKey(), e.getValue()); } Object response = null; try { response = engine.eval(expression, newContext); if (!(response instanceof Boolean)) { final String type = response != null ? response.getClass() .getName() : null; throw new RuntimeException("Unexpected response " + response + ", type " + type + " by evaluating " + expression + " with args " + args); } return (Boolean) response; } catch (ScriptException e) { throw new RuntimeException("failed to evaluate " + expression + " with args " + args + " resulting in " + response, e); } } }