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