1 package net.sf.saxon.sort; 2 import net.sf.saxon.type.Type; 3 import net.sf.saxon.value.*; 4 import net.sf.saxon.ConversionContext; 5 6 import java.text.CollationKey ; 7 import java.text.Collator ; 8 import java.util.Comparator ; 9 10 23 24 public class AtomicSortComparer implements Comparator , java.io.Serializable { 25 26 private Comparator collator; 27 private ConversionContext conversion; 28 29 public AtomicSortComparer(Comparator collator, ConversionContext conversion) { 30 this.collator = collator; 31 if (collator == null) { 32 this.collator = CodepointCollator.getInstance(); 33 } 34 this.conversion = conversion; 35 } 36 37 50 51 public int compare(Object a, Object b) { 52 53 if (a instanceof AtomicValue && !((AtomicValue)a).hasBuiltInType()) { 55 a = ((AtomicValue)a).getPrimitiveValue(); 56 } 57 if (b instanceof AtomicValue && !((AtomicValue)b).hasBuiltInType()) { 58 b = ((AtomicValue)b).getPrimitiveValue(); 59 } 60 if (a instanceof UntypedAtomicValue) { 61 return ((UntypedAtomicValue)a).compareTo(b, collator, conversion); 62 } else if (b instanceof UntypedAtomicValue) { 63 return -((UntypedAtomicValue)b).compareTo(a, collator, conversion); 64 } else if (a instanceof DoubleValue && Double.isNaN(((DoubleValue)a).getDoubleValue())) { 65 if (b instanceof DoubleValue && Double.isNaN(((DoubleValue)b).getDoubleValue())) { 66 return 0; 67 } else { 68 return -1; 69 } 70 } else if (b instanceof DoubleValue && Double.isNaN(((DoubleValue)b).getDoubleValue())) { 71 return +1; 72 } else if (a instanceof CalendarValue && b instanceof CalendarValue) { 73 return ((CalendarValue)a).compareTo((CalendarValue)b, conversion); 74 } else if (a instanceof Comparable ) { 75 return ((Comparable )a).compareTo(b); 76 } else if (a instanceof StringValue && b instanceof StringValue) { 77 return collator.compare(((StringValue)a).getStringValue(), ((StringValue)b).getStringValue()); 78 } else if (a instanceof AtomicValue && b instanceof AtomicValue) { 79 throw new ClassCastException ("Objects are not comparable (" + 80 ((AtomicValue)a).getItemType() + ", " + ((AtomicValue)b).getItemType() + ")"); 81 } else { 82 throw new ClassCastException ("Objects are not comparable (" + 83 a.getClass() + ", " + b.getClass() + ")"); 84 } 85 } 86 87 92 93 public ComparisonKey getComparisonKey(AtomicValue a) { 94 AtomicValue prim = a.getPrimitiveValue(); 95 if (prim instanceof NumericValue) { 96 if (((NumericValue)prim).isNaN()) { 97 return new ComparisonKey(Type.NUMBER, NaN); 99 } else { 100 return new ComparisonKey(Type.NUMBER, prim); 101 } 102 } else if (prim instanceof StringValue) { 103 if (collator instanceof Collator ) { 104 return new ComparisonKey(Type.STRING, 105 ((Collator )collator).getCollationKey(((StringValue)prim).getStringValue())); 106 } else { 107 return new ComparisonKey(Type.STRING, prim); 108 } 109 } else { 110 return new ComparisonKey(prim.getItemType().getPrimitiveType(), prim); 111 } 112 } 113 114 private static StringValue NaN = new StringValue("NaN"); 115 116 120 121 public static class ComparisonKey { 122 int category; 123 Object value; 124 125 131 132 public ComparisonKey(int category, AtomicValue value) { 133 this.category = category; 134 this.value = value; 135 } 136 137 143 public ComparisonKey(int category, CollationKey value) { 144 this.category = category; 145 this.value = value; 146 } 147 148 154 public boolean equals(Object other) { 155 if (other instanceof ComparisonKey) { 156 ComparisonKey otherKey = (ComparisonKey)other; 157 return this.category == otherKey.category && 158 this.value.equals(otherKey.value); 159 } else { 160 throw new ClassCastException ("Cannot compare a ComparisonKey to an object of a different class"); 161 } 162 } 163 164 168 public int hashCode() { 169 return value.hashCode() ^ category; 170 } 171 172 } 173 174 } 175 176 177 | Popular Tags |