1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package org.archive.crawler.settings;
26
27 import java.util.ArrayList;
28 import java.util.Collection;
29 import java.util.Iterator;
30 import java.util.List;
31 import java.util.ListIterator;
32
33 import org.archive.util.SubList;
34
35 /*** Super type for all lists.
36 *
37 * @author John Erik Halse
38 */
39 public abstract class ListType<T> extends Type implements List<Object> {
40
41 private final List<T> listData = new ArrayList<T>();
42 private final String description;
43
44 /*** Constructs a new ListType.
45 *
46 * @param name the name of the list
47 * @param description the description of the list
48 */
49 public ListType(String name, String description) {
50 super(name, null);
51 this.description = description;
52 }
53
54 /*** Appends the specified element to the end of this list.
55 *
56 * @param element element to be appended to this list.
57 * @throws ClassCastException is thrown if the element was of wrong type
58 * and could not be converted.
59 * @return true if this collection changed as a result of the call (as
60 * per the Collections.add contract).
61 */
62 public boolean add(Object element) {
63 T checked = checkType(element);
64 return this.listData.add(checked);
65 }
66
67 /*** Inserts the specified element at the specified position in this list.
68 *
69 * Shifts the element currently at that position (if any) and any
70 * subsequent elements to the right (adds one to their indices).
71 *
72 * @param index index at which the specified element is to be inserted.
73 * @param element element to be inserted.
74 * @throws ClassCastException is thrown if the element was of wrong type
75 * and could not be converted.
76 */
77 public void add(int index, Object element) {
78 T checked = checkType(element);
79 this.listData.add(index, checked);
80 }
81
82 /*** Appends all of the elements in the specified list to the end of this
83 * list, in the order that they are returned by the specified lists's
84 * iterator.
85 *
86 * The behavior of this operation is unspecified if the specified
87 * collection is modified while the operation is in progress.
88 *
89 * This method is a helper method for subclasses.
90 *
91 * @param l list whose elements are to be added to this list.
92 */
93 protected void addAll(ListType<T> l) {
94 this.listData.addAll(l.listData);
95 }
96
97 /*** Replaces the element at the specified position in this list with the
98 * specified element.
99 *
100 * @param index index at which the specified element is to be inserted.
101 * @param element element to be inserted.
102 * @return the element previously at the specified position.
103 * @throws ClassCastException is thrown if the element was of wrong type
104 * and could not be converted.
105 */
106 public Object set(int index, Object element) {
107 T checked = checkType(element);
108 return this.listData.set(index, checked);
109 }
110
111 /*** Returns an iterator over the elements in this list in proper sequence.
112 *
113 * @return an iterator over the elements in this list.
114 */
115 public Iterator<Object> iterator() {
116 return new ListIter();
117 }
118
119 /*** Get the number of elements in this list.
120 *
121 * @return number of elements.
122 */
123 public int size() {
124 return this.listData.size();
125 }
126
127 /*** Returns true if this list contains no elements.
128 *
129 * @return true if this list contains no elements.
130 */
131 public boolean isEmpty() {
132 return this.listData.isEmpty();
133 }
134
135 /*** Check if element is of right type for this list.
136 *
137 * If this method gets a String, it should try to convert it to
138 * the right element type before throwing an exception.
139 *
140 * @param element element to check.
141 * @return element of the right type.
142 * @throws ClassCastException is thrown if the element was of wrong type
143 * and could not be converted.
144 */
145 public abstract T checkType(Object element) throws ClassCastException;
146
147
148
149
150 public Object getDefaultValue() {
151 return this;
152 }
153
154
155
156
157 public String getDescription() {
158 return this.description;
159 }
160
161 /*** Removes all elements from this list.
162 */
163 public void clear() {
164 this.listData.clear();
165 }
166
167 /***
168 * Returns the object stored at the index specified
169 * @param index The location of the object to get within the list.
170 * @return the object stored at the index specified
171 */
172 public Object get(int index){
173 return this.listData.get(index);
174 }
175
176 /*** The getLegalValues is not applicable for list so this method will
177 * always return null.
178 *
179 * @return null
180 * @see org.archive.crawler.settings.Type#getLegalValues()
181 */
182 public Object[] getLegalValues() {
183 return null;
184 }
185
186 /*** Returns this object.
187 *
188 * This method is implemented to be able to treat the ListType as an
189 * subclass of {@link javax.management.Attribute}.
190 *
191 * @return this object.
192 * @see javax.management.Attribute#getValue()
193 */
194 public Object getValue() {
195 return this;
196 }
197
198 public boolean addAll(Collection<? extends Object> c)
199 {
200 for (Object o : c) {
201 T checked = checkType(o);
202 listData.add(checked);
203 }
204 return true;
205 }
206
207 public boolean addAll(int index, Collection<? extends Object> c)
208 {
209 for (Object o : c) {
210 T checked = checkType(o);
211 listData.add(index, checked);
212 index++;
213 }
214 return true;
215 }
216
217 public boolean contains(Object o)
218 {
219 return this.listData.contains(o);
220 }
221
222 public boolean containsAll(Collection c)
223 {
224 return this.listData.containsAll(c);
225 }
226
227 public int indexOf(Object o)
228 {
229 return this.listData.indexOf(o);
230 }
231
232 public int lastIndexOf(Object o)
233 {
234 return this.listData.lastIndexOf(o);
235 }
236
237 public ListIterator<Object> listIterator()
238 {
239 return new ListIter();
240 }
241
242 public ListIterator<Object> listIterator(int index)
243 {
244 return new ListIter(index);
245 }
246
247 public List<Object> subList(int fromIndex, int toIndex)
248 {
249 return new SubList<Object>(this, fromIndex, toIndex);
250 }
251
252 public Object[] toArray()
253 {
254 return this.listData.toArray();
255 }
256
257 public <X> X[] toArray(X[] a)
258 {
259 return this.listData.toArray(a);
260 }
261
262 public Object remove(int index)
263 {
264 return this.listData.remove(index);
265 }
266
267 public boolean remove(Object o)
268 {
269 return this.listData.remove(o);
270 }
271
272 public boolean removeAll(Collection c)
273 {
274 return this.listData.removeAll(c);
275 }
276
277 public boolean retainAll(Collection c)
278 {
279 return this.listData.retainAll(c);
280 }
281
282 /***
283 * Returns a compile-time typesafe version of this list. Unlike this
284 * List, the returned list will not accept String values as elements.
285 *
286 * @return a typesafe version of this list
287 */
288 public List<T> typesafe() {
289 return listData;
290 }
291
292 private class ListIter implements ListIterator<Object> {
293
294 final private ListIterator<T> delegate;
295
296 public ListIter() {
297 this.delegate = listData.listIterator();
298 }
299
300 public ListIter(int index) {
301 this.delegate = listData.listIterator(index);
302 }
303
304 public void add(Object o) {
305 T checked = checkType(o);
306 delegate.add(checked);
307 }
308
309 public boolean hasNext() {
310 return delegate.hasNext();
311 }
312
313 public boolean hasPrevious() {
314 return delegate.hasPrevious();
315 }
316
317 public Object next() {
318 return delegate.next();
319 }
320
321 public int nextIndex() {
322 return delegate.nextIndex();
323 }
324
325 public Object previous() {
326 return delegate.previous();
327 }
328
329 public int previousIndex() {
330 return delegate.previousIndex();
331 }
332
333 public void remove() {
334 delegate.remove();
335 }
336
337 public void set(Object o) {
338 T checked = checkType(o);
339 delegate.set(checked);
340 }
341
342 }
343 }