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 }