1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 package org.jaxen.test;
49
50 import java.util.Comparator;
51 import java.util.List;
52
53 import org.jaxen.expr.AdditiveExpr;
54 import org.jaxen.expr.AllNodeStep;
55 import org.jaxen.expr.CommentNodeStep;
56 import org.jaxen.expr.EqualityExpr;
57 import org.jaxen.expr.FilterExpr;
58 import org.jaxen.expr.FunctionCallExpr;
59 import org.jaxen.expr.LiteralExpr;
60 import org.jaxen.expr.LocationPath;
61 import org.jaxen.expr.LogicalExpr;
62 import org.jaxen.expr.MultiplicativeExpr;
63 import org.jaxen.expr.NameStep;
64 import org.jaxen.expr.NumberExpr;
65 import org.jaxen.expr.PathExpr;
66 import org.jaxen.expr.Predicate;
67 import org.jaxen.expr.ProcessingInstructionNodeStep;
68 import org.jaxen.expr.RelationalExpr;
69 import org.jaxen.expr.TextNodeStep;
70 import org.jaxen.expr.UnaryExpr;
71 import org.jaxen.expr.UnionExpr;
72 import org.jaxen.expr.VariableReferenceExpr;
73
74
75 class ExprComparator implements Comparator {
76
77 public static final Comparator EXPR_COMPARATOR = new ExprComparator();
78
79 private static final int TYPE_ADDITIVE_EXPR = 1;
80 private static final int TYPE_ALL_NODE_STEP = 2;
81 private static final int TYPE_COMMENT_NODE_STEP = 3;
82 private static final int TYPE_EQUALITY_EXPR = 4;
83 private static final int TYPE_FILTER_EXPR = 5;
84 private static final int TYPE_FUNCTION_CALL_EXPR = 6;
85 private static final int TYPE_LITERAL_EXPR = 7;
86 private static final int TYPE_LOCATION_PATH = 8;
87 private static final int TYPE_LOGICAL_EXP = 9;
88 private static final int TYPE_MULTIPLICATIVE_EXPR = 10;
89 private static final int TYPE_NAME_STEP = 11;
90 private static final int TYPE_NUMBER_EXPR = 12;
91 private static final int TYPE_PATH_EXPR = 13;
92 private static final int TYPE_PREDICATE = 14;
93 private static final int TYPE_PROCESSING_INSTRUCTION_NODE_STEP = 15;
94 private static final int TYPE_RELATIONAL_EXPR = 16;
95 private static final int TYPE_TEXT_NODE_STEP = 17;
96 private static final int TYPE_UNARY_EXPR = 18;
97 private static final int TYPE_UNION_EXPR = 19;
98 private static final int TYPE_VARIABLE_REFERENCE_EXPR = 20;
99
100 private ExprComparator()
101 {
102 }
103
104 public int compare(Object o1, Object o2)
105 {
106 int type1 = getType(o1);
107 int type2 = getType(o2);
108
109 int cmp;
110 if (type1 == type2)
111 {
112 switch (type1)
113 {
114 case TYPE_ADDITIVE_EXPR:
115 AdditiveExpr additiveExpr1 = (AdditiveExpr)o1;
116 AdditiveExpr additiveExpr2 = (AdditiveExpr)o2;
117 cmp = additiveExpr1.getOperator().compareTo(additiveExpr2.getOperator());
118 if (cmp == 0)
119 {
120 cmp = compare(additiveExpr1.getLHS(), additiveExpr2.getLHS());
121 if (cmp == 0)
122 {
123 cmp = compare(additiveExpr1.getRHS(), additiveExpr2.getRHS());
124 }
125 }
126 break;
127 case TYPE_ALL_NODE_STEP:
128 AllNodeStep allNodeStep1 = (AllNodeStep)o1;
129 AllNodeStep allNodeStep2 = (AllNodeStep)o2;
130 cmp = allNodeStep1.getAxis() - allNodeStep2.getAxis();
131 if (cmp == 0)
132 {
133 cmp = compareLists(allNodeStep1.getPredicates(), allNodeStep2.getPredicates());
134 }
135 break;
136 case TYPE_COMMENT_NODE_STEP:
137 CommentNodeStep commentNodeStep1 = (CommentNodeStep)o1;
138 CommentNodeStep commentNodeStep2 = (CommentNodeStep)o2;
139 cmp = commentNodeStep1.getAxis() - commentNodeStep2.getAxis();
140 if (cmp == 0)
141 {
142 cmp = compareLists(commentNodeStep1.getPredicates(), commentNodeStep2.getPredicates());
143 }
144 break;
145 case TYPE_EQUALITY_EXPR:
146 EqualityExpr equalityExpr1 = (EqualityExpr)o1;
147 EqualityExpr equalityExpr2 = (EqualityExpr)o2;
148 cmp = equalityExpr1.getOperator().compareTo(equalityExpr2.getOperator());
149 if (cmp == 0)
150 {
151 cmp = compare(equalityExpr1.getLHS(), equalityExpr1.getLHS());
152 if (cmp == 0)
153 {
154 cmp = compare(equalityExpr1.getRHS(), equalityExpr1.getRHS());
155 }
156 }
157 break;
158 case TYPE_FILTER_EXPR:
159 if (true)
160 throw new RuntimeException("Not yet implemented!");
161 break;
162 case TYPE_FUNCTION_CALL_EXPR:
163 FunctionCallExpr functionCallExpr1 = (FunctionCallExpr)o1;
164 FunctionCallExpr functionCallExpr2 = (FunctionCallExpr)o2;
165 cmp = compareStrings(functionCallExpr1.getPrefix(), functionCallExpr2.getPrefix());
166 if (cmp == 0)
167 {
168 cmp = functionCallExpr1.getFunctionName().compareTo(functionCallExpr2.getFunctionName());
169 if (cmp == 0)
170 {
171 cmp = compareLists(functionCallExpr1.getParameters(), functionCallExpr2.getParameters());
172 }
173 }
174 break;
175 case TYPE_LITERAL_EXPR:
176 LiteralExpr literalExpr1 = (LiteralExpr)o1;
177 LiteralExpr literalExpr2 = (LiteralExpr)o2;
178 cmp = literalExpr1.getLiteral().compareTo(literalExpr2.getLiteral());
179 break;
180 case TYPE_LOCATION_PATH:
181 LocationPath locationPath1 = (LocationPath)o1;
182 LocationPath locationPath2 = (LocationPath)o2;
183 if (locationPath1.isAbsolute() == locationPath2.isAbsolute())
184 {
185 cmp = compareLists(locationPath1.getSteps(), locationPath2.getSteps());
186 }
187 else if (locationPath1.isAbsolute())
188 {
189 cmp = 1;
190 }
191 else
192 {
193 cmp = -1;
194 }
195 break;
196 case TYPE_LOGICAL_EXP:
197 LogicalExpr logicalExpr1 = (LogicalExpr)o1;
198 LogicalExpr logicalExpr2 = (LogicalExpr)o2;
199 cmp = logicalExpr1.getOperator().compareTo(logicalExpr2.getOperator());
200 if (cmp == 0)
201 {
202 cmp = compare(logicalExpr1.getLHS(), logicalExpr2.getLHS());
203 if (cmp == 0)
204 {
205 cmp = compare(logicalExpr1.getRHS(), logicalExpr2.getRHS());
206 }
207 }
208 break;
209 case TYPE_MULTIPLICATIVE_EXPR:
210 MultiplicativeExpr multiplicativeExpr1 = (MultiplicativeExpr)o1;
211 MultiplicativeExpr multiplicativeExpr2 = (MultiplicativeExpr)o2;
212 cmp = multiplicativeExpr1.getOperator().compareTo(multiplicativeExpr2.getOperator());
213 if (cmp == 0)
214 {
215 cmp = compare(multiplicativeExpr1.getLHS(), multiplicativeExpr2.getLHS());
216 if (cmp == 0)
217 {
218 cmp = compare(multiplicativeExpr1.getRHS(), multiplicativeExpr2.getRHS());
219 }
220 }
221 break;
222 case TYPE_NAME_STEP:
223 NameStep nameStep1 = (NameStep)o1;
224 NameStep nameStep2 = (NameStep)o2;
225 cmp = nameStep1.getAxis() - nameStep2.getAxis();
226 if (cmp == 0)
227 {
228 cmp = compareStrings(nameStep1.getPrefix(), nameStep2.getPrefix());
229
230 if (cmp == 0)
231 {
232 cmp = nameStep1.getLocalName().compareTo(nameStep2.getLocalName());
233 if (cmp == 0)
234 {
235 cmp = compareLists(nameStep1.getPredicates(), nameStep2.getPredicates());
236 }
237 }
238 }
239 break;
240 case TYPE_NUMBER_EXPR:
241 NumberExpr numberExpr1 = (NumberExpr)o1;
242 NumberExpr numberExpr2 = (NumberExpr)o2;
243 cmp = new Double(numberExpr1.getNumber().doubleValue()).compareTo(new Double(numberExpr2.getNumber().doubleValue()));
244 break;
245 case TYPE_PATH_EXPR:
246 PathExpr pathExpr1 = (PathExpr)o1;
247 PathExpr pathExpr2 = (PathExpr)o2;
248 cmp = compare(pathExpr1.getLocationPath(), pathExpr2.getLocationPath());
249 if (cmp == 0)
250 {
251 cmp = compare(pathExpr1.getFilterExpr(), pathExpr2.getFilterExpr());
252 }
253 break;
254 case TYPE_PREDICATE:
255 Predicate predicate1 = (Predicate)o1;
256 Predicate predicate2 = (Predicate)o2;
257 cmp = compare(predicate1.getExpr(), predicate2.getExpr());
258 break;
259 case TYPE_PROCESSING_INSTRUCTION_NODE_STEP:
260 ProcessingInstructionNodeStep processingInstructionNodeStep1 = (ProcessingInstructionNodeStep)o1;
261 ProcessingInstructionNodeStep processingInstructionNodeStep2 = (ProcessingInstructionNodeStep)o2;
262 cmp = processingInstructionNodeStep1.getAxis() - processingInstructionNodeStep2.getAxis();
263 if (cmp == 0)
264 {
265 cmp = compareStrings(processingInstructionNodeStep1.getName(), processingInstructionNodeStep2.getName());
266 if (cmp == 0)
267 {
268 cmp = compareLists(processingInstructionNodeStep1.getPredicates(), processingInstructionNodeStep2.getPredicates());
269 }
270 }
271 break;
272 case TYPE_RELATIONAL_EXPR:
273 RelationalExpr relationalExpr1 = (RelationalExpr)o1;
274 RelationalExpr relationalExpr2 = (RelationalExpr)o2;
275 cmp = relationalExpr1.getOperator().compareTo(relationalExpr2.getOperator());
276 if (cmp == 0)
277 {
278 cmp = compare(relationalExpr1.getLHS(), relationalExpr2.getLHS());
279 if (cmp == 0)
280 {
281 cmp = compare(relationalExpr1.getRHS(), relationalExpr2.getRHS());
282 }
283 }
284 break;
285 case TYPE_TEXT_NODE_STEP:
286 TextNodeStep textNodeStep1 = (TextNodeStep)o1;
287 TextNodeStep textNodeStep2 = (TextNodeStep)o2;
288 cmp = textNodeStep1.getAxis() - textNodeStep2.getAxis();
289 if (cmp == 0)
290 {
291 cmp = compareLists(textNodeStep1.getPredicates(), textNodeStep2.getPredicates());
292 }
293 break;
294 case TYPE_UNARY_EXPR:
295 UnaryExpr unaryExpr1 = (UnaryExpr)o1;
296 UnaryExpr unaryExpr2 = (UnaryExpr)o2;
297 cmp = compare(unaryExpr1.getExpr(), unaryExpr2.getExpr());
298 break;
299 case TYPE_UNION_EXPR:
300 if (true)
301 throw new RuntimeException("Not yet implemented!");
302 break;
303 case TYPE_VARIABLE_REFERENCE_EXPR:
304 VariableReferenceExpr variableReferenceExpr1 = (VariableReferenceExpr)o1;
305 VariableReferenceExpr variableReferenceExpr2 = (VariableReferenceExpr)o2;
306 cmp = compareStrings(variableReferenceExpr1.getPrefix(), variableReferenceExpr2.getPrefix());
307 if (cmp == 0)
308 {
309 cmp = variableReferenceExpr1.getVariableName().compareTo(variableReferenceExpr2.getVariableName());
310 }
311 break;
312 default:
313 throw new IllegalArgumentException("Unhandled type: " + type1);
314 }
315 }
316 else
317 {
318 cmp = type1 - type2;
319 }
320 return cmp;
321 }
322
323 private int compareStrings(String s1, String s2)
324 {
325 int cmp;
326 if (s1 == s2)
327 {
328 cmp = 0;
329 }
330 else if (s1 == null)
331 {
332 cmp = -1;
333 }
334 else if (s2 == null)
335 {
336 cmp = 1;
337 }
338 else
339 {
340 cmp = s1.compareTo(s2);
341 }
342 return cmp;
343 }
344
345 private int compareLists(List list1, List list2)
346 {
347 int cmp;
348 if (list1 == list2)
349 {
350 cmp = 0;
351 }
352 else if (list1 == null)
353 {
354 cmp = -1;
355 }
356 else if (list2 == null)
357 {
358 cmp = 1;
359 }
360 else
361 {
362 cmp = list1.size() - list2.size();
363 if (cmp == 0)
364 {
365 for (int i = 0; i < list1.size() && cmp == 0; i++)
366 {
367 cmp = compare(list1.get(i), list2.get(i));
368 }
369 }
370 }
371 return cmp;
372 }
373
374 private int getType(Object node)
375 {
376 if (node instanceof AdditiveExpr)
377 {
378 return TYPE_ADDITIVE_EXPR;
379 }
380 else if (node instanceof AllNodeStep)
381 {
382 return TYPE_ALL_NODE_STEP;
383 }
384 else if (node instanceof CommentNodeStep)
385 {
386 return TYPE_COMMENT_NODE_STEP;
387 }
388 else if (node instanceof EqualityExpr)
389 {
390 return TYPE_EQUALITY_EXPR;
391 }
392 else if (node instanceof FilterExpr)
393 {
394 return TYPE_FILTER_EXPR;
395 }
396 else if (node instanceof FunctionCallExpr)
397 {
398 return TYPE_FUNCTION_CALL_EXPR;
399 }
400 else if (node instanceof LiteralExpr)
401 {
402 return TYPE_LITERAL_EXPR;
403 }
404 else if (node instanceof LocationPath)
405 {
406 return TYPE_LOCATION_PATH;
407 }
408 else if (node instanceof LogicalExpr)
409 {
410 return TYPE_LOGICAL_EXP;
411 }
412 else if (node instanceof MultiplicativeExpr)
413 {
414 return TYPE_MULTIPLICATIVE_EXPR;
415 }
416 else if (node instanceof NameStep)
417 {
418 return TYPE_NAME_STEP;
419 }
420 else if (node instanceof NumberExpr)
421 {
422 return TYPE_NUMBER_EXPR;
423 }
424 else if (node instanceof PathExpr)
425 {
426 return TYPE_PATH_EXPR;
427 }
428 else if (node instanceof Predicate)
429 {
430 return TYPE_PREDICATE;
431 }
432 else if (node instanceof ProcessingInstructionNodeStep)
433 {
434 return TYPE_PROCESSING_INSTRUCTION_NODE_STEP;
435 }
436 else if (node instanceof RelationalExpr)
437 {
438 return TYPE_RELATIONAL_EXPR;
439 }
440 else if (node instanceof TextNodeStep)
441 {
442 return TYPE_TEXT_NODE_STEP;
443 }
444 else if (node instanceof UnaryExpr)
445 {
446 return TYPE_UNARY_EXPR;
447 }
448 else if (node instanceof UnionExpr)
449 {
450 return TYPE_UNION_EXPR;
451 }
452 else if (node instanceof VariableReferenceExpr)
453 {
454 return TYPE_VARIABLE_REFERENCE_EXPR;
455 }
456 else
457 {
458 throw new IllegalArgumentException("Unknown Jaxen AST node type: " + node);
459 }
460 }
461 }