1 /* 2 * Redistribution and use of this software and associated documentation ("Software"), with or 3 * without modification, are permitted provided that the following conditions are met: 4 * 5 * 1. Redistributions of source code must retain copyright statements and notices. Redistributions 6 * must also contain a copy of this document. 7 * 8 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of 9 * conditions and the following disclaimer in the documentation and/or other materials provided with 10 * the distribution. 11 * 12 * 3. The name "Exolab" must not be used to endorse or promote products derived from this Software 13 * without prior written permission of Intalio, Inc. For written permission, please contact 14 * info@exolab.org. 15 * 16 * 4. Products derived from this Software may not be called "Exolab" nor may "Exolab" appear in 17 * their names without prior written permission of Intalio, Inc. Exolab is a registered trademark of 18 * Intalio, Inc. 19 * 20 * 5. Due credit should be given to the Exolab Project (http://www.exolab.org/). 21 * 22 * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 24 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTALIO, INC. OR ITS 25 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY 29 * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 * 31 * Copyright 2002 (C) Intalio, Inc. All Rights Reserved. 32 * 33 * $Id$ 34 */ 35 package org.exolab.castor.xml.util; 36 37 import org.exolab.castor.xml.XMLFieldDescriptor; 38 39 /** 40 * A class which represents a collection of XMLFieldDescriptor instances. 41 * 42 * @author <a href="mailto:kvisco@intalio.com">Keith Visco</a> 43 * @version $Revision$ $Date: 2005-12-13 14:58:48 -0700 (Tue, 13 Dec 2005) $ 44 * @see java.util.List 45 * @see java.util.Collection 46 */ 47 public class XMLFieldDescriptors { 48 49 private static final int DEFAULT_SIZE = 11; 50 51 private XMLFieldDescriptor[] _elements; 52 53 /** 54 * The next available location in the elements array. 55 */ 56 private int _elementCount = 0; 57 58 /** 59 * Creates a new XMLFieldDescriptors with the default Size. 60 */ 61 public XMLFieldDescriptors() { 62 _elements = new XMLFieldDescriptor[DEFAULT_SIZE]; 63 } // -- XMLFieldDescriptors 64 65 /** 66 * Creates a new XMLFieldDescriptors with the given size. 67 * 68 * @param size the initial size of the internal collection. 69 */ 70 public XMLFieldDescriptors(int size) { 71 _elements = new XMLFieldDescriptor[size]; 72 } // -- XMLFieldDescriptors 73 74 /** 75 * Adds the specified XMLFieldDescriptor to the collection. If the specified XMLFieldDescriptor is 76 * already contained in the collection, it will not be re-added, false will be returned. 77 * 78 * @param descriptor the XMLFieldDescriptor to add 79 * @return true if the descriptor is added, false otherwise. 80 */ 81 public boolean add(XMLFieldDescriptor descriptor) { 82 83 for (int i = 0; i < _elementCount; i++) { 84 if (_elements[i] == descriptor) 85 return false; 86 } 87 if (_elementCount == _elements.length) 88 increaseSize(); 89 _elements[_elementCount++] = descriptor; 90 return true; 91 } // -- add 92 93 /** 94 * Removes all descriptors from this collection. 95 */ 96 public void clear() { 97 for (int i = 0; i < _elementCount; i++) { 98 _elements[i] = null; 99 } 100 _elementCount = 0; 101 } // -- clear 102 103 public Object clone() { 104 Object obj = null; 105 try { 106 obj = super.clone(); 107 } catch (CloneNotSupportedException e) { 108 // this should never happen 109 } 110 return obj; 111 } // -- clone 112 113 /** 114 * Returns true if the specified descriptor is contained in this collection. If the descriptor is 115 * null, then if this collection contains a null value, true will be returned. 116 * 117 * @param descriptor the XMLFieldDescriptor to search the list for 118 * @return true if specified descriptor is contained in the list 119 **/ 120 public boolean contains(XMLFieldDescriptor descriptor) { 121 return (indexOf(descriptor) >= 0); 122 } // -- contains 123 124 /** 125 * Compares the specified object with this list for equality. Returns true if and only if the 126 * specified Object is a list and all of its associated elements are equal to the elements of this 127 * list 128 * 129 * @return true if the given object is considered equal to this list. 130 */ 131 public boolean equals(Object obj) { 132 if (obj == null) 133 return false; 134 if (obj == this) 135 return true; 136 if (!(obj instanceof XMLFieldDescriptors)) 137 return false; 138 XMLFieldDescriptors descs = (XMLFieldDescriptors) obj; 139 if (descs._elementCount != _elementCount) 140 return false; 141 for (int i = 0; i < _elementCount; i++) { 142 Object e1 = get(i); 143 Object e2 = descs._elements[i]; 144 if (!((e1 == null) ? (e2 == null) : e1.equals(e2))) 145 return false; 146 } 147 return true; 148 } // -- equals 149 150 /** 151 * Returns the XMLFieldDescriptor at the specified position in this list. 152 * 153 * @param index the position of the descriptor to return 154 * @exception IndexOutOfBoundsException 155 */ 156 public XMLFieldDescriptor get(int index) throws IndexOutOfBoundsException { 157 if ((index < 0) || index >= _elementCount) { 158 throw new IndexOutOfBoundsException(); 159 } 160 return _elements[index]; 161 } // -- get 162 163 /** 164 * As defined by the JDK 1.2 API spec:<BR> 165 * Returns the hash code value for this list. The hash code of a list is defined to be the result 166 * of the following calculation: <BR> 167 * <code> 168 * hashCode = 1; 169 * Iterator i = list.iterator(); 170 * while (i.hasNext()) { 171 * Object obj = i.next(); 172 * hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode()); 173 * } 174 * </code> 175 * 176 * @return the hash code value for this list 177 */ 178 public int hashCode() { 179 int hashCode = 1; 180 for (int i = 0; i < _elementCount; i++) { 181 Object obj = _elements[i]; 182 hashCode = 31 * hashCode + (obj == null ? 0 : obj.hashCode()); 183 } 184 return hashCode; 185 } // -- hashCode 186 187 /** 188 * Returns the index of the first occurrence of the specified XMLFieldDescriptor, or -1 if the 189 * descriptor is not contained in the collection. 190 * 191 * @param descriptor the XMLFieldDescriptor to get the index of 192 */ 193 public int indexOf(XMLFieldDescriptor descriptor) { 194 if (descriptor == null) { 195 for (int i = 0; i < _elementCount; i++) { 196 if (_elements[i] == null) 197 return i; 198 } 199 } else { 200 for (int i = 0; i < _elementCount; i++) { 201 if (descriptor.equals(_elements[i])) 202 return i; 203 } 204 } 205 return -1; 206 } // -- indexOf 207 208 /** 209 * Returns true if there are no descriptors in the collection. 210 * 211 * @return true if the collection is empty. 212 */ 213 public boolean isEmpty() { 214 return (_elementCount == 0); 215 } // -- isEmpty 216 217 /** 218 * Removes the descriptor at the specified index from the list. 219 * 220 * @param index the position in the list to remove the descriptor from. 221 * @return the descriptor that was removed from the list. 222 */ 223 public XMLFieldDescriptor remove(int index) { 224 225 if ((index < 0) || (index > _elementCount)) 226 return null; 227 XMLFieldDescriptor desc = _elements[index]; 228 shiftDown(index + 1); 229 --_elementCount; 230 return desc; 231 } // -- remove 232 233 /** 234 * Removes the given XMLFieldDescriptor from the list. 235 * 236 * @param descriptor the XMLFieldDescriptor to remove from the list. 237 * @return true if the descriptor was removed from the list. 238 */ 239 public boolean remove(XMLFieldDescriptor descriptor) { 240 int index = indexOf(descriptor); 241 if (index > -1) { 242 remove(index); 243 return true; 244 } 245 return false; 246 } // -- remove 247 248 /** 249 * Reduces the capacity of the internal buffer to the current size freeing up unused memory. 250 */ 251 public void trimToSize() { 252 if (_elements.length == _elementCount) 253 return; 254 XMLFieldDescriptor[] pointer = _elements; 255 _elements = new XMLFieldDescriptor[_elementCount]; 256 System.arraycopy(pointer, 0, _elements, 0, _elementCount); 257 pointer = null; 258 } // -- trimToSize 259 260 /** 261 * Returns the number of descriptors in the list. 262 * 263 * @return the number of descriptors in the list. 264 */ 265 public int size() { 266 return _elementCount; 267 } // -- size 268 269 /** 270 * Returns an array containing all of the descriptors in this list in proper sequence. 271 * 272 * @return the array of descriptors of this List 273 */ 274 public XMLFieldDescriptor[] toArray() { 275 XMLFieldDescriptor[] objArray = new XMLFieldDescriptor[_elementCount]; 276 System.arraycopy(_elements, 0, objArray, 0, _elementCount); 277 return objArray; 278 } // -- toArray 279 280 /** 281 * Returns an array containing all of the descriptors in this list in proper sequence. 282 * 283 * @return the array of descriptors of this list. 284 */ 285 public XMLFieldDescriptor[] toArray(XMLFieldDescriptor[] dst) { 286 return toArray(dst, 0); 287 } // -- toArray 288 289 /** 290 * Returns an array containing all of the elements in this list in proper sequence. 291 * 292 * @return the array of descriptors of this list. 293 */ 294 public XMLFieldDescriptor[] toArray(XMLFieldDescriptor[] dst, int offset) { 295 296 XMLFieldDescriptor[] objArray = null; 297 298 if (dst.length >= _elementCount) 299 objArray = dst; 300 else { 301 objArray = new XMLFieldDescriptor[_elementCount]; 302 } 303 System.arraycopy(_elements, 0, objArray, offset, _elementCount); 304 return objArray; 305 } // -- toArray 306 307 308 // -------------------/ 309 // - Private Methods -/ 310 // -------------------/ 311 312 /** 313 * Basically the same as a vector, increase the list by a factor of its initial size 314 */ 315 private void increaseSize() { 316 XMLFieldDescriptor[] pointer = _elements; 317 int length = (pointer.length > 0) ? pointer.length : 1; 318 _elements = new XMLFieldDescriptor[(length * 3) / 2 + 1]; 319 System.arraycopy(pointer, 0, _elements, 0, pointer.length); 320 pointer = null; 321 } // -- increaseSize 322 323 /** 324 * Shifts all elements at the specified index to down by 1 325 */ 326 private void shiftDown(int index) { 327 if ((index <= 0) || (index >= _elementCount)) 328 return; 329 System.arraycopy(_elements, index, _elements, index - 1, _elementCount - index); 330 // clean up for gc 331 _elements[_elementCount - 1] = null; 332 } // -- shiftDown 333 334 } // -- XMLFieldDescriptors