KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > saxon > sort > AtomicComparer


1 package net.sf.saxon.sort;
2 import net.sf.saxon.value.AtomicValue;
3 import net.sf.saxon.value.StringValue;
4 import net.sf.saxon.value.UntypedAtomicValue;
5 import net.sf.saxon.value.CalendarValue;
6 import net.sf.saxon.ConversionContext;
7
8 import java.text.Collator JavaDoc;
9 import java.util.Comparator JavaDoc;
10
11 /**
12  * A Comparator used for comparing atomic values of arbitrary item types. It encapsulates
13  * a Collator that is used when the values to be compared are strings. It also supports
14  * a separate method for testing equality of items, which can be used for data types that
15  * are not ordered.
16  *
17  * @author Michael H. Kay
18  *
19  */

20
21 public class AtomicComparer implements Comparator JavaDoc, java.io.Serializable JavaDoc {
22
23     // TODO: create specialized AtomicComparers (and/or AtomicSortComparers) for particular data types
24

25     private Comparator JavaDoc collator;
26     private ConversionContext conversion;
27
28     public AtomicComparer(Comparator JavaDoc collator, ConversionContext conversion) {
29         this.collator = collator;
30         if (collator == null) {
31             this.collator = CodepointCollator.getInstance();
32         }
33         this.conversion = conversion;
34     }
35
36     /**
37     * Compare two AtomicValue objects according to the rules for their data type. UntypedAtomic
38     * values are compared as if they were strings; if different semantics are wanted, the conversion
39     * must be done by the caller.
40     * @param a the first object to be compared. It is intended that this should be an instance
41     * of AtomicValue, though this restriction is not enforced. If it is a StringValue, the
42     * collator is used to compare the values, otherwise the value must implement the java.util.Comparable
43     * interface.
44     * @param b the second object to be compared. This must be comparable with the first object: for
45     * example, if one is a string, they must both be strings.
46     * @return <0 if a<b, 0 if a=b, >0 if a>b
47     * @throws ClassCastException if the objects are not comparable
48     */

49
50     public int compare(Object JavaDoc a, Object JavaDoc b) {
51
52         // System.err.println("Comparing " + a.getClass() + "(" + a + ") with " + b.getClass() + "(" + b + ") using " + collator);
53

54         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
61         if (a instanceof UntypedAtomicValue) {
62             return ((UntypedAtomicValue)a).compareTo(b, collator, conversion);
63         } else if (b instanceof UntypedAtomicValue) {
64             return -((UntypedAtomicValue)b).compareTo(a, collator, conversion);
65         } else if (a instanceof CalendarValue && b instanceof CalendarValue) {
66             return ((CalendarValue)a).compareTo((CalendarValue)b, conversion);
67         } else if (a instanceof Comparable JavaDoc) {
68             return ((Comparable JavaDoc)a).compareTo(b);
69         } else if (a instanceof StringValue) {
70             return collator.compare(((StringValue)a).getStringValue(), ((StringValue)b).getStringValue());
71         } else {
72             throw new ClassCastException JavaDoc("Objects are not comparable (" + a.getClass() + ", " + b.getClass() + ')');
73         }
74     }
75
76     /**
77     * Compare two AtomicValue objects for equality according to the rules for their data type. UntypedAtomic
78     * values are compared by converting to the type of the other operand.
79     * @param a the first object to be compared. It is intended that this should be an instance
80     * of AtomicValue, though this restriction is not enforced. If it is a StringValue, the
81     * collator is used to compare the values, otherwise the value must implement the equals() method.
82     * @param b the second object to be compared. This must be comparable with the first object: for
83     * example, if one is a string, they must both be strings.
84     * @return <0 if a<b, 0 if a=b, >0 if a>b
85     * @throws ClassCastException if the objects are not comparable
86     */

87
88     public boolean comparesEqual(Object JavaDoc a, Object JavaDoc b) {
89         // System.err.println("Comparing " + a.getClass() + ": " + a + " with " + b.getClass() + ": " + b);
90

91         if (a instanceof AtomicValue && !((AtomicValue)a).hasBuiltInType()) {
92             a = ((AtomicValue)a).getPrimitiveValue();
93         }
94         if (b instanceof AtomicValue && !((AtomicValue)b).hasBuiltInType()) {
95             b = ((AtomicValue)b).getPrimitiveValue();
96         }
97
98         if (a instanceof UntypedAtomicValue) {
99             return ((UntypedAtomicValue)a).compareTo(b, collator, conversion) == 0;
100         } else if (b instanceof UntypedAtomicValue) {
101             return ((UntypedAtomicValue)b).compareTo(a, collator, conversion) == 0;
102         } else if (a instanceof StringValue) {
103             return collator.compare(((StringValue)a).getStringValue(), ((StringValue)b).getStringValue()) == 0;
104         } else if (a instanceof String JavaDoc) {
105             return collator.compare(a, b) == 0;
106         } else {
107             return a.equals(b);
108         }
109     }
110
111     /**
112     * Get a comparison key for an object. This must satisfy the rule that if two objects are equal,
113     * then their comparison keys are equal, and vice versa. There is no requirement that the
114     * comparison keys should reflect the ordering of the underlying objects.
115     */

116
117     public Object JavaDoc getComparisonKey(Object JavaDoc a) {
118
119         if (a instanceof AtomicValue && !((AtomicValue)a).hasBuiltInType()) {
120             a = ((AtomicValue)a).getPrimitiveValue();
121         }
122
123         if (a instanceof StringValue) {
124             if (collator instanceof Collator JavaDoc) {
125                 return ((Collator JavaDoc)collator).getCollationKey(((StringValue)a).getStringValue());
126             } else {
127                 return ((StringValue)a).getStringValue();
128             }
129         } else {
130             return a;
131         }
132     }
133
134
135 }
136
137
138 //
139
// The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
140
// you may not use this file except in compliance with the License. You may obtain a copy of the
141
// License at http://www.mozilla.org/MPL/
142
//
143
// Software distributed under the License is distributed on an "AS IS" basis,
144
// WITHOUT WARRANTY OF ANY KIND, either express or implied.
145
// See the License for the specific language governing rights and limitations under the License.
146
//
147
// The Original Code is: all this file.
148
//
149
// The Initial Developer of the Original Code is Michael H. Kay
150
//
151
// Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
152
//
153
// Contributor(s): none
154
//
Popular Tags