001: package net.sf.saxon.sort;
002:
003: import net.sf.saxon.om.Item;
004: import net.sf.saxon.trans.XPathException;
005: import net.sf.saxon.value.NumericValue;
006: import net.sf.saxon.value.Value;
007:
008: import java.util.Comparator;
009:
010: /**
011: * A Comparer used for comparing sort keys when data-type="number". The items to be
012: * compared are converted to numbers, and the numbers are then compared directly
013: *
014: * @author Michael H. Kay
015: *
016: */
017:
018: public class NumericComparer implements Comparator,
019: java.io.Serializable {
020:
021: public NumericComparer() {
022: }
023:
024: /**
025: * Compare two Items by converting them to numbers and comparing the numeric values. If either
026: * value cannot be converted to a number, it is treated as NaN, and compares less that the other
027: * (two NaN values compare equal).
028: * @param a the first Item to be compared.
029: * @param b the second Item to be compared.
030: * @return <0 if a<b, 0 if a=b, >0 if a>b
031: * @throws ClassCastException if the objects are not Items
032: */
033:
034: public int compare(Object a, Object b) {
035:
036: double d1, d2;
037:
038: if (a instanceof NumericValue) {
039: d1 = ((NumericValue) a).getDoubleValue();
040: } else {
041: try {
042: String s1 = (a instanceof String ? (String) a
043: : ((Item) a).getStringValue());
044: d1 = Value.stringToNumber(s1);
045: //} catch (XPathException err) {
046: // d1 = Double.NaN;
047: } catch (NumberFormatException err) {
048: d1 = Double.NaN;
049: }
050: }
051:
052: if (b instanceof NumericValue) {
053: d2 = ((NumericValue) b).getDoubleValue();
054: } else {
055: try {
056: String s2 = (b instanceof String ? (String) b
057: : ((Item) b).getStringValue());
058: d2 = Value.stringToNumber(s2);
059: //} catch (XPathException err) {
060: // d2 = Double.NaN;
061: } catch (NumberFormatException err) {
062: d2 = Double.NaN;
063: }
064: }
065:
066: if (Double.isNaN(d1)) {
067: if (Double.isNaN(d2)) {
068: return 0;
069: } else {
070: return -1;
071: }
072: }
073: if (Double.isNaN(d2)) {
074: return +1;
075: }
076: if (d1 < d2)
077: return -1;
078: if (d1 > d2)
079: return +1;
080: return 0;
081:
082: }
083:
084: }
085:
086: //
087: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
088: // you may not use this file except in compliance with the License. You may obtain a copy of the
089: // License at http://www.mozilla.org/MPL/
090: //
091: // Software distributed under the License is distributed on an "AS IS" basis,
092: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
093: // See the License for the specific language governing rights and limitations under the License.
094: //
095: // The Original Code is: all this file.
096: //
097: // The Initial Developer of this module is Michael H. Kay
098: //
099: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
100: //
101: // Contributor(s): none.
102: //
|