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.UnaryFunction;
22 import org.apache.commons.functor.UnaryPredicate;
23 import org.apache.commons.lang3.Validate;
24
25 /**
26 * A {@link UnaryFunction UnaryFunction}
27 * similiar to Java's "ternary"
28 * or "conditional" operator (<code>? :</code>).
29 * Given a {@link UnaryPredicate predicate}
30 * <i>p</i> and {@link UnaryFunction functions}
31 * <i>f</i> and <i>g</i>, {@link #evaluate evalautes}
32 * to
33 * <code>p.test(x) ? f.evaluate(x) : g.evaluate(x)</code>.
34 * <p>
35 * Note that although this class implements
36 * {@link Serializable}, a given instance will
37 * only be truly <code>Serializable</code> if all the
38 * underlying functors are. Attempts to serialize
39 * an instance whose delegates are not all
40 * <code>Serializable</code> will result in an exception.
41 * </p>
42 * @param <A> the argument type.
43 * @param <T> the returned value type.
44 * @version $Revision: 1365329 $ $Date: 2012-07-24 19:34:23 -0300 (Tue, 24 Jul 2012) $
45 */
46 public final class ConditionalUnaryFunction<A, T> implements UnaryFunction<A, T>, Serializable {
47 /**
48 * serialVersionUID declaration.
49 */
50 private static final long serialVersionUID = -8152490481969255068L;
51
52 /** Base hash integer used to shift hash. */
53 private static final int HASH_SHIFT = 4;
54 // attributes
55 // ------------------------------------------------------------------------
56 /**
57 * the condition to be evaluated.
58 */
59 private final UnaryPredicate<? super A> ifPred;
60 /**
61 * the function executed if the condition is satisfied.
62 */
63 private final UnaryFunction<? super A, ? extends T> thenFunc;
64 /**
65 * the function executed if the condition is not satisfied.
66 */
67 private final UnaryFunction<? super A, ? extends T> elseFunc;
68
69 // constructor
70 // ------------------------------------------------------------------------
71 /**
72 * Create a new ConditionalUnaryFunction.
73 * @param ifPred if
74 * @param thenFunc then
75 * @param elseFunc else
76 */
77 public ConditionalUnaryFunction(UnaryPredicate<? super A> ifPred, UnaryFunction<? super A, ? extends T> thenFunc,
78 UnaryFunction<? super A, ? extends T> elseFunc) {
79 this.ifPred = Validate.notNull(ifPred, "UnaryPredicate argument was null");
80 this.thenFunc = Validate.notNull(thenFunc, "'then' UnaryFunction argument was null");
81 this.elseFunc = Validate.notNull(elseFunc, "'else' UnaryFunction argument was null");
82 }
83
84 // predicate interface
85 // ------------------------------------------------------------------------
86 /**
87 * {@inheritDoc}
88 */
89 public T evaluate(A obj) {
90 if (ifPred.test(obj)) {
91 return thenFunc.evaluate(obj);
92 } else {
93 return elseFunc.evaluate(obj);
94 }
95 }
96
97 /**
98 * {@inheritDoc}
99 */
100 @Override
101 public boolean equals(Object that) {
102 return that == this || (that instanceof ConditionalUnaryFunction<?, ?>
103 && equals((ConditionalUnaryFunction<?, ?>) that));
104 }
105
106 /**
107 * Learn whether another ConditionalUnaryFunction is equal to this.
108 * @param that ConditionalUnaryFunction to test
109 * @return boolean
110 */
111 public boolean equals(ConditionalUnaryFunction<?, ?> that) {
112 return null != that
113 && ifPred.equals(that.ifPred)
114 && thenFunc.equals(that.thenFunc)
115 && elseFunc.equals(that.elseFunc);
116 }
117
118 /**
119 * {@inheritDoc}
120 */
121 @Override
122 public int hashCode() {
123 int hash = "ConditionalUnaryFunction".hashCode();
124 hash <<= HASH_SHIFT;
125 hash ^= ifPred.hashCode();
126 hash <<= HASH_SHIFT;
127 hash ^= thenFunc.hashCode();
128 hash <<= HASH_SHIFT;
129 hash ^= elseFunc.hashCode();
130 return hash;
131 }
132
133 /**
134 * {@inheritDoc}
135 */
136 @Override
137 public String toString() {
138 return "ConditionalUnaryFunction<" + ifPred + "?" + thenFunc + ":" + elseFunc + ">";
139 }
140
141 }