1 package org.opendaylight.controller.md.sal.dom.xsql;
3 import java.io.Serializable;
4 import java.lang.reflect.Method;
6 import java.util.concurrent.ConcurrentHashMap;
8 public class XSQLCriteria implements Serializable {
9 private static final long serialVersionUID = 1L;
11 private static final String operators[] =
12 new String[] {" and ", " or ", ">=", "<=", "!=", "=", ">", "<", "like",
13 "is null", "not null", "skip"};
14 private static final String STRING_CHAR = "'";
16 public static final int OP_CODE_AND = 0;
17 public static final int OP_CODE_OR = 1;
18 public static final int OP_CODE_GTEQ = 2;
19 public static final int OP_CODE_LTEQ = 3;
20 public static final int OP_CODE_NOT_EQ = 4;
21 public static final int OP_CODE_EQUAL = 5;
22 public static final int OP_CODE_GT = 6;
23 public static final int OP_CODE_LT = 7;
24 public static final int OP_CODE_LIKE = 8;
25 public static final int OP_CODE_NULL = 9;
26 public static final int OP_CODE_NOT_NULL = 10;
27 public static final int OP_CODE_SKIP = 11;
29 private XSQLCriteria left = null;
30 private XSQLCriteria right = null;
32 private int operation = -1;
34 private Object leftValue = null;
35 private Object rightValue = null;
36 private String criteria = null;
38 private static final Map<Class<?>, Map<String, Method>> methodCache =
39 new ConcurrentHashMap<Class<?>, Map<String, Method>>();
41 public XSQLCriteria(final String data, final int parentOperation) {
43 parse(data, parentOperation);
46 private void parse(String data, int parentOperation) {
50 int index1 = data.indexOf("(");
52 String leftCondition = data.substring(0, index1).trim();
53 if (leftCondition.trim().equals("")) {
54 int index2 = data.lastIndexOf(")");
55 if (index2 < data.length() - 1) {
56 String rtValue = data.substring(index2 + 1).trim();
57 if (!rtValue.equals("")) {
59 new XSQLCriteria(data.substring(index1 + 1, index2),
61 data = data.substring(index2 + 1);
63 data = data.substring(1, index2);
66 data = data.substring(1, index2);
69 right = new XSQLCriteria(
70 data.substring(index1 + 1, data.length() - 1),
72 data = data.substring(0, index1);
76 for (int i = 0; i < operators.length; i++) {
77 index1 = data.indexOf(operators[i]);
81 left = new XSQLCriteria(data.substring(0, index1),
84 if (left.leftValue != null && left.rightValue == null
85 && left.right == null) {
86 leftValue = left.leftValue;
90 right = new XSQLCriteria(
91 data.substring(index1 + operators[i].length()),
94 if (right.leftValue != null && right.rightValue == null
95 && right.right == null) {
96 rightValue = right.leftValue;
103 if (data.startsWith("'") && data.endsWith("'")) {
104 data = data.substring(1, data.length() - 1);
107 if (parentOperation == OP_CODE_LIKE && data.startsWith("%") && data.endsWith("%")
108 && data.substring(1, data.length() - 1).indexOf("%") == -1) {
109 data = data.substring(1, data.length() - 1);
115 public static Object getValue(Object element, String propertyName) {
117 Map<String, Method> cache = methodCache.get(element.getClass());
119 cache = new ConcurrentHashMap<String, Method>();
120 methodCache.put(element.getClass(), cache);
123 Method m = cache.get(propertyName);
125 Method methods[] = element.getClass().getMethods();
126 for (Method mm : methods) {
127 if (mm.getName().equals(propertyName) || mm.getName()
128 .equals("get" + propertyName) || mm.getName()
129 .equals("is" + propertyName)) {
131 m.setAccessible(true);
132 cache.put(propertyName, m);
142 if (m.getParameterTypes() == null
143 || m.getParameterTypes().length == 0) {
144 value = m.invoke(element, null);
146 if (String.class.isAssignableFrom(m.getParameterTypes()[0])) {
149 Object arg = m.getParameterTypes()[0].newInstance();
150 value = m.invoke(element, arg);
153 } catch (Exception err) {
154 err.printStackTrace();
159 public int isObjectFitCriteria(Object element, String propertyName) {
160 Object value = getValue(element, propertyName);
162 value = value.toString();
164 return checkValue(value);
167 public int checkValue(Object value) {
168 if (leftValue != null && rightValue != null) {
171 if (leftValue.equals("?")) {
177 if (rightValue.equals("?")) {
182 if (operation != OP_CODE_SKIP && operation != OP_CODE_NULL) {
183 if (aSide == null && bSide != null) {
185 } else if (aSide != null && bSide == null) {
187 } else if (aSide == null && bSide == null) {
193 if (aSide.equals(bSide)) {
199 if (!aSide.equals(bSide)) {
205 if (aSide.toString().indexOf(bSide.toString()) != -1) {
216 case OP_CODE_NOT_NULL:
223 if (aSide == null || bSide == null) {
226 if (Double.parseDouble(aSide.toString().trim()) > Double
227 .parseDouble(bSide.toString().trim())) {
233 if (aSide == null || bSide == null) {
236 if (Double.parseDouble(aSide.toString().trim()) >= Double
237 .parseDouble(bSide.toString().trim())) {
244 if (aSide == null || bSide == null) {
247 if (Double.parseDouble(aSide.toString().trim()) < Double
248 .parseDouble(bSide.toString().trim())) {
254 if (aSide == null || bSide == null) {
257 if (Double.parseDouble(aSide.toString().trim()) <= Double
258 .parseDouble(bSide.toString().trim())) {
268 leftResult = left.checkValue(value);
273 rightResult = right.checkValue(value);
276 if (operation == OP_CODE_SKIP) {
277 if (rightResult == 0) {
284 if (operation == OP_CODE_AND) {
285 if (leftResult == 0) {
288 if (rightResult == 0) {
291 if (leftResult >= 2) {
294 if (rightResult >= 2) {
301 if (operation == OP_CODE_OR) {
302 if (leftResult == 0 && rightResult == 0) {
305 if (leftResult >= 2) {
308 if (rightResult >= 2) {
317 public String toString() {
321 public String getCriteriaForProperty(XSQLColumn col) {
322 StringBuffer result = new StringBuffer();
323 if (criteria == null) {
327 if (leftValue != null && rightValue != null) {
328 if (leftValue.toString().toLowerCase().equals(col.getName().toLowerCase()) ||
329 leftValue.toString().toLowerCase().equals(col.toString().toLowerCase()) /*||
330 /*col.getName().toLowerCase().indexOf(leftValue.toString().toLowerCase()) != -1*/) {
331 result.append("? ").append(operators[operation]).append(" ").append(rightValue);
333 if (rightValue.toString().toLowerCase().equals(col.getName().toLowerCase()) ||
334 rightValue.toString().toLowerCase().equals(col.toString().toLowerCase()) /*||
335 col.getName().toLowerCase().indexOf(rightValue.toString().toLowerCase()) != -1*/) {
336 result.append("? ").append(operators[operation]).append(" ").append(leftValue);
338 return result.toString();
339 } else if (left != null && right != null) {
340 String leftString = left.getCriteriaForProperty(col);
341 String rightString = right.getCriteriaForProperty(col);
342 if (!leftString.equals("") && !rightString.equals("")) {
343 return leftString + " " + operators[operation] + " "
345 } else if (!leftString.equals("")) {
347 } else if (!rightString.equals("")) {
351 } else if (leftValue != null && leftValue.toString().toLowerCase()
352 .equals(col.toString().toLowerCase()) && right != null) {
353 return "? " + operators[operation] + " (" + right
354 .getCriteriaForProperty(col) + ")";
355 } else if (rightValue != null && rightValue.toString().toLowerCase()
356 .equals(col.toString().toLowerCase()) && left != null) {
357 return "(" + left.getCriteriaForProperty(col) + ") "
358 + operators[operation] + " ?";
363 public static void main(String args[]) {
365 new XSQLCriteria("ip like '%101%' or (354>=0 or 456>=3)", -1);
366 System.out.println(p.checkValue("192.268.4.4"));
367 p = new XSQLCriteria("? like '%267%'", -1);
368 System.out.println(p.checkValue("192.268.4.4"));