01: /**
02: * Copyright 2007 Jens Dietrich Licensed under the Apache License, Version 2.0 (the "License");
03: * you may not use this file except in compliance with the License.
04: * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
05: * Unless required by applicable law or agreed to in writing, software distributed under the
06: * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
07: * either express or implied. See the License for the specific language governing permissions
08: * and limitations under the License.
09: */package nz.org.take.rt;
10:
11: import java.util.ArrayList;
12: import java.util.List;
13:
14: /**
15: * Nested iterator.
16: * @author <a href="http://www-ist.massey.ac.nz/JBDietrich/">Jens Dietrich</a>
17: * @param <O> the outer iterator type
18: * @param <I> the inner iterator type
19: */
20: public abstract class NestedIterator<O, I> extends AbstractIterator<I> {
21:
22: private ResourceIterator<O> outerIterator = null;
23: private ResourceIterator<I> innerIterator = null;
24: private List<ResourceIterator> usedIterators = null;
25: private boolean exhausted = false;
26:
27: public NestedIterator(ResourceIterator<O> outerIterator) {
28: super ();
29: this .outerIterator = outerIterator;
30: }
31:
32: public boolean hasNext() {
33: if (exhausted)
34: return false;
35: boolean hasMore = false;
36: if (this .innerIterator == null || !this .innerIterator.hasNext()) {
37: while (!hasMore && !exhausted)
38: hasMore = moveCursor();
39: return !exhausted && this .innerIterator.hasNext();
40: } else
41: return true;
42: }
43:
44: public I next() {
45: if (hasNext())
46: return innerIterator.next();
47: else
48: return null;
49: }
50:
51: private boolean moveCursor() {
52: if (this .outerIterator.hasNext()) {
53: O selectedObject = this .outerIterator.next();
54: this .innerIterator = this .getNextIterator(selectedObject);
55: if (usedIterators == null) {
56: usedIterators = new ArrayList<ResourceIterator>();
57: }
58: usedIterators.add(innerIterator);
59: return innerIterator.hasNext();
60: } else {
61: exhausted = true;
62: return false;
63: }
64: }
65:
66: /**
67: * Get the iterator for the next object returned by the outer iterator.
68: * @param object an object
69: * @return an iterator.
70: */
71: protected abstract ResourceIterator<I> getNextIterator(O object);
72:
73: /**
74: * Close the iterator.
75: */
76: public void close() {
77: this .outerIterator.close();
78: if (usedIterators != null) {
79: for (ResourceIterator iter : this.usedIterators) {
80: iter.close();
81: }
82: }
83: this.usedIterators = null;
84: this.innerIterator = null;
85: this.outerIterator = null;
86:
87: }
88:
89: }
|