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