001: /*
002: * Janino - An embedded Java[TM] compiler
003: *
004: * Copyright (c) 2006, Arno Unkrig
005: * All rights reserved.
006: *
007: * Redistribution and use in source and binary forms, with or without
008: * modification, are permitted provided that the following conditions
009: * are met:
010: *
011: * 1. Redistributions of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: * 2. Redistributions in binary form must reproduce the above
014: * copyright notice, this list of conditions and the following
015: * disclaimer in the documentation and/or other materials
016: * provided with the distribution.
017: * 3. The name of the author may not be used to endorse or promote
018: * products derived from this software without specific prior
019: * written permission.
020: *
021: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
022: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
023: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
024: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
025: * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
026: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
027: * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
028: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
029: * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
030: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
031: * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
032: */
033:
034: package org.codehaus.janino.util;
035:
036: import java.util.*;
037:
038: /**
039: * An {@link java.util.Iterator} that traverses a {@link java.util.Collection} of
040: * {@link java.util.Iterator}s.
041: */
042: public class MultiIterator implements Iterator {
043: private static final Iterator AT_END = new Iterator() {
044: public boolean hasNext() {
045: return false;
046: }
047:
048: public Object next() {
049: throw new NoSuchElementException();
050: }
051:
052: public void remove() {
053: throw new UnsupportedOperationException();
054: }
055: };
056:
057: private final Iterator outer; // Over Iterators, Collections or arrays
058: private Iterator inner = MultiIterator.AT_END;
059:
060: /**
061: * @param iterators An array of {@link Iterator}s
062: */
063: public MultiIterator(Iterator[] iterators) {
064: this .outer = Arrays.asList(iterators).iterator();
065: }
066:
067: /**
068: * @param collections An array of {@link Collection}s
069: */
070: public MultiIterator(Collection[] collections) {
071: this .outer = Arrays.asList(collections).iterator();
072: }
073:
074: /**
075: * @param arrays An array of arrays
076: */
077: public MultiIterator(Object[][] arrays) {
078: this .outer = Arrays.asList(arrays).iterator();
079: }
080:
081: /**
082: * @param collection A {@link Collection} of {@link Collection}s, {@link Iterator}s and/or arrays
083: */
084: public MultiIterator(Collection collection) {
085: this .outer = collection.iterator();
086: }
087:
088: /**
089: * @param iterator An iterator over {@link Collection}s, {@link Iterator}s and/or arrays
090: */
091: public MultiIterator(Iterator iterator) {
092: this .outer = iterator;
093: }
094:
095: /**
096: * @param array An array of {@link Collection}s, {@link Iterator}s and/or arrays
097: */
098: public MultiIterator(Object[] array) {
099: this .outer = Arrays.asList(array).iterator();
100: }
101:
102: /**
103: * Iterates over the given {@link Collection}, prepended with the given {@link Object}.
104: */
105: public MultiIterator(Object object, Collection collection) {
106: this .outer = Arrays.asList(
107: new Object[] { new Object[] { object }, collection })
108: .iterator();
109: }
110:
111: /**
112: * Iterates over the given {@link Collection}, appended with the given {@link Object}.
113: */
114: public MultiIterator(Collection collection, Object object) {
115: this .outer = Arrays.asList(
116: new Object[] { collection, new Object[] { object } })
117: .iterator();
118: }
119:
120: /**
121: * Iterates over the given {@link Iterator}, prepended with the given <code>prefix</code>.
122: */
123: public MultiIterator(Object prefix, Iterator iterator) {
124: this .outer = Arrays.asList(
125: new Object[] { new Object[] { prefix }, iterator })
126: .iterator();
127: }
128:
129: /**
130: * Iterates over the given {@link Iterator}, appended with the given <code>suffix</code>.
131: */
132: public MultiIterator(Iterator iterator, Object suffix) {
133: this .outer = Arrays.asList(
134: new Object[] { iterator, new Object[] { suffix } })
135: .iterator();
136: }
137:
138: public boolean hasNext() {
139: for (;;) {
140: if (this .inner.hasNext())
141: return true;
142: if (!this .outer.hasNext())
143: return false;
144: Object o = this .outer.next();
145: if (o instanceof Iterator) {
146: this .inner = (Iterator) o;
147: } else if (o instanceof Collection) {
148: this .inner = ((Collection) o).iterator();
149: } else if (o instanceof Object[]) {
150: this .inner = Arrays.asList((Object[]) o).iterator();
151: } else {
152: throw new RuntimeException("Unexpected element type \""
153: + o.getClass().getName() + "\"");
154: }
155: }
156: }
157:
158: public Object next() {
159: if (this .hasNext())
160: return this .inner.next();
161: throw new NoSuchElementException();
162: }
163:
164: public void remove() {
165: this.inner.remove();
166: }
167: }
|