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 }