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.UnaryPredicate;
22 import org.apache.commons.functor.UnaryProcedure;
23 import org.apache.commons.functor.core.NoOp;
24
25 /**
26 * A {@link UnaryProcedure UnaryProcedure}
27 * similiar to Java's "ternary"
28 * or "conditional" operator (<code>? :</code>).
29 * Given a {@link UnaryPredicate predicate}
30 * <i>p</i> and {@link UnaryProcedure procedures}
31 * <i>q</i> and <i>r</i>, {@link #run runs}
32 * <code>if (p.test(x)) { q.run(x); } else { r.run(x); }</code>.
33 * <p>
34 * Note that although this class implements
35 * {@link Serializable}, a given instance will
36 * only be truly <code>Serializable</code> if all the
37 * underlying functors are. Attempts to serialize
38 * an instance whose delegates are not all
39 * <code>Serializable</code> will result in an exception.
40 * </p>
41 * @version $Revision: 1170782 $ $Date: 2011-09-14 21:18:31 +0200 (Wed, 14 Sep 2011) $
42 * @author Rodney Waldhoff
43 */
44 public final class ConditionalUnaryProcedure<A> implements UnaryProcedure<A>, Serializable {
45 /**
46 * serialVersionUID declaration.
47 */
48 private static final long serialVersionUID = -895833369740247391L;
49
50 /** Base hash integer used to shift hash */
51 private static final int HASH_SHIFT = 4;
52 // attributes
53 // ------------------------------------------------------------------------
54 private final UnaryPredicate<? super A> ifPred;
55 private final UnaryProcedure<? super A> thenProc;
56 private final UnaryProcedure<? super A> elseProc;
57
58 // constructor
59 // ------------------------------------------------------------------------
60 /**
61 * Create a new ConditionalUnaryProcedure.
62 * @param ifPred if
63 * @param thenProc then
64 */
65 public ConditionalUnaryProcedure(UnaryPredicate<? super A> ifPred, UnaryProcedure<? super A> thenProc) {
66 this(ifPred, thenProc, NoOp.instance());
67 }
68
69 /**
70 * Create a new ConditionalUnaryProcedure.
71 * @param ifPred if
72 * @param thenProc then
73 * @param elseProc else
74 */
75 public ConditionalUnaryProcedure(UnaryPredicate<? super A> ifPred,
76 UnaryProcedure<? super A> thenProc,
77 UnaryProcedure<? super A> elseProc) {
78 if (ifPred == null) {
79 throw new IllegalArgumentException("UnaryPredicate argument was null");
80 }
81 this.ifPred = ifPred;
82 if (thenProc == null || elseProc == null) {
83 throw new IllegalArgumentException("One or more UnaryProcedure arguments was null");
84 }
85 this.thenProc = thenProc;
86 this.elseProc = elseProc;
87 }
88
89 // predicate interface
90 // ------------------------------------------------------------------------
91 /**
92 * {@inheritDoc}
93 */
94 public void run(A obj) {
95 if (ifPred.test(obj)) {
96 thenProc.run(obj);
97 } else {
98 elseProc.run(obj);
99 }
100 }
101
102 /**
103 * {@inheritDoc}
104 */
105 public boolean equals(Object that) {
106 return that == this || (that instanceof ConditionalUnaryProcedure<?>
107 && equals((ConditionalUnaryProcedure<?>) that));
108 }
109
110 /**
111 * Learn whether another ConditionalUnaryProcedure is equal to this.
112 * @param that ConditionalUnaryProcedure to test
113 * @return boolean
114 */
115 public boolean equals(ConditionalUnaryProcedure<?> that) {
116 return null != that
117 && (null == ifPred ? null == that.ifPred : ifPred.equals(that.ifPred))
118 && (null == thenProc ? null == that.thenProc : thenProc.equals(that.thenProc))
119 && (null == elseProc ? null == that.elseProc : elseProc.equals(that.elseProc));
120 }
121
122 /**
123 * {@inheritDoc}
124 */
125 public int hashCode() {
126 int hash = "ConditionalUnaryProcedure".hashCode();
127 if (null != ifPred) {
128 hash <<= HASH_SHIFT;
129 hash ^= ifPred.hashCode();
130 }
131 if (null != thenProc) {
132 hash <<= HASH_SHIFT;
133 hash ^= thenProc.hashCode();
134 }
135 if (null != elseProc) {
136 hash <<= HASH_SHIFT;
137 hash ^= elseProc.hashCode();
138 }
139 return hash;
140 }
141
142 /**
143 * {@inheritDoc}
144 */
145 public String toString() {
146 return "ConditionalUnaryProcedure<" + ifPred + "?" + thenProc + ":" + elseProc + ">";
147 }
148
149 }