View Javadoc

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.core.composite;
18  
19  import java.io.Serializable;
20  
21  import org.apache.commons.functor.BinaryPredicate;
22  import org.apache.commons.functor.UnaryFunction;
23  
24  /**
25   * A {@link BinaryPredicate BinaryPredicate} composed of
26   * one binary predicate, <i>p</i>, and two unary
27   * functions, <i>f</i> and <i>g</i>,
28   * evaluating the ordered parameters <i>x</i>, <i>y</i>
29   * to <code><i>p</i>(<i>f</i>(<i>x</i>),<i>g</i>(<i>y</i>))</code>.
30   * <p>
31   * Note that although this class implements
32   * {@link Serializable}, a given instance will
33   * only be truly <code>Serializable</code> if all the
34   * underlying functors are.  Attempts to serialize
35   * an instance whose delegates are not all
36   * <code>Serializable</code> will result in an exception.
37   * </p>
38   * @version $Revision: 1156337 $ $Date: 2011-08-10 21:44:54 +0200 (Wed, 10 Aug 2011) $
39   * @author Rodney Waldhoff
40   */
41  public class UnaryCompositeBinaryPredicate<L, R> implements BinaryPredicate<L, R>, Serializable {
42      /**
43       * serialVersionUID declaration.
44       */
45      private static final long serialVersionUID = 3841123079006929493L;
46  
47      private static class Helper<G, H, L, R> implements BinaryPredicate<L, R>, Serializable {
48          /**
49           * serialVersionUID declaration.
50           */
51          private static final long serialVersionUID = -3463108273324567825L;
52          private BinaryPredicate<? super G, ? super H> f;
53          private UnaryFunction<? super L, ? extends G> g;
54          private UnaryFunction<? super R, ? extends H> h;
55  
56          /**
57           * Create a new Helper.
58           * @param f BinaryPredicate to test <i>output(</i><code>f</code><i>), output(</i><code>g</code><i>)</i>
59           * @param g left UnaryFunction
60           * @param h right UnaryFunction
61           */
62          public Helper(BinaryPredicate<? super G, ? super H> f, UnaryFunction<? super L, ? extends G> g,
63                  UnaryFunction<? super R, ? extends H> h) {
64              this.f = f;
65              this.g = g;
66              this.h = h;
67          }
68  
69          /**
70           * {@inheritDoc}
71           */
72          public boolean test(L left, R right) {
73              return f.test(g.evaluate(left), h.evaluate(right));
74          }
75      }
76  
77      // attributes
78      // ------------------------------------------------------------------------
79      private final Helper<?, ?, L, R> helper;
80  
81      // constructor
82      // ------------------------------------------------------------------------
83      /**
84       * Create a new UnaryCompositeBinaryPredicate.
85       * @param f BinaryPredicate to test <i>output(</i><code>f</code><i>), output(</i><code>g</code><i>)</i>
86       * @param g left UnaryFunction
87       * @param h right UnaryFunction
88       */
89      public <G, H> UnaryCompositeBinaryPredicate(final BinaryPredicate<? super G, ? super H> f,
90              final UnaryFunction<? super L, ? extends G> g, final UnaryFunction<? super R, ? extends H> h) {
91          if (f == null) {
92              throw new IllegalArgumentException("BinaryPredicate must not be null");
93          }
94          if (g == null || h == null) {
95              throw new IllegalArgumentException("Left and right UnaryFunctions may not be null");
96          }
97          helper = new Helper<G, H, L, R>(f, g, h);
98      }
99  
100     // function interface
101     // ------------------------------------------------------------------------
102     /**
103      * {@inheritDoc}
104      */
105     public boolean test(L left, R right) {
106         return helper.test(left, right);
107     }
108 
109     /**
110      * {@inheritDoc}
111      */
112     public boolean equals(Object that) {
113         return that == this || (that instanceof UnaryCompositeBinaryPredicate<?, ?>
114                                     && equals((UnaryCompositeBinaryPredicate<?, ?>) that));
115     }
116 
117     /**
118      * Learn whether another UnaryCompositeBinaryPredicate is equal to this.
119      * @param that UnaryCompositeBinaryPredicate to test
120      * @return boolean
121      */
122     public boolean equals(UnaryCompositeBinaryPredicate<?, ?> that) {
123         return null != that && helper.f.equals(that.helper.f) && helper.g.equals(that.helper.g)
124                 && helper.h.equals(that.helper.h);
125     }
126 
127     /**
128      * {@inheritDoc}
129      */
130     public int hashCode() {
131         int hash = "UnaryCompositeBinaryPredicate".hashCode();
132         hash <<= 4;
133         hash ^= helper.f.hashCode();
134         hash <<= 4;
135         hash ^= helper.g.hashCode();
136         hash <<= 4;
137         hash ^= helper.h.hashCode();
138         return hash;
139     }
140 
141     /**
142      * {@inheritDoc}
143      */
144     public String toString() {
145         return "UnaryCompositeBinaryPredicate<" + helper.f + ";" + helper.g + ";" + helper.h + ">";
146     }
147 
148 }