1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.jxpath.ri.compiler;
18
19 import java.util.Collection;
20 import java.util.HashSet;
21 import java.util.Iterator;
22
23 import org.apache.commons.jxpath.ri.EvalContext;
24 import org.apache.commons.jxpath.ri.InfoSetUtil;
25 import org.apache.commons.jxpath.ri.axes.InitialContext;
26 import org.apache.commons.jxpath.ri.axes.SelfContext;
27
28
29
30
31
32
33
34
35 public abstract class CoreOperationRelationalExpression extends CoreOperation {
36
37
38
39
40
41 protected CoreOperationRelationalExpression(Expression[] args) {
42 super(args);
43 }
44
45 public final Object computeValue(EvalContext context) {
46 return compute(args[0].compute(context), args[1].compute(context))
47 ? Boolean.TRUE : Boolean.FALSE;
48 }
49
50 protected final int getPrecedence() {
51 return RELATIONAL_EXPR_PRECEDENCE;
52 }
53
54 protected final boolean isSymmetric() {
55 return false;
56 }
57
58
59
60
61
62
63 protected abstract boolean evaluateCompare(int compare);
64
65
66
67
68
69
70
71 private boolean compute(Object left, Object right) {
72 left = reduce(left);
73 right = reduce(right);
74
75 if (left instanceof InitialContext) {
76 ((InitialContext) left).reset();
77 }
78 if (right instanceof InitialContext) {
79 ((InitialContext) right).reset();
80 }
81 if (left instanceof Iterator && right instanceof Iterator) {
82 return findMatch((Iterator) left, (Iterator) right);
83 }
84 if (left instanceof Iterator) {
85 return containsMatch((Iterator) left, right);
86 }
87 if (right instanceof Iterator) {
88 return containsMatch(left, (Iterator) right);
89 }
90 double ld = InfoSetUtil.doubleValue(left);
91 if (Double.isNaN(ld)) {
92 return false;
93 }
94 double rd = InfoSetUtil.doubleValue(right);
95 if (Double.isNaN(rd)) {
96 return false;
97 }
98 return evaluateCompare(ld == rd ? 0 : ld < rd ? -1 : 1);
99 }
100
101
102
103
104
105
106 private Object reduce(Object o) {
107 if (o instanceof SelfContext) {
108 o = ((EvalContext) o).getSingleNodePointer();
109 }
110 if (o instanceof Collection) {
111 o = ((Collection) o).iterator();
112 }
113 return o;
114 }
115
116
117
118
119
120
121
122 private boolean containsMatch(Iterator it, Object value) {
123 while (it.hasNext()) {
124 Object element = it.next();
125 if (compute(element, value)) {
126 return true;
127 }
128 }
129 return false;
130 }
131
132
133
134
135
136
137
138 private boolean containsMatch(Object value, Iterator it) {
139 while (it.hasNext()) {
140 Object element = it.next();
141 if (compute(value, element)) {
142 return true;
143 }
144 }
145 return false;
146 }
147
148
149
150
151
152
153
154 private boolean findMatch(Iterator lit, Iterator rit) {
155 HashSet left = new HashSet();
156 while (lit.hasNext()) {
157 left.add(lit.next());
158 }
159 while (rit.hasNext()) {
160 if (containsMatch(left.iterator(), rit.next())) {
161 return true;
162 }
163 }
164 return false;
165 }
166
167 }