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.BinaryPredicate;
020import org.apache.commons.functor.NullaryPredicate;
021import org.apache.commons.lang3.Validate;
022
023/**
024 * Adapts a
025 * {@link BinaryPredicate BinaryPredicate}
026 * to the
027 * {@link org.apache.commons.functor.NullaryPredicate NullaryPredicate} interface
028 * using a constant left-side argument.
029 *
030 * @version $Revision: 1365377 $ $Date: 2012-07-24 21:59:23 -0300 (Tue, 24 Jul 2012) $
031 */
032public final class FullyBoundNullaryPredicate implements NullaryPredicate {
033
034    /** The {@link BinaryPredicate BinaryPredicate} I'm wrapping. */
035    private final BinaryPredicate<Object, Object> predicate;
036    /** The left parameter to pass to {@code predicate}. */
037    private final Object left;
038    /** The right parameter to pass to {@code predicate}. */
039    private final Object right;
040
041    /**
042     * Create a new FullyBoundNullaryPredicate instance.
043     * @param <L> left type
044     * @param <R> right type
045     * @param predicate the predicate to adapt
046     * @param left the left argument to use
047     * @param right the right argument to use
048     */
049    @SuppressWarnings("unchecked")
050    public <L, R> FullyBoundNullaryPredicate(BinaryPredicate<? super L, ? super R> predicate, L left, R right) {
051        this.predicate =
052            (BinaryPredicate<Object, Object>) Validate.notNull(predicate,
053                "BinaryPredicate argument was null");
054        this.left = left;
055        this.right = right;
056    }
057
058    /**
059     * {@inheritDoc}
060     */
061    public boolean test() {
062        return predicate.test(left, right);
063    }
064
065    /**
066     * {@inheritDoc}
067     */
068    @Override
069    public boolean equals(Object obj) {
070        if (obj == this) {
071            return true;
072        }
073        if (!(obj instanceof FullyBoundNullaryPredicate)) {
074            return false;
075        }
076        FullyBoundNullaryPredicate that = (FullyBoundNullaryPredicate) obj;
077        return predicate.equals(that.predicate)
078                && (null == left ? null == that.left : left.equals(that.left))
079                && (null == right ? null == that.right : right.equals(that.right));
080    }
081
082    /**
083     * {@inheritDoc}
084     */
085    @Override
086    public int hashCode() {
087        int hash = "FullyBoundNullaryPredicate".hashCode();
088        hash <<= 2;
089        hash ^= predicate.hashCode();
090        hash <<= 2;
091        if (null != left) {
092            hash ^= left.hashCode();
093        }
094        hash <<= 2;
095        if (null != right) {
096            hash ^= right.hashCode();
097        }
098        return hash;
099    }
100
101    /**
102     * {@inheritDoc}
103     */
104    @Override
105    public String toString() {
106        return "FullyBoundNullaryPredicate<" + predicate + "(" + left + ", " + right + ")>";
107    }
108
109    /**
110     * Adapt a BinaryPredicate to the NullaryPredicate interface.
111     * @param predicate to adapt
112     * @param <L> left type
113     * @param <R> right type
114     * @param left L argument to always send as the left operand to the wrapped function
115     * @param right R argument to always send as the right operand to the wrapped function
116     * @return FullyBoundNullaryPredicate
117     */
118    public static <L, R> FullyBoundNullaryPredicate bind(
119            BinaryPredicate<? super L, ? super R> predicate, L left, R right) {
120        return null == predicate ? null : new FullyBoundNullaryPredicate(predicate, left, right);
121    }
122}