KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xpath > internal > objects > XNodeSet


1 /*
2  * Copyright 1999-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 /*
17  * $Id: XNodeSet.java,v 1.28 2004/02/17 04:34:38 minchau Exp $
18  */

19 package com.sun.org.apache.xpath.internal.objects;
20
21 import com.sun.org.apache.xml.internal.dtm.DTM;
22 import com.sun.org.apache.xml.internal.dtm.DTMIterator;
23 import com.sun.org.apache.xml.internal.dtm.DTMManager;
24 import com.sun.org.apache.xml.internal.utils.XMLString;
25 import com.sun.org.apache.xpath.internal.NodeSetDTM;
26 import com.sun.org.apache.xpath.internal.axes.NodeSequence;
27
28 import org.w3c.dom.NodeList JavaDoc;
29 import org.w3c.dom.traversal.NodeIterator;
30
31 /**
32  * This class represents an XPath nodeset object, and is capable of
33  * converting the nodeset to other types, such as a string.
34  * @xsl.usage general
35  */

36 public class XNodeSet extends NodeSequence
37 {
38   /**
39    * Default constructor for derived objects.
40    */

41   protected XNodeSet()
42   {
43   }
44
45   /**
46    * Construct a XNodeSet object.
47    *
48    * @param val Value of the XNodeSet object
49    */

50   public XNodeSet(DTMIterator val)
51   {
52     super();
53     if(val instanceof XNodeSet)
54     {
55         setIter(((XNodeSet)val).m_iter);
56         m_dtmMgr = ((XNodeSet)val).m_dtmMgr;
57         m_last = ((XNodeSet)val).m_last;
58         if(!((XNodeSet)val).hasCache())
59             ((XNodeSet)val).setShouldCacheNodes(true);
60         m_obj = ((XNodeSet)val).m_obj;
61     }
62     else
63         setIter(val);
64   }
65   
66   /**
67    * Construct a XNodeSet object.
68    *
69    * @param val Value of the XNodeSet object
70    */

71   public XNodeSet(XNodeSet val)
72   {
73     super();
74     setIter(val.m_iter);
75     m_dtmMgr = val.m_dtmMgr;
76     m_last = val.m_last;
77     if(!val.hasCache())
78         val.setShouldCacheNodes(true);
79     m_obj = val.m_obj;
80   }
81
82
83   /**
84    * Construct an empty XNodeSet object. This is used to create a mutable
85    * nodeset to which random nodes may be added.
86    */

87   public XNodeSet(DTMManager dtmMgr)
88   {
89      this(DTM.NULL,dtmMgr);
90   }
91
92   /**
93    * Construct a XNodeSet object for one node.
94    *
95    * @param n Node to add to the new XNodeSet object
96    */

97   public XNodeSet(int n, DTMManager dtmMgr)
98   {
99
100     super(new NodeSetDTM(dtmMgr));
101     m_dtmMgr = dtmMgr;
102
103     if (DTM.NULL != n)
104     {
105       ((NodeSetDTM) m_obj).addNode(n);
106       m_last = 1;
107     }
108     else
109         m_last = 0;
110   }
111
112   /**
113    * Tell that this is a CLASS_NODESET.
114    *
115    * @return type CLASS_NODESET
116    */

117   public int getType()
118   {
119     return CLASS_NODESET;
120   }
121
122   /**
123    * Given a request type, return the equivalent string.
124    * For diagnostic purposes.
125    *
126    * @return type string "#NODESET"
127    */

128   public String JavaDoc getTypeString()
129   {
130     return "#NODESET";
131   }
132
133   /**
134    * Get numeric value of the string conversion from a single node.
135    *
136    * @param n Node to convert
137    *
138    * @return numeric value of the string conversion from a single node.
139    */

140   public double getNumberFromNode(int n)
141   {
142     XMLString xstr = m_dtmMgr.getDTM(n).getStringValue(n);
143     return xstr.toDouble();
144   }
145
146   /**
147    * Cast result object to a number.
148    *
149    * @return numeric value of the string conversion from the
150    * next node in the NodeSetDTM, or NAN if no node was found
151    */

152   public double num()
153   {
154
155     int node = item(0);
156     return (node != DTM.NULL) ? getNumberFromNode(node) : Double.NaN;
157   }
158   
159   /**
160    * Cast result object to a number, but allow side effects, such as the
161    * incrementing of an iterator.
162    *
163    * @return numeric value of the string conversion from the
164    * next node in the NodeSetDTM, or NAN if no node was found
165    */

166   public double numWithSideEffects()
167   {
168     int node = nextNode();
169
170     return (node != DTM.NULL) ? getNumberFromNode(node) : Double.NaN;
171   }
172
173
174   /**
175    * Cast result object to a boolean.
176    *
177    * @return True if there is a next node in the nodeset
178    */

179   public boolean bool()
180   {
181     return (item(0) != DTM.NULL);
182   }
183   
184   /**
185    * Cast result object to a boolean, but allow side effects, such as the
186    * incrementing of an iterator.
187    *
188    * @return True if there is a next node in the nodeset
189    */

190   public boolean boolWithSideEffects()
191   {
192     return (nextNode() != DTM.NULL);
193   }
194
195   
196   /**
197    * Get the string conversion from a single node.
198    *
199    * @param n Node to convert
200    *
201    * @return the string conversion from a single node.
202    */

203   public XMLString getStringFromNode(int n)
204   {
205     // %OPT%
206
// I guess we'll have to get a static instance of the DTM manager...
207
if(DTM.NULL != n)
208     {
209       return m_dtmMgr.getDTM(n).getStringValue(n);
210     }
211     else
212     {
213       return com.sun.org.apache.xpath.internal.objects.XString.EMPTYSTRING;
214     }
215   }
216   
217   /**
218    * Directly call the
219    * characters method on the passed ContentHandler for the
220    * string-value. Multiple calls to the
221    * ContentHandler's characters methods may well occur for a single call to
222    * this method.
223    *
224    * @param ch A non-null reference to a ContentHandler.
225    *
226    * @throws org.xml.sax.SAXException
227    */

228   public void dispatchCharactersEvents(org.xml.sax.ContentHandler JavaDoc ch)
229           throws org.xml.sax.SAXException JavaDoc
230   {
231     int node = item(0);
232     
233     if(node != DTM.NULL)
234     {
235       m_dtmMgr.getDTM(node).dispatchCharactersEvents(node, ch, false);
236     }
237     
238   }
239   
240   /**
241    * Cast result object to an XMLString.
242    *
243    * @return The document fragment node data or the empty string.
244    */

245   public XMLString xstr()
246   {
247     int node = item(0);
248     return (node != DTM.NULL) ? getStringFromNode(node) : XString.EMPTYSTRING;
249   }
250   
251   /**
252    * Cast result object to a string.
253    *
254    * @return The string this wraps or the empty string if null
255    */

256   public void appendToFsb(com.sun.org.apache.xml.internal.utils.FastStringBuffer fsb)
257   {
258     XString xstring = (XString)xstr();
259     xstring.appendToFsb(fsb);
260   }
261   
262
263   /**
264    * Cast result object to a string.
265    *
266    * @return the string conversion from the next node in the nodeset
267    * or "" if there is no next node
268    */

269   public String JavaDoc str()
270   {
271     int node = item(0);
272     return (node != DTM.NULL) ? getStringFromNode(node).toString() : "";
273   }
274   
275   /**
276    * Return a java object that's closest to the representation
277    * that should be handed to an extension.
278    *
279    * @return The object that this class wraps
280    */

281   public Object JavaDoc object()
282   {
283     if(null == m_obj)
284         return this;
285     else
286         return m_obj;
287   }
288
289   // %REVIEW%
290
// hmmm...
291
// /**
292
// * Cast result object to a result tree fragment.
293
// *
294
// * @param support The XPath context to use for the conversion
295
// *
296
// * @return the nodeset as a result tree fragment.
297
// */
298
// public DocumentFragment rtree(XPathContext support)
299
// {
300
// DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
301
// DocumentBuilder db = dbf.newDocumentBuilder();
302
// Document myDoc = db.newDocument();
303
//
304
// DocumentFragment docFrag = myDoc.createDocumentFragment();
305
//
306
// DTMIterator nl = iter();
307
// int node;
308
//
309
// while (DTM.NULL != (node = nl.nextNode()))
310
// {
311
// frag.appendChild(node, true, true);
312
// }
313
//
314
// return frag.getDocument();
315
// }
316

317   /**
318    * Cast result object to a nodelist.
319    *
320    * @return a NodeIterator.
321    *
322    * @throws javax.xml.transform.TransformerException
323    */

324   public NodeIterator nodeset() throws javax.xml.transform.TransformerException JavaDoc
325   {
326     return new com.sun.org.apache.xml.internal.dtm.ref.DTMNodeIterator(iter());
327   }
328   
329   /**
330    * Cast result object to a nodelist.
331    *
332    * @return a NodeList.
333    *
334    * @throws javax.xml.transform.TransformerException
335    */

336   public NodeList JavaDoc nodelist() throws javax.xml.transform.TransformerException JavaDoc
337   {
338     com.sun.org.apache.xml.internal.dtm.ref.DTMNodeList nodelist = new com.sun.org.apache.xml.internal.dtm.ref.DTMNodeList(this);
339     // Creating a DTMNodeList has the side-effect that it will create a clone
340
// XNodeSet with cache and run m_iter to the end. You cannot get any node
341
// from m_iter after this call. As a fix, we call SetVector() on the clone's
342
// cache. See Bugzilla 14406.
343
XNodeSet clone = (XNodeSet)nodelist.getDTMIterator();
344     SetVector(clone.getVector());
345     return nodelist;
346   }
347
348   
349 // /**
350
// * Return a java object that's closest to the representation
351
// * that should be handed to an extension.
352
// *
353
// * @return The object that this class wraps
354
// */
355
// public Object object()
356
// {
357
// return new com.sun.org.apache.xml.internal.dtm.ref.DTMNodeList(iter());
358
// }
359

360   /**
361    * Return the iterator without cloning, etc.
362    */

363   public DTMIterator iterRaw()
364   {
365     return this;
366   }
367   
368   public void release(DTMIterator iter)
369   {
370   }
371   
372   /**
373    * Cast result object to a nodelist.
374    *
375    * @return The nodeset as a nodelist
376    */

377   public DTMIterator iter()
378   {
379     try
380     {
381         if(hasCache())
382             return cloneWithReset();
383         else
384             return this; // don't bother to clone... won't do any good!
385
}
386     catch (CloneNotSupportedException JavaDoc cnse)
387     {
388       throw new RuntimeException JavaDoc(cnse.getMessage());
389     }
390   }
391   
392   /**
393    * Get a fresh copy of the object. For use with variables.
394    *
395    * @return A fresh nodelist.
396    */

397   public XObject getFresh()
398   {
399     try
400     {
401         if(hasCache())
402             return (XObject)cloneWithReset();
403         else
404             return this; // don't bother to clone... won't do any good!
405
}
406     catch (CloneNotSupportedException JavaDoc cnse)
407     {
408       throw new RuntimeException JavaDoc(cnse.getMessage());
409     }
410   }
411
412   /**
413    * Cast result object to a mutableNodeset.
414    *
415    * @return The nodeset as a mutableNodeset
416    */

417   public NodeSetDTM mutableNodeset()
418   {
419     NodeSetDTM mnl;
420
421     if(m_obj instanceof NodeSetDTM)
422     {
423       mnl = (NodeSetDTM) m_obj;
424     }
425     else
426     {
427       mnl = new NodeSetDTM(iter());
428       m_obj = mnl;
429       setCurrentPos(0);
430     }
431
432     return mnl;
433   }
434
435   /** Less than comparator */
436   static LessThanComparator S_LT = new LessThanComparator();
437
438   /** Less than or equal comparator */
439   static LessThanOrEqualComparator S_LTE = new LessThanOrEqualComparator();
440
441   /** Greater than comparator */
442   static GreaterThanComparator S_GT = new GreaterThanComparator();
443
444   /** Greater than or equal comparator */
445   static GreaterThanOrEqualComparator S_GTE =
446     new GreaterThanOrEqualComparator();
447
448   /** Equal comparator */
449   static EqualComparator S_EQ = new EqualComparator();
450
451   /** Not equal comparator */
452   static NotEqualComparator S_NEQ = new NotEqualComparator();
453
454   /**
455    * Tell if one object is less than the other.
456    *
457    * @param obj2 Object to compare this nodeset to
458    * @param comparator Comparator to use
459    *
460    * @return See the comments below for each object type comparison
461    *
462    * @throws javax.xml.transform.TransformerException
463    */

464   public boolean compare(XObject obj2, Comparator comparator)
465           throws javax.xml.transform.TransformerException JavaDoc
466   {
467
468     boolean result = false;
469     int type = obj2.getType();
470
471     if (XObject.CLASS_NODESET == type)
472     {
473       // %OPT% This should be XMLString based instead of string based...
474

475       // From http://www.w3.org/TR/xpath:
476
// If both objects to be compared are node-sets, then the comparison
477
// will be true if and only if there is a node in the first node-set
478
// and a node in the second node-set such that the result of performing
479
// the comparison on the string-values of the two nodes is true.
480
// Note this little gem from the draft:
481
// NOTE: If $x is bound to a node-set, then $x="foo"
482
// does not mean the same as not($x!="foo"): the former
483
// is true if and only if some node in $x has the string-value
484
// foo; the latter is true if and only if all nodes in $x have
485
// the string-value foo.
486
DTMIterator list1 = iterRaw();
487       DTMIterator list2 = ((XNodeSet) obj2).iterRaw();
488       int node1;
489       java.util.Vector JavaDoc node2Strings = null;
490
491       while (DTM.NULL != (node1 = list1.nextNode()))
492       {
493         XMLString s1 = getStringFromNode(node1);
494
495         if (null == node2Strings)
496         {
497           int node2;
498
499           while (DTM.NULL != (node2 = list2.nextNode()))
500           {
501             XMLString s2 = getStringFromNode(node2);
502
503             if (comparator.compareStrings(s1, s2))
504             {
505               result = true;
506
507               break;
508             }
509
510             if (null == node2Strings)
511               node2Strings = new java.util.Vector JavaDoc();
512
513             node2Strings.addElement(s2);
514           }
515         }
516         else
517         {
518           int n = node2Strings.size();
519
520           for (int i = 0; i < n; i++)
521           {
522             if (comparator.compareStrings(s1, (XMLString)node2Strings.elementAt(i)))
523             {
524               result = true;
525
526               break;
527             }
528           }
529         }
530       }
531       list1.reset();
532       list2.reset();
533     }
534     else if (XObject.CLASS_BOOLEAN == type)
535     {
536
537       // From http://www.w3.org/TR/xpath:
538
// If one object to be compared is a node-set and the other is a boolean,
539
// then the comparison will be true if and only if the result of
540
// performing the comparison on the boolean and on the result of
541
// converting the node-set to a boolean using the boolean function
542
// is true.
543
double num1 = bool() ? 1.0 : 0.0;
544       double num2 = obj2.num();
545
546       result = comparator.compareNumbers(num1, num2);
547     }
548     else if (XObject.CLASS_NUMBER == type)
549     {
550
551       // From http://www.w3.org/TR/xpath:
552
// If one object to be compared is a node-set and the other is a number,
553
// then the comparison will be true if and only if there is a
554
// node in the node-set such that the result of performing the
555
// comparison on the number to be compared and on the result of
556
// converting the string-value of that node to a number using
557
// the number function is true.
558
DTMIterator list1 = iterRaw();
559       double num2 = obj2.num();
560       int node;
561
562       while (DTM.NULL != (node = list1.nextNode()))
563       {
564         double num1 = getNumberFromNode(node);
565
566         if (comparator.compareNumbers(num1, num2))
567         {
568           result = true;
569
570           break;
571         }
572       }
573       list1.reset();
574     }
575     else if (XObject.CLASS_RTREEFRAG == type)
576     {
577       XMLString s2 = obj2.xstr();
578       DTMIterator list1 = iterRaw();
579       int node;
580
581       while (DTM.NULL != (node = list1.nextNode()))
582       {
583         XMLString s1 = getStringFromNode(node);
584
585         if (comparator.compareStrings(s1, s2))
586         {
587           result = true;
588
589           break;
590         }
591       }
592       list1.reset();
593     }
594     else if (XObject.CLASS_STRING == type)
595     {
596
597       // From http://www.w3.org/TR/xpath:
598
// If one object to be compared is a node-set and the other is a
599
// string, then the comparison will be true if and only if there
600
// is a node in the node-set such that the result of performing
601
// the comparison on the string-value of the node and the other
602
// string is true.
603
XMLString s2 = obj2.xstr();
604       DTMIterator list1 = iterRaw();
605       int node;
606
607       while (DTM.NULL != (node = list1.nextNode()))
608       {
609         XMLString s1 = getStringFromNode(node);
610         if (comparator.compareStrings(s1, s2))
611         {
612           result = true;
613
614           break;
615         }
616       }
617       list1.reset();
618     }
619     else
620     {
621       result = comparator.compareNumbers(this.num(), obj2.num());
622     }
623
624     return result;
625   }
626
627   /**
628    * Tell if one object is less than the other.
629    *
630    * @param obj2 object to compare this nodeset to
631    *
632    * @return see this.compare(...)
633    *
634    * @throws javax.xml.transform.TransformerException
635    */

636   public boolean lessThan(XObject obj2) throws javax.xml.transform.TransformerException JavaDoc
637   {
638     return compare(obj2, S_LT);
639   }
640
641   /**
642    * Tell if one object is less than or equal to the other.
643    *
644    * @param obj2 object to compare this nodeset to
645    *
646    * @return see this.compare(...)
647    *
648    * @throws javax.xml.transform.TransformerException
649    */

650   public boolean lessThanOrEqual(XObject obj2) throws javax.xml.transform.TransformerException JavaDoc
651   {
652     return compare(obj2, S_LTE);
653   }
654
655   /**
656    * Tell if one object is less than the other.
657    *
658    * @param obj2 object to compare this nodeset to
659    *
660    * @return see this.compare(...)
661    *
662    * @throws javax.xml.transform.TransformerException
663    */

664   public boolean greaterThan(XObject obj2) throws javax.xml.transform.TransformerException JavaDoc
665   {
666     return compare(obj2, S_GT);
667   }
668
669   /**
670    * Tell if one object is less than the other.
671    *
672    * @param obj2 object to compare this nodeset to
673    *
674    * @return see this.compare(...)
675    *
676    * @throws javax.xml.transform.TransformerException
677    */

678   public boolean greaterThanOrEqual(XObject obj2)
679           throws javax.xml.transform.TransformerException JavaDoc
680   {
681     return compare(obj2, S_GTE);
682   }
683
684   /**
685    * Tell if two objects are functionally equal.
686    *
687    * @param obj2 object to compare this nodeset to
688    *
689    * @return see this.compare(...)
690    *
691    * @throws javax.xml.transform.TransformerException
692    */

693   public boolean equals(XObject obj2)
694   {
695     try
696     {
697       return compare(obj2, S_EQ);
698     }
699     catch(javax.xml.transform.TransformerException JavaDoc te)
700     {
701       throw new com.sun.org.apache.xml.internal.utils.WrappedRuntimeException(te);
702     }
703   }
704
705   /**
706    * Tell if two objects are functionally not equal.
707    *
708    * @param obj2 object to compare this nodeset to
709    *
710    * @return see this.compare(...)
711    *
712    * @throws javax.xml.transform.TransformerException
713    */

714   public boolean notEquals(XObject obj2) throws javax.xml.transform.TransformerException JavaDoc
715   {
716     return compare(obj2, S_NEQ);
717   }
718 }
719
720 /**
721  * compares nodes for various boolean operations.
722  */

723 abstract class Comparator
724 {
725
726   /**
727    * Compare two strings
728    *
729    *
730    * @param s1 First string to compare
731    * @param s2 Second String to compare
732    *
733    * @return Whether the strings are equal or not
734    */

735   abstract boolean compareStrings(XMLString s1, XMLString s2);
736
737   /**
738    * Compare two numbers
739    *
740    *
741    * @param n1 First number to compare
742    * @param n2 Second number to compare
743    *
744    * @return Whether the numbers are equal or not
745    */

746   abstract boolean compareNumbers(double n1, double n2);
747 }
748
749 /**
750  * Compare strings or numbers for less than.
751  */

752 class LessThanComparator extends Comparator
753 {
754
755   /**
756    * Compare two strings for less than.
757    *
758    *
759    * @param s1 First string to compare
760    * @param s2 Second String to compare
761    *
762    * @return True if s1 is less than s2
763    */

764   boolean compareStrings(XMLString s1, XMLString s2)
765   {
766     return (s1.toDouble() < s2.toDouble());
767     // return s1.compareTo(s2) < 0;
768
}
769
770   /**
771    * Compare two numbers for less than.
772    *
773    *
774    * @param n1 First number to compare
775    * @param n2 Second number to compare
776    *
777    * @return true if n1 is less than n2
778    */

779   boolean compareNumbers(double n1, double n2)
780   {
781     return n1 < n2;
782   }
783 }
784
785 /**
786  * Compare strings or numbers for less than or equal.
787  */

788 class LessThanOrEqualComparator extends Comparator
789 {
790
791   /**
792    * Compare two strings for less than or equal.
793    *
794    *
795    * @param s1 First string to compare
796    * @param s2 Second String to compare
797    *
798    * @return true if s1 is less than or equal to s2
799    */

800   boolean compareStrings(XMLString s1, XMLString s2)
801   {
802     return (s1.toDouble() <= s2.toDouble());
803     // return s1.compareTo(s2) <= 0;
804
}
805
806   /**
807    * Compare two numbers for less than or equal.
808    *
809    *
810    * @param n1 First number to compare
811    * @param n2 Second number to compare
812    *
813    * @return true if n1 is less than or equal to n2
814    */

815   boolean compareNumbers(double n1, double n2)
816   {
817     return n1 <= n2;
818   }
819 }
820
821 /**
822  * Compare strings or numbers for greater than.
823  */

824 class GreaterThanComparator extends Comparator
825 {
826
827   /**
828    * Compare two strings for greater than.
829    *
830    *
831    * @param s1 First string to compare
832    * @param s2 Second String to compare
833    *
834    * @return true if s1 is greater than s2
835    */

836   boolean compareStrings(XMLString s1, XMLString s2)
837   {
838     return (s1.toDouble() > s2.toDouble());
839     // return s1.compareTo(s2) > 0;
840
}
841
842   /**
843    * Compare two numbers for greater than.
844    *
845    *
846    * @param n1 First number to compare
847    * @param n2 Second number to compare
848    *
849    * @return true if n1 is greater than n2
850    */

851   boolean compareNumbers(double n1, double n2)
852   {
853     return n1 > n2;
854   }
855 }
856
857 /**
858  * Compare strings or numbers for greater than or equal.
859  */

860 class GreaterThanOrEqualComparator extends Comparator
861 {
862
863   /**
864    * Compare two strings for greater than or equal.
865    *
866    *
867    * @param s1 First string to compare
868    * @param s2 Second String to compare
869    *
870    * @return true if s1 is greater than or equal to s2
871    */

872   boolean compareStrings(XMLString s1, XMLString s2)
873   {
874     return (s1.toDouble() >= s2.toDouble());
875     // return s1.compareTo(s2) >= 0;
876
}
877
878   /**
879    * Compare two numbers for greater than or equal.
880    *
881    *
882    * @param n1 First number to compare
883    * @param n2 Second number to compare
884    *
885    * @return true if n1 is greater than or equal to n2
886    */

887   boolean compareNumbers(double n1, double n2)
888   {
889     return n1 >= n2;
890   }
891 }
892
893 /**
894  * Compare strings or numbers for equality.
895  */

896 class EqualComparator extends Comparator
897 {
898
899   /**
900    * Compare two strings for equality.
901    *
902    *
903    * @param s1 First string to compare
904    * @param s2 Second String to compare
905    *
906    * @return true if s1 is equal to s2
907    */

908   boolean compareStrings(XMLString s1, XMLString s2)
909   {
910     return s1.equals(s2);
911   }
912
913   /**
914    * Compare two numbers for equality.
915    *
916    *
917    * @param n1 First number to compare
918    * @param n2 Second number to compare
919    *
920    * @return true if n1 is equal to n2
921    */

922   boolean compareNumbers(double n1, double n2)
923   {
924     return n1 == n2;
925   }
926 }
927
928 /**
929  * Compare strings or numbers for non-equality.
930  */

931 class NotEqualComparator extends Comparator
932 {
933
934   /**
935    * Compare two strings for non-equality.
936    *
937    *
938    * @param s1 First string to compare
939    * @param s2 Second String to compare
940    *
941    * @return true if s1 is not equal to s2
942    */

943   boolean compareStrings(XMLString s1, XMLString s2)
944   {
945     return !s1.equals(s2);
946   }
947
948   /**
949    * Compare two numbers for non-equality.
950    *
951    *
952    * @param n1 First number to compare
953    * @param n2 Second number to compare
954    *
955    * @return true if n1 is not equal to n2
956    */

957   boolean compareNumbers(double n1, double n2)
958   {
959     return n1 != n2;
960   }
961 }
962
Popular Tags