    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *      http://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 * Unless required by applicable law or agreed to in writing, software
    012 * distributed under the License is distributed on an "AS IS" BASIS,
    013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 * See the License for the specific language governing permissions and
    015 * limitations under the License.
    016 */
    017package org.apache.commons.collections4.iterators;
    018
    019import java.util.Iterator;
    020
    021import org.apache.commons.collections4.Transformer;
    022
    023/**
    024 * Decorates an iterator such that each element returned is transformed.
    025 *
    026 * @param <I> the type of the input to the function.
    027 * @param <O> the type of the result of the function.
    028 * @since 1.0
    029 */
    030public class TransformIterator<I, O> implements Iterator<O> {
    031
    032    /** The iterator being used */
    033    private Iterator<? extends I> iterator;
    034    /** The transformer being used */
    035    private Transformer<? super I, ? extends O> transformer;
    036
    037    /**
    038     * Constructs a new {@code TransformIterator} that will not function
    039     * until the {@link #setIterator(Iterator) setIterator} and
    040     * {@link #setTransformer(Transformer)} methods are invoked.
    041     */
    042    public TransformIterator() {
    043    }
    044
    045    /**
    046     * Constructs a new {@code TransformIterator} that won't transform
    047     * elements from the given iterator.
    048     *
    049     * @param iterator  the iterator to use
    050     */
    051    public TransformIterator(final Iterator<? extends I> iterator) {
    052        this.iterator = iterator;
    053    }
    054
    055    /**
    056     * Constructs a new {@code TransformIterator} that will use the
    057     * given iterator and transformer.  If the given transformer is null,
    058     * then objects will not be transformed.
    059     *
    060     * @param iterator  the iterator to use
    061     * @param transformer  the transformer to use
    062     */
    063    public TransformIterator(final Iterator<? extends I> iterator,
    064                             final Transformer<? super I, ? extends O> transformer) {
    065        this.iterator = iterator;
    066        this.transformer = transformer;
    067    }
    068
    069    /**
    070     * Gets the iterator this iterator is using.
    071     *
    072     * @return the iterator.
    073     */
    074    public Iterator<? extends I> getIterator() {
    075        return iterator;
    076    }
    077
    078    /**
    079     * Gets the transformer this iterator is using.
    080     *
    081     * @return the transformer.
    082     */
    083    public Transformer<? super I, ? extends O> getTransformer() {
    084        return transformer;
    085    }
    086
    087    @Override
    088    public boolean hasNext() {
    089        return iterator.hasNext();
    090    }
    091
    092    /**
    093     * Gets the next object from the iteration, transforming it using the
    094     * current transformer. If the transformer is null, no transformation
    095     * occurs and the object from the iterator is returned directly.
    096     *
    097     * @return the next object
    098     * @throws java.util.NoSuchElementException if there are no more elements
    099     */
    100    @Override
    101    public O next() {
    102        return transform(iterator.next());
    103    }
    104
    105    @Override
    106    public void remove() {
    107        iterator.remove();
    108    }
    109
    110    /**
    111     * Sets the iterator for this iterator to use.
    112     * If iteration has started, this effectively resets the iterator.
    113     *
    114     * @param iterator  the iterator to use
    115     */
    116    public void setIterator(final Iterator<? extends I> iterator) {
    117        this.iterator = iterator;
    118    }
    119
    120    /**
    121     * Sets the transformer this the iterator to use.
    122     * A null transformer is a no-op transformer.
    123     *
    124     * @param transformer  the transformer to use
    125     */
    126    public void setTransformer(final Transformer<? super I, ? extends O> transformer) {
    127        this.transformer = transformer;
    128    }
    129
    130    /**
    131     * Transforms the given object using the transformer.
    132     * If the transformer is null, the original object is returned as-is.
    133     *
    134     * @param source  the object to transform
    135     * @return the transformed object
    136     */
    137    protected O transform(final I source) {
    138        return transformer.apply(source);
    139    }
    140}