4e426fd92ef831af45a6e49fdb8a760820778721
[iotcloud.git] / version2 / src / java / iotcloud / Guard.java
1 package iotcloud;
2
3 import java.util.Set;
4 import java.util.HashSet;
5 import java.util.Collection;
6 import java.nio.ByteBuffer;
7
8 import javax.script.ScriptEngine;
9 import javax.script.ScriptEngineManager;
10 import javax.script.ScriptException;
11 import java.lang.NullPointerException;
12
13
14 class Guard {
15
16     static final byte Equal = 1;
17     static final byte NotEqual = 2;
18
19     private IoTString booleanExpression;
20
21     public Guard() {
22         booleanExpression = null;
23     }
24
25     public Guard(IoTString _booleanExpression) {
26         booleanExpression = _booleanExpression;
27     }
28
29     /**
30      * Create an equality expression for a key value.
31      *
32      */
33     public static String createExpression(IoTString keyName, IoTString keyValue, byte op) {
34         if (op == Equal) {
35             return keyName.toString() + "=='" + keyValue.toString() + "'";
36         } else if (op == NotEqual) {
37             return keyName.toString() + "!='" + keyValue.toString() + "'";
38         }
39
40         // Unrecognized op
41         return null;
42     }
43
44     /**
45      * Add a boolean expression to the guard.
46      *
47      */
48     public void setGuardExpression(String expr) {
49         booleanExpression = new IoTString(expr);
50     }
51
52     /**
53      * Evaluate the guard expression for a given set of key value pairs.
54      *
55      */
56     public boolean evaluate(Collection<KeyValue> kvSet) throws ScriptException, NullPointerException {
57
58         // There are no conditions to evaluate
59         if (booleanExpression == null) {
60             return true;
61         }
62
63         // All the current key value pairs that we need to evaluate the condition
64         String[] variables = new String[kvSet.size()];
65
66         // Fill the variables array
67         int i = 0;
68         for (KeyValue kv : kvSet) {
69             variables[i] = kv.getKey() + " ='" + kv.getValue() + "'";
70             i++;
71         }
72
73         // Prep the evaluation engine (script engine)
74         ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
75         for (String s : variables) {
76             engine.eval(s);
77         }
78
79         // Evaluate the guard condition
80         return 1 == (Integer)engine.eval(booleanExpression.toString());
81     }
82
83     /**
84      * Get the size of the guard condition
85      *
86      */
87     public int getSize() {
88
89         if (booleanExpression == null) {
90             return Integer.BYTES;
91         }
92
93         return Integer.BYTES + booleanExpression.length();
94     }
95
96     public void encode(ByteBuffer bb) {
97         if (booleanExpression == null) {
98             bb.putInt(0);
99         } else {
100             bb.putInt(booleanExpression.length());
101             bb.put(booleanExpression.internalBytes());
102         }
103     }
104
105     static Guard decode(ByteBuffer bb) {
106         int exprLength = bb.getInt();
107
108         if (exprLength != 0) {
109             byte[] expr = new byte[exprLength];
110             bb.get(expr);
111             return new Guard(IoTString.shallow(expr));
112         }
113         return new Guard(null);
114     }
115
116     public Guard getCopy() {
117
118         if (booleanExpression == null) {
119             return new Guard(null);
120         }
121
122         return new Guard(IoTString.shallow(booleanExpression.internalBytes()));
123     }
124
125 }