1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.functor.adapter;
18  
19  import java.io.Serializable;
20  
21  import org.apache.commons.functor.BinaryFunction;
22  import org.apache.commons.functor.BinaryPredicate;
23  import org.apache.commons.lang3.Validate;
24  
25  /**
26   * Adapts a <code>Boolean</code>-valued {@link BinaryFunction BinaryFunction} to
27   * the {@link BinaryPredicate BinaryPredicate} interface. <p> Note that although
28   * this class implements {@link Serializable}, a given instance will only be
29   * truly <code>Serializable</code> if the underlying functor is. Attempts to
30   * serialize an instance whose delegate is not <code>Serializable</code> will
31   * result in an exception. </p>
32   * @param <L> the left argument type.
33   * @param <R> the right argument type.
34   * @version $Revision: 1365377 $ $Date: 2012-07-24 21:59:23 -0300 (Tue, 24 Jul 2012) $
35   */
36  public final class BinaryFunctionBinaryPredicate<L, R> implements BinaryPredicate<L, R>, Serializable {
37      /**
38       * serialVersionUID declaration.
39       */
40      private static final long serialVersionUID = -5150315320718936186L;
41      /** The {@link BinaryFunction BinaryFunction} I'm wrapping. */
42      private final BinaryFunction<? super L, ? super R, Boolean> function;
43  
44      /**
45       * Create an {@link BinaryPredicate BinaryPredicate} wrapping the given
46       * {@link BinaryFunction BinaryFunction}.
47       * @param function the {@link BinaryFunction BinaryFunction} to wrap
48       */
49      public BinaryFunctionBinaryPredicate(final BinaryFunction<? super L, ? super R, Boolean> function) {
50          this.function = Validate.notNull(function, "BinaryFunction argument must not be null");
51      }
52  
53      /**
54       * {@inheritDoc} Returns the <code>boolean</code> value of the
55       * non-<code>null</code> <code>Boolean</code> returned by the
56       * {@link BinaryFunction#evaluate evaluate} method of my underlying
57       * function.
58       *
59       * The mehod throws NullPointerException if the underlying function returns
60       * <code>null</code>, and
61       * ClassCastException if the underlying function returns a
62       * non-<code>Boolean</code>
63       */
64      public boolean test(final L left, final R right) {
65          return function.evaluate(left, right).booleanValue();
66      }
67  
68      /**
69       * {@inheritDoc}
70       */
71      @Override
72      public boolean equals(final Object that) {
73          return that == this
74                  || (that instanceof BinaryFunctionBinaryPredicate<?, ?>
75                  && equals((BinaryFunctionBinaryPredicate<?, ?>) that));
76      }
77  
78      /**
79       * Learn whether another BinaryFunctionBinaryPredicate is equal to this.
80       * @param that BinaryFunctionBinaryPredicate to test
81       * @return boolean
82       */
83      public boolean equals(final BinaryFunctionBinaryPredicate<?, ?> that) {
84          return null != that && function.equals(that.function);
85      }
86  
87      /**
88       * {@inheritDoc}
89       */
90      @Override
91      public int hashCode() {
92          int hash = "BinaryFunctionBinaryPredicate".hashCode();
93          hash ^= function.hashCode();
94          return hash;
95      }
96  
97      /**
98       * {@inheritDoc}
99       */
100     @Override
101     public String toString() {
102         return "BinaryFunctionBinaryPredicate<" + function + ">";
103     }
104 
105     /**
106      * Adapt the given, possibly-<code>null</code>, {@link BinaryFunction
107      * BinaryFunction} to the {@link BinaryPredicate BinaryPredicate} interface.
108      * When the given <code>BinaryFunction</code> is <code>null</code>, returns
109      * <code>null</code>.
110      *
111      * @param <L> left type
112      * @param <R> right type
113      * @param <T> result type
114      * @param function the possibly-<code>null</code> {@link BinaryFunction
115      * BinaryFunction} to adapt
116      * @return a <code>BinaryFunctionBinaryPredicate</code> wrapping the given
117      * {@link BinaryFunction BinaryFunction}, or <code>null</code> if the given
118      * <code>BinaryFunction</code> is <code>null</code>
119      */
120     public static <L, R, T> BinaryFunctionBinaryPredicate<L, R> adapt(
121             final BinaryFunction<? super L, ? super R, Boolean> function) {
122         return null == function ? null : new BinaryFunctionBinaryPredicate<L, R>(function);
123     }
124 
125 }