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 }