001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with this
004 * work for additional information regarding copyright ownership. The ASF
005 * licenses this file to You under the Apache License, Version 2.0 (the
006 * "License"); you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
009 * or agreed to in writing, software distributed under the License is
010 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
011 * KIND, either express or implied. See the License for the specific language
012 * governing permissions and limitations under the License.
013 */
014package org.apache.commons.collections4.iterators;
015
016import java.util.Iterator;
017
018import org.apache.commons.collections4.ResettableIterator;
019
020/**
021 * Adapter to make an {@link Iterator Iterator} instance appear to be an
022 * {@link Iterable Iterable} instance.  The iterable can be constructed in one
023 * of two variants:  single use, multiple use.
024 *
025 * <p>
026 * In the single use iterable case, the iterable is only usable for one
027 * iterative operation over the source iterator.  Subsequent iterative
028 * operations use the same, exhausted source iterator.  To create a single use
029 * iterable, construct a new {@link IteratorIterable} using a {@link Iterator}
030 * that is NOT a {@link ResettableIterator} iterator:
031 * <pre>
032 *   Iterator<Integer> iterator = // some non-resettable iterator
033 *   Iterable<Integer> iterable = new IteratorIterable<Integer>(iterator);
034 * </pre>
035 * </p>
036 *
037 * <p>
038 * In the multiple use iterable case, the iterable is usable for any number of
039 * iterative operations over the source iterator.  Of special note, even though
040 * the iterable supports multiple iterations, it does not support concurrent
041 * iterations. To implicitly create a multiple use iterable, construct a new
042 * {@link IteratorIterable} using a {@link ResettableIterator} iterator:
043 * <pre>
044 *   Integer[] array = {Integer.valueOf(1),Integer.valueOf(2),Integer.valueOf(3)};
045 *   Iterator<Integer> iterator = IteratorUtils.arrayIterator(array); // a resettable iterator
046 *   Iterable<Integer> iterable = new IteratorIterable<Integer>(iterator);
047 * </pre>
048 * </p>
049 *
050 * <p>
051 * A multiple use iterable can also be explicitly constructed using any
052 * {@link Iterator} and specifying <code>true</code> for the
053 * <code>multipleUse</code> flag:
054 * <pre>
055 *   Iterator<Integer> iterator = // some non-resettable iterator
056 *   Iterable<Integer> iterable = new IteratorIterable<Integer>(iterator, true);
057 * </pre>
058 * </p>
059 *
060 * @since 4.0
061 * @version $Id: IteratorIterable.html 972421 2015-11-14 20:00:04Z tn $
062 */
063public class IteratorIterable<E> implements Iterable<E> {
064
065    /**
066     * Factory method to create an {@link Iterator Iterator} from another
067     * iterator over objects of a different subtype.
068     */
069    private static <E> Iterator<E> createTypesafeIterator(
070            final Iterator<? extends E> iterator) {
071        return new Iterator<E>() {
072            public boolean hasNext() {
073                return iterator.hasNext();
074            }
075
076            public E next() {
077                return iterator.next();
078            }
079
080            public void remove() {
081                iterator.remove();
082            }
083        };
084    }
085
086    /** the iterator being adapted into an iterable. */
087    private final Iterator<? extends E> iterator;
088
089    /** the iterator parameterized as the {@link #iterator()} return type. */
090    private final Iterator<E> typeSafeIterator;
091
092    /**
093     * Constructs a new <code>IteratorIterable</code> that will use the given
094     * iterator.
095     *
096     * @param iterator the iterator to use.
097     */
098    public IteratorIterable(final Iterator<? extends E> iterator) {
099        this(iterator, false);
100    }
101
102    /**
103     * Constructs a new <code>IteratorIterable</code> that will use the given
104     * iterator.
105     *
106     * @param iterator the iterator to use.
107     * @param multipleUse <code>true</code> if the new iterable can be used in multiple iterations
108     */
109    public IteratorIterable(final Iterator<? extends E> iterator, final boolean multipleUse) {
110        super();
111        if (multipleUse && !(iterator instanceof ResettableIterator)) {
112            this.iterator = new ListIteratorWrapper<E>(iterator);
113        } else {
114            this.iterator = iterator;
115        }
116        this.typeSafeIterator = createTypesafeIterator(this.iterator);
117    }
118
119    /**
120     * Gets the iterator wrapped by this iterable.
121     *
122     * @return the iterator
123     */
124    public Iterator<E> iterator() {
125        if (iterator instanceof ResettableIterator) {
126            ((ResettableIterator<? extends E>)iterator).reset();
127        }
128        return typeSafeIterator;
129    }
130}