286N/A/*
286N/A * reserved comment block
286N/A * DO NOT REMOVE OR ALTER!
286N/A */
286N/A/*
286N/A * Copyright 1999-2004 The Apache Software Foundation.
286N/A *
286N/A * Licensed under the Apache License, Version 2.0 (the "License");
286N/A * you may not use this file except in compliance with the License.
286N/A * You may obtain a copy of the License at
286N/A *
286N/A * http://www.apache.org/licenses/LICENSE-2.0
286N/A *
286N/A * Unless required by applicable law or agreed to in writing, software
286N/A * distributed under the License is distributed on an "AS IS" BASIS,
286N/A * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
286N/A * See the License for the specific language governing permissions and
286N/A * limitations under the License.
286N/A */
286N/A/*
286N/A * $Id: XNodeSet.java,v 1.2.4.2 2005/09/14 20:34:45 jeffsuttor Exp $
286N/A */
286N/Apackage com.sun.org.apache.xpath.internal.objects;
286N/A
286N/Aimport com.sun.org.apache.xml.internal.dtm.DTM;
286N/Aimport com.sun.org.apache.xml.internal.dtm.DTMIterator;
286N/Aimport com.sun.org.apache.xml.internal.dtm.DTMManager;
286N/Aimport com.sun.org.apache.xml.internal.utils.XMLString;
286N/Aimport com.sun.org.apache.xpath.internal.NodeSetDTM;
286N/Aimport com.sun.org.apache.xpath.internal.axes.NodeSequence;
286N/A
286N/Aimport org.w3c.dom.NodeList;
286N/Aimport org.w3c.dom.traversal.NodeIterator;
286N/A
286N/A/**
286N/A * This class represents an XPath nodeset object, and is capable of
286N/A * converting the nodeset to other types, such as a string.
286N/A * @xsl.usage general
286N/A */
286N/Apublic class XNodeSet extends NodeSequence
286N/A{
286N/A static final long serialVersionUID = 1916026368035639667L;
286N/A /**
286N/A * Default constructor for derived objects.
286N/A */
286N/A protected XNodeSet()
286N/A {
286N/A }
286N/A
286N/A /**
286N/A * Construct a XNodeSet object.
286N/A *
286N/A * @param val Value of the XNodeSet object
286N/A */
286N/A public XNodeSet(DTMIterator val)
286N/A {
286N/A super();
286N/A if(val instanceof XNodeSet)
286N/A {
286N/A final XNodeSet nodeSet = (XNodeSet) val;
286N/A setIter(nodeSet.m_iter);
286N/A m_dtmMgr = nodeSet.m_dtmMgr;
286N/A m_last = nodeSet.m_last;
286N/A // First make sure the DTMIterator val has a cache,
286N/A // so if it doesn't have one, make one.
286N/A if(!nodeSet.hasCache())
286N/A nodeSet.setShouldCacheNodes(true);
286N/A
286N/A // Get the cache from val and use it ourselves (we share it).
286N/A setObject(nodeSet.getIteratorCache());
286N/A }
286N/A else
286N/A setIter(val);
286N/A }
286N/A
286N/A /**
286N/A * Construct a XNodeSet object.
286N/A *
286N/A * @param val Value of the XNodeSet object
286N/A */
286N/A public XNodeSet(XNodeSet val)
286N/A {
286N/A super();
286N/A setIter(val.m_iter);
286N/A m_dtmMgr = val.m_dtmMgr;
286N/A m_last = val.m_last;
286N/A if(!val.hasCache())
286N/A val.setShouldCacheNodes(true);
286N/A setObject(val.m_obj);
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Construct an empty XNodeSet object. This is used to create a mutable
286N/A * nodeset to which random nodes may be added.
286N/A */
286N/A public XNodeSet(DTMManager dtmMgr)
286N/A {
286N/A this(DTM.NULL,dtmMgr);
286N/A }
286N/A
286N/A /**
286N/A * Construct a XNodeSet object for one node.
286N/A *
286N/A * @param n Node to add to the new XNodeSet object
286N/A */
286N/A public XNodeSet(int n, DTMManager dtmMgr)
286N/A {
286N/A
286N/A super(new NodeSetDTM(dtmMgr));
286N/A m_dtmMgr = dtmMgr;
286N/A
286N/A if (DTM.NULL != n)
286N/A {
286N/A ((NodeSetDTM) m_obj).addNode(n);
286N/A m_last = 1;
286N/A }
286N/A else
286N/A m_last = 0;
286N/A }
286N/A
286N/A /**
286N/A * Tell that this is a CLASS_NODESET.
286N/A *
286N/A * @return type CLASS_NODESET
286N/A */
286N/A public int getType()
286N/A {
286N/A return CLASS_NODESET;
286N/A }
286N/A
286N/A /**
286N/A * Given a request type, return the equivalent string.
286N/A * For diagnostic purposes.
286N/A *
286N/A * @return type string "#NODESET"
286N/A */
286N/A public String getTypeString()
286N/A {
286N/A return "#NODESET";
286N/A }
286N/A
286N/A /**
286N/A * Get numeric value of the string conversion from a single node.
286N/A *
286N/A * @param n Node to convert
286N/A *
286N/A * @return numeric value of the string conversion from a single node.
286N/A */
286N/A public double getNumberFromNode(int n)
286N/A {
286N/A XMLString xstr = m_dtmMgr.getDTM(n).getStringValue(n);
286N/A return xstr.toDouble();
286N/A }
286N/A
286N/A /**
286N/A * Cast result object to a number.
286N/A *
286N/A * @return numeric value of the string conversion from the
286N/A * next node in the NodeSetDTM, or NAN if no node was found
286N/A */
286N/A public double num()
286N/A {
286N/A
286N/A int node = item(0);
286N/A return (node != DTM.NULL) ? getNumberFromNode(node) : Double.NaN;
286N/A }
286N/A
286N/A /**
286N/A * Cast result object to a number, but allow side effects, such as the
286N/A * incrementing of an iterator.
286N/A *
286N/A * @return numeric value of the string conversion from the
286N/A * next node in the NodeSetDTM, or NAN if no node was found
286N/A */
286N/A public double numWithSideEffects()
286N/A {
286N/A int node = nextNode();
286N/A
286N/A return (node != DTM.NULL) ? getNumberFromNode(node) : Double.NaN;
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Cast result object to a boolean.
286N/A *
286N/A * @return True if there is a next node in the nodeset
286N/A */
286N/A public boolean bool()
286N/A {
286N/A return (item(0) != DTM.NULL);
286N/A }
286N/A
286N/A /**
286N/A * Cast result object to a boolean, but allow side effects, such as the
286N/A * incrementing of an iterator.
286N/A *
286N/A * @return True if there is a next node in the nodeset
286N/A */
286N/A public boolean boolWithSideEffects()
286N/A {
286N/A return (nextNode() != DTM.NULL);
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Get the string conversion from a single node.
286N/A *
286N/A * @param n Node to convert
286N/A *
286N/A * @return the string conversion from a single node.
286N/A */
286N/A public XMLString getStringFromNode(int n)
286N/A {
286N/A // %OPT%
286N/A // I guess we'll have to get a static instance of the DTM manager...
286N/A if(DTM.NULL != n)
286N/A {
286N/A return m_dtmMgr.getDTM(n).getStringValue(n);
286N/A }
286N/A else
286N/A {
286N/A return com.sun.org.apache.xpath.internal.objects.XString.EMPTYSTRING;
286N/A }
286N/A }
286N/A
286N/A /**
286N/A * Directly call the
286N/A * characters method on the passed ContentHandler for the
286N/A * string-value. Multiple calls to the
286N/A * ContentHandler's characters methods may well occur for a single call to
286N/A * this method.
286N/A *
286N/A * @param ch A non-null reference to a ContentHandler.
286N/A *
286N/A * @throws org.xml.sax.SAXException
286N/A */
286N/A public void dispatchCharactersEvents(org.xml.sax.ContentHandler ch)
286N/A throws org.xml.sax.SAXException
286N/A {
286N/A int node = item(0);
286N/A
286N/A if(node != DTM.NULL)
286N/A {
286N/A m_dtmMgr.getDTM(node).dispatchCharactersEvents(node, ch, false);
286N/A }
286N/A
286N/A }
286N/A
286N/A /**
286N/A * Cast result object to an XMLString.
286N/A *
286N/A * @return The document fragment node data or the empty string.
286N/A */
286N/A public XMLString xstr()
286N/A {
286N/A int node = item(0);
286N/A return (node != DTM.NULL) ? getStringFromNode(node) : XString.EMPTYSTRING;
286N/A }
286N/A
286N/A /**
286N/A * Cast result object to a string.
286N/A *
286N/A * @return The string this wraps or the empty string if null
286N/A */
286N/A public void appendToFsb(com.sun.org.apache.xml.internal.utils.FastStringBuffer fsb)
286N/A {
286N/A XString xstring = (XString)xstr();
286N/A xstring.appendToFsb(fsb);
286N/A }
286N/A
286N/A
286N/A /**
286N/A * Cast result object to a string.
286N/A *
286N/A * @return the string conversion from the next node in the nodeset
286N/A * or "" if there is no next node
286N/A */
286N/A public String str()
286N/A {
286N/A int node = item(0);
286N/A return (node != DTM.NULL) ? getStringFromNode(node).toString() : "";
286N/A }
286N/A
286N/A /**
286N/A * Return a java object that's closest to the representation
286N/A * that should be handed to an extension.
286N/A *
286N/A * @return The object that this class wraps
286N/A */
286N/A public Object object()
286N/A {
286N/A if(null == m_obj)
286N/A return this;
286N/A else
286N/A return m_obj;
286N/A }
286N/A
286N/A // %REVIEW%
286N/A // hmmm...
286N/A// /**
286N/A// * Cast result object to a result tree fragment.
286N/A// *
286N/A// * @param support The XPath context to use for the conversion
286N/A// *
286N/A// * @return the nodeset as a result tree fragment.
286N/A// */
286N/A// public DocumentFragment rtree(XPathContext support)
286N/A// {
286N/A// DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
286N/A// DocumentBuilder db = dbf.newDocumentBuilder();
286N/A// Document myDoc = db.newDocument();
286N/A//
286N/A// DocumentFragment docFrag = myDoc.createDocumentFragment();
286N/A//
286N/A// DTMIterator nl = iter();
286N/A// int node;
286N/A//
286N/A// while (DTM.NULL != (node = nl.nextNode()))
286N/A// {
286N/A// frag.appendChild(node, true, true);
286N/A// }
286N/A//
286N/A// return frag.getDocument();
286N/A// }
286N/A
286N/A /**
286N/A * Cast result object to a nodelist.
286N/A *
286N/A * @return a NodeIterator.
286N/A *
286N/A * @throws javax.xml.transform.TransformerException
286N/A */
286N/A public NodeIterator nodeset() throws javax.xml.transform.TransformerException
286N/A {
286N/A return new com.sun.org.apache.xml.internal.dtm.ref.DTMNodeIterator(iter());
286N/A }
286N/A
286N/A /**
286N/A * Cast result object to a nodelist.
286N/A *
286N/A * @return a NodeList.
286N/A *
286N/A * @throws javax.xml.transform.TransformerException
286N/A */
286N/A public NodeList nodelist() throws javax.xml.transform.TransformerException
286N/A {
286N/A com.sun.org.apache.xml.internal.dtm.ref.DTMNodeList nodelist = new com.sun.org.apache.xml.internal.dtm.ref.DTMNodeList(this);
286N/A // Creating a DTMNodeList has the side-effect that it will create a clone
286N/A // XNodeSet with cache and run m_iter to the end. You cannot get any node
286N/A // from m_iter after this call. As a fix, we call SetVector() on the clone's
286N/A // cache. See Bugzilla 14406.
286N/A XNodeSet clone = (XNodeSet)nodelist.getDTMIterator();
286N/A SetVector(clone.getVector());
286N/A return nodelist;
286N/A }
286N/A
286N/A
286N/A// /**
286N/A// * Return a java object that's closest to the representation
286N/A// * that should be handed to an extension.
286N/A// *
286N/A// * @return The object that this class wraps
286N/A// */
286N/A// public Object object()
286N/A// {
286N/A// return new com.sun.org.apache.xml.internal.dtm.ref.DTMNodeList(iter());
286N/A// }
286N/A
286N/A /**
286N/A * Return the iterator without cloning, etc.
286N/A */
286N/A public DTMIterator iterRaw()
286N/A {
286N/A return this;
286N/A }
286N/A
286N/A public void release(DTMIterator iter)
286N/A {
286N/A }
286N/A
286N/A /**
286N/A * Cast result object to a nodelist.
286N/A *
286N/A * @return The nodeset as a nodelist
286N/A */
286N/A public DTMIterator iter()
286N/A {
286N/A try
286N/A {
286N/A if(hasCache())
286N/A return cloneWithReset();
286N/A else
286N/A return this; // don't bother to clone... won't do any good!
286N/A }
286N/A catch (CloneNotSupportedException cnse)
286N/A {
286N/A throw new RuntimeException(cnse.getMessage());
286N/A }
286N/A }
286N/A
286N/A /**
286N/A * Get a fresh copy of the object. For use with variables.
286N/A *
286N/A * @return A fresh nodelist.
286N/A */
286N/A public XObject getFresh()
286N/A {
286N/A try
286N/A {
286N/A if(hasCache())
286N/A return (XObject)cloneWithReset();
286N/A else
286N/A return this; // don't bother to clone... won't do any good!
286N/A }
286N/A catch (CloneNotSupportedException cnse)
286N/A {
286N/A throw new RuntimeException(cnse.getMessage());
286N/A }
286N/A }
286N/A
286N/A /**
286N/A * Cast result object to a mutableNodeset.
286N/A *
286N/A * @return The nodeset as a mutableNodeset
286N/A */
286N/A public NodeSetDTM mutableNodeset()
286N/A {
286N/A NodeSetDTM mnl;
286N/A
286N/A if(m_obj instanceof NodeSetDTM)
286N/A {
286N/A mnl = (NodeSetDTM) m_obj;
286N/A }
286N/A else
286N/A {
286N/A mnl = new NodeSetDTM(iter());
286N/A setObject(mnl);
286N/A setCurrentPos(0);
286N/A }
286N/A
286N/A return mnl;
286N/A }
286N/A
286N/A /** Less than comparator */
286N/A static final LessThanComparator S_LT = new LessThanComparator();
286N/A
286N/A /** Less than or equal comparator */
286N/A static final LessThanOrEqualComparator S_LTE = new LessThanOrEqualComparator();
286N/A
286N/A /** Greater than comparator */
286N/A static final GreaterThanComparator S_GT = new GreaterThanComparator();
286N/A
286N/A /** Greater than or equal comparator */
286N/A static final GreaterThanOrEqualComparator S_GTE =
286N/A new GreaterThanOrEqualComparator();
286N/A
286N/A /** Equal comparator */
286N/A static final EqualComparator S_EQ = new EqualComparator();
286N/A
286N/A /** Not equal comparator */
286N/A static final NotEqualComparator S_NEQ = new NotEqualComparator();
286N/A
286N/A /**
286N/A * Tell if one object is less than the other.
286N/A *
286N/A * @param obj2 Object to compare this nodeset to
286N/A * @param comparator Comparator to use
286N/A *
286N/A * @return See the comments below for each object type comparison
286N/A *
286N/A * @throws javax.xml.transform.TransformerException
286N/A */
286N/A public boolean compare(XObject obj2, Comparator comparator)
286N/A throws javax.xml.transform.TransformerException
286N/A {
286N/A
286N/A boolean result = false;
286N/A int type = obj2.getType();
286N/A
286N/A if (XObject.CLASS_NODESET == type)
286N/A {
286N/A // %OPT% This should be XMLString based instead of string based...
286N/A
286N/A // From http://www.w3.org/TR/xpath:
286N/A // If both objects to be compared are node-sets, then the comparison
286N/A // will be true if and only if there is a node in the first node-set
286N/A // and a node in the second node-set such that the result of performing
286N/A // the comparison on the string-values of the two nodes is true.
286N/A // Note this little gem from the draft:
286N/A // NOTE: If $x is bound to a node-set, then $x="foo"
286N/A // does not mean the same as not($x!="foo"): the former
286N/A // is true if and only if some node in $x has the string-value
286N/A // foo; the latter is true if and only if all nodes in $x have
286N/A // the string-value foo.
286N/A DTMIterator list1 = iterRaw();
286N/A DTMIterator list2 = ((XNodeSet) obj2).iterRaw();
286N/A int node1;
286N/A java.util.Vector node2Strings = null;
286N/A
286N/A while (DTM.NULL != (node1 = list1.nextNode()))
286N/A {
286N/A XMLString s1 = getStringFromNode(node1);
286N/A
286N/A if (null == node2Strings)
286N/A {
286N/A int node2;
286N/A
286N/A while (DTM.NULL != (node2 = list2.nextNode()))
286N/A {
286N/A XMLString s2 = getStringFromNode(node2);
286N/A
286N/A if (comparator.compareStrings(s1, s2))
286N/A {
286N/A result = true;
286N/A
286N/A break;
286N/A }
286N/A
286N/A if (null == node2Strings)
286N/A node2Strings = new java.util.Vector();
286N/A
286N/A node2Strings.addElement(s2);
286N/A }
286N/A }
286N/A else
286N/A {
286N/A int n = node2Strings.size();
286N/A
286N/A for (int i = 0; i < n; i++)
286N/A {
286N/A if (comparator.compareStrings(s1, (XMLString)node2Strings.elementAt(i)))
286N/A {
286N/A result = true;
286N/A
286N/A break;
286N/A }
286N/A }
286N/A }
286N/A }
286N/A list1.reset();
286N/A list2.reset();
286N/A }
286N/A else if (XObject.CLASS_BOOLEAN == type)
286N/A {
286N/A
286N/A // From http://www.w3.org/TR/xpath:
286N/A // If one object to be compared is a node-set and the other is a boolean,
286N/A // then the comparison will be true if and only if the result of
286N/A // performing the comparison on the boolean and on the result of
286N/A // converting the node-set to a boolean using the boolean function
286N/A // is true.
286N/A double num1 = bool() ? 1.0 : 0.0;
286N/A double num2 = obj2.num();
286N/A
286N/A result = comparator.compareNumbers(num1, num2);
286N/A }
286N/A else if (XObject.CLASS_NUMBER == type)
286N/A {
286N/A
286N/A // From http://www.w3.org/TR/xpath:
286N/A // If one object to be compared is a node-set and the other is a number,
286N/A // then the comparison will be true if and only if there is a
286N/A // node in the node-set such that the result of performing the
286N/A // comparison on the number to be compared and on the result of
286N/A // converting the string-value of that node to a number using
286N/A // the number function is true.
286N/A DTMIterator list1 = iterRaw();
286N/A double num2 = obj2.num();
286N/A int node;
286N/A
286N/A while (DTM.NULL != (node = list1.nextNode()))
286N/A {
286N/A double num1 = getNumberFromNode(node);
286N/A
286N/A if (comparator.compareNumbers(num1, num2))
286N/A {
286N/A result = true;
286N/A
286N/A break;
286N/A }
286N/A }
286N/A list1.reset();
286N/A }
286N/A else if (XObject.CLASS_RTREEFRAG == type)
286N/A {
286N/A XMLString s2 = obj2.xstr();
286N/A DTMIterator list1 = iterRaw();
286N/A int node;
286N/A
286N/A while (DTM.NULL != (node = list1.nextNode()))
286N/A {
286N/A XMLString s1 = getStringFromNode(node);
286N/A
286N/A if (comparator.compareStrings(s1, s2))
286N/A {
286N/A result = true;
286N/A
286N/A break;
286N/A }
286N/A }
286N/A list1.reset();
286N/A }
286N/A else if (XObject.CLASS_STRING == type)
286N/A {
286N/A
286N/A // From http://www.w3.org/TR/xpath:
286N/A // If one object to be compared is a node-set and the other is a
286N/A // string, then the comparison will be true if and only if there
286N/A // is a node in the node-set such that the result of performing
286N/A // the comparison on the string-value of the node and the other
286N/A // string is true.
286N/A XMLString s2 = obj2.xstr();
286N/A DTMIterator list1 = iterRaw();
286N/A int node;
286N/A
286N/A while (DTM.NULL != (node = list1.nextNode()))
286N/A {
286N/A XMLString s1 = getStringFromNode(node);
286N/A if (comparator.compareStrings(s1, s2))
286N/A {
286N/A result = true;
286N/A
286N/A break;
286N/A }
286N/A }
286N/A list1.reset();
286N/A }
286N/A else
286N/A {
286N/A result = comparator.compareNumbers(this.num(), obj2.num());
286N/A }
286N/A
286N/A return result;
286N/A }
286N/A
286N/A /**
286N/A * Tell if one object is less than the other.
286N/A *
286N/A * @param obj2 object to compare this nodeset to
286N/A *
286N/A * @return see this.compare(...)
286N/A *
286N/A * @throws javax.xml.transform.TransformerException
286N/A */
286N/A public boolean lessThan(XObject obj2) throws javax.xml.transform.TransformerException
286N/A {
286N/A return compare(obj2, S_LT);
286N/A }
286N/A
286N/A /**
286N/A * Tell if one object is less than or equal to the other.
286N/A *
286N/A * @param obj2 object to compare this nodeset to
286N/A *
286N/A * @return see this.compare(...)
286N/A *
286N/A * @throws javax.xml.transform.TransformerException
286N/A */
286N/A public boolean lessThanOrEqual(XObject obj2) throws javax.xml.transform.TransformerException
286N/A {
286N/A return compare(obj2, S_LTE);
286N/A }
286N/A
286N/A /**
286N/A * Tell if one object is less than the other.
286N/A *
286N/A * @param obj2 object to compare this nodeset to
286N/A *
286N/A * @return see this.compare(...)
286N/A *
286N/A * @throws javax.xml.transform.TransformerException
286N/A */
286N/A public boolean greaterThan(XObject obj2) throws javax.xml.transform.TransformerException
286N/A {
286N/A return compare(obj2, S_GT);
286N/A }
286N/A
286N/A /**
286N/A * Tell if one object is less than the other.
286N/A *
286N/A * @param obj2 object to compare this nodeset to
286N/A *
286N/A * @return see this.compare(...)
286N/A *
286N/A * @throws javax.xml.transform.TransformerException
286N/A */
286N/A public boolean greaterThanOrEqual(XObject obj2)
286N/A throws javax.xml.transform.TransformerException
286N/A {
286N/A return compare(obj2, S_GTE);
286N/A }
286N/A
286N/A /**
286N/A * Tell if two objects are functionally equal.
286N/A *
286N/A * @param obj2 object to compare this nodeset to
286N/A *
286N/A * @return see this.compare(...)
286N/A *
286N/A * @throws javax.xml.transform.TransformerException
286N/A */
286N/A public boolean equals(XObject obj2)
286N/A {
286N/A try
286N/A {
286N/A return compare(obj2, S_EQ);
286N/A }
286N/A catch(javax.xml.transform.TransformerException te)
286N/A {
286N/A throw new com.sun.org.apache.xml.internal.utils.WrappedRuntimeException(te);
286N/A }
286N/A }
286N/A
286N/A /**
286N/A * Tell if two objects are functionally not equal.
286N/A *
286N/A * @param obj2 object to compare this nodeset to
286N/A *
286N/A * @return see this.compare(...)
286N/A *
286N/A * @throws javax.xml.transform.TransformerException
286N/A */
286N/A public boolean notEquals(XObject obj2) throws javax.xml.transform.TransformerException
286N/A {
286N/A return compare(obj2, S_NEQ);
286N/A }
286N/A}
286N/A
286N/A/**
286N/A * compares nodes for various boolean operations.
286N/A */
286N/Aabstract class Comparator
286N/A{
286N/A
286N/A /**
286N/A * Compare two strings
286N/A *
286N/A *
286N/A * @param s1 First string to compare
286N/A * @param s2 Second String to compare
286N/A *
286N/A * @return Whether the strings are equal or not
286N/A */
286N/A abstract boolean compareStrings(XMLString s1, XMLString s2);
286N/A
286N/A /**
286N/A * Compare two numbers
286N/A *
286N/A *
286N/A * @param n1 First number to compare
286N/A * @param n2 Second number to compare
286N/A *
286N/A * @return Whether the numbers are equal or not
286N/A */
286N/A abstract boolean compareNumbers(double n1, double n2);
286N/A}
286N/A
286N/A/**
286N/A * Compare strings or numbers for less than.
286N/A */
286N/Aclass LessThanComparator extends Comparator
286N/A{
286N/A
286N/A /**
286N/A * Compare two strings for less than.
286N/A *
286N/A *
286N/A * @param s1 First string to compare
286N/A * @param s2 Second String to compare
286N/A *
286N/A * @return True if s1 is less than s2
286N/A */
286N/A boolean compareStrings(XMLString s1, XMLString s2)
286N/A {
286N/A return (s1.toDouble() < s2.toDouble());
286N/A // return s1.compareTo(s2) < 0;
286N/A }
286N/A
286N/A /**
286N/A * Compare two numbers for less than.
286N/A *
286N/A *
286N/A * @param n1 First number to compare
286N/A * @param n2 Second number to compare
286N/A *
286N/A * @return true if n1 is less than n2
286N/A */
286N/A boolean compareNumbers(double n1, double n2)
286N/A {
286N/A return n1 < n2;
286N/A }
286N/A}
286N/A
286N/A/**
286N/A * Compare strings or numbers for less than or equal.
286N/A */
286N/Aclass LessThanOrEqualComparator extends Comparator
286N/A{
286N/A
286N/A /**
286N/A * Compare two strings for less than or equal.
286N/A *
286N/A *
286N/A * @param s1 First string to compare
286N/A * @param s2 Second String to compare
286N/A *
286N/A * @return true if s1 is less than or equal to s2
286N/A */
286N/A boolean compareStrings(XMLString s1, XMLString s2)
286N/A {
286N/A return (s1.toDouble() <= s2.toDouble());
286N/A // return s1.compareTo(s2) <= 0;
286N/A }
286N/A
286N/A /**
286N/A * Compare two numbers for less than or equal.
286N/A *
286N/A *
286N/A * @param n1 First number to compare
286N/A * @param n2 Second number to compare
286N/A *
286N/A * @return true if n1 is less than or equal to n2
286N/A */
286N/A boolean compareNumbers(double n1, double n2)
286N/A {
286N/A return n1 <= n2;
286N/A }
286N/A}
286N/A
286N/A/**
286N/A * Compare strings or numbers for greater than.
286N/A */
286N/Aclass GreaterThanComparator extends Comparator
286N/A{
286N/A
286N/A /**
286N/A * Compare two strings for greater than.
286N/A *
286N/A *
286N/A * @param s1 First string to compare
286N/A * @param s2 Second String to compare
286N/A *
286N/A * @return true if s1 is greater than s2
286N/A */
286N/A boolean compareStrings(XMLString s1, XMLString s2)
286N/A {
286N/A return (s1.toDouble() > s2.toDouble());
286N/A // return s1.compareTo(s2) > 0;
286N/A }
286N/A
286N/A /**
286N/A * Compare two numbers for greater than.
286N/A *
286N/A *
286N/A * @param n1 First number to compare
286N/A * @param n2 Second number to compare
286N/A *
286N/A * @return true if n1 is greater than n2
286N/A */
286N/A boolean compareNumbers(double n1, double n2)
286N/A {
286N/A return n1 > n2;
286N/A }
286N/A}
286N/A
286N/A/**
286N/A * Compare strings or numbers for greater than or equal.
286N/A */
286N/Aclass GreaterThanOrEqualComparator extends Comparator
286N/A{
286N/A
286N/A /**
286N/A * Compare two strings for greater than or equal.
286N/A *
286N/A *
286N/A * @param s1 First string to compare
286N/A * @param s2 Second String to compare
286N/A *
286N/A * @return true if s1 is greater than or equal to s2
286N/A */
286N/A boolean compareStrings(XMLString s1, XMLString s2)
286N/A {
286N/A return (s1.toDouble() >= s2.toDouble());
286N/A // return s1.compareTo(s2) >= 0;
286N/A }
286N/A
286N/A /**
286N/A * Compare two numbers for greater than or equal.
286N/A *
286N/A *
286N/A * @param n1 First number to compare
286N/A * @param n2 Second number to compare
286N/A *
286N/A * @return true if n1 is greater than or equal to n2
286N/A */
286N/A boolean compareNumbers(double n1, double n2)
286N/A {
286N/A return n1 >= n2;
286N/A }
286N/A}
286N/A
286N/A/**
286N/A * Compare strings or numbers for equality.
286N/A */
286N/Aclass EqualComparator extends Comparator
286N/A{
286N/A
286N/A /**
286N/A * Compare two strings for equality.
286N/A *
286N/A *
286N/A * @param s1 First string to compare
286N/A * @param s2 Second String to compare
286N/A *
286N/A * @return true if s1 is equal to s2
286N/A */
286N/A boolean compareStrings(XMLString s1, XMLString s2)
286N/A {
286N/A return s1.equals(s2);
286N/A }
286N/A
286N/A /**
286N/A * Compare two numbers for equality.
286N/A *
286N/A *
286N/A * @param n1 First number to compare
286N/A * @param n2 Second number to compare
286N/A *
286N/A * @return true if n1 is equal to n2
286N/A */
286N/A boolean compareNumbers(double n1, double n2)
286N/A {
286N/A return n1 == n2;
286N/A }
286N/A}
286N/A
286N/A/**
286N/A * Compare strings or numbers for non-equality.
286N/A */
286N/Aclass NotEqualComparator extends Comparator
286N/A{
286N/A
286N/A /**
286N/A * Compare two strings for non-equality.
286N/A *
286N/A *
286N/A * @param s1 First string to compare
286N/A * @param s2 Second String to compare
286N/A *
286N/A * @return true if s1 is not equal to s2
286N/A */
286N/A boolean compareStrings(XMLString s1, XMLString s2)
286N/A {
286N/A return !s1.equals(s2);
286N/A }
286N/A
286N/A /**
286N/A * Compare two numbers for non-equality.
286N/A *
286N/A *
286N/A * @param n1 First number to compare
286N/A * @param n2 Second number to compare
286N/A *
286N/A * @return true if n1 is not equal to n2
286N/A */
286N/A boolean compareNumbers(double n1, double n2)
286N/A {
286N/A return n1 != n2;
286N/A }
286N/A}