001    /* ===========================================================
002     * JFreeChart : a free chart library for the Java(tm) platform
003     * ===========================================================
004     *
005     * (C) Copyright 2000-2008, by Object Refinery Limited and Contributors.
006     *
007     * Project Info:  http://www.jfree.org/jfreechart/index.html
008     *
009     * This library is free software; you can redistribute it and/or modify it
010     * under the terms of the GNU Lesser General Public License as published by
011     * the Free Software Foundation; either version 2.1 of the License, or
012     * (at your option) any later version.
013     *
014     * This library is distributed in the hope that it will be useful, but
015     * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
016     * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
017     * License for more details.
018     *
019     * You should have received a copy of the GNU Lesser General Public
020     * License along with this library; if not, write to the Free Software
021     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
022     * USA.
023     *
024     * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
025     * in the United States and other countries.]
026     *
027     * -------------------------
028     * KeyedValueComparator.java
029     * -------------------------
030     * (C) Copyright 2003-2008, by Object Refinery Limited.
031     *
032     * Original Author:  David Gilbert (for Object Refinery Limited);
033     * Contributor(s):   -;
034     *
035     * Changes:
036     * --------
037     * 05-Mar-2003 : Version 1 (DG);
038     * 27-Aug-2003 : Moved SortOrder from org.jfree.data --> org.jfree.util (DG);
039     * 12-Jan-2005 : Added accessor methods (DG);
040     *
041     */
042    
043    package org.jfree.data;
044    
045    import java.util.Comparator;
046    
047    import org.jfree.util.SortOrder;
048    
049    /**
050     * A utility class that can compare and order two {@link KeyedValue} instances
051     * and sort them into ascending or descending order by key or by value.
052     */
053    public class KeyedValueComparator implements Comparator {
054    
055        /** The comparator type. */
056        private KeyedValueComparatorType type;
057    
058        /** The sort order. */
059        private SortOrder order;
060    
061        /**
062         * Creates a new comparator.
063         *
064         * @param type  the type (<code>BY_KEY</code> or <code>BY_VALUE</code>,
065         *              <code>null</code> not permitted).
066         * @param order  the order (<code>null</code> not permitted).
067         */
068        public KeyedValueComparator(KeyedValueComparatorType type,
069                                    SortOrder order) {
070            if (order == null) {
071                throw new IllegalArgumentException("Null 'order' argument.");
072            }
073            this.type = type;
074            this.order = order;
075        }
076    
077        /**
078         * Returns the type.
079         *
080         * @return The type (never <code>null</code>).
081         */
082        public KeyedValueComparatorType getType() {
083            return this.type;
084        }
085    
086        /**
087         * Returns the sort order.
088         *
089         * @return The sort order (never <code>null</code>).
090         */
091        public SortOrder getOrder() {
092            return this.order;
093        }
094    
095        /**
096         * Compares two {@link KeyedValue} instances and returns an
097         * <code>int</code> that indicates the relative order of the two objects.
098         *
099         * @param o1  object 1.
100         * @param o2  object 2.
101         *
102         * @return An int indicating the relative order of the objects.
103         */
104        public int compare(Object o1, Object o2) {
105    
106            if (o2 == null) {
107                return -1;
108            }
109            if (o1 == null) {
110                return 1;
111            }
112    
113            int result;
114    
115            KeyedValue kv1 = (KeyedValue) o1;
116            KeyedValue kv2 = (KeyedValue) o2;
117    
118            if (this.type == KeyedValueComparatorType.BY_KEY) {
119                if (this.order.equals(SortOrder.ASCENDING)) {
120                    result = kv1.getKey().compareTo(kv2.getKey());
121                }
122                else if (this.order.equals(SortOrder.DESCENDING)) {
123                    result = kv2.getKey().compareTo(kv1.getKey());
124                }
125                else {
126                    throw new IllegalArgumentException("Unrecognised sort order.");
127                }
128            }
129            else if (this.type == KeyedValueComparatorType.BY_VALUE) {
130                Number n1 = kv1.getValue();
131                Number n2 = kv2.getValue();
132                if (n2 == null) {
133                    return -1;
134                }
135                if (n1 == null) {
136                    return 1;
137                }
138                double d1 = n1.doubleValue();
139                double d2 = n2.doubleValue();
140                if (this.order.equals(SortOrder.ASCENDING)) {
141                    if (d1 > d2) {
142                        result = 1;
143                    }
144                    else if (d1 < d2) {
145                        result = -1;
146                    }
147                    else {
148                        result = 0;
149                    }
150                }
151                else if (this.order.equals(SortOrder.DESCENDING)) {
152                    if (d1 > d2) {
153                        result = -1;
154                    }
155                    else if (d1 < d2) {
156                        result = 1;
157                    }
158                    else {
159                        result = 0;
160                    }
161                }
162                else {
163                    throw new IllegalArgumentException("Unrecognised sort order.");
164                }
165            }
166            else {
167                throw new IllegalArgumentException("Unrecognised type.");
168            }
169    
170            return result;
171        }
172    
173    }