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.core.algorithm;
018
019import org.apache.commons.functor.BinaryPredicate;
020import org.apache.commons.functor.Predicate;
021import org.apache.commons.functor.Procedure;
022import org.apache.commons.functor.generator.Generator;
023
024/**
025 * Tests whether a {@link Generator} contains an element that matches a {@link Predicate}.
026 *
027 * @param <T> the predicate argument type.
028 * @version $Revision: 1537906 $ $Date: 2013-11-01 12:47:33 +0100 (Fr, 01 Nov 2013) $
029 */
030public final class GeneratorContains<T> implements BinaryPredicate<Generator<? extends T>, Predicate<? super T>> {
031    /**
032     * A static {@link GeneratorContains} instance reference.
033     */
034    private static final GeneratorContains<Object> INSTANCE = new GeneratorContains<Object>();
035
036    /**
037     * Helper procedure.
038     *
039     * @param <T> the predicate argument type.
040     */
041    private static class ContainsProcedure<T> implements Procedure<T> {
042        /**
043         * The wrapped predicate.
044         */
045        private final Predicate<? super T> pred;
046        /**
047         * Flag to mark if the wrapped predicate succeeded or not.
048         */
049        private boolean found;
050
051        /**
052         * Create a new ContainsProcedure.
053         *
054         * @param pred The wrapped predicate
055         */
056        public ContainsProcedure(Predicate<? super T> pred) {
057            this.pred = pred;
058        }
059
060        /**
061         * {@inheritDoc}
062         */
063        public void run(T obj) {
064            found |= pred.test(obj);
065        }
066    }
067
068    /**
069     * {@inheritDoc}
070     * @param left Generator
071     * @param right Predicate
072     */
073    public boolean test(Generator<? extends T> left, Predicate<? super T> right) {
074        ContainsProcedure<T> findProcedure = new ContainsProcedure<T>(right);
075        left.run(findProcedure);
076        return findProcedure.found;
077    }
078
079    /**
080     * {@inheritDoc}
081     */
082    @Override
083    public boolean equals(Object obj) {
084        return obj == this || obj != null && obj.getClass().equals(getClass());
085    }
086
087    /**
088     * {@inheritDoc}
089     */
090    @Override
091    public int hashCode() {
092        return System.identityHashCode(INSTANCE);
093    }
094
095    /**
096     * {@inheritDoc}
097     */
098    @Override
099    public String toString() {
100        return "GeneratorContains";
101    }
102
103    /**
104     * Get a static {@link GeneratorContains} instance.
105     * @return {@link GeneratorContains}
106     */
107    public static GeneratorContains<Object> instance() {
108        return INSTANCE;
109    }
110}