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