    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     * KeyedObjects.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: KeyedObjects.java,v 1.5.2.1 2005/10/25 21:29:13 mungady Exp $
    036     *
    037     * Changes:
    038     * --------
    039     * 31-Oct-2002 : Version 1 (DG);
    040     * 11-Jan-2005 : Minor tidy up (DG);
    041     *
    042     */
    043
    044    package org.jfree.data;
    045
    046    import java.io.Serializable;
    047    import java.util.Iterator;
    048    import java.util.List;
    049
    050    import org.jfree.util.PublicCloneable;
    051
    052    /**
    053     * A collection of (key, object) pairs.
    054     */
    055    public class KeyedObjects  implements Cloneable, PublicCloneable, Serializable {
    056
    057        /** For serialization. */
    058        private static final long serialVersionUID = 1321582394193530984L;
    059
    060        /** Storage for the data. */
    061        private List data;
    062
    063        /**
    064         * Creates a new collection (initially empty).
    065         */
    066        public KeyedObjects() {
    067            this.data = new java.util.ArrayList();
    068        }
    069
    070        /**
    071         * Returns the number of items (values) in the collection.
    072         *
    073         * @return The item count.
    074         */
    075        public int getItemCount() {
    076            return this.data.size();
    077        }
    078
    079        /**
    080         * Returns an object.
    081         *
    082         * @param item  the item index (zero-based).
    083         *
    084         * @return The object (<code>null</code> if the index is out of range).
    085         */
    086        public Object getObject(int item) {
    087            Object result = null;
    088            if (item >= 0 && item < this.data.size()) {
    089                KeyedObject kobj = (KeyedObject) this.data.get(item);
    090                if (kobj != null) {
    091                    result = kobj.getObject();
    092                }
    093            }
    094            return result;
    095        }
    096
    097        /**
    098         * Returns a key.
    099         *
    100         * @param index  the item index (zero-based).
    101         *
    102         * @return The row key.
    103         *
    104         * @throws IndexOutOfBoundsException if <code>index</code> is out of bounds.
    105         */
    106        public Comparable getKey(int index) {
    107            Comparable result = null;
    108            if (index >= 0 && index < this.data.size()) {
    109                KeyedObject item = (KeyedObject) this.data.get(index);
    110                if (item != null) {
    111                    result = item.getKey();
    112                }
    113            }
    114            return result;
    115        }
    116
    117        /**
    118         * Returns the index for a given key.
    119         *
    120         * @param key  the key.
    121         *
    122         * @return The index, or <code>-1</code> if the key is unrecognised.
    123         */
    124        public int getIndex(Comparable key) {
    125            int result = -1;
    126            int i = 0;
    127            Iterator iterator = this.data.iterator();
    128            while (iterator.hasNext()) {
    129                KeyedObject ko = (KeyedObject) iterator.next();
    130                if (ko.getKey().equals(key)) {
    131                    result = i;
    132                }
    133                i++;
    134            }
    135            return result;
    136        }
    137
    138        /**
    139         * Returns the keys.
    140         *
    141         * @return The keys (never <code>null</code>).
    142         */
    143        public List getKeys() {
    144            List result = new java.util.ArrayList();
    145            Iterator iterator = this.data.iterator();
    146            while (iterator.hasNext()) {
    147                KeyedObject ko = (KeyedObject) iterator.next();
    148                result.add(ko.getKey());
    149            }
    150            return result;
    151        }
    152
    153        /**
    154         * Returns the object for a given key. If the key is not recognised, the
    155         * method should return <code>null</code>.
    156         *
    157         * @param key  the key.
    158         *
    159         * @return The object (possibly <code>null</code>).
    160         */
    161        public Object getObject(Comparable key) {
    162            return getObject(getIndex(key));
    163        }
    164
    165        /**
    166         * Adds a new object to the collection, or overwrites an existing object.
    167         * This is the same as the {@link #setObject(Comparable, Object)} method.
    168         *
    169         * @param key  the key.
    170         * @param object  the object.
    171         */
    172        public void addObject(Comparable key, Object object) {
    173            setObject(key, object);
    174        }
    175
    176        /**
    177         * Replaces an existing object, or adds a new object to the collection.
    178         * This is the same as the {@link #addObject(Comparable, Object)}
    179         * method.
    180         *
    181         * @param key  the key.
    182         * @param object  the object.
    183         */
    184        public void setObject(Comparable key, Object object) {
    185            int keyIndex = getIndex(key);
    186            if (keyIndex >= 0) {
    187                KeyedObject ko = (KeyedObject) this.data.get(keyIndex);
    188                ko.setObject(object);
    189            }
    190            else {
    191                KeyedObject ko = new KeyedObject(key, object);
    192                this.data.add(ko);
    193            }
    194        }
    195
    196        /**
    197         * Removes a value from the collection.
    198         *
    199         * @param index  the index of the item to remove.
    200         */
    201        public void removeValue(int index) {
    202            this.data.remove(index);
    203        }
    204
    205        /**
    206         * Removes a value from the collection.
    207         *
    208         * @param key  the key of the item to remove.
    209         */
    210        public void removeValue(Comparable key) {
    211            removeValue(getIndex(key));
    212        }
    213
    214        /**
    215         * Returns a clone of this object.
    216         *
    217         * @return A clone.
    218         *
    219         * @throws CloneNotSupportedException if there is a problem cloning.
    220         */
    221        public Object clone() throws CloneNotSupportedException {
    222            KeyedObjects clone = (KeyedObjects) super.clone();
    223            clone.data = new java.util.ArrayList();
    224            Iterator iterator = this.data.iterator();
    225            while (iterator.hasNext()) {
    226                KeyedObject ko = (KeyedObject) iterator.next();
    227                clone.data.add(ko.clone());
    228            }
    229            return clone;
    230        }
    231
    232        /**
    233         * Tests if this object is equal to another.
    234         *
    235         * @param o  the other object.
    236         *
    237         * @return A boolean.
    238         */
    239        public boolean equals(Object o) {
    240
    241            if (o == null) {
    242                return false;
    243            }
    244            if (o == this) {
    245                return true;
    246            }
    247
    248            if (!(o instanceof KeyedObjects)) {
    249                return false;
    250            }
    251
    252            KeyedObjects kos = (KeyedObjects) o;
    253            int count = getItemCount();
    254            if (count != kos.getItemCount()) {
    255                return false;
    256            }
    257
    258            for (int i = 0; i < count; i++) {
    259                Comparable k1 = getKey(i);
    260                Comparable k2 = kos.getKey(i);
    261                if (!k1.equals(k2)) {
    262                    return false;
    263                }
    264                Object o1 = getObject(i);
    265                Object o2 = kos.getObject(i);
    266                if (o1 == null) {
    267                    if (o2 != null) {
    268                        return false;
    269                    }
    270                }
    271                else {
    272                    if (!o1.equals(o2)) {
    273                        return false;
    274                    }
    275                }
    276            }
    277            return true;
    278
    279        }
    280
    281    }