package iotcloud; import java.util.Set; import java.util.HashSet; import java.util.Collection; import java.util.List; import java.util.ArrayList; import java.nio.ByteBuffer; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; import java.lang.NullPointerException; class Guard { static final byte Equal = 1; static final byte NotEqual = 2; private IoTString booleanExpression; private List keyValsNeeded = null; public Guard() { booleanExpression = null; } public Guard(IoTString _booleanExpression) { booleanExpression = _booleanExpression; } /** * Create an equality expression for a key value. * */ public static String createExpression(IoTString keyName, IoTString keyValue, byte op) { if (op == Equal) { return keyName.toString() + "=='" + keyValue.toString() + "'"; } else if (op == NotEqual) { return keyName.toString() + "!='" + keyValue.toString() + "'"; } // Unrecognized op return null; } /** * Add a boolean expression to the guard. * */ public void setGuardExpression(String expr) { booleanExpression = new IoTString(expr); } /** * Evaluate the guard expression for a given set of key value pairs. * */ public boolean evaluate(Collection kvSet) throws ScriptException, NullPointerException { // There are no conditions to evaluate if (booleanExpression == null) { return true; } ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript"); if (keyValsNeeded == null) { keyValsNeeded = new ArrayList(); String booleanExprString = booleanExpression.toString(); for (KeyValue kv : kvSet) { if (booleanExprString.contains(kv.getKey().toString())) { keyValsNeeded.add(kv); } } } // All the current key value pairs that we need to evaluate the condition // String[] variables = new String[kvSet.size()]; // Fill the variables array // int i = 0; // for (KeyValue kv : kvSet) { // for (KeyValue kv : keyValsNeeded) { // variables[i] = kv.getKey() + " ='" + kv.getValue() + "'"; // i++; // } String varEval = ""; for (KeyValue kv : keyValsNeeded) { varEval += "var " + kv.getKey() + " ='" + kv.getValue() + "'; \n"; } varEval += booleanExpression.toString(); // Prep the evaluation engine (script engine) // for (String s : variables) { // engine.eval(s); // } // engine.eval(varEval); // boolean engineEval = (Boolean)engine.eval(booleanExpression.toString()); boolean engineEval = false; try { engineEval = (Boolean)engine.eval(varEval); } catch (Exception e) { // If there was an error then the script evaluated to false engineEval = false; } // Evaluate the guard condition // return 1 == (Integer)engine.eval(booleanExpression.toString()); return engineEval; } /** * Get the size of the guard condition * */ public int getSize() { if (booleanExpression == null) { return Integer.BYTES; } return Integer.BYTES + booleanExpression.length(); } public void encode(ByteBuffer bb) { if (booleanExpression == null) { bb.putInt(0); } else { bb.putInt(booleanExpression.length()); bb.put(booleanExpression.internalBytes()); } } static Guard decode(ByteBuffer bb) { int exprLength = bb.getInt(); if (exprLength != 0) { byte[] expr = new byte[exprLength]; bb.get(expr); return new Guard(IoTString.shallow(expr)); } return new Guard(null); } public Guard getCopy() { if (booleanExpression == null) { return new Guard(null); } return new Guard(IoTString.shallow(booleanExpression.internalBytes())); } }