mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Matthew Swift
25.33.2012 263d085885df024dca9250cc03c807912b0a7662
opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/util/Iterators.java
@@ -6,17 +6,16 @@
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opendj3/legal-notices/CDDLv1_0.txt
 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
 * or http://forgerock.org/license/CDDLv1.0.html.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opendj3/legal-notices/CDDLv1_0.txt.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 * file and include the License file at legal-notices/CDDLv1_0.txt.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
@@ -27,521 +26,391 @@
package com.forgerock.opendj.util;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
 * Utility methods for manipulating {@link Iterator}s.
 */
public final class Iterators
{
  private static final class ArrayIterator<M> implements Iterator<M>
  {
    private int i = 0;
    private final M[] a;
public final class Iterators {
    private static final class ArrayIterator<M> implements Iterator<M> {
        private int i = 0;
        private final M[] a;
    // Constructed via factory methods.
    private ArrayIterator(final M[] a)
    {
      this.a = a;
    }
    /**
     * {@inheritDoc}
     */
    public boolean hasNext()
    {
      return i < a.length;
    }
    /**
     * {@inheritDoc}
     */
    public M next()
    {
      if (hasNext())
      {
        return a[i++];
      }
      else
      {
        throw new NoSuchElementException();
      }
    }
    /**
     * {@inheritDoc}
     */
    public void remove()
    {
      throw new UnsupportedOperationException();
    }
  };
  private static final class EmptyIterator<M> implements Iterator<M>
  {
    /**
     * {@inheritDoc}
     */
    public boolean hasNext()
    {
      return false;
    }
    /**
     * {@inheritDoc}
     */
    public M next()
    {
      throw new NoSuchElementException();
    }
    /**
     * {@inheritDoc}
     */
    public void remove()
    {
      throw new UnsupportedOperationException();
    }
  }
  private static final class FilteredIterator<M, P> implements Iterator<M>
  {
    private boolean hasNextMustIterate = true;
    private final Iterator<M> iterator;
    private M next = null;
    private final P parameter;
    private final Predicate<? super M, P> predicate;
    // Constructed via factory methods.
    private FilteredIterator(final Iterator<M> iterator,
        final Predicate<? super M, P> predicate, final P p)
    {
      this.iterator = iterator;
      this.predicate = predicate;
      this.parameter = p;
    }
    /**
     * {@inheritDoc}
     */
    public boolean hasNext()
    {
      if (hasNextMustIterate)
      {
        hasNextMustIterate = false;
        while (iterator.hasNext())
        {
          next = iterator.next();
          if (predicate.matches(next, parameter))
          {
            return true;
          }
        // Constructed via factory methods.
        private ArrayIterator(final M[] a) {
            this.a = a;
        }
        next = null;
        return false;
      }
      else
      {
        return next != null;
      }
        /**
         * {@inheritDoc}
         */
        public boolean hasNext() {
            return i < a.length;
        }
        /**
         * {@inheritDoc}
         */
        public M next() {
            if (hasNext()) {
                return a[i++];
            } else {
                throw new NoSuchElementException();
            }
        }
        /**
         * {@inheritDoc}
         */
        public void remove() {
            throw new UnsupportedOperationException();
        }
    };
    private static final class EmptyIterator<M> implements Iterator<M> {
        /**
         * {@inheritDoc}
         */
        public boolean hasNext() {
            return false;
        }
        /**
         * {@inheritDoc}
         */
        public M next() {
            throw new NoSuchElementException();
        }
        /**
         * {@inheritDoc}
         */
        public void remove() {
            throw new UnsupportedOperationException();
        }
    }
    private static final class FilteredIterator<M, P> implements Iterator<M> {
        private boolean hasNextMustIterate = true;
        private final Iterator<M> iterator;
        private M next = null;
        private final P parameter;
        private final Predicate<? super M, P> predicate;
        // Constructed via factory methods.
        private FilteredIterator(final Iterator<M> iterator,
                final Predicate<? super M, P> predicate, final P p) {
            this.iterator = iterator;
            this.predicate = predicate;
            this.parameter = p;
        }
        /**
         * {@inheritDoc}
         */
        public boolean hasNext() {
            if (hasNextMustIterate) {
                hasNextMustIterate = false;
                while (iterator.hasNext()) {
                    next = iterator.next();
                    if (predicate.matches(next, parameter)) {
                        return true;
                    }
                }
                next = null;
                return false;
            } else {
                return next != null;
            }
        }
        /**
         * {@inheritDoc}
         */
        public M next() {
            if (!hasNext()) {
                throw new NoSuchElementException();
            }
            hasNextMustIterate = true;
            return next;
        }
        /**
         * {@inheritDoc}
         */
        public void remove() {
            iterator.remove();
        }
    }
    private static final class SingletonIterator<M> implements Iterator<M> {
        private M value;
        // Constructed via factory methods.
        private SingletonIterator(final M value) {
            this.value = value;
        }
        /**
         * {@inheritDoc}
         */
        public boolean hasNext() {
            return value != null;
        }
        /**
         * {@inheritDoc}
         */
        public M next() {
            if (value != null) {
                final M tmp = value;
                value = null;
                return tmp;
            } else {
                throw new NoSuchElementException();
            }
        }
        /**
         * {@inheritDoc}
         */
        public void remove() {
            throw new UnsupportedOperationException();
        }
    }
    private static final class TransformedIterator<M, N, P> implements Iterator<N> {
        private final Function<? super M, ? extends N, P> function;
        private final Iterator<M> iterator;
        private final P parameter;
        // Constructed via factory methods.
        private TransformedIterator(final Iterator<M> iterator,
                final Function<? super M, ? extends N, P> function, final P p) {
            this.iterator = iterator;
            this.function = function;
            this.parameter = p;
        }
        /**
         * {@inheritDoc}
         */
        public boolean hasNext() {
            return iterator.hasNext();
        }
        /**
         * {@inheritDoc}
         */
        public N next() {
            return function.apply(iterator.next(), parameter);
        }
        /**
         * {@inheritDoc}
         */
        public void remove() {
            iterator.remove();
        }
    }
    private static final class UnmodifiableIterator<M> implements Iterator<M> {
        private final Iterator<M> iterator;
        private UnmodifiableIterator(final Iterator<M> iterator) {
            this.iterator = iterator;
        }
        /**
         * {@inheritDoc}
         */
        public boolean hasNext() {
            return iterator.hasNext();
        }
        /**
         * {@inheritDoc}
         */
        public M next() {
            return iterator.next();
        }
        /**
         * {@inheritDoc}
         */
        public void remove() {
            throw new UnsupportedOperationException();
        }
    }
    private static final Iterator<Object> EMPTY_ITERATOR = new EmptyIterator<Object>();
    /**
     * {@inheritDoc}
     * Returns an iterator over the elements contained in {@code a}. The
     * returned iterator does not support element removal via the
     * {@code remove()} method.
     *
     * @param <M>
     *            The type of elements contained in {@code a}.
     * @param a
     *            The array of elements to be returned by the iterator.
     * @return An iterator over the elements contained in {@code a}.
     */
    public M next()
    {
      if (!hasNext())
      {
        throw new NoSuchElementException();
      }
      hasNextMustIterate = true;
      return next;
    public static <M> Iterator<M> arrayIterator(final M[] a) {
        return new ArrayIterator<M>(a);
    }
    /**
     * {@inheritDoc}
     * Returns an immutable empty iterator.
     *
     * @param <M>
     *            The required type of the empty iterator.
     * @return An immutable empty iterator.
     */
    public void remove()
    {
      iterator.remove();
    @SuppressWarnings("unchecked")
    public static <M> Iterator<M> emptyIterator() {
        return (Iterator<M>) EMPTY_ITERATOR;
    }
  }
  private static final class SingletonIterator<M> implements Iterator<M>
  {
    private M value;
    // Constructed via factory methods.
    private SingletonIterator(final M value)
    {
      this.value = value;
    }
    /**
     * {@inheritDoc}
     * Returns a filtered view of {@code iterator} containing only those
     * elements which match {@code predicate}. The returned iterator supports
     * element removal via the {@code remove()} method subject to any
     * constraints imposed by {@code iterator}.
     *
     * @param <M>
     *            The type of elements contained in {@code iterator}.
     * @param <P>
     *            The type of the additional parameter to the predicate's
     *            {@code matches} method. Use {@link java.lang.Void} for
     *            predicates that do not need an additional parameter.
     * @param iterator
     *            The iterator to be filtered.
     * @param predicate
     *            The predicate.
     * @param p
     *            A predicate specified parameter.
     * @return A filtered view of {@code iterator} containing only those
     *         elements which match {@code predicate}.
     */
    public boolean hasNext()
    {
      return value != null;
    public static <M, P> Iterator<M> filteredIterator(final Iterator<M> iterator,
            final Predicate<? super M, P> predicate, final P p) {
        return new FilteredIterator<M, P>(iterator, predicate, p);
    }
    /**
     * {@inheritDoc}
     * Returns a filtered view of {@code iterator} containing only those
     * elements which match {@code predicate}. The returned iterator supports
     * element removal via the {@code remove()} method subject to any
     * constraints imposed by {@code iterator}.
     *
     * @param <M>
     *            The type of elements contained in {@code iterator}.
     * @param iterator
     *            The iterator to be filtered.
     * @param predicate
     *            The predicate.
     * @return A filtered view of {@code iterator} containing only those
     *         elements which match {@code predicate}.
     */
    public M next()
    {
      if (value != null)
      {
        final M tmp = value;
        value = null;
        return tmp;
      }
      else
      {
        throw new NoSuchElementException();
      }
    public static <M> Iterator<M> filteredIterator(final Iterator<M> iterator,
            final Predicate<? super M, Void> predicate) {
        return new FilteredIterator<M, Void>(iterator, predicate, null);
    }
    /**
     * {@inheritDoc}
     * Returns an iterator containing the single element {@code value}. The
     * returned iterator does not support element removal via the
     * {@code remove()} method.
     *
     * @param <M>
     *            The type of the single element {@code value}.
     * @param value
     *            The single element to be returned by the iterator.
     * @return An iterator containing the single element {@code value}.
     */
    public void remove()
    {
      throw new UnsupportedOperationException();
    public static <M> Iterator<M> singletonIterator(final M value) {
        return new SingletonIterator<M>(value);
    }
  }
  private static final class TransformedIterator<M, N, P> implements
      Iterator<N>
  {
    private final Function<? super M, ? extends N, P> function;
    private final Iterator<M> iterator;
    private final P parameter;
    // Constructed via factory methods.
    private TransformedIterator(final Iterator<M> iterator,
        final Function<? super M, ? extends N, P> function, final P p)
    {
      this.iterator = iterator;
      this.function = function;
      this.parameter = p;
    }
    /**
     * {@inheritDoc}
     * Returns a view of {@code iterator} whose values have been mapped to
     * elements of type {@code N} using {@code function}. The returned iterator
     * supports element removal via the {@code remove()} method subject to any
     * constraints imposed by {@code iterator}.
     *
     * @param <M>
     *            The type of elements contained in {@code iterator}.
     * @param <N>
     *            The type of elements contained in the returned iterator.
     * @param <P>
     *            The type of the additional parameter to the function's
     *            {@code apply} method. Use {@link java.lang.Void} for functions
     *            that do not need an additional parameter.
     * @param iterator
     *            The iterator to be transformed.
     * @param function
     *            The function.
     * @param p
     *            A predicate specified parameter.
     * @return A view of {@code iterator} whose values have been mapped to
     *         elements of type {@code N} using {@code function}.
     */
    public boolean hasNext()
    {
      return iterator.hasNext();
    public static <M, N, P> Iterator<N> transformedIterator(final Iterator<M> iterator,
            final Function<? super M, ? extends N, P> function, final P p) {
        return new TransformedIterator<M, N, P>(iterator, function, p);
    }
    /**
     * {@inheritDoc}
     * Returns a view of {@code iterator} whose values have been mapped to
     * elements of type {@code N} using {@code function}. The returned iterator
     * supports element removal via the {@code remove()} method subject to any
     * constraints imposed by {@code iterator}.
     *
     * @param <M>
     *            The type of elements contained in {@code iterator}.
     * @param <N>
     *            The type of elements contained in the returned iterator.
     * @param iterator
     *            The iterator to be transformed.
     * @param function
     *            The function.
     * @return A view of {@code iterator} whose values have been mapped to
     *         elements of type {@code N} using {@code function}.
     */
    public N next()
    {
      return function.apply(iterator.next(), parameter);
    public static <M, N> Iterator<N> transformedIterator(final Iterator<M> iterator,
            final Function<? super M, ? extends N, Void> function) {
        return new TransformedIterator<M, N, Void>(iterator, function, null);
    }
    /**
     * {@inheritDoc}
     * Returns a read-only view of {@code iterator} which does not support
     * element removal via the {@code remove()}. Attempts to use the
     * {@code remove()} method will result in a
     * {@code UnsupportedOperationException}.
     *
     * @param <M>
     *            The type of elements contained in {@code iterator}.
     * @param iterator
     *            The iterator to be made read-only.
     * @return A read-only view of {@code iterator} which does not support
     *         element removal via the {@code remove()}.
     */
    public void remove()
    {
      iterator.remove();
    public static <M> Iterator<M> unmodifiableIterator(final Iterator<M> iterator) {
        return new UnmodifiableIterator<M>(iterator);
    }
  }
  private static final class UnmodifiableIterator<M> implements Iterator<M>
  {
    private final Iterator<M> iterator;
    private UnmodifiableIterator(final Iterator<M> iterator)
    {
      this.iterator = iterator;
    // Prevent instantiation
    private Iterators() {
        // Do nothing.
    }
    /**
     * {@inheritDoc}
     */
    public boolean hasNext()
    {
      return iterator.hasNext();
    }
    /**
     * {@inheritDoc}
     */
    public M next()
    {
      return iterator.next();
    }
    /**
     * {@inheritDoc}
     */
    public void remove()
    {
      throw new UnsupportedOperationException();
    }
  }
  private static final Iterator<Object> EMPTY_ITERATOR = new EmptyIterator<Object>();
  /**
   * Returns an iterator over the elements contained in {@code a}. The returned
   * iterator does not support element removal via the {@code remove()} method.
   *
   * @param <M>
   *          The type of elements contained in {@code a}.
   * @param a
   *          The array of elements to be returned by the iterator.
   * @return An iterator over the elements contained in {@code a}.
   */
  public static <M> Iterator<M> arrayIterator(final M[] a)
  {
    return new ArrayIterator<M>(a);
  }
  /**
   * Returns an immutable empty iterator.
   *
   * @param <M>
   *          The required type of the empty iterator.
   * @return An immutable empty iterator.
   */
  @SuppressWarnings("unchecked")
  public static <M> Iterator<M> emptyIterator()
  {
    return (Iterator<M>) EMPTY_ITERATOR;
  }
  /**
   * Returns a filtered view of {@code iterator} containing only those elements
   * which match {@code predicate}. The returned iterator supports element
   * removal via the {@code remove()} method subject to any constraints imposed
   * by {@code iterator}.
   *
   * @param <M>
   *          The type of elements contained in {@code iterator}.
   * @param <P>
   *          The type of the additional parameter to the predicate's
   *          {@code matches} method. Use {@link java.lang.Void} for predicates
   *          that do not need an additional parameter.
   * @param iterator
   *          The iterator to be filtered.
   * @param predicate
   *          The predicate.
   * @param p
   *          A predicate specified parameter.
   * @return A filtered view of {@code iterator} containing only those elements
   *         which match {@code predicate}.
   */
  public static <M, P> Iterator<M> filteredIterator(final Iterator<M> iterator,
      final Predicate<? super M, P> predicate, final P p)
  {
    return new FilteredIterator<M, P>(iterator, predicate, p);
  }
  /**
   * Returns a filtered view of {@code iterator} containing only those elements
   * which match {@code predicate}. The returned iterator supports element
   * removal via the {@code remove()} method subject to any constraints imposed
   * by {@code iterator}.
   *
   * @param <M>
   *          The type of elements contained in {@code iterator}.
   * @param iterator
   *          The iterator to be filtered.
   * @param predicate
   *          The predicate.
   * @return A filtered view of {@code iterator} containing only those elements
   *         which match {@code predicate}.
   */
  public static <M> Iterator<M> filteredIterator(final Iterator<M> iterator,
      final Predicate<? super M, Void> predicate)
  {
    return new FilteredIterator<M, Void>(iterator, predicate, null);
  }
  /**
   * Returns an iterator containing the single element {@code value}. The
   * returned iterator does not support element removal via the {@code remove()}
   * method.
   *
   * @param <M>
   *          The type of the single element {@code value}.
   * @param value
   *          The single element to be returned by the iterator.
   * @return An iterator containing the single element {@code value}.
   */
  public static <M> Iterator<M> singletonIterator(final M value)
  {
    return new SingletonIterator<M>(value);
  }
  /**
   * Returns a view of {@code iterator} whose values have been mapped to
   * elements of type {@code N} using {@code function}. The returned iterator
   * supports element removal via the {@code remove()} method subject to any
   * constraints imposed by {@code iterator}.
   *
   * @param <M>
   *          The type of elements contained in {@code iterator}.
   * @param <N>
   *          The type of elements contained in the returned iterator.
   * @param <P>
   *          The type of the additional parameter to the function's
   *          {@code apply} method. Use {@link java.lang.Void} for functions
   *          that do not need an additional parameter.
   * @param iterator
   *          The iterator to be transformed.
   * @param function
   *          The function.
   * @param p
   *          A predicate specified parameter.
   * @return A view of {@code iterator} whose values have been mapped to
   *         elements of type {@code N} using {@code function}.
   */
  public static <M, N, P> Iterator<N> transformedIterator(
      final Iterator<M> iterator,
      final Function<? super M, ? extends N, P> function, final P p)
  {
    return new TransformedIterator<M, N, P>(iterator, function, p);
  }
  /**
   * Returns a view of {@code iterator} whose values have been mapped to
   * elements of type {@code N} using {@code function}. The returned iterator
   * supports element removal via the {@code remove()} method subject to any
   * constraints imposed by {@code iterator}.
   *
   * @param <M>
   *          The type of elements contained in {@code iterator}.
   * @param <N>
   *          The type of elements contained in the returned iterator.
   * @param iterator
   *          The iterator to be transformed.
   * @param function
   *          The function.
   * @return A view of {@code iterator} whose values have been mapped to
   *         elements of type {@code N} using {@code function}.
   */
  public static <M, N> Iterator<N> transformedIterator(
      final Iterator<M> iterator,
      final Function<? super M, ? extends N, Void> function)
  {
    return new TransformedIterator<M, N, Void>(iterator, function, null);
  }
  /**
   * Returns a read-only view of {@code iterator} which does not support element
   * removal via the {@code remove()}. Attempts to use the {@code remove()}
   * method will result in a {@code UnsupportedOperationException}.
   *
   * @param <M>
   *          The type of elements contained in {@code iterator}.
   * @param iterator
   *          The iterator to be made read-only.
   * @return A read-only view of {@code iterator} which does not support element
   *         removal via the {@code remove()}.
   */
  public static <M> Iterator<M> unmodifiableIterator(final Iterator<M> iterator)
  {
    return new UnmodifiableIterator<M>(iterator);
  }
  // Prevent instantiation
  private Iterators()
  {
    // Do nothing.
  }
}