View Javadoc
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