View Javadoc

1   /*
2    * Copyright 2004-2005 the original author or authors.
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5    * use this file except in compliance with the License. You may obtain a copy of
6    * 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, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations under
14   * the License.
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 }