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.adapter;
018
019import org.apache.commons.functor.Function;
020import org.apache.commons.functor.Predicate;
021import org.apache.commons.lang3.Validate;
022
023/**
024 * Adapts a <code>Boolean</code>-valued
025 * {@link Function Function}
026 * to the {@link Predicate Predicate}
027 * interface.
028 *
029 * @param <A> the argument type.
030 * @version $Revision: 1537906 $ $Date: 2013-11-01 12:47:33 +0100 (Fr, 01 Nov 2013) $
031 */
032public final class FunctionPredicate<A> implements Predicate<A> {
033    /** The {@link Function Function} I'm wrapping. */
034    private final Function<? super A, Boolean> function;
035
036    /**
037     * Create an {@link Predicate Predicate} wrapping
038     * the given {@link Function Function}.
039     * @param function the {@link Function Function} to wrap
040     */
041    public FunctionPredicate(Function<? super A, Boolean> function) {
042        this.function = Validate.notNull(function, "Function argument was null");
043    }
044
045    /**
046     * {@inheritDoc}
047     * Returns the <code>boolean</code> value of the non-<code>null</code>
048     * <code>Boolean</code> returned by the {@link Function#evaluate evaluate}
049     * method of my underlying function.
050     */
051    public boolean test(A obj) {
052        return function.evaluate(obj).booleanValue();
053    }
054
055    /**
056     * {@inheritDoc}
057     */
058    @Override
059    public boolean equals(Object obj) {
060        if (obj == this) {
061            return true;
062        }
063        if (!(obj instanceof FunctionPredicate<?>)) {
064            return false;
065        }
066        FunctionPredicate<?> that = (FunctionPredicate<?>) obj;
067        return this.function.equals(that.function);
068    }
069
070    /**
071     * {@inheritDoc}
072     */
073    @Override
074    public int hashCode() {
075        int hash = "FunctionPredicate".hashCode();
076        hash ^= function.hashCode();
077        return hash;
078    }
079
080    /**
081     * {@inheritDoc}
082     */
083    @Override
084    public String toString() {
085        return "FunctionPredicate<" + function + ">";
086    }
087
088    /**
089     * Adapt the given, possibly-<code>null</code>,
090     * {@link Function Function} to the
091     * {@link Predicate Predicate} interface.
092     * When the given <code>Function</code> is <code>null</code>,
093     * returns <code>null</code>.
094     *
095     * @param <A> the argument type.
096     * @param function the possibly-<code>null</code>
097     *        {@link Function Function} to adapt
098     * @return a {@link Predicate Predicate} wrapping the given
099     *         {@link Function Function}, or <code>null</code>
100     *         if the given <code>Function</code> is <code>null</code>
101     */
102    public static <A> FunctionPredicate<A> adapt(Function<? super A, Boolean> function) {
103        return null == function ? null : new FunctionPredicate<A>(function);
104    }
105
106}