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