001: /*
002: * Copyright 1999-2006 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.apache.commons.collections.iterators;
017:
018: import java.util.ArrayList;
019: import java.util.Iterator;
020: import java.util.List;
021: import java.util.NoSuchElementException;
022:
023: import org.apache.commons.collections.ResettableListIterator;
024:
025: /**
026: * Converts an iterator into a list iterator by caching the returned entries.
027: * <p>
028: * The <code>ListIterator</code> interface has additional useful methods
029: * for navigation - <code>previous()</code> and the index methods.
030: * This class allows a regular <code>Iterator</code> to behave as a
031: * <code>ListIterator</code>. It achieves this by building a list internally
032: * of as the underlying iterator is traversed.
033: * <p>
034: * The optional operations of <code>ListIterator</code> are not supported.
035: * <p>
036: * This class implements ResettableListIterator from Commons Collections 3.2.
037: *
038: * @since Commons Collections 2.1
039: * @version $Revision: 405925 $ $Date: 2006-05-12 23:52:43 +0100 (Fri, 12 May 2006) $
040: *
041: * @author Morgan Delagrange
042: * @author Stephen Colebourne
043: */
044: public class ListIteratorWrapper implements ResettableListIterator {
045:
046: /** Message used when remove, set or add are called. */
047: private static final String UNSUPPORTED_OPERATION_MESSAGE = "ListIteratorWrapper does not support optional operations of ListIterator.";
048:
049: /** The underlying iterator being decorated. */
050: private final Iterator iterator;
051: /** The list being used to cache the iterator. */
052: private final List list = new ArrayList();
053:
054: /** The current index of this iterator. */
055: private int currentIndex = 0;
056: /** The current index of the wrapped iterator. */
057: private int wrappedIteratorIndex = 0;
058:
059: // Constructor
060: //-------------------------------------------------------------------------
061: /**
062: * Constructs a new <code>ListIteratorWrapper</code> that will wrap
063: * the given iterator.
064: *
065: * @param iterator the iterator to wrap
066: * @throws NullPointerException if the iterator is null
067: */
068: public ListIteratorWrapper(Iterator iterator) {
069: super ();
070: if (iterator == null) {
071: throw new NullPointerException("Iterator must not be null");
072: }
073: this .iterator = iterator;
074: }
075:
076: // ListIterator interface
077: //-------------------------------------------------------------------------
078: /**
079: * Throws {@link UnsupportedOperationException}.
080: *
081: * @param obj the object to add, ignored
082: * @throws UnsupportedOperationException always
083: */
084: public void add(Object obj) throws UnsupportedOperationException {
085: throw new UnsupportedOperationException(
086: UNSUPPORTED_OPERATION_MESSAGE);
087: }
088:
089: /**
090: * Returns true if there are more elements in the iterator.
091: *
092: * @return true if there are more elements
093: */
094: public boolean hasNext() {
095: if (currentIndex == wrappedIteratorIndex) {
096: return iterator.hasNext();
097: }
098: return true;
099: }
100:
101: /**
102: * Returns true if there are previous elements in the iterator.
103: *
104: * @return true if there are previous elements
105: */
106: public boolean hasPrevious() {
107: if (currentIndex == 0) {
108: return false;
109: }
110: return true;
111: }
112:
113: /**
114: * Returns the next element from the iterator.
115: *
116: * @return the next element from the iterator
117: * @throws NoSuchElementException if there are no more elements
118: */
119: public Object next() throws NoSuchElementException {
120: if (currentIndex < wrappedIteratorIndex) {
121: ++currentIndex;
122: return list.get(currentIndex - 1);
123: }
124:
125: Object retval = iterator.next();
126: list.add(retval);
127: ++currentIndex;
128: ++wrappedIteratorIndex;
129: return retval;
130: }
131:
132: /**
133: * Returns in the index of the next element.
134: *
135: * @return the index of the next element
136: */
137: public int nextIndex() {
138: return currentIndex;
139: }
140:
141: /**
142: * Returns the the previous element.
143: *
144: * @return the previous element
145: * @throws NoSuchElementException if there are no previous elements
146: */
147: public Object previous() throws NoSuchElementException {
148: if (currentIndex == 0) {
149: throw new NoSuchElementException();
150: }
151: --currentIndex;
152: return list.get(currentIndex);
153: }
154:
155: /**
156: * Returns the index of the previous element.
157: *
158: * @return the index of the previous element
159: */
160: public int previousIndex() {
161: return currentIndex - 1;
162: }
163:
164: /**
165: * Throws {@link UnsupportedOperationException}.
166: *
167: * @throws UnsupportedOperationException always
168: */
169: public void remove() throws UnsupportedOperationException {
170: throw new UnsupportedOperationException(
171: UNSUPPORTED_OPERATION_MESSAGE);
172: }
173:
174: /**
175: * Throws {@link UnsupportedOperationException}.
176: *
177: * @param obj the object to set, ignored
178: * @throws UnsupportedOperationException always
179: */
180: public void set(Object obj) throws UnsupportedOperationException {
181: throw new UnsupportedOperationException(
182: UNSUPPORTED_OPERATION_MESSAGE);
183: }
184:
185: // ResettableIterator interface
186: //-------------------------------------------------------------------------
187: /**
188: * Resets this iterator back to the position at which the iterator
189: * was created.
190: *
191: * @since Commons Collections 3.2
192: */
193: public void reset() {
194: currentIndex = 0;
195: }
196:
197: }
|