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.Pointer;
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
35
36 public abstract class CoreOperationCompare extends CoreOperation {
37 private boolean invert;
38
39
40
41
42
43
44 public CoreOperationCompare(Expression arg1, Expression arg2) {
45 this(arg1, arg2, false);
46 }
47
48
49
50
51
52
53
54 protected CoreOperationCompare(Expression arg1, Expression arg2, boolean invert) {
55 super(new Expression[] { arg1, arg2 });
56 this.invert = invert;
57 }
58
59 public Object computeValue(EvalContext context) {
60 return equal(context, args[0], args[1]) ? Boolean.TRUE : Boolean.FALSE;
61 }
62
63 protected int getPrecedence() {
64 return COMPARE_PRECEDENCE;
65 }
66
67 protected boolean isSymmetric() {
68 return true;
69 }
70
71
72
73
74
75
76
77
78 protected boolean equal(EvalContext context, Expression left,
79 Expression right) {
80 Object l = left.compute(context);
81 Object r = right.compute(context);
82
83 if (l instanceof InitialContext) {
84 ((EvalContext) l).reset();
85 }
86
87 if (l instanceof SelfContext) {
88 l = ((EvalContext) l).getSingleNodePointer();
89 }
90
91 if (r instanceof InitialContext) {
92 ((EvalContext) r).reset();
93 }
94
95 if (r instanceof SelfContext) {
96 r = ((EvalContext) r).getSingleNodePointer();
97 }
98
99 if (l instanceof Collection) {
100 l = ((Collection) l).iterator();
101 }
102
103 if (r instanceof Collection) {
104 r = ((Collection) r).iterator();
105 }
106
107 if (l instanceof Iterator && r instanceof Iterator) {
108 return findMatch((Iterator) l, (Iterator) r);
109 }
110 if (l instanceof Iterator) {
111 return contains((Iterator) l, r);
112 }
113 if (r instanceof Iterator) {
114 return contains((Iterator) r, l);
115 }
116 return equal(l, r);
117 }
118
119
120
121
122
123
124
125 protected boolean contains(Iterator it, Object value) {
126 while (it.hasNext()) {
127 Object element = it.next();
128 if (equal(element, value)) {
129 return true;
130 }
131 }
132 return false;
133 }
134
135
136
137
138
139
140
141 protected boolean findMatch(Iterator lit, Iterator rit) {
142 HashSet left = new HashSet();
143 while (lit.hasNext()) {
144 left.add(lit.next());
145 }
146 while (rit.hasNext()) {
147 if (contains(left.iterator(), rit.next())) {
148 return true;
149 }
150 }
151 return false;
152 }
153
154
155
156
157
158
159
160 protected boolean equal(Object l, Object r) {
161 if (l instanceof Pointer) {
162 l = ((Pointer) l).getValue();
163 }
164
165 if (r instanceof Pointer) {
166 r = ((Pointer) r).getValue();
167 }
168
169 boolean result;
170 if (l instanceof Boolean || r instanceof Boolean) {
171 result = l == r || InfoSetUtil.booleanValue(l) == InfoSetUtil.booleanValue(r);
172 }
173 else if (l instanceof Number || r instanceof Number) {
174
175 double ld = InfoSetUtil.doubleValue(l);
176 if (Double.isNaN(ld)) {
177 return false;
178 }
179 double rd = InfoSetUtil.doubleValue(r);
180 if (Double.isNaN(rd)) {
181 return false;
182 }
183 result = ld == rd;
184 }
185 else {
186 if (l instanceof String || r instanceof String) {
187 l = InfoSetUtil.stringValue(l);
188 r = InfoSetUtil.stringValue(r);
189 }
190 result = l == r || l != null && l.equals(r);
191 }
192 return result ^ invert;
193 }
194
195 }