Fix license header violations in sal-dom-xsql
[controller.git] / opendaylight / md-sal / sal-dom-xsql / src / main / java / org / opendaylight / controller / md / sal / dom / xsql / XSQLCriteria.java
1 /*
2  * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.controller.md.sal.dom.xsql;
10
11 import java.io.Serializable;
12 import java.lang.reflect.Method;
13 import java.util.Map;
14 import java.util.concurrent.ConcurrentHashMap;
15
16 public class XSQLCriteria implements Serializable {
17     private static final long serialVersionUID = 1L;
18
19     private static final String operators[] =
20         new String[] {" and ", " or ", ">=", "<=", "!=", "=", ">", "<", "like",
21             "is null", "not null", "skip"};
22     private static final String STRING_CHAR = "'";
23
24     public static final int OP_CODE_AND = 0;
25     public static final int OP_CODE_OR = 1;
26     public static final int OP_CODE_GTEQ = 2;
27     public static final int OP_CODE_LTEQ = 3;
28     public static final int OP_CODE_NOT_EQ = 4;
29     public static final int OP_CODE_EQUAL = 5;
30     public static final int OP_CODE_GT = 6;
31     public static final int OP_CODE_LT = 7;
32     public static final int OP_CODE_LIKE = 8;
33     public static final int OP_CODE_NULL = 9;
34     public static final int OP_CODE_NOT_NULL = 10;
35     public static final int OP_CODE_SKIP = 11;
36
37     private XSQLCriteria left = null;
38     private XSQLCriteria right = null;
39
40     private int operation = -1;
41
42     private Object leftValue = null;
43     private Object rightValue = null;
44     private String criteria = null;
45
46     private static final Map<Class<?>, Map<String, Method>> methodCache =
47         new ConcurrentHashMap<Class<?>, Map<String, Method>>();
48
49     public XSQLCriteria(final String data, final int parentOperation) {
50         criteria = data;
51         parse(data, parentOperation);
52     }
53
54     private void parse(String data, int parentOperation) {
55
56         data = data.trim();
57
58         int index1 = data.indexOf("(");
59         if (index1 != -1) {
60             String leftCondition = data.substring(0, index1).trim();
61             if (leftCondition.trim().equals("")) {
62                 int index2 = data.lastIndexOf(")");
63                 if (index2 < data.length() - 1) {
64                     String rtValue = data.substring(index2 + 1).trim();
65                     if (!rtValue.equals("")) {
66                         left =
67                             new XSQLCriteria(data.substring(index1 + 1, index2),
68                                 parentOperation);
69                         data = data.substring(index2 + 1);
70                     } else {
71                         data = data.substring(1, index2);
72                     }
73                 } else {
74                     data = data.substring(1, index2);
75                 }
76             } else {
77                 right = new XSQLCriteria(
78                     data.substring(index1 + 1, data.length() - 1),
79                     parentOperation);
80                 data = data.substring(0, index1);
81             }
82         }
83
84         for (int i = 0; i < operators.length; i++) {
85             index1 = data.indexOf(operators[i]);
86             if (index1 != -1) {
87                 this.operation = i;
88                 if (left == null) {
89                     left = new XSQLCriteria(data.substring(0, index1),
90                         this.operation);
91                 }
92                 if (left.leftValue != null && left.rightValue == null
93                     && left.right == null) {
94                     leftValue = left.leftValue;
95                     left = null;
96                 }
97                 if (right == null) {
98                     right = new XSQLCriteria(
99                         data.substring(index1 + operators[i].length()),
100                         this.operation);
101                 }
102                 if (right.leftValue != null && right.rightValue == null
103                     && right.right == null) {
104                     rightValue = right.leftValue;
105                     right = null;
106                 }
107                 return;
108             }
109         }
110
111         if (data.startsWith("'") && data.endsWith("'")) {
112             data = data.substring(1, data.length() - 1);
113         }
114
115         if (parentOperation == OP_CODE_LIKE && data.startsWith("%") && data.endsWith("%")
116             && data.substring(1, data.length() - 1).indexOf("%") == -1) {
117             data = data.substring(1, data.length() - 1);
118         }
119
120         leftValue = data;
121     }
122
123     public static Object getValue(Object element, String propertyName) {
124         try {
125             Map<String, Method> cache = methodCache.get(element.getClass());
126             if (cache == null) {
127                 cache = new ConcurrentHashMap<String, Method>();
128                 methodCache.put(element.getClass(), cache);
129             }
130
131             Method m = cache.get(propertyName);
132             if (m == null) {
133                 Method methods[] = element.getClass().getMethods();
134                 for (Method mm : methods) {
135                     if (mm.getName().equals(propertyName) || mm.getName()
136                         .equals("get" + propertyName) || mm.getName()
137                         .equals("is" + propertyName)) {
138                         m = mm;
139                         m.setAccessible(true);
140                         cache.put(propertyName, m);
141                         break;
142                     }
143                 }
144             }
145
146             Object value = null;
147             if (m == null) {
148                 return null;
149             }
150             if (m.getParameterTypes() == null
151                 || m.getParameterTypes().length == 0) {
152                 value = m.invoke(element, null);
153             } else {
154                 if (String.class.isAssignableFrom(m.getParameterTypes()[0])) {
155                     return null;
156                 }
157                 Object arg = m.getParameterTypes()[0].newInstance();
158                 value = m.invoke(element, arg);
159             }
160             return value;
161         } catch (Exception err) {
162             err.printStackTrace();
163         }
164         return null;
165     }
166
167     public int isObjectFitCriteria(Object element, String propertyName) {
168         Object value = getValue(element, propertyName);
169         if (value != null) {
170             value = value.toString();
171         }
172         return checkValue(value);
173     }
174
175     public int checkValue(Object value) {
176         if (leftValue != null && rightValue != null) {
177             Object aSide = null;
178             Object bSide = null;
179             if (leftValue.equals("?")) {
180                 aSide = value;
181             } else {
182                 aSide = leftValue;
183             }
184
185             if (rightValue.equals("?")) {
186                 bSide = value;
187             } else {
188                 bSide = rightValue;
189             }
190             if (operation != OP_CODE_SKIP && operation != OP_CODE_NULL) {
191                 if (aSide == null && bSide != null) {
192                     return 0;
193                 } else if (aSide != null && bSide == null) {
194                     return 0;
195                 } else if (aSide == null && bSide == null) {
196                     return 1;
197                 }
198             }
199             switch (operation) {
200                 case OP_CODE_EQUAL:
201                     if (aSide.equals(bSide)) {
202                         return 1;
203                     } else {
204                         return 0;
205                     }
206                 case OP_CODE_NOT_EQ:
207                     if (!aSide.equals(bSide)) {
208                         return 1;
209                     } else {
210                         return 0;
211                     }
212                 case OP_CODE_LIKE:
213                     if (aSide.toString().indexOf(bSide.toString()) != -1) {
214                         return 1;
215                     } else {
216                         return 0;
217                     }
218                 case OP_CODE_NULL:
219                     if (aSide == null) {
220                         return 1;
221                     } else {
222                         return 0;
223                     }
224                 case OP_CODE_NOT_NULL:
225                     if (aSide != null) {
226                         return 1;
227                     } else {
228                         return 0;
229                     }
230                 case OP_CODE_GT:
231                     if (aSide == null || bSide == null) {
232                         return 0;
233                     }
234                     if (Double.parseDouble(aSide.toString().trim()) > Double
235                         .parseDouble(bSide.toString().trim())) {
236                         return 1;
237                     } else {
238                         return 0;
239                     }
240                 case OP_CODE_GTEQ:
241                     if (aSide == null || bSide == null) {
242                         return 0;
243                     }
244                     if (Double.parseDouble(aSide.toString().trim()) >= Double
245                         .parseDouble(bSide.toString().trim())) {
246                         return 1;
247                     } else {
248                         return 0;
249                     }
250
251                 case OP_CODE_LT:
252                     if (aSide == null || bSide == null) {
253                         return 0;
254                     }
255                     if (Double.parseDouble(aSide.toString().trim()) < Double
256                         .parseDouble(bSide.toString().trim())) {
257                         return 1;
258                     } else {
259                         return 0;
260                     }
261                 case OP_CODE_LTEQ:
262                     if (aSide == null || bSide == null) {
263                         return 0;
264                     }
265                     if (Double.parseDouble(aSide.toString().trim()) <= Double
266                         .parseDouble(bSide.toString().trim())) {
267                         return 1;
268                     } else {
269                         return 0;
270                     }
271             }
272         }
273
274         int leftResult = 0;
275         if (left != null) {
276             leftResult = left.checkValue(value);
277         }
278
279         int rightResult = 0;
280         if (right != null) {
281             rightResult = right.checkValue(value);
282         }
283
284         if (operation == OP_CODE_SKIP) {
285             if (rightResult == 0) {
286                 return 2;
287             } else {
288                 return 3;
289             }
290         }
291
292         if (operation == OP_CODE_AND) {
293             if (leftResult == 0) {
294                 return 0;
295             }
296             if (rightResult == 0) {
297                 return 0;
298             }
299             if (leftResult >= 2) {
300                 return leftResult;
301             }
302             if (rightResult >= 2) {
303                 return rightResult;
304             }
305
306             return 1;
307         }
308
309         if (operation == OP_CODE_OR) {
310             if (leftResult == 0 && rightResult == 0) {
311                 return 0;
312             }
313             if (leftResult >= 2) {
314                 return leftResult;
315             }
316             if (rightResult >= 2) {
317                 return rightResult;
318             }
319             return 1;
320         }
321
322         return 0;
323     }
324
325     public String toString() {
326         return criteria;
327     }
328
329     public String getCriteriaForProperty(XSQLColumn col) {
330         StringBuffer result = new StringBuffer();
331         if (criteria == null) {
332             return "";
333         }
334
335         if (leftValue != null && rightValue != null) {
336             if (leftValue.toString().toLowerCase().equals(col.getName().toLowerCase()) ||
337                 leftValue.toString().toLowerCase().equals(col.toString().toLowerCase()) /*||
338                 /*col.getName().toLowerCase().indexOf(leftValue.toString().toLowerCase()) != -1*/) {
339                 result.append("? ").append(operators[operation]).append(" ").append(rightValue);
340             }else
341             if (rightValue.toString().toLowerCase().equals(col.getName().toLowerCase()) ||
342                     rightValue.toString().toLowerCase().equals(col.toString().toLowerCase()) /*||
343                     col.getName().toLowerCase().indexOf(rightValue.toString().toLowerCase()) != -1*/) {
344                     result.append("? ").append(operators[operation]).append(" ").append(leftValue);
345             }
346             return result.toString();
347         } else if (left != null && right != null) {
348             String leftString = left.getCriteriaForProperty(col);
349             String rightString = right.getCriteriaForProperty(col);
350             if (!leftString.equals("") && !rightString.equals("")) {
351                 return leftString + " " + operators[operation] + " "
352                     + rightString;
353             } else if (!leftString.equals("")) {
354                 return leftString;
355             } else if (!rightString.equals("")) {
356                 return rightString;
357             }
358             return "";
359         } else if (leftValue != null && leftValue.toString().toLowerCase()
360             .equals(col.toString().toLowerCase()) && right != null) {
361             return "? " + operators[operation] + " (" + right
362                 .getCriteriaForProperty(col) + ")";
363         } else if (rightValue != null && rightValue.toString().toLowerCase()
364             .equals(col.toString().toLowerCase()) && left != null) {
365             return "(" + left.getCriteriaForProperty(col) + ") "
366                 + operators[operation] + " ?";
367         }
368         return "";
369     }
370
371     public static void main(String args[]) {
372         XSQLCriteria p =
373             new XSQLCriteria("ip like '%101%' or (354>=0 or 456>=3)", -1);
374         System.out.println(p.checkValue("192.268.4.4"));
375         p = new XSQLCriteria("? like '%267%'", -1);
376         System.out.println(p.checkValue("192.268.4.4"));
377
378     }
379 }