package de.neuland.jade4j.expression; import de.neuland.jade4j.exceptions.ExpressionException; import de.neuland.jade4j.model.JadeModel; //import jdk.nashorn.api.scripting.ScriptObjectMirror; import javax.script.*; import java.util.*; /** * Work In Progress - Using ScriptEngineManager */ public class JsExpressionHandler implements ExpressionHandler { JexlExpressionHandler jexlExpressionHandler = new JexlExpressionHandler(); ScriptEngineManager mgr = new ScriptEngineManager(); ScriptEngine jsEngine = mgr.getEngineByName("JavaScript"); public JsExpressionHandler() { } @Override public Boolean evaluateBooleanExpression(String expression, JadeModel model) throws ExpressionException { return BooleanUtil.convert(evaluateExpression(expression, model)); } @Override public Object evaluateExpression(String expression, JadeModel model) throws ExpressionException { try{ Bindings bindings = jsEngine.createBindings(); bindings.putAll(model); Object eval; if(expression.startsWith("{")){ eval = ((Map)jsEngine.eval("["+expression+"]", bindings)).get("0"); }else{ eval = jsEngine.eval(expression, bindings); } for (Map.Entry<String, Object> stringObjectEntry : bindings.entrySet()) { model.put(stringObjectEntry.getKey(),convertToJadeModelValue(stringObjectEntry.getValue())); } return convertToJadeModelValue(eval); } catch (ScriptException ex){ // return expression; throw new ExpressionException(expression, ex); } } // public static Object[] toArray(ScriptObjectMirror scriptObjectMirror) // { // if (!scriptObjectMirror.isArray()) // { // throw new IllegalArgumentException("ScriptObjectMirror is no array"); // } // // if (scriptObjectMirror.isEmpty()) // { // return new Object[0]; // } // // Object[] array = new Object[scriptObjectMirror.size()]; // // int i = 0; // // for (Map.Entry<String, Object> entry : scriptObjectMirror.entrySet()) // { // Object result = entry.getValue(); // // System.err.println(result.getClass()); // // if (result instanceof ScriptObjectMirror && scriptObjectMirror.isArray()) // { // array[i] = toArray((ScriptObjectMirror) result); // } // else // { // array[i] = result; // } // // i++; // } // // return array; // } // private static Object convert(final Object obj) { // if (obj instanceof Bindings) { // try { // final Class<?> cls = Class.forName("jdk.nashorn.api.scripting.ScriptObjectMirror"); // if (cls.isAssignableFrom(obj.getClass())) { // final Method isArray = cls.getMethod("isArray"); // final Object result = isArray.invoke(obj); // if (result != null && result.equals(true)) { // final Method values = cls.getMethod("values"); // final Object vals = values.invoke(obj); // if (vals instanceof Collection<?>) { // final Collection<?> coll = (Collection<?>) vals; // return toArray((ScriptObjectMirror) obj); // } // } // } // } catch(ClassNotFoundException | NoSuchMethodException | SecurityException // | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { // // } // } // if (obj instanceof List<?>) { // final List<?> list = (List<?>) obj; // return list.toArray(new Object[0]); // } // return obj; // } private Object convertToJadeModelValue(Object eval) { if(eval instanceof Double){ String s = String.valueOf(eval); if(s.endsWith(".0")){ return Integer.valueOf(s.substring(0,s.length()-2)); } } // eval = convert(eval); // if(eval instanceof NativeArray){ // NativeArray n = (NativeArray) eval; // for(int i=0;i<n.getLength();i++){ // n.get(0); // } // } return eval; } @Override public String evaluateStringExpression(String expression, JadeModel model) throws ExpressionException { Object result = evaluateExpression(expression, model); return result == null ? "" : result.toString(); } @Override public void assertExpression(String expression) throws ExpressionException { jexlExpressionHandler.assertExpression(expression); } @Override public void setCache(boolean cache) { } @Override public void clearCache() { } }