001: /* ListType
002: *
003: * $Id: ListType.java 4648 2006-09-25 16:25:53Z paul_jack $
004: *
005: * Created on Jan 7, 2004
006: *
007: * Copyright (C) 2004 Internet Archive.
008: *
009: * This file is part of the Heritrix web crawler (crawler.archive.org).
010: *
011: * Heritrix is free software; you can redistribute it and/or modify
012: * it under the terms of the GNU Lesser Public License as published by
013: * the Free Software Foundation; either version 2.1 of the License, or
014: * any later version.
015: *
016: * Heritrix is distributed in the hope that it will be useful,
017: * but WITHOUT ANY WARRANTY; without even the implied warranty of
018: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
019: * GNU Lesser Public License for more details.
020: *
021: * You should have received a copy of the GNU Lesser Public License
022: * along with Heritrix; if not, write to the Free Software
023: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
024: */
025: package org.archive.crawler.settings;
026:
027: import java.util.ArrayList;
028: import java.util.Collection;
029: import java.util.Iterator;
030: import java.util.List;
031: import java.util.ListIterator;
032:
033: import org.archive.util.SubList;
034:
035: /** Super type for all lists.
036: *
037: * @author John Erik Halse
038: */
039: public abstract class ListType<T> extends Type implements List<Object> {
040:
041: private final List<T> listData = new ArrayList<T>();
042: private final String description;
043:
044: /** Constructs a new ListType.
045: *
046: * @param name the name of the list
047: * @param description the description of the list
048: */
049: public ListType(String name, String description) {
050: super (name, null);
051: this .description = description;
052: }
053:
054: /** Appends the specified element to the end of this list.
055: *
056: * @param element element to be appended to this list.
057: * @throws ClassCastException is thrown if the element was of wrong type
058: * and could not be converted.
059: * @return true if this collection changed as a result of the call (as
060: * per the Collections.add contract).
061: */
062: public boolean add(Object element) {
063: T checked = checkType(element);
064: return this .listData.add(checked);
065: }
066:
067: /** Inserts the specified element at the specified position in this list.
068: *
069: * Shifts the element currently at that position (if any) and any
070: * subsequent elements to the right (adds one to their indices).
071: *
072: * @param index index at which the specified element is to be inserted.
073: * @param element element to be inserted.
074: * @throws ClassCastException is thrown if the element was of wrong type
075: * and could not be converted.
076: */
077: public void add(int index, Object element) {
078: T checked = checkType(element);
079: this .listData.add(index, checked);
080: }
081:
082: /** Appends all of the elements in the specified list to the end of this
083: * list, in the order that they are returned by the specified lists's
084: * iterator.
085: *
086: * The behavior of this operation is unspecified if the specified
087: * collection is modified while the operation is in progress.
088: *
089: * This method is a helper method for subclasses.
090: *
091: * @param l list whose elements are to be added to this list.
092: */
093: protected void addAll(ListType<T> l) {
094: this .listData.addAll(l.listData);
095: }
096:
097: /** Replaces the element at the specified position in this list with the
098: * specified element.
099: *
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)
146: throws ClassCastException;
147:
148: /* (non-Javadoc)
149: * @see org.archive.crawler.settings.Type#getDefaultValue()
150: */
151: public Object getDefaultValue() {
152: return this ;
153: }
154:
155: /* (non-Javadoc)
156: * @see org.archive.crawler.settings.Type#getDescription()
157: */
158: public String getDescription() {
159: return this .description;
160: }
161:
162: /** Removes all elements from this list.
163: */
164: public void clear() {
165: this .listData.clear();
166: }
167:
168: /**
169: * Returns the object stored at the index specified
170: * @param index The location of the object to get within the list.
171: * @return the object stored at the index specified
172: */
173: public Object get(int index) {
174: return this .listData.get(index);
175: }
176:
177: /** The getLegalValues is not applicable for list so this method will
178: * always return null.
179: *
180: * @return null
181: * @see org.archive.crawler.settings.Type#getLegalValues()
182: */
183: public Object[] getLegalValues() {
184: return null;
185: }
186:
187: /** Returns this object.
188: *
189: * This method is implemented to be able to treat the ListType as an
190: * subclass of {@link javax.management.Attribute}.
191: *
192: * @return this object.
193: * @see javax.management.Attribute#getValue()
194: */
195: public Object getValue() {
196: return this ;
197: }
198:
199: public boolean addAll(Collection<? extends Object> c) {
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: for (Object o : c) {
209: T checked = checkType(o);
210: listData.add(index, checked);
211: index++;
212: }
213: return true;
214: }
215:
216: public boolean contains(Object o) {
217: return this .listData.contains(o);
218: }
219:
220: public boolean containsAll(Collection c) {
221: return this .listData.containsAll(c);
222: }
223:
224: public int indexOf(Object o) {
225: return this .listData.indexOf(o);
226: }
227:
228: public int lastIndexOf(Object o) {
229: return this .listData.lastIndexOf(o);
230: }
231:
232: public ListIterator<Object> listIterator() {
233: return new ListIter();
234: }
235:
236: public ListIterator<Object> listIterator(int index) {
237: return new ListIter(index);
238: }
239:
240: public List<Object> subList(int fromIndex, int toIndex) {
241: return new SubList<Object>(this , fromIndex, toIndex);
242: }
243:
244: public Object[] toArray() {
245: return this .listData.toArray();
246: }
247:
248: public <X> X[] toArray(X[] a) {
249: return this .listData.toArray(a);
250: }
251:
252: public Object remove(int index) {
253: return this .listData.remove(index);
254: }
255:
256: public boolean remove(Object o) {
257: return this .listData.remove(o);
258: }
259:
260: public boolean removeAll(Collection c) {
261: return this .listData.removeAll(c);
262: }
263:
264: public boolean retainAll(Collection c) {
265: return this .listData.retainAll(c);
266: }
267:
268: /**
269: * Returns a compile-time typesafe version of this list. Unlike this
270: * List, the returned list will not accept String values as elements.
271: *
272: * @return a typesafe version of this list
273: */
274: public List<T> typesafe() {
275: return listData;
276: }
277:
278: private class ListIter implements ListIterator<Object> {
279:
280: final private ListIterator<T> delegate;
281:
282: public ListIter() {
283: this .delegate = listData.listIterator();
284: }
285:
286: public ListIter(int index) {
287: this .delegate = listData.listIterator(index);
288: }
289:
290: public void add(Object o) {
291: T checked = checkType(o);
292: delegate.add(checked);
293: }
294:
295: public boolean hasNext() {
296: return delegate.hasNext();
297: }
298:
299: public boolean hasPrevious() {
300: return delegate.hasPrevious();
301: }
302:
303: public Object next() {
304: return delegate.next();
305: }
306:
307: public int nextIndex() {
308: return delegate.nextIndex();
309: }
310:
311: public Object previous() {
312: return delegate.previous();
313: }
314:
315: public int previousIndex() {
316: return delegate.previousIndex();
317: }
318:
319: public void remove() {
320: delegate.remove();
321: }
322:
323: public void set(Object o) {
324: T checked = checkType(o);
325: delegate.set(checked);
326: }
327:
328: }
329: }
|