Frames | No Frames |
1: /* ======================================================================== 2: * JCommon : a free general purpose class library for the Java(tm) platform 3: * ======================================================================== 4: * 5: * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors. 6: * 7: * Project Info: http://www.jfree.org/jcommon/index.html 8: * 9: * This library is free software; you can redistribute it and/or modify it 10: * under the terms of the GNU Lesser General Public License as published by 11: * the Free Software Foundation; either version 2.1 of the License, or 12: * (at your option) any later version. 13: * 14: * This library is distributed in the hope that it will be useful, but 15: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 16: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 17: * License for more details. 18: * 19: * You should have received a copy of the GNU Lesser General Public 20: * License along with this library; if not, write to the Free Software 21: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 22: * USA. 23: * 24: * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 25: * in the United States and other countries.] 26: * 27: * ----------------------- 28: * AbstractObjectList.java 29: * ----------------------- 30: * (C)opyright 2003, 2004, by Object Refinery Limited and Contributors. 31: * 32: * Original Author: David Gilbert (for Object Refinery Limited); 33: * Contributor(s): Bill Kelemen; 34: * Nicolas Brodu 35: * 36: * $Id: AbstractObjectList.java,v 1.5 2005/10/18 13:24:19 mungady Exp $ 37: * 38: * Changes 39: * ------- 40: * 13-Aug-2003 : Version 1, based on ObjectList (DG); 41: * 24-Aug-2003 : Fixed size (BK); 42: * 15-Sep-2003 : Fix serialization for subclasses (ShapeList, PaintList) (NB); 43: */ 44: 45: package org.jfree.util; 46: 47: import java.io.IOException; 48: import java.io.ObjectInputStream; 49: import java.io.ObjectOutputStream; 50: import java.io.Serializable; 51: import java.util.Arrays; 52: 53: /** 54: * A list of objects that can grow as required. 55: * 56: * @author David Gilbert 57: */ 58: public class AbstractObjectList implements Cloneable, Serializable { 59: 60: /** For serialization. */ 61: private static final long serialVersionUID = 7789833772597351595L; 62: 63: /** The default initial capacity of the list. */ 64: public static final int DEFAULT_INITIAL_CAPACITY = 8; 65: 66: /** Storage for the objects. */ 67: private transient Object[] objects; 68: 69: /** The current list size. */ 70: private int size = 0; 71: 72: /** The default increment. */ 73: private int increment = DEFAULT_INITIAL_CAPACITY; 74: 75: /** 76: * Creates a new list with the default initial capacity. 77: */ 78: protected AbstractObjectList() { 79: this(DEFAULT_INITIAL_CAPACITY); 80: } 81: 82: /** 83: * Creates a new list. 84: * 85: * @param initialCapacity the initial capacity. 86: */ 87: protected AbstractObjectList(final int initialCapacity) { 88: this (initialCapacity, initialCapacity); 89: } 90: 91: /** 92: * Creates a new list. 93: * 94: * @param initialCapacity the initial capacity. 95: * @param increment the increment. 96: */ 97: protected AbstractObjectList(final int initialCapacity, 98: final int increment) { 99: this.objects = new Object[initialCapacity]; 100: this.increment = increment; 101: } 102: 103: /** 104: * Returns the object at the specified index, if there is one, or 105: * <code>null</code>. 106: * 107: * @param index the object index. 108: * 109: * @return The object or <code>null</code>. 110: */ 111: protected Object get(final int index) { 112: Object result = null; 113: if (index >= 0 && index < this.size) { 114: result = this.objects[index]; 115: } 116: return result; 117: } 118: 119: /** 120: * Sets an object reference (overwriting any existing object). 121: * 122: * @param index the object index. 123: * @param object the object (<code>null</code> permitted). 124: */ 125: protected void set(final int index, final Object object) { 126: if (index < 0) { 127: throw new IllegalArgumentException("Requires index >= 0."); 128: } 129: if (index >= this.objects.length) { 130: final Object[] enlarged = new Object[index + this.increment]; 131: System.arraycopy(this.objects, 0, enlarged, 0, this.objects.length); 132: this.objects = enlarged; 133: } 134: this.objects[index] = object; 135: this.size = Math.max(this.size, index + 1); 136: } 137: 138: /** 139: * Clears the list. 140: */ 141: public void clear() { 142: Arrays.fill(this.objects, null); 143: this.size = 0; 144: } 145: 146: /** 147: * Returns the size of the list. 148: * 149: * @return The size of the list. 150: */ 151: public int size() { 152: return this.size; 153: } 154: 155: /** 156: * Returns the index of the specified object, or -1 if the object is not in 157: * the list. 158: * 159: * @param object the object. 160: * 161: * @return The index or -1. 162: */ 163: protected int indexOf(final Object object) { 164: for (int index = 0; index < this.size; index++) { 165: if (this.objects[index] == object) { 166: return (index); 167: } 168: } 169: return -1; 170: } 171: 172: /** 173: * Tests this list for equality with another object. 174: * 175: * @param obj the object to test. 176: * 177: * @return A boolean. 178: */ 179: public boolean equals(final Object obj) { 180: 181: if (obj == null) { 182: return false; 183: } 184: 185: if (obj == this) { 186: return true; 187: } 188: 189: if (!(obj instanceof AbstractObjectList)) { 190: return false; 191: } 192: 193: final AbstractObjectList other = (AbstractObjectList) obj; 194: final int listSize = size(); 195: for (int i = 0; i < listSize; i++) { 196: if (!ObjectUtilities.equal(get(i), other.get(i))) { 197: return false; 198: } 199: } 200: return true; 201: } 202: 203: /** 204: * Returns a hash code value for the object. 205: * 206: * @return the hashcode 207: */ 208: public int hashCode() { 209: return super.hashCode(); 210: } 211: 212: /** 213: * Clones the list of objects. The objects in the list are not cloned, so 214: * this is method makes a 'shallow' copy of the list. 215: * 216: * @return A clone. 217: * 218: * @throws CloneNotSupportedException if an item in the list does not 219: * support cloning. 220: */ 221: public Object clone() throws CloneNotSupportedException { 222: 223: final AbstractObjectList clone = (AbstractObjectList) super.clone(); 224: if (this.objects != null) { 225: clone.objects = new Object[this.objects.length]; 226: System.arraycopy( 227: this.objects, 0, clone.objects, 0, this.objects.length 228: ); 229: } 230: return clone; 231: 232: } 233: 234: /** 235: * Provides serialization support. 236: * 237: * @param stream the output stream. 238: * 239: * @throws IOException if there is an I/O error. 240: */ 241: private void writeObject(final ObjectOutputStream stream) 242: throws IOException { 243: 244: stream.defaultWriteObject(); 245: final int count = size(); 246: stream.writeInt(count); 247: for (int i = 0; i < count; i++) { 248: final Object object = get(i); 249: if (object != null && object instanceof Serializable) { 250: stream.writeInt(i); 251: stream.writeObject(object); 252: } 253: else { 254: stream.writeInt(-1); 255: } 256: } 257: 258: } 259: 260: /** 261: * Provides serialization support. 262: * 263: * @param stream the input stream. 264: * 265: * @throws IOException if there is an I/O error. 266: * @throws ClassNotFoundException if there is a classpath problem. 267: */ 268: private void readObject(final ObjectInputStream stream) 269: throws IOException, ClassNotFoundException { 270: 271: stream.defaultReadObject(); 272: this.objects = new Object[this.size]; 273: final int count = stream.readInt(); 274: for (int i = 0; i < count; i++) { 275: final int index = stream.readInt(); 276: if (index != -1) { 277: set(index, stream.readObject()); 278: } 279: } 280: 281: } 282: 283: }