1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.core.api.criteria;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.kuali.rice.core.api.search.SearchOperator;
20
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.List;
24 import java.util.Map;
25
26 import static org.kuali.rice.core.api.criteria.PredicateFactory.and;
27 import static org.kuali.rice.core.api.criteria.PredicateFactory.between;
28 import static org.kuali.rice.core.api.criteria.PredicateFactory.equal;
29 import static org.kuali.rice.core.api.criteria.PredicateFactory.equalIgnoreCase;
30 import static org.kuali.rice.core.api.criteria.PredicateFactory.greaterThan;
31 import static org.kuali.rice.core.api.criteria.PredicateFactory.greaterThanOrEqual;
32 import static org.kuali.rice.core.api.criteria.PredicateFactory.isNotNull;
33 import static org.kuali.rice.core.api.criteria.PredicateFactory.isNull;
34 import static org.kuali.rice.core.api.criteria.PredicateFactory.lessThan;
35 import static org.kuali.rice.core.api.criteria.PredicateFactory.lessThanOrEqual;
36 import static org.kuali.rice.core.api.criteria.PredicateFactory.likeIgnoreCase;
37 import static org.kuali.rice.core.api.criteria.PredicateFactory.notEqualIgnoreCase;
38 import static org.kuali.rice.core.api.criteria.PredicateFactory.notLike;
39 import static org.kuali.rice.core.api.criteria.PredicateFactory.or;
40
41
42
43
44
45
46
47 public final class PredicateUtils {
48
49 private PredicateUtils() {
50 throw new UnsupportedOperationException("do not call");
51 }
52
53 public static Predicate convertObjectMapToPredicate(Map<String, Object> criteria) {
54 List<Predicate> p = new ArrayList<Predicate>();
55 for (Map.Entry<String, Object> entry : criteria.entrySet()) {
56 if (entry.getValue() != null) {
57 if (entry.getValue() instanceof String) {
58 p.add(equalIgnoreCase(entry.getKey(), (String)entry.getValue()));
59 } else {
60 p.add(equal(entry.getKey(), (String)entry.getValue()));
61 }
62
63 }
64 }
65
66 return and(p.toArray(new Predicate[p.size()]));
67 }
68
69
70
71
72
73 public static Predicate convertMapToPredicate(Map<String, String> criteria) {
74 List<Predicate> p = new ArrayList<Predicate>();
75 for (Map.Entry<String, String> entry : criteria.entrySet()) {
76 if (StringUtils.isNotBlank(entry.getValue())) {
77 List<String> values = new ArrayList<String>();
78 getValueRecursive(entry.getValue(), values);
79 List<Predicate> tempPredicates = new ArrayList<Predicate>();
80 p.addAll(tempPredicates);
81
82
83 for (String value : values) {
84 tempPredicates.add(parsePredicate(entry.getKey(), value));
85 }
86 if (entry.getValue().contains(SearchOperator.AND.op())) {
87 p.add(and(tempPredicates.toArray(new Predicate[tempPredicates.size()])));
88 } else if (entry.getValue().contains(SearchOperator.OR.op())) {
89 p.add(or(tempPredicates.toArray(new Predicate[tempPredicates.size()])));
90 } else {
91 p.addAll(tempPredicates);
92 }
93 }
94 }
95
96 return and(p.toArray(new Predicate[p.size()]));
97 }
98
99
100
101
102
103
104
105 private static Predicate parsePredicate(String key, String value) {
106 if (value.contains(SearchOperator.NULL.op())) {
107 if (isNot(value)) {
108 return isNotNull(key);
109 } else {
110 return isNull(key);
111 }
112 } else if (value.contains(SearchOperator.BETWEEN_EXCLUSIVE_UPPER.op())) {
113 String[] betweenVals = StringUtils.split(value, SearchOperator.BETWEEN_EXCLUSIVE_UPPER.op());
114 if (betweenVals.length == 2) {
115 return between(key, betweenVals[0], betweenVals[1], SearchOperator.BETWEEN_EXCLUSIVE_UPPER);
116 }
117 return null;
118 } else if (value.contains(SearchOperator.BETWEEN.op())) {
119 String[] betweenVals = StringUtils.split(value, SearchOperator.BETWEEN.op());
120 if (betweenVals.length == 2) {
121 return between(key, betweenVals[0], betweenVals[1]);
122 }
123 return null;
124 } else if (value.contains(SearchOperator.GREATER_THAN_EQUAL.op())) {
125 return greaterThanOrEqual(key, StringUtils.replace(value, SearchOperator.GREATER_THAN_EQUAL.op(), ""));
126 } else if (value.contains(SearchOperator.LESS_THAN_EQUAL.op())) {
127 return lessThanOrEqual(key, StringUtils.replace(value, SearchOperator.LESS_THAN_EQUAL.op(), ""));
128 } else if (value.contains(SearchOperator.GREATER_THAN.op())) {
129 return greaterThan(key, StringUtils.replace(value, SearchOperator.GREATER_THAN.op(), ""));
130 } else if (value.contains(SearchOperator.LESS_THAN.op())) {
131 return lessThan(key, StringUtils.replace(value, SearchOperator.LESS_THAN.op(), ""));
132 } else if (value.contains(SearchOperator.LIKE_MANY.op()) || (value.contains(SearchOperator.LIKE_ONE.op()))) {
133 if (isNot(value)) {
134 return notLike(key, stripNot(value));
135 } else {
136 return likeIgnoreCase(key, value);
137 }
138 } else {
139 if (isNot(value)) {
140 return notEqualIgnoreCase(key, stripNot(value));
141 } else {
142 return equalIgnoreCase(key, value);
143 }
144 }
145 }
146
147 private static void getValueRecursive(String valueEntered, List<String> lRet) {
148 if(valueEntered == null) {
149 return;
150 }
151
152 valueEntered = valueEntered.trim();
153 valueEntered = valueEntered.replaceAll("%", "*");
154 if(lRet == null){
155 throw new NullPointerException("The list passed in is by reference and should never be null.");
156 }
157
158 if (StringUtils.contains(valueEntered, SearchOperator.OR.op())) {
159 List<String> l = Arrays.asList(StringUtils.split(valueEntered, SearchOperator.OR.op()));
160 for(String value : l){
161 getValueRecursive(value, lRet);
162 }
163 return;
164 }
165 if (StringUtils.contains(valueEntered, SearchOperator.AND.op())) {
166
167 List<String> l = Arrays.asList(StringUtils.split(valueEntered, SearchOperator.AND.op()));
168 for(String value : l){
169 getValueRecursive(value, lRet);
170 }
171 return;
172 }
173
174
175 lRet.add(valueEntered);
176 }
177
178 private static boolean isNot(String value) {
179 if (value == null) {
180 return false;
181 }
182 return value.contains(SearchOperator.NOT.op());
183 }
184
185
186 private static String stripNot(String value) {
187 if (value.trim().startsWith(SearchOperator.NOT.op())) {
188 value = value.trim().replaceFirst(SearchOperator.NOT.op(), "");
189 }
190 return value;
191 }
192 }
193
194