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