    1   /*
    2    * Copyright 2002-2004 The Apache Software Foundation
    3    *
    4    * Licensed under the Apache License, Version 2.0 (the "License");
    5    * you may not use this file except in compliance with the License.
    6    * You may obtain a copy of the License at
    7    *
    8    *     http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  package org.apache.commons.jxpath.ri.compiler;
    17
    18  import java.util.Collection;
    19  import java.util.HashSet;
    20  import java.util.Iterator;
    21
    22  import org.apache.commons.jxpath.Pointer;
    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   * Common superclass for the implementations of Expression for the operations
    30   * "=" and "!=".
    31   *
    32   * @author Dmitri Plotnikov
    33   * @version $Revision: 1.3 $ $Date: 2004/02/29 14:17:38 $
    34   */
    35  public abstract class CoreOperationCompare extends CoreOperation {
    36
    37      public CoreOperationCompare(Expression arg1, Expression arg2) {
    38          super(new Expression[] { arg1, arg2 });
    39      }
    40
    41      /***
    42       * Compares two values
    43       */
    44      protected boolean equal(
    45          EvalContext context,
    46          Expression left,
    47          Expression right)
    48      {
    49          Object l = left.compute(context);
    50          Object r = right.compute(context);
    51
    52  //        System.err.println("COMPARING: " +
    53  //            (l == null ? "null" : l.getClass().getName()) + " " +
    54  //            (r == null ? "null" : r.getClass().getName()));
    55
    56          if (l instanceof InitialContext || l instanceof SelfContext) {
    57              l = ((EvalContext) l).getSingleNodePointer();
    58          }
    59
    60          if (r instanceof InitialContext || r instanceof SelfContext) {
    61              r = ((EvalContext) r).getSingleNodePointer();
    62          }
    63
    64          if (l instanceof Collection) {
    65              l = ((Collection) l).iterator();
    66          }
    67
    68          if (r instanceof Collection) {
    69              r = ((Collection) r).iterator();
    70          }
    71
    72          if ((l instanceof Iterator) && !(r instanceof Iterator)) {
    73              return contains((Iterator) l, r);
    74          }
    75          else if (!(l instanceof Iterator) && (r instanceof Iterator)) {
    76              return contains((Iterator) r, l);
    77          }
    78          else if (l instanceof Iterator && r instanceof Iterator) {
    79              return findMatch((Iterator) l, (Iterator) r);
    80          }
    81
    82          return equal(l, r);
    83      }
    84
    85      protected boolean contains(Iterator it, Object value) {
    86          while (it.hasNext()) {
    87              Object element = it.next();
    88              if (equal(element, value)) {
    89                  return true;
    90              }
    91          }
    92          return false;
    93      }
    94
    95      protected boolean findMatch(Iterator lit, Iterator rit) {
    96          HashSet left = new HashSet();
    97          while (lit.hasNext()) {
    98              left.add(lit.next());
    99          }
    100         while (rit.hasNext()) {
    101             if (contains(left.iterator(), rit.next())) {
    102                 return true;
    103             }
    104         }
    105         return false;
    106     }
    107
    108     protected boolean equal(Object l, Object r) {
    109         if (l instanceof Pointer && r instanceof Pointer) {
    110             if (l.equals(r)) {
    111                 return true;
    112             }
    113         }
    114
    115         if (l instanceof Pointer) {
    116             l = ((Pointer) l).getValue();
    117         }
    118
    119         if (r instanceof Pointer) {
    120             r = ((Pointer) r).getValue();
    121         }
    122
    123         if (l == r) {
    124             return true;
    125         }
    126
    127 //        System.err.println("COMPARING VALUES: " + l + " " + r);
    128         if (l instanceof Boolean || r instanceof Boolean) {
    129             return (InfoSetUtil.booleanValue(l) == InfoSetUtil.booleanValue(r));
    130         }
    131         else if (l instanceof Number || r instanceof Number) {
    132             return (InfoSetUtil.doubleValue(l) == InfoSetUtil.doubleValue(r));
    133         }
    134         else if (l instanceof String || r instanceof String) {
    135             return (
    136                 InfoSetUtil.stringValue(l).equals(InfoSetUtil.stringValue(r)));
    137         }
    138         else if (l == null) {
    139             return r == null;
    140         }
    141         return l.equals(r);
    142     }
    143
    144 }