001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.collections.iterators;
018
019 import java.util.ListIterator;
020 import java.util.NoSuchElementException;
021
022 import org.apache.commons.collections.ResettableListIterator;
023
024 /**
025 * <code>SingletonIterator</code> is an {@link ListIterator} over a single
026 * object instance.
027 *
028 * @since Commons Collections 2.1
029 * @version $Revision: 646777 $ $Date: 2008-04-10 13:33:15 +0100 (Thu, 10 Apr 2008) $
030 *
031 * @author Stephen Colebourne
032 * @author Rodney Waldhoff
033 */
034 public class SingletonListIterator implements ListIterator, ResettableListIterator {
035
036 private boolean beforeFirst = true;
037 private boolean nextCalled = false;
038 private boolean removed = false;
039 private Object object;
040
041 /**
042 * Constructs a new <code>SingletonListIterator</code>.
043 *
044 * @param object the single object to return from the iterator
045 */
046 public SingletonListIterator(Object object) {
047 super();
048 this.object = object;
049 }
050
051 /**
052 * Is another object available from the iterator?
053 * <p>
054 * This returns true if the single object hasn't been returned yet.
055 *
056 * @return true if the single object hasn't been returned yet
057 */
058 public boolean hasNext() {
059 return beforeFirst && !removed;
060 }
061
062 /**
063 * Is a previous object available from the iterator?
064 * <p>
065 * This returns true if the single object has been returned.
066 *
067 * @return true if the single object has been returned
068 */
069 public boolean hasPrevious() {
070 return !beforeFirst && !removed;
071 }
072
073 /**
074 * Returns the index of the element that would be returned by a subsequent
075 * call to <tt>next</tt>.
076 *
077 * @return 0 or 1 depending on current state.
078 */
079 public int nextIndex() {
080 return (beforeFirst ? 0 : 1);
081 }
082
083 /**
084 * Returns the index of the element that would be returned by a subsequent
085 * call to <tt>previous</tt>. A return value of -1 indicates that the iterator is currently at
086 * the start.
087 *
088 * @return 0 or -1 depending on current state.
089 */
090 public int previousIndex() {
091 return (beforeFirst ? -1 : 0);
092 }
093
094 /**
095 * Get the next object from the iterator.
096 * <p>
097 * This returns the single object if it hasn't been returned yet.
098 *
099 * @return the single object
100 * @throws NoSuchElementException if the single object has already
101 * been returned
102 */
103 public Object next() {
104 if (!beforeFirst || removed) {
105 throw new NoSuchElementException();
106 }
107 beforeFirst = false;
108 nextCalled = true;
109 return object;
110 }
111
112 /**
113 * Get the previous object from the iterator.
114 * <p>
115 * This returns the single object if it has been returned.
116 *
117 * @return the single object
118 * @throws NoSuchElementException if the single object has not already
119 * been returned
120 */
121 public Object previous() {
122 if (beforeFirst || removed) {
123 throw new NoSuchElementException();
124 }
125 beforeFirst = true;
126 return object;
127 }
128
129 /**
130 * Remove the object from this iterator.
131 * @throws IllegalStateException if the <tt>next</tt> or <tt>previous</tt>
132 * method has not yet been called, or the <tt>remove</tt> method
133 * has already been called after the last call to <tt>next</tt>
134 * or <tt>previous</tt>.
135 */
136 public void remove() {
137 if(!nextCalled || removed) {
138 throw new IllegalStateException();
139 } else {
140 object = null;
141 removed = true;
142 }
143 }
144
145 /**
146 * Add always throws {@link UnsupportedOperationException}.
147 *
148 * @throws UnsupportedOperationException always
149 */
150 public void add(Object obj) {
151 throw new UnsupportedOperationException("add() is not supported by this iterator");
152 }
153
154 /**
155 * Set sets the value of the singleton.
156 *
157 * @param obj the object to set
158 * @throws IllegalStateException if <tt>next</tt> has not been called
159 * or the object has been removed
160 */
161 public void set(Object obj) {
162 if (!nextCalled || removed) {
163 throw new IllegalStateException();
164 }
165 this.object = obj;
166 }
167
168 /**
169 * Reset the iterator back to the start.
170 */
171 public void reset() {
172 beforeFirst = true;
173 nextCalled = false;
174 }
175
176 }