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.BinaryFunction;
22  import org.apache.commons.functor.UnaryFunction;
23  
24  /**
25   * A {@link BinaryFunction BinaryFunction} composed of
26   * one binary function, <i>f</i>, and two unary
27   * functions, <i>g</i> and <i>h</i>,
28   * evaluating the ordered parameters <i>x</i>, <i>y</i>
29   * to <code><i>f</i>(<i>g</i>(<i>x</i>),<i>h</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 UnaryCompositeBinaryFunction<L, R, T> implements BinaryFunction<L, R, T>, Serializable {
42  
43      /**
44       * serialVersionUID declaration.
45       */
46      private static final long serialVersionUID = 264219357293822629L;
47  
48      private static class Helper<G, H, L, R, T> implements BinaryFunction<L, R, T>, Serializable {
49          /**
50           * serialVersionUID declaration.
51           */
52          private static final long serialVersionUID = 4513309646430305164L;
53          private BinaryFunction<? super G, ? super H, ? extends T> f;
54          private UnaryFunction<? super L, ? extends G> g;
55          private UnaryFunction<? super R, ? extends H> h;
56  
57          /**
58           * Create a new Helper.
59           * @param f BinaryFunction to receive <code>(output(g), output(h))</code>
60           * @param g left UnaryFunction
61           * @param h right UnaryFunction
62           */
63          public Helper(BinaryFunction<? super G, ? super H, ? extends T> f, UnaryFunction<? super L, ? extends G> g,
64                  UnaryFunction<? super R, ? extends H> h) {
65              this.f = f;
66              this.g = g;
67              this.h = h;
68          }
69  
70          /**
71           * {@inheritDoc}
72           */
73          public T evaluate(L left, R right) {
74              return f.evaluate(g.evaluate(left), h.evaluate(right));
75          }
76      }
77  
78      private final Helper<?, ?, L, R, T> helper;
79  
80      // constructor
81      // ------------------------------------------------------------------------
82      /**
83       * Create a new UnaryCompositeBinaryFunction.
84       * @param f BinaryFunction to receive <code>(output(g), output(h))</code>
85       * @param g left UnaryFunction
86       * @param h right UnaryFunction
87       */
88      public <G, H> UnaryCompositeBinaryFunction(BinaryFunction<? super G, ? super H, ? extends T> f,
89              UnaryFunction<? super L, ? extends G> g, UnaryFunction<? super R, ? extends H> h) {
90          if (f == null) {
91              throw new IllegalArgumentException("BinaryFunction must not be null");
92          }
93          if (g == null || h == null) {
94              throw new IllegalArgumentException("Left and right UnaryFunctions may not be null");
95          }
96          this.helper = new Helper<G, H, L, R, T>(f, g, h);
97      }
98  
99      // function interface
100     // ------------------------------------------------------------------------
101     /**
102      * {@inheritDoc}
103      */
104     public T evaluate(L left, R right) {
105         return helper.evaluate(left, right);
106     }
107 
108     /**
109      * {@inheritDoc}
110      */
111     public boolean equals(Object that) {
112         return that == this || (that instanceof UnaryCompositeBinaryFunction<?, ?, ?>
113                                     && equals((UnaryCompositeBinaryFunction<?, ?, ?>) that));
114     }
115 
116     /**
117      * Learn whether a given UnaryCompositeBinaryFunction is equal to this.
118      * @param that UnaryCompositeBinaryFunction to test
119      * @return boolean
120      */
121     public boolean equals(UnaryCompositeBinaryFunction<?, ?, ?> that) {
122         return null != that
123                 && helper.f.equals(that.helper.f)
124                 && helper.g.equals(that.helper.g)
125                 && helper.h.equals(that.helper.h);
126     }
127 
128     /**
129      * {@inheritDoc}
130      */
131     public int hashCode() {
132         int hash = "UnaryCompositeBinaryFunction".hashCode();
133         hash <<= 4;
134         hash ^= helper.f.hashCode();
135         hash <<= 4;
136         hash ^= helper.g.hashCode();
137         hash <<= 4;
138         hash ^= helper.h.hashCode();
139         return hash;
140     }
141 
142     /**
143      * {@inheritDoc}
144      */
145     public String toString() {
146         return "UnaryCompositeBinaryFunction<" + helper.f + ";" + helper.g + ";" + helper.h + ">";
147     }
148 
149 }