001/*
002 * Licensed under the Apache License, Version 2.0 (the "License");
003 * you may not use this file except in compliance with the License.
004 * You may obtain a copy of the License at
005 *
006 *      http://www.apache.org/licenses/LICENSE-2.0
007 *
008 * Unless required by applicable law or agreed to in writing, software
009 * distributed under the License is distributed on an "AS IS" BASIS,
010 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
011 * See the License for the specific language governing permissions and
012 * limitations under the License.
013 */
014
015package org.apache.commons.functor.generator;
016
017import java.util.Collection;
018
019import org.apache.commons.functor.UnaryFunction;
020import org.apache.commons.functor.generator.util.CollectionTransformer;
021
022/**
023 * Base class for generators. Adds support for all of the Algorithms to
024 * each subclass.
025 *
026 * @param <E> the type of elements held in this generator.
027 * @since 1.0
028 * @version $Revision: 1370922 $ $Date: 2012-08-08 15:53:37 -0400 (Wed, 08 Aug 2012) $
029 */
030public abstract class BaseGenerator<E> implements Generator<E> {
031
032    /** A generator can wrap another generator. */
033    private final Generator<?> wrappedGenerator;
034
035    /** Set to true when the generator is {@link #stop stopped}. */
036    private boolean stopped = false;
037
038    /** Create a new generator. */
039    public BaseGenerator() {
040        this(null);
041    }
042
043    /**
044     * A generator can wrap another generator. When wrapping generators you
045     * should use probably this constructor since doing so will cause the
046     * {@link #stop} method to stop the wrapped generator as well.
047     * @param generator Generator to wrap
048     */
049    public BaseGenerator(Generator<?> generator) {
050        this.wrappedGenerator = generator;
051    }
052
053    /**
054     * Get the generator that is being wrapped.
055     * @return Generator
056     */
057    protected Generator<?> getWrappedGenerator() {
058        return wrappedGenerator;
059    }
060
061    /**
062     * {@inheritDoc}
063     * Stop the generator. Will stop the wrapped generator if one was set.
064     */
065    public void stop() {
066        if (wrappedGenerator != null) {
067            wrappedGenerator.stop();
068        }
069        stopped = true;
070    }
071
072    /**
073     * {@inheritDoc}
074     * Check if the generator is stopped.
075     */
076    public boolean isStopped() {
077        return stopped;
078    }
079
080    /**
081     * {@inheritDoc}
082     * Transforms this generator using the passed in
083     * UnaryFunction. An example function might turn the contents of the
084     * generator into a {@link Collection} of elements.
085     */
086    public final <T> T to(UnaryFunction<Generator<? extends E>, ? extends T> transformer) {
087        return transformer.evaluate(this);
088    }
089
090    /**
091     * {@inheritDoc}
092     * Same as to(new CollectionTransformer(collection)).
093     */
094    public final <C extends Collection<? super E>> C to(C collection) {
095        return to(new CollectionTransformer<E, C>(collection));
096    }
097
098    /**
099     * {@inheritDoc}
100     * Same as to(new CollectionTransformer()).
101     */
102    public final Collection<E> toCollection() {
103        return to(CollectionTransformer.<E> toCollection());
104    }
105}