2 * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved.
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
9 package org.opendaylight.controller.md.sal.dom.xsql;
11 import java.io.Serializable;
12 import java.lang.reflect.Method;
14 import java.util.concurrent.ConcurrentHashMap;
16 public class XSQLCriteria implements Serializable {
17 private static final long serialVersionUID = 1L;
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 = "'";
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;
37 private XSQLCriteria left = null;
38 private XSQLCriteria right = null;
40 private int operation = -1;
42 private Object leftValue = null;
43 private Object rightValue = null;
44 private String criteria = null;
46 private static final Map<Class<?>, Map<String, Method>> methodCache =
47 new ConcurrentHashMap<Class<?>, Map<String, Method>>();
49 public XSQLCriteria(final String data, final int parentOperation) {
51 parse(data, parentOperation);
54 private void parse(String data, int parentOperation) {
58 int index1 = data.indexOf("(");
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("")) {
67 new XSQLCriteria(data.substring(index1 + 1, index2),
69 data = data.substring(index2 + 1);
71 data = data.substring(1, index2);
74 data = data.substring(1, index2);
77 right = new XSQLCriteria(
78 data.substring(index1 + 1, data.length() - 1),
80 data = data.substring(0, index1);
84 for (int i = 0; i < operators.length; i++) {
85 index1 = data.indexOf(operators[i]);
89 left = new XSQLCriteria(data.substring(0, index1),
92 if (left.leftValue != null && left.rightValue == null
93 && left.right == null) {
94 leftValue = left.leftValue;
98 right = new XSQLCriteria(
99 data.substring(index1 + operators[i].length()),
102 if (right.leftValue != null && right.rightValue == null
103 && right.right == null) {
104 rightValue = right.leftValue;
111 if (data.startsWith("'") && data.endsWith("'")) {
112 data = data.substring(1, data.length() - 1);
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);
123 public static Object getValue(Object element, String propertyName) {
125 Map<String, Method> cache = methodCache.get(element.getClass());
127 cache = new ConcurrentHashMap<String, Method>();
128 methodCache.put(element.getClass(), cache);
131 Method m = cache.get(propertyName);
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)) {
139 m.setAccessible(true);
140 cache.put(propertyName, m);
150 if (m.getParameterTypes() == null
151 || m.getParameterTypes().length == 0) {
152 value = m.invoke(element, null);
154 if (String.class.isAssignableFrom(m.getParameterTypes()[0])) {
157 Object arg = m.getParameterTypes()[0].newInstance();
158 value = m.invoke(element, arg);
161 } catch (Exception err) {
162 err.printStackTrace();
167 public int isObjectFitCriteria(Object element, String propertyName) {
168 Object value = getValue(element, propertyName);
170 value = value.toString();
172 return checkValue(value);
175 public int checkValue(Object value) {
176 if (leftValue != null && rightValue != null) {
179 if (leftValue.equals("?")) {
185 if (rightValue.equals("?")) {
190 if (operation != OP_CODE_SKIP && operation != OP_CODE_NULL) {
191 if (aSide == null && bSide != null) {
193 } else if (aSide != null && bSide == null) {
195 } else if (aSide == null && bSide == null) {
201 if (aSide.equals(bSide)) {
207 if (!aSide.equals(bSide)) {
213 if (aSide.toString().indexOf(bSide.toString()) != -1) {
224 case OP_CODE_NOT_NULL:
231 if (aSide == null || bSide == null) {
234 if (Double.parseDouble(aSide.toString().trim()) > Double
235 .parseDouble(bSide.toString().trim())) {
241 if (aSide == null || bSide == null) {
244 if (Double.parseDouble(aSide.toString().trim()) >= Double
245 .parseDouble(bSide.toString().trim())) {
252 if (aSide == null || bSide == null) {
255 if (Double.parseDouble(aSide.toString().trim()) < Double
256 .parseDouble(bSide.toString().trim())) {
262 if (aSide == null || bSide == null) {
265 if (Double.parseDouble(aSide.toString().trim()) <= Double
266 .parseDouble(bSide.toString().trim())) {
276 leftResult = left.checkValue(value);
281 rightResult = right.checkValue(value);
284 if (operation == OP_CODE_SKIP) {
285 if (rightResult == 0) {
292 if (operation == OP_CODE_AND) {
293 if (leftResult == 0) {
296 if (rightResult == 0) {
299 if (leftResult >= 2) {
302 if (rightResult >= 2) {
309 if (operation == OP_CODE_OR) {
310 if (leftResult == 0 && rightResult == 0) {
313 if (leftResult >= 2) {
316 if (rightResult >= 2) {
325 public String toString() {
329 public String getCriteriaForProperty(XSQLColumn col) {
330 StringBuffer result = new StringBuffer();
331 if (criteria == null) {
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);
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);
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] + " "
353 } else if (!leftString.equals("")) {
355 } else if (!rightString.equals("")) {
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] + " ?";
371 public static void main(String args[]) {
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"));