Example #1
0
  /**
   * Tell if two objects are functionally equal.
   *
   * @param obj2 Object to compare this to
   * @return true if the two objects are equal
   * @throws javax.xml.transform.TransformerException
   */
  public boolean equals(XObject obj2) {

    // In order to handle the 'all' semantics of
    // nodeset comparisons, we always call the
    // nodeset function.
    int t = obj2.getType();
    try {
      if (XObject.CLASS_NODESET == t) return obj2.equals(this);
      // If at least one object to be compared is a boolean, then each object
      // to be compared is converted to a boolean as if by applying the
      // boolean function.
      else if (XObject.CLASS_BOOLEAN == t) return obj2.bool() == bool();
      // Otherwise, if at least one object to be compared is a number, then each object
      // to be compared is converted to a number as if by applying the number function.
      else if (XObject.CLASS_NUMBER == t) return obj2.num() == num();
    } catch (javax.xml.transform.TransformerException te) {
      throw new com.sun.org.apache.xml.internal.utils.WrappedRuntimeException(te);
    }

    // Otherwise, both objects to be compared are converted to strings as
    // if by applying the string function.
    return xstr().equals(obj2.xstr());
  }
  /**
   * Tell if one object is less than the other.
   *
   * @param obj2 Object to compare this nodeset to
   * @param comparator Comparator to use
   * @return See the comments below for each object type comparison
   * @throws javax.xml.transform.TransformerException
   */
  public boolean compare(XObject obj2, Comparator comparator)
      throws javax.xml.transform.TransformerException {

    boolean result = false;
    int type = obj2.getType();

    if (XObject.CLASS_NODESET == type) {
      // %OPT% This should be XMLString based instead of string based...

      // From http://www.w3.org/TR/xpath:
      // If both objects to be compared are node-sets, then the comparison
      // will be true if and only if there is a node in the first node-set
      // and a node in the second node-set such that the result of performing
      // the comparison on the string-values of the two nodes is true.
      // Note this little gem from the draft:
      // NOTE: If $x is bound to a node-set, then $x="foo"
      // does not mean the same as not($x!="foo"): the former
      // is true if and only if some node in $x has the string-value
      // foo; the latter is true if and only if all nodes in $x have
      // the string-value foo.
      DTMIterator list1 = iterRaw();
      DTMIterator list2 = ((XNodeSet) obj2).iterRaw();
      int node1;
      java.util.Vector node2Strings = null;

      while (DTM.NULL != (node1 = list1.nextNode())) {
        XMLString s1 = getStringFromNode(node1);

        if (null == node2Strings) {
          int node2;

          while (DTM.NULL != (node2 = list2.nextNode())) {
            XMLString s2 = getStringFromNode(node2);

            if (comparator.compareStrings(s1, s2)) {
              result = true;

              break;
            }

            if (null == node2Strings) node2Strings = new java.util.Vector();

            node2Strings.addElement(s2);
          }
        } else {
          int n = node2Strings.size();

          for (int i = 0; i < n; i++) {
            if (comparator.compareStrings(s1, (XMLString) node2Strings.elementAt(i))) {
              result = true;

              break;
            }
          }
        }
      }
      list1.reset();
      list2.reset();
    } else if (XObject.CLASS_BOOLEAN == type) {

      // From http://www.w3.org/TR/xpath:
      // If one object to be compared is a node-set and the other is a boolean,
      // then the comparison will be true if and only if the result of
      // performing the comparison on the boolean and on the result of
      // converting the node-set to a boolean using the boolean function
      // is true.
      double num1 = bool() ? 1.0 : 0.0;
      double num2 = obj2.num();

      result = comparator.compareNumbers(num1, num2);
    } else if (XObject.CLASS_NUMBER == type) {

      // From http://www.w3.org/TR/xpath:
      // If one object to be compared is a node-set and the other is a number,
      // then the comparison will be true if and only if there is a
      // node in the node-set such that the result of performing the
      // comparison on the number to be compared and on the result of
      // converting the string-value of that node to a number using
      // the number function is true.
      DTMIterator list1 = iterRaw();
      double num2 = obj2.num();
      int node;

      while (DTM.NULL != (node = list1.nextNode())) {
        double num1 = getNumberFromNode(node);

        if (comparator.compareNumbers(num1, num2)) {
          result = true;

          break;
        }
      }
      list1.reset();
    } else if (XObject.CLASS_RTREEFRAG == type) {
      XMLString s2 = obj2.xstr();
      DTMIterator list1 = iterRaw();
      int node;

      while (DTM.NULL != (node = list1.nextNode())) {
        XMLString s1 = getStringFromNode(node);

        if (comparator.compareStrings(s1, s2)) {
          result = true;

          break;
        }
      }
      list1.reset();
    } else if (XObject.CLASS_STRING == type) {

      // From http://www.w3.org/TR/xpath:
      // If one object to be compared is a node-set and the other is a
      // string, then the comparison will be true if and only if there
      // is a node in the node-set such that the result of performing
      // the comparison on the string-value of the node and the other
      // string is true.
      XMLString s2 = obj2.xstr();
      DTMIterator list1 = iterRaw();
      int node;

      while (DTM.NULL != (node = list1.nextNode())) {
        XMLString s1 = getStringFromNode(node);
        if (comparator.compareStrings(s1, s2)) {
          result = true;

          break;
        }
      }
      list1.reset();
    } else {
      result = comparator.compareNumbers(this.num(), obj2.num());
    }

    return result;
  }