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.functor.generator;
018
019import org.apache.commons.functor.Predicate;
020import org.apache.commons.functor.Procedure;
021import org.apache.commons.functor.core.composite.ConditionalProcedure;
022import org.apache.commons.lang3.Validate;
023
024/**
025 * Generator that filters another Generator by only passing through those elements
026 * that are matched by a specified Predicate.
027 *
028 * @param <E> the type of elements held in this generator.
029 * @version $Revision: 1522355 $ $Date: 2013-09-12 06:29:46 +0200 (Do, 12 Sep 2013) $
030 */
031public class FilteredGenerator<E> extends BaseGenerator<E> {
032
033    /**
034     * A generator can wrap another generator.
035     * */
036    private Generator<? extends E> wrappedGenerator;
037
038    /**
039     * The predicate used to filter.
040     */
041    private final Predicate<? super E> pred;
042
043    /**
044     * Create a new FilteredGenerator.
045     * @param wrapped Generator to wrap
046     * @param pred filtering Predicate
047     */
048    public FilteredGenerator(Generator<? extends E> wrapped, Predicate<? super E> pred) {
049        this.wrappedGenerator = Validate.notNull(wrapped, "Generator argument was null");
050        this.pred = Validate.notNull(pred, "Predicate argument was null");
051    }
052
053    /**
054     * {@inheritDoc}
055     */
056    public void run(Procedure<? super E> proc) {
057        getWrappedGenerator().run(new ConditionalProcedure<E>(pred, proc));
058    }
059
060    /**
061     * Get the generator that is being wrapped.
062     * @return Generator
063     */
064    protected Generator<? extends E> getWrappedGenerator() {
065        return this.wrappedGenerator;
066    }
067
068    /**
069     * {@inheritDoc}
070     */
071    @Override
072    public boolean equals(Object obj) {
073        if (obj == this) {
074            return true;
075        }
076        if (!(obj instanceof FilteredGenerator<?>)) {
077            return false;
078        }
079        FilteredGenerator<?> other = (FilteredGenerator<?>) obj;
080        return other.getWrappedGenerator().equals(getWrappedGenerator()) && other.pred.equals(pred);
081    }
082
083    /**
084     * {@inheritDoc}
085     */
086    @Override
087    public int hashCode() {
088        int result = "FilteredGenerator".hashCode();
089        result <<= 2;
090        Generator<?> gen = getWrappedGenerator();
091        result ^= gen.hashCode();
092        result <<= 2;
093        result ^= pred.hashCode();
094        return result;
095    }
096}