001    /* ===========================================================
002     * JFreeChart : a free chart library for the Java(tm) platform
003     * ===========================================================
004     *
005     * (C) Copyright 2000-2005, 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-2005, by Object Refinery Limited.
031     *
032     * Original Author:  David Gilbert (for Object Refinery Limited);
033     * Contributor(s):   -;
034     *
035     * $Id: KeyedValueComparator.java,v 1.4.2.1 2005/10/25 21:29:13 mungady Exp $
036     *
037     * Changes:
038     * --------
039     * 05-Mar-2003 : Version 1 (DG);
040     * 27-Aug-2003 : Moved SortOrder from org.jfree.data --> org.jfree.util (DG);
041     * 12-Jan-2005 : Added accessor methods (DG);
042     *
043     */
044    
045    package org.jfree.data;
046    
047    import java.util.Comparator;
048    
049    import org.jfree.util.SortOrder;
050    
051    /**
052     * A utility class that can compare and order two {@link KeyedValue} instances 
053     * and sort them into ascending or descending order by key or by value.
054     */
055    public class KeyedValueComparator implements Comparator {
056    
057        /** The comparator type. */
058        private KeyedValueComparatorType type;
059    
060        /** The sort order. */
061        private SortOrder order;
062    
063        /**
064         * Creates a new comparator.
065         *
066         * @param type  the type (<code>BY_KEY</code> or <code>BY_VALUE</code>, 
067         *              <code>null</code> not permitted).
068         * @param order  the order (<code>null</code> not permitted).
069         */
070        public KeyedValueComparator(KeyedValueComparatorType type, 
071                                    SortOrder order) {
072            if (order == null) {
073                throw new IllegalArgumentException("Null 'order' argument.");
074            }
075            this.type = type;
076            this.order = order;
077        }
078    
079        /**
080         * Returns the type.
081         * 
082         * @return The type (never <code>null</code>).
083         */
084        public KeyedValueComparatorType getType() {
085            return this.type;
086        }
087        
088        /**
089         * Returns the sort order.
090         * 
091         * @return The sort order (never <code>null</code>).
092         */
093        public SortOrder getOrder() {
094            return this.order;
095        }
096        
097        /**
098         * Compares two {@link KeyedValue} instances and returns an 
099         * <code>int</code> that indicates the relative order of the two objects.
100         *
101         * @param o1  object 1.
102         * @param o2  object 2.
103         *
104         * @return An int indicating the relative order of the objects.
105         */
106        public int compare(Object o1, Object o2) {
107    
108            if (o2 == null) {
109                return -1;
110            }
111            if (o1 == null) {
112                return 1;
113            }
114    
115            int result;
116    
117            KeyedValue kv1 = (KeyedValue) o1;
118            KeyedValue kv2 = (KeyedValue) o2;
119    
120            if (this.type == KeyedValueComparatorType.BY_KEY) {
121                if (this.order.equals(SortOrder.ASCENDING)) {
122                    result = kv1.getKey().compareTo(kv2.getKey());
123                }
124                else if (this.order.equals(SortOrder.DESCENDING)) {
125                    result = kv2.getKey().compareTo(kv1.getKey());
126                }
127                else {
128                    throw new IllegalArgumentException("Unrecognised sort order.");
129                }
130            }
131            else if (this.type == KeyedValueComparatorType.BY_VALUE) {
132                Number n1 = kv1.getValue();
133                Number n2 = kv2.getValue();
134                if (n2 == null) {
135                    return -1;
136                }
137                if (n1 == null) {
138                    return 1;
139                }
140                double d1 = n1.doubleValue();
141                double d2 = n2.doubleValue();
142                if (this.order.equals(SortOrder.ASCENDING)) {
143                    if (d1 > d2) {
144                        result = 1;
145                    }
146                    else if (d1 < d2) {
147                        result = -1;
148                    }
149                    else {
150                        result = 0;
151                    }
152                }
153                else if (this.order.equals(SortOrder.DESCENDING)) {
154                    if (d1 > d2) {
155                        result = -1;
156                    }
157                    else if (d1 < d2) {
158                        result = 1;
159                    }
160                    else {
161                        result = 0;
162                    }
163                }
164                else {
165                    throw new IllegalArgumentException("Unrecognised sort order.");
166                }
167            }
168            else {
169                throw new IllegalArgumentException("Unrecognised type.");
170            }
171    
172            return result;
173        }
174    
175    }