001: /*
002: * Copyright 1999-2004 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.ListIterator;
019: import java.util.NoSuchElementException;
020:
021: import org.apache.commons.collections.ResettableListIterator;
022:
023: /**
024: * Implements a {@link ListIterator} over an array of objects.
025: * <p>
026: * This iterator does not support {@link #add} or {@link #remove}, as the object array
027: * cannot be structurally modified. The {@link #set} method is supported however.
028: * <p>
029: * The iterator implements a {@link #reset} method, allowing the reset of the iterator
030: * back to the start if required.
031: *
032: * @see org.apache.commons.collections.iterators.ObjectArrayIterator
033: * @see java.util.Iterator
034: * @see java.util.ListIterator
035: *
036: * @since Commons Collections 3.0
037: * @version $Revision: 155406 $ $Date: 2005-02-26 12:55:26 +0000 (Sat, 26 Feb 2005) $
038: *
039: * @author Neil O'Toole
040: * @author Stephen Colebourne
041: * @author Phil Steitz
042: */
043: public class ObjectArrayListIterator extends ObjectArrayIterator
044: implements ListIterator, ResettableListIterator {
045:
046: /**
047: * Holds the index of the last item returned by a call to <code>next()</code>
048: * or <code>previous()</code>. This is set to <code>-1</code> if neither method
049: * has yet been invoked. <code>lastItemIndex</code> is used to to implement the
050: * {@link #set} method.
051: */
052: protected int lastItemIndex = -1;
053:
054: /**
055: * Constructor for use with <code>setArray</code>.
056: * <p>
057: * Using this constructor, the iterator is equivalent to an empty iterator
058: * until {@link #setArray} is called to establish the array to iterate over.
059: */
060: public ObjectArrayListIterator() {
061: super ();
062: }
063:
064: /**
065: * Constructs an ObjectArrayListIterator that will iterate over the values in the
066: * specified array.
067: *
068: * @param array the array to iterate over
069: * @throws NullPointerException if <code>array</code> is <code>null</code>
070: */
071: public ObjectArrayListIterator(Object[] array) {
072: super (array);
073: }
074:
075: /**
076: * Constructs an ObjectArrayListIterator that will iterate over the values in the
077: * specified array from a specific start index.
078: *
079: * @param array the array to iterate over
080: * @param start the index to start iterating at
081: * @throws NullPointerException if <code>array</code> is <code>null</code>
082: * @throws IndexOutOfBoundsException if the start index is out of bounds
083: */
084: public ObjectArrayListIterator(Object[] array, int start) {
085: super (array, start);
086: }
087:
088: /**
089: * Construct an ObjectArrayListIterator that will iterate over a range of values
090: * in the specified array.
091: *
092: * @param array the array to iterate over
093: * @param start the index to start iterating at
094: * @param end the index (exclusive) to finish iterating at
095: * @throws IndexOutOfBoundsException if the start or end index is out of bounds
096: * @throws IllegalArgumentException if end index is before the start
097: * @throws NullPointerException if <code>array</code> is <code>null</code>
098: */
099: public ObjectArrayListIterator(Object[] array, int start, int end) {
100: super (array, start, end);
101: }
102:
103: // ListIterator interface
104: //-------------------------------------------------------------------------
105:
106: /**
107: * Returns true if there are previous elements to return from the array.
108: *
109: * @return true if there is a previous element to return
110: */
111: public boolean hasPrevious() {
112: return (this .index > this .startIndex);
113: }
114:
115: /**
116: * Gets the previous element from the array.
117: *
118: * @return the previous element
119: * @throws NoSuchElementException if there is no previous element
120: */
121: public Object previous() {
122: if (hasPrevious() == false) {
123: throw new NoSuchElementException();
124: }
125: this .lastItemIndex = --this .index;
126: return this .array[this .index];
127: }
128:
129: /**
130: * Gets the next element from the array.
131: *
132: * @return the next element
133: * @throws NoSuchElementException if there is no next element
134: */
135: public Object next() {
136: if (hasNext() == false) {
137: throw new NoSuchElementException();
138: }
139: this .lastItemIndex = this .index;
140: return this .array[this .index++];
141: }
142:
143: /**
144: * Gets the next index to be retrieved.
145: *
146: * @return the index of the item to be retrieved next
147: */
148: public int nextIndex() {
149: return this .index - this .startIndex;
150: }
151:
152: /**
153: * Gets the index of the item to be retrieved if {@link #previous()} is called.
154: *
155: * @return the index of the item to be retrieved next
156: */
157: public int previousIndex() {
158: return this .index - this .startIndex - 1;
159: }
160:
161: /**
162: * This iterator does not support modification of its backing array's size, and so will
163: * always throw an {@link UnsupportedOperationException} when this method is invoked.
164: *
165: * @param obj the object to add
166: * @throws UnsupportedOperationException always thrown.
167: */
168: public void add(Object obj) {
169: throw new UnsupportedOperationException(
170: "add() method is not supported");
171: }
172:
173: /**
174: * Sets the element under the cursor.
175: * <p>
176: * This method sets the element that was returned by the last call
177: * to {@link #next()} of {@link #previous()}.
178: *
179: * <b>Note:</b> {@link ListIterator} implementations that support <code>add()</code>
180: * and <code>remove()</code> only allow <code>set()</code> to be called once per call
181: * to <code>next()</code> or <code>previous</code> (see the {@link ListIterator}
182: * javadoc for more details). Since this implementation does not support
183: * <code>add()</code> or <code>remove()</code>, <code>set()</code> may be
184: * called as often as desired.
185: *
186: * @param obj the object to set into the array
187: * @throws IllegalStateException if next() has not yet been called.
188: * @throws ClassCastException if the object type is unsuitable for the array
189: */
190: public void set(Object obj) {
191: if (this .lastItemIndex == -1) {
192: throw new IllegalStateException(
193: "must call next() or previous() before a call to set()");
194: }
195:
196: this .array[this .lastItemIndex] = obj;
197: }
198:
199: /**
200: * Resets the iterator back to the start index.
201: */
202: public void reset() {
203: super .reset();
204: this .lastItemIndex = -1;
205: }
206:
207: }
|