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 import org.apache.commons.lang3.Validate;
24
25 /**
26 * A BinaryFunction whose result is then run through a UnaryFunction.
27 *
28 * @param <L> the left argument type.
29 * @param <R> the right argument type.
30 * @param <T> the returned value type.
31 * @version $Revision: 1365329 $ $Date: 2012-07-24 19:34:23 -0300 (Tue, 24 Jul 2012) $
32 */
33 public class TransformedBinaryFunction<L, R, T> implements BinaryFunction<L, R, T>, Serializable {
34 /**
35 * serialVersionUID declaration.
36 */
37 private static final long serialVersionUID = 3312781645741807814L;
38
39 /**
40 * Type-remembering helper.
41 *
42 * @param <X> the following function left argument.
43 */
44 private static final class Helper<X, L, R, T> implements BinaryFunction<L, R, T>, Serializable {
45 /**
46 * serialVersionUID declaration.
47 */
48 private static final long serialVersionUID = 8141488776884860650L;
49 /**
50 * The preceding function.
51 */
52 private BinaryFunction<? super L, ? super R, ? extends X> preceding;
53 /**
54 * The following function.
55 */
56 private UnaryFunction<? super X, ? extends T> following;
57
58 /**
59 * Create a new Helper.
60 * @param preceding BinaryFunction
61 * @param following UnaryFunction
62 */
63 private Helper(BinaryFunction<? super L, ? super R, ? extends X> preceding,
64 UnaryFunction<? super X, ? extends T> following) {
65 this.preceding = Validate.notNull(preceding, "BinaryFunction argument was null");
66 this.following = Validate.notNull(following, "UnaryFunction argument was null");
67 }
68
69 /**
70 * {@inheritDoc}
71 */
72 public T evaluate(L left, R right) {
73 return following.evaluate(preceding.evaluate(left, right));
74 }
75 }
76
77 /**
78 * The adapted helper.
79 */
80 private final Helper<?, L, R, T> helper;
81
82 /**
83 * Create a new TransformedBinaryFunction.
84 * @param <X> the following function left argument.
85 * @param preceding BinaryFunction
86 * @param following UnaryFunction
87 */
88 public <X> TransformedBinaryFunction(BinaryFunction<? super L, ? super R, ? extends X> preceding,
89 UnaryFunction<? super X, ? extends T> following) {
90 this.helper = new Helper<X, L, R, T>(preceding, following);
91 }
92
93 /**
94 * {@inheritDoc}
95 */
96 public final T evaluate(L left, R right) {
97 return helper.evaluate(left, right);
98 }
99
100 /**
101 * {@inheritDoc}
102 */
103 @Override
104 public final boolean equals(Object obj) {
105 return obj == this || obj instanceof TransformedBinaryFunction<?, ?, ?>
106 && equals((TransformedBinaryFunction<?, ?, ?>) obj);
107 }
108
109 /**
110 * Learn whether another TransformedBinaryFunction is equal to <code>this</code>.
111 * @param that instance to test
112 * @return whether equal
113 */
114 public final boolean equals(TransformedBinaryFunction<?, ?, ?> that) {
115 return that != null && that.helper.preceding.equals(this.helper.preceding)
116 && that.helper.following.equals(this.helper.following);
117 }
118
119 /**
120 * {@inheritDoc}
121 */
122 @Override
123 public int hashCode() {
124 int result = "TransformedBinaryFunction".hashCode();
125 result <<= 2;
126 result |= helper.following.hashCode();
127 result <<= 2;
128 result |= helper.preceding.hashCode();
129 return result;
130 }
131
132 /**
133 * {@inheritDoc}
134 */
135 @Override
136 public String toString() {
137 return "TransformedBinaryFunction<" + helper.preceding + "; " + helper.following + ">";
138 }
139 }