1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.gridsystems.beanfilter;
18
19 import java.util.Collection;
20 import java.util.HashSet;
21 import java.util.Set;
22
23
24
25
26
27
28
29 public class CollectionNode extends EvalNode implements FilterParserConstants {
30
31
32
33 private EvalValue lval;
34
35
36
37
38 private EvalValue rval;
39
40
41
42
43 private int op;
44
45
46
47
48
49
50
51
52 public CollectionNode(EvalValue lval, int op, EvalValue rval) {
53 super(lval.getLinePos(), lval.getCharPos());
54 this.lval = lval;
55 this.rval = rval;
56 this.op = op;
57 }
58
59
60
61
62 @Override public boolean eval(Object src) throws EvalException {
63 Object o1 = lval.getValue(src);
64 Object o2 = rval.getValue(src);
65
66
67 if (((o1 == null) && !(o2 instanceof Set))
68 || ((o2 == null) && !(o1 instanceof Set))) {
69 switch (op) {
70 case CONTAINS:
71 case IN:
72
73 break;
74 case EQ:
75 return o1 == o2;
76 case NE:
77 return o1 != o2;
78 default:
79 return false;
80 }
81 }
82
83 Set<Object> s1 = toHashSet(o1);
84 Set<Object> s2 = toHashSet(o2);
85 Collection<Object> c1 = deref(s1, src);
86 Collection<Object> c2 = deref(s2, src);
87
88 switch (op) {
89 case CONTAINS:
90 return c1.containsAll(c2);
91 case IN:
92 return c2.containsAll(c1);
93
94 case EQ:
95 if ((s1 instanceof AllItemsHashSet) || (s2 instanceof AllItemsHashSet)) {
96 return c1.equals(c2);
97 } else {
98 return operateOneByOne(s1, s2, c1, c2);
99 }
100 case NE:
101 if ((s1 instanceof AllItemsHashSet) || (s2 instanceof AllItemsHashSet)) {
102 return operateOneByOne(s1, s2, c1, c2);
103 } else {
104 return !c1.equals(c2);
105 }
106
107 default:
108 return operateOneByOne(s1, s2, c1, c2);
109 }
110 }
111
112
113
114
115
116
117
118
119
120
121 private boolean operateOneByOne(Set<Object> s1, Set<Object> s2,
122 Collection<Object> c1, Collection<Object> c2) throws EvalException {
123 boolean existsFalse = false;
124 boolean existsTrue = false;
125 Object[] list1 = c1.toArray();
126 Object[] list2 = c2.toArray();
127 if ((list1.length == 0) || (list2.length == 0)) {
128 switch (op) {
129 case EQ:
130 return list1.length == list2.length;
131 case LE:
132 return list1.length <= list2.length;
133 case GE:
134 return list1.length >= list2.length;
135 case NE:
136 return list1.length != list2.length;
137 case LT:
138 return list1.length < list2.length;
139 case GT:
140 return list1.length > list2.length;
141 default:
142 return false;
143 }
144 }
145 for (int i = 0; i < list1.length; i++) {
146 for (int j = 0; j < list2.length; j++) {
147 if (CompareNode.evaluateOperation(lval, rval, list1[i], op, list2[j])) {
148 existsTrue = true;
149 } else {
150 existsFalse = true;
151 }
152 }
153 }
154 if ((s1 instanceof AllItemsHashSet) || (s2 instanceof AllItemsHashSet)) {
155 return !existsFalse;
156 } else {
157 return existsTrue;
158 }
159 }
160
161
162
163
164
165
166
167
168
169 private Set<Object> deref(Set<Object> set, Object src) throws EvalException {
170 Set<Object> set2 = new HashSet<Object>();
171 for (Object item : set) {
172 if (item instanceof EvalValue) {
173 item = ((EvalValue)item).getValue(src);
174 }
175 set2.add(normalize(item));
176 }
177 return set2;
178 }
179
180
181
182
183
184
185
186
187
188
189 private Object normalize(Object obj) {
190 if (obj instanceof Integer || obj instanceof Short || obj instanceof Byte) {
191 long longValue = ((Number)obj).longValue();
192 return longValue;
193 } else if (obj instanceof Float) {
194 double doubleValue = ((Number)obj).doubleValue();
195 return doubleValue;
196 } else {
197 return obj;
198 }
199 }
200
201
202
203
204
205
206
207
208 @SuppressWarnings("unchecked")
209 private HashSet<Object> toHashSet(Object obj) {
210 if (obj == null) {
211 HashSet<Object> hash = new AllItemsHashSet();
212 hash.add(null);
213 return hash;
214 } else if (obj instanceof HashSet) {
215 return (HashSet<Object>)obj;
216 } else {
217 HashSet<Object> set;
218 if (obj.getClass().isArray()) {
219 set = ArrayValue.arrayToHash(obj, ArrayValue.ArrayType.ALL_ITEMS);
220 } else {
221 set = new AnyItemsHashSet();
222 set.add(obj);
223 }
224 return set;
225 }
226 }
227
228
229
230
231 @Override public String toString() {
232 String oper = tokenImage[op];
233 if (oper.startsWith("\"")) {
234 oper = oper.substring(1, oper.length() - 1);
235 }
236 return lval + " " + oper + " " + rval;
237 }
238 }