1. /*
  2. * Copyright 1999-2004 The Apache Software Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.apache.commons.collections.iterators;
  17. import java.util.ListIterator;
  18. import java.util.NoSuchElementException;
  19. import org.apache.commons.collections.ResettableListIterator;
  20. /**
  21. * <code>SingletonIterator</code> is an {@link ListIterator} over a single
  22. * object instance.
  23. *
  24. * @since Commons Collections 2.1
  25. * @version $Revision: 1.13 $ $Date: 2004/02/18 00:59:50 $
  26. *
  27. * @author Stephen Colebourne
  28. * @author Rodney Waldhoff
  29. */
  30. public class SingletonListIterator implements ListIterator, ResettableListIterator {
  31. private boolean beforeFirst = true;
  32. private boolean nextCalled = false;
  33. private boolean removed = false;
  34. private Object object;
  35. /**
  36. * Constructs a new <code>SingletonListIterator</code>.
  37. *
  38. * @param object the single object to return from the iterator
  39. */
  40. public SingletonListIterator(Object object) {
  41. super();
  42. this.object = object;
  43. }
  44. /**
  45. * Is another object available from the iterator?
  46. * <p>
  47. * This returns true if the single object hasn't been returned yet.
  48. *
  49. * @return true if the single object hasn't been returned yet
  50. */
  51. public boolean hasNext() {
  52. return beforeFirst && !removed;
  53. }
  54. /**
  55. * Is a previous object available from the iterator?
  56. * <p>
  57. * This returns true if the single object has been returned.
  58. *
  59. * @return true if the single object has been returned
  60. */
  61. public boolean hasPrevious() {
  62. return !beforeFirst && !removed;
  63. }
  64. /**
  65. * Returns the index of the element that would be returned by a subsequent
  66. * call to <tt>next</tt>.
  67. *
  68. * @return 0 or 1 depending on current state.
  69. */
  70. public int nextIndex() {
  71. return (beforeFirst ? 0 : 1);
  72. }
  73. /**
  74. * Returns the index of the element that would be returned by a subsequent
  75. * call to <tt>previous</tt>. A return value of -1 indicates that the iterator is currently at
  76. * the start.
  77. *
  78. * @return 0 or -1 depending on current state.
  79. */
  80. public int previousIndex() {
  81. return (beforeFirst ? -1 : 0);
  82. }
  83. /**
  84. * Get the next object from the iterator.
  85. * <p>
  86. * This returns the single object if it hasn't been returned yet.
  87. *
  88. * @return the single object
  89. * @throws NoSuchElementException if the single object has already
  90. * been returned
  91. */
  92. public Object next() {
  93. if (!beforeFirst || removed) {
  94. throw new NoSuchElementException();
  95. }
  96. beforeFirst = false;
  97. nextCalled = true;
  98. return object;
  99. }
  100. /**
  101. * Get the previous object from the iterator.
  102. * <p>
  103. * This returns the single object if it has been returned.
  104. *
  105. * @return the single object
  106. * @throws NoSuchElementException if the single object has not already
  107. * been returned
  108. */
  109. public Object previous() {
  110. if (beforeFirst || removed) {
  111. throw new NoSuchElementException();
  112. }
  113. beforeFirst = true;
  114. return object;
  115. }
  116. /**
  117. * Remove the object from this iterator.
  118. * @throws IllegalStateException if the <tt>next</tt> or <tt>previous</tt>
  119. * method has not yet been called, or the <tt>remove</tt> method
  120. * has already been called after the last call to <tt>next</tt>
  121. * or <tt>previous</tt>.
  122. */
  123. public void remove() {
  124. if(!nextCalled || removed) {
  125. throw new IllegalStateException();
  126. } else {
  127. object = null;
  128. removed = true;
  129. }
  130. }
  131. /**
  132. * Add always throws {@link UnsupportedOperationException}.
  133. *
  134. * @throws UnsupportedOperationException always
  135. */
  136. public void add(Object obj) {
  137. throw new UnsupportedOperationException("add() is not supported by this iterator");
  138. }
  139. /**
  140. * Set sets the value of the singleton.
  141. *
  142. * @param obj the object to set
  143. * @throws IllegalStateException if <tt>next</tt> has not been called
  144. * or the object has been removed
  145. */
  146. public void set(Object obj) {
  147. if (!nextCalled || removed) {
  148. throw new IllegalStateException();
  149. }
  150. this.object = obj;
  151. }
  152. /**
  153. * Reset the iterator back to the start.
  154. */
  155. public void reset() {
  156. beforeFirst = true;
  157. nextCalled = false;
  158. }
  159. }