1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package net.sf.morph.transform.support;
17
18 import java.util.ArrayList;
19 import java.util.Iterator;
20 import java.util.List;
21 import java.util.NoSuchElementException;
22
23 /**
24 * Reads the contents of an Iterator and saves them so that the Iterator can be
25 * iterated over multiple times.
26 *
27 * @author Matt Sgarlata
28 * @since Dec 5, 2004
29 */
30 public class ResetableIteratorWrapper implements Iterator {
31 private static final String NULL_ITERATOR = "The supplied iterator was null";
32 private static final String NEVER_SET = "You must set the iterator to wrap before calling this method";
33 private static final String ALREADY_SET = "You can only set the delegate iterator once";
34 private static final String NO_MORE = "There are no more elements to iterate over";
35
36 private boolean frozen;
37 private int index;
38 private List list;
39
40 public ResetableIteratorWrapper() {
41 this.frozen = false;
42 this.index = 0;
43 }
44
45 public ResetableIteratorWrapper(Iterator iterator) {
46 this();
47 setIterator(iterator);
48 }
49
50 public synchronized boolean hasNext() {
51 if (!frozen) {
52 throw new IllegalStateException(NEVER_SET);
53 }
54 return list != null && index < list.size();
55 }
56
57 public synchronized Object next() {
58 if (hasNext()) {
59 return list.get(index++);
60 }
61 throw new NoSuchElementException(NO_MORE);
62 }
63
64 public void remove() {
65 throw new UnsupportedOperationException();
66 }
67
68 public synchronized void reset() {
69 this.index = 0;
70 }
71
72 /**
73 * Returns a fresh copy of the wrapped iterator that is ready for another
74 * iteration.
75 *
76 * @return <code>null</code> if the delegate iterator was never set
77 */
78 public synchronized Iterator getIterator() {
79 return list == null ? null : list.iterator();
80 }
81
82 /**
83 * Sets the delegate iterator for this wrapper.
84 * @param iterator the Iterator to set
85 * @throws IllegalStateException if the iterator has already been set
86 * @throws IllegalArgumentException if the iterator is null
87 */
88 public synchronized void setIterator(Iterator iterator) {
89 if (frozen) {
90 throw new IllegalStateException(ALREADY_SET);
91 }
92 if (iterator == null) {
93 throw new IllegalArgumentException(NULL_ITERATOR);
94 }
95 this.frozen = true;
96 list = new ArrayList();
97 while (iterator.hasNext()) {
98 list.add(iterator.next());
99 }
100 }
101
102 /**
103 * Get the size of the underlying Iterator.
104 * @return int
105 */
106 public int size() {
107 if (!frozen) {
108 throw new IllegalStateException(NEVER_SET);
109 }
110 return list.size();
111 }
112
113 public String toString() {
114 return "ResetableIteratorWrapper" + list;
115 }
116
117 }