Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
TypedList |
|
| 0.0;0 |
1 | /* | |
2 | * Licensed under the MIT License | |
3 | * | |
4 | * Copyright 2010 (c) Flávio Silva, http://flsilva.com | |
5 | * | |
6 | * Permission is hereby granted, free of charge, to any person | |
7 | * obtaining a copy of this software and associated documentation | |
8 | * files (the "Software"), to deal in the Software without | |
9 | * restriction, including without limitation the rights to use, | |
10 | * copy, modify, merge, publish, distribute, sublicense, and/or sell | |
11 | * copies of the Software, and to permit persons to whom the | |
12 | * Software is furnished to do so, subject to the following | |
13 | * conditions: | |
14 | * | |
15 | * The above copyright notice and this permission notice shall be | |
16 | * included in all copies or substantial portions of the Software. | |
17 | * | |
18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
19 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | |
20 | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
21 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | |
22 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | |
23 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
24 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
25 | * OTHER DEALINGS IN THE SOFTWARE. | |
26 | * | |
27 | * http://www.opensource.org/licenses/mit-license.php | |
28 | */ | |
29 | ||
30 | 1 | package org.as3collections.lists |
31 | { | |
32 | import org.as3collections.ICollection; | |
33 | import org.as3collections.IList; | |
34 | import org.as3collections.IListIterator; | |
35 | import org.as3collections.TypedCollection; | |
36 | import org.as3collections.iterators.ListIterator; | |
37 | import org.as3collections.utils.CollectionUtil; | |
38 | import org.as3utils.ReflectionUtil; | |
39 | ||
40 | /** | |
41 | * <code>TypedList</code> works as a wrapper for a <code>IList</code> object. | |
42 | * Since ActionScript 3.0 does not support typed arrays, <code>TypedList</code> is a way to create typed lists. | |
43 | * It stores the <code>wrapList</code> constructor's argument internaly. | |
44 | * So every method call to this class is forwarded to the <code>wrappedList</code> object. | |
45 | * The methods that need to be checked for the type of the elements are previously validated before forward the call. | |
46 | * If the type of an element requested to be added to this list is incompatible with the type of the list a <code>org.as3coreaddendum.errors.ClassCastError</code> is thrown. | |
47 | * The calls that are forwarded to the <code>wrappedList</code> returns the return of the <code>wrappedList</code> call. | |
48 | * <p><code>TypedList</code> does not allow <code>null</code> elements.</p> | |
49 | * <p>You can also create unique and typed lists. See below the link "ListUtil.getUniqueTypedList()".</p> | |
50 | * | |
51 | * @example | |
52 | * | |
53 | * <listing version="3.0"> | |
54 | * import org.as3collections.IList; | |
55 | * import org.as3collections.IListIterator; | |
56 | * import org.as3collections.lists.ArrayList; | |
57 | * import org.as3collections.lists.TypedList; | |
58 | * import org.as3collections.utils.ListUtil; | |
59 | * | |
60 | * var l1:IList = new ArrayList([3, 5, 1, 7]); | |
61 | * | |
62 | * var list1:IList = new TypedList(l1, int); // you can use this way | |
63 | * | |
64 | * //var list1:IList = ListUtil.getTypedList(l1, int); // or you can use this way | |
65 | * | |
66 | * list1 // [3,5,1,7] | |
67 | * list1.size() // 4 | |
68 | * | |
69 | * list1.add(8) // true | |
70 | * list1 // [3,5,1,7,8] | |
71 | * list1.size() // 5 | |
72 | * | |
73 | * list1.addAt(1, 4) // true | |
74 | * list1 // [3,4,5,1,7,8] | |
75 | * list1.size() // 6 | |
76 | * | |
77 | * list1.remove("abc") // false | |
78 | * list1 // [3,4,5,1,7,8] | |
79 | * list1.size() // 6 | |
80 | * | |
81 | * var it:IListIterator = list1.listIterator(); | |
82 | * var e:int; | |
83 | * | |
84 | * while (it.hasNext()) | |
85 | * { | |
86 | * | |
87 | * e = it.next() | |
88 | * e // 3 | |
89 | * | |
90 | * e = it.next() | |
91 | * e: // 4 | |
92 | * | |
93 | * e = it.next() | |
94 | * e // 5 | |
95 | * | |
96 | * if (e == 5) | |
97 | * { | |
98 | * it.add(0) | |
99 | * | |
100 | * list1 // [3,4,5,0,1,7,8] | |
101 | * list1.size() // 7 | |
102 | * } | |
103 | * | |
104 | * e = it.next() | |
105 | * e // 1 | |
106 | * | |
107 | * if (e == 1) | |
108 | * { | |
109 | * it.add(3) | |
110 | * | |
111 | * list1 // [3,4,5,0,1,3,7,8] | |
112 | * list1.size() // 8 | |
113 | * } | |
114 | * | |
115 | * e = it.next() | |
116 | * e // 7 | |
117 | * | |
118 | * e = it.next() | |
119 | * e // 8 | |
120 | * | |
121 | * if (e == 8) | |
122 | * { | |
123 | * it.add("ghi") // ClassCastError: Invalid element type. element: ghi | type: String | expected type: int | |
124 | * } | |
125 | * } | |
126 | * | |
127 | * list1 // [3,4,5,0,1,3,7,8] | |
128 | * list1.size() // 8 | |
129 | * | |
130 | * list1.add("def") // ClassCastError: Invalid element type. element: def | type: String | expected type: int | |
131 | * | |
132 | * list1.setAt(0, 1) // 3 | |
133 | * list1 // [1,4,5,0,1,3,7,8] | |
134 | * list1.size() // 8 | |
135 | * | |
136 | * list1.setAt(0, [1,2]) // ClassCastError: Invalid element type. element: 1,2 | type: Array | expected type: int | |
137 | * </listing> | |
138 | * | |
139 | * @see org.as3collections.utils.ListUtil#getTypedList() ListUtil.getTypedList() | |
140 | * @see org.as3collections.utils.ListUtil#getUniqueTypedList() ListUtil.getUniqueTypedList() | |
141 | * @author Flávio Silva | |
142 | */ | |
143 | public class TypedList extends TypedCollection implements IList | |
144 | { | |
145 | /** | |
146 | * Returns the return of the call <code>wrappedList.modCount</code>. | |
147 | */ | |
148 | public function get modCount(): int { return wrappedList.modCount; } | |
149 | ||
150 | /** | |
151 | * @private | |
152 | */ | |
153 | protected function get wrappedList(): IList { return wrappedCollection as IList; } | |
154 | ||
155 | /** | |
156 | * Constructor, creates a new <code>TypedList</code> object. | |
157 | * | |
158 | * @param wrapList the target list to wrap. | |
159 | * @param type the type of the elements allowed by this list. | |
160 | * @throws ArgumentError if the <code>wrapList</code> argument is <code>null</code>. | |
161 | * @throws ArgumentError if the <code>type</code> argument is <code>null</code>. | |
162 | * @throws org.as3coreaddendum.errors.ClassCastError if the types of one or more elements in the <code>wrapList</code> argument are incompatible with the <code>type</code> argument. | |
163 | */ | |
164 | public function TypedList(wrapList:IList, type:*) | |
165 | { | |
166 | 1 | super(wrapList, type); |
167 | 1 | } |
168 | ||
169 | /** | |
170 | * The collection is validated to be forwarded to <code>wrappedList.addAllAt</code>. | |
171 | * | |
172 | * @param index | |
173 | * @param collection the collection to forward to <code>wrappedList.addAllAt</code>. | |
174 | * @throws org.as3coreaddendum.errors.ClassCastError if the types of one or more elements in the <code>collection</code> argument are incompatible with the type of this list. | |
175 | * @return the return of the call <code>wrappedList.addAllAt</code>. | |
176 | */ | |
177 | public function addAllAt(index:int, collection:ICollection): Boolean | |
178 | { | |
179 | 1 | validateCollection(collection); |
180 | 1 | return wrappedList.addAllAt(index, collection); |
181 | } | |
182 | ||
183 | /** | |
184 | * The element is validated to be forwarded to <code>wrappedList.addAt</code>. | |
185 | * | |
186 | * @param index | |
187 | * @param element the element to forward to <code>wrappedList.addAt</code>. | |
188 | * @throws org.as3coreaddendum.errors.ClassCastError if the type of the element is incompatible with the type of this list. | |
189 | * @return the return of the call <code>wrappedList.addAt</code>. | |
190 | */ | |
191 | public function addAt(index:int, element:*): Boolean | |
192 | { | |
193 | 1 | validateElement(element); |
194 | 1 | return wrappedList.addAt(index, element); |
195 | } | |
196 | ||
197 | /** | |
198 | * Creates and return a new <code>TypedList</code> object with a clone of the <code>wrappedList</code> object. | |
199 | * | |
200 | * @return a new <code>TypedList</code> object with a clone of the <code>wrappedList</code> object. | |
201 | */ | |
202 | override public function clone(): * | |
203 | { | |
204 | 1 | return new TypedList(wrappedList.clone(), type); |
205 | } | |
206 | ||
207 | /** | |
208 | * This method first checks if <code>other</code> argument is a <code>TypedList</code>. | |
209 | * If not it returns <code>false</code>. | |
210 | * If <code>true</code> it checks the <code>type</code> property of both lists. | |
211 | * If they are different it returns <code>false</code>. | |
212 | * Otherwise it uses <code>CollectionUtil.equalConsideringOrder</code> method to perform equality, sending this list and <code>other</code> argument. | |
213 | * | |
214 | * @param other the object to be compared for equality. | |
215 | * @return <code>true</code> if the arbitrary evaluation considers the objects equal. | |
216 | * @see org.as3collections.utils.CollectionUtil#equalConsideringOrder() CollectionUtil.equalConsideringOrder() | |
217 | */ | |
218 | override public function equals(other:*): Boolean | |
219 | { | |
220 | 1 | if (this == other) return true; |
221 | 1 | if (!ReflectionUtil.classPathEquals(this, other)) return false; |
222 | ||
223 | 1 | var otherList:TypedList = other as TypedList; |
224 | 1 | if (type != otherList.type) return false; |
225 | ||
226 | 1 | return CollectionUtil.equalConsideringOrder(this, other); |
227 | } | |
228 | ||
229 | /** | |
230 | * Forwards the call to <code>wrappedList.getAt</code>. | |
231 | * | |
232 | * @param index | |
233 | * @return the return of the call <code>wrappedList.getAt</code>. | |
234 | */ | |
235 | public function getAt(index:int): * | |
236 | { | |
237 | 1 | return wrappedList.getAt(index); |
238 | } | |
239 | ||
240 | /** | |
241 | * Forwards the call to <code>wrappedList.indexOf</code>. | |
242 | * | |
243 | * @param element | |
244 | * @param fromIndex | |
245 | * @return the return of the call <code>wrappedList.indexOf</code>. | |
246 | */ | |
247 | public function indexOf(element:*, fromIndex:int = 0): int | |
248 | { | |
249 | 1 | return wrappedList.indexOf(element, fromIndex); |
250 | } | |
251 | ||
252 | /** | |
253 | * Forwards the call to <code>wrappedList.lastIndexOf</code>. | |
254 | * | |
255 | * @param element | |
256 | * @param fromIndex | |
257 | * @return the return of the call <code>wrappedList.lastIndexOf</code>. | |
258 | */ | |
259 | public function lastIndexOf(element:*, fromIndex:int = 0x7fffffff): int | |
260 | { | |
261 | 1 | return wrappedList.lastIndexOf(element, fromIndex); |
262 | } | |
263 | ||
264 | /** | |
265 | * Returns a list iterator of the elements in this list (in proper sequence), starting at the specified position in this list. The specified index indicates the first element that would be returned by an initial call to <code>next</code>. An initial call to <code>previous</code> would return the element with the specified index minus one. | |
266 | * <p>This implementation returns an <code>ListIterator</code> object.</p> | |
267 | * | |
268 | * @param index index of first element to be returned from the list iterator (by a call to the <code>next</code> method) | |
269 | * @return a list iterator of the elements in this list (in proper sequence), starting at the specified position in this list. | |
270 | * @see org.as3collections.iterators.ListIterator ListIterator | |
271 | */ | |
272 | public function listIterator(index:int = 0): IListIterator | |
273 | { | |
274 | 1 | return new ListIterator(this, index); |
275 | } | |
276 | ||
277 | /** | |
278 | * Forwards the call to <code>wrappedList.removeAt</code>. | |
279 | * | |
280 | * @param index | |
281 | * @return the return of the call <code>wrappedList.removeAt</code>. | |
282 | */ | |
283 | public function removeAt(index:int): * | |
284 | { | |
285 | 1 | return wrappedList.removeAt(index); |
286 | } | |
287 | ||
288 | /** | |
289 | * Forwards the call to <code>wrappedList.removeRange</code>. | |
290 | * | |
291 | * @param fromIndex | |
292 | * @param toIndex | |
293 | * @return the return of the call <code>wrappedList.removeRange</code>. | |
294 | */ | |
295 | public function removeRange(fromIndex:int, toIndex:int): ICollection | |
296 | { | |
297 | 1 | return wrappedList.removeRange(fromIndex, toIndex); |
298 | } | |
299 | ||
300 | /** | |
301 | * Forwards the call to <code>wrappedList.reverse</code>. | |
302 | */ | |
303 | public function reverse(): void | |
304 | { | |
305 | 1 | wrappedList.reverse(); |
306 | 1 | } |
307 | ||
308 | /** | |
309 | * The element is validated to be forwarded to <code>wrappedList.setAt</code>. | |
310 | * | |
311 | * @param index | |
312 | * @param element the element to forward to <code>wrappedList.setAt</code>. | |
313 | * @throws org.as3coreaddendum.errors.ClassCastError if the type of the element is incompatible with the type of this list. | |
314 | * @return the return of the call <code>wrappedList.setAt</code>. | |
315 | */ | |
316 | public function setAt(index:int, element:*): * | |
317 | { | |
318 | 1 | validateElement(element); |
319 | 1 | return wrappedList.setAt(index, element); |
320 | } | |
321 | ||
322 | /** | |
323 | * Returns a new <code>TypedList(wrappedList.subList(fromIndex, toIndex))</code>. | |
324 | * <p>Modifications in the returned <code>TypedList</code> object does not affect this list.</p> | |
325 | * | |
326 | * @param fromIndex the index to start retrieving elements (inclusive). | |
327 | * @param toIndex the index to stop retrieving elements (exclusive). | |
328 | * @throws org.as3collections.errors.IndexOutOfBoundsError if <code>fromIndex</code> or <code>toIndex</code> is out of range <code>(index < 0 || index > size())</code>. | |
329 | * @return a new <code>TypedList(wrappedList.subList(fromIndex, toIndex))</code>. | |
330 | */ | |
331 | public function subList(fromIndex:int, toIndex:int): IList | |
332 | { | |
333 | 1 | return new TypedList(wrappedList.subList(fromIndex, toIndex), type); |
334 | } | |
335 | ||
336 | } | |
337 | ||
338 | } |