try to fix some minor dropdown bugs
[potlatch2.git] / org / idmedia / as3commons / util / ArrayList.as
1 /*
2  * Copyright the original author or authors.
3  * 
4  * Licensed under the MOZILLA PUBLIC LICENSE, Version 1.1 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  * 
8  *      http://www.mozilla.org/MPL/MPL-1.1.html
9  * 
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.idmedia.as3commons.util {
17   import org.idmedia.as3commons.lang.NullPointerException;
18   import org.idmedia.as3commons.lang.IndexOutOfBoundsException;
19   
20   /**
21    * Resizable-array implementation of the <tt>List</tt> interface.  Implements
22    * all optional list operations, and permits all elements, including
23    * <tt>null</tt>.  In addition to implementing the <tt>List</tt> interface,
24    * this class provides methods to manipulate the size of the array that is
25    * used internally to store the list.<p>
26    *
27    * An application can increase the capacity of an <tt>ArrayList</tt> instance
28    * before adding a large number of elements using the <tt>ensureCapacity</tt>
29    * operation.  This may reduce the amount of incremental reallocation.<p>
30    *
31    * The iterators returned by this class's <tt>iterator</tt> and
32    * <tt>listIterator</tt> methods are <i>fail-fast</i>: if list is structurally
33    * modified at any time after the iterator is created, in any way except
34    * through the iterator's own remove or add methods, the iterator will throw a
35    * ConcurrentModificationException.  Thus, in the face of concurrent
36    * modification, the iterator fails quickly and cleanly, rather than risking
37    * arbitrary, non-deterministic behavior at an undetermined time in the
38    * future.<p>
39    *
40    * Note that the fail-fast behavior of an iterator cannot be guaranteed
41    * as it is, generally speaking, impossible to make any hard guarantees in the
42    * presence of unsynchronized concurrent modification.  Fail-fast iterators
43    * throw <tt>ConcurrentModificationException</tt> on a best-effort basis. 
44    * Therefore, it would be wrong to write a program that depended on this
45    * exception for its correctness: <i>the fail-fast behavior of iterators
46    * should be used only to detect bugs.</i><p>
47    * 
48    * @author sleistner
49    */
50   public class ArrayList extends AbstractList implements List {
51     
52     private var elementData:Array;
53     private var elementSize:int;
54     
55     /**
56      * @param  value Collection
57      */
58     public function ArrayList(value:Collection = null) {
59       elementData = new Array();
60       elementSize = 0;
61       if(value != null) {
62         elementData = elementData.concat(value.toArray());
63         elementSize = elementData.length;
64       }
65     }
66     
67     /**
68      * Appends the specified element to the end of this list.
69      *
70      * @param elem element to be appended to this list.
71      * @return <tt>true</tt> (as per the general contract of Collection.add).
72      */
73     override public function add(elem:*):Boolean {
74       elementData[elementSize++] = elem;
75       return true;      
76     }
77     
78     override public function setAt(index:int, value:*):Boolean {
79       rangeCheck(index);
80       elementData[index] = value;
81       return true;
82     }
83     
84     override public function addAt(index:int, value:*):Boolean {
85       rangeCheck(index);
86       var s:Array = elementData.slice(0, index);
87       var e:Array = elementData.slice(index);
88       elementData = s.concat(value).concat(e);
89       elementSize = elementData.length;
90       return true;
91     }
92     
93     /**
94      * Appends all of the elements in the specified Collection to the end of
95      * this list, in the order that they are returned by the
96      * specified Collection's Iterator.  The behavior of this operation is
97      * undefined if the specified Collection is modified while the operation
98      * is in progress.  (This implies that the behavior of this call is
99      * undefined if the specified Collection is this list, and this
100      * list is nonempty.)
101      *
102      * @param c the elements to be inserted into this list.
103      * @return <tt>true</tt> if this list changed as a result of the call.
104      * @throws    NullPointerException if the specified collection is null.
105      */
106     override public function addAll(c:Collection):Boolean {
107       if(c == null) {
108         throw new NullPointerException();       
109       }
110       var a:Array = c.toArray();
111       var newNum:int = elementSize + a.length;
112       elementData = elementData.concat(a);
113       elementSize = elementData.length;
114       return elementSize === newNum;
115     }
116     
117     /**
118      * Returns the element at the specified position in this list.
119      *
120      * @param  index index of element to return.
121      * @return the element at the specified position in this list.
122      * @throws    IndexOutOfBoundsException if index is out of range <tt>(index
123      *            &lt; 0 || index &gt;= size())</tt>.
124      */
125     override public function get(index:int):* {
126       rangeCheck(index);
127       return elementData[index];
128     }
129     
130     /**
131      * Removes the element at the specified position in this list.
132      * Shifts any subsequent elements to the left (subtracts one from their
133      * indices).
134      *
135      * @param index the index of the element to removed.
136      * @return boolean
137      * @throws    IndexOutOfBoundsException if index out of range <tt>(index
138      *            &lt; 0 || index &gt;= size())</tt>.
139      */
140     override public function removeAt(index:int):Boolean {
141       return removeAtTo(index, 1);
142     }
143     
144     /**
145      * Removes the element at the specified position in this list.
146      * Shifts any subsequent elements to the left (subtracts one from their
147      * indices).
148      *
149      * @param index the index of the element to removed.
150      * @return the element that was removed from the list.
151      * @throws    IndexOutOfBoundsException if index out of range <tt>(index
152      *            &lt; 0 || index &gt;= size())</tt>.
153      */
154     override public function removeAtAndReturn(index:int):* {
155       return removeAtToAndReturn(index, 1);
156     }
157     
158     /**
159      * Removes the elements at the specified start position to end position 
160      * in this list.
161      * Shifts any subsequent elements to the left (subtracts one from their
162      * indices).
163      *
164      * @param index the index of the element to removed.
165      * @param to the last element to remove
166      * @return boolean
167      * @throws    IndexOutOfBoundsException if index out of range <tt>(index
168      *            &lt; 0 || index &gt;= size())</tt>.
169      */
170     override public function removeAtTo(index:int, toPos:int):Boolean {
171       rangeCheck(index);
172       elementData.splice(index, toPos);
173       elementSize = elementData.length;
174       return true;
175     }
176     
177     /**
178      * Removes the elements at the specified start position to end position 
179      * in this list.
180      * Shifts any subsequent elements to the left (subtracts one from their
181      * indices).
182      *
183      * @param index the index of the element to removed.
184      * @param to the last element to remove
185      * @return the element that was removed from the list.
186      * @throws    IndexOutOfBoundsException if index out of range <tt>(index
187      *            &lt; 0 || index &gt;= size())</tt>.
188      */
189     public function removeAtToAndReturn(index:int, to:int):* {
190       rangeCheck(index);
191       var old:* = get(index);
192       removeAtTo(index, to);
193       return old;
194     }
195     
196     /**
197      * Removes all of the elements from this list.  The list will
198      * be empty after this call returns.
199      */
200     override public function clear():void {
201       elementData = new Array();
202       elementSize = 0;
203     }
204     
205     /**
206      * Returns the number of elements in this list.
207      *
208      * @return  the number of elements in this list.
209      */
210     override public function size():int {
211       return elementSize || 0;
212     }
213     
214     /**
215      * Tests if this list has no elements.
216      *
217      * @return  <tt>true</tt> if this list has no elements;
218      *          <tt>false</tt> otherwise.
219      */
220     override public function isEmpty():Boolean {
221       return elementSize == 0;
222     }
223     
224     /**
225      * Returns an array containing all of the elements in this list
226      * in the correct order.
227      *
228      * @return an array containing all of the elements in this list
229      *         in the correct order.
230      */
231     override public function toArray():Array {
232       return [].concat(elementData);
233     }
234     
235     /**
236      * Check if the given index is in range.
237      */
238     private function rangeCheck(index:int):void {
239       if (index > elementSize || index < 0) {
240         throw new IndexOutOfBoundsException("Index: " + index + ", " + "Size: " + elementSize);
241       }
242     }
243   }
244 }