1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.collections4.functors;
18
19 import java.io.Serializable;
20 import java.util.Map;
21 import java.util.Objects;
22
23 import org.apache.commons.collections4.Closure;
24 import org.apache.commons.collections4.Predicate;
25
26
27
28
29
30
31
32
33 public class SwitchClosure<T> implements Closure<T>, Serializable {
34
35
36 private static final long serialVersionUID = 3518477308466486130L;
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 @SuppressWarnings("unchecked")
57 public static <E> Closure<E> switchClosure(final Map<Predicate<E>, Closure<E>> predicatesAndClosures) {
58 Objects.requireNonNull(predicatesAndClosures, "predicatesAndClosures");
59
60 final Closure<? super E> defaultClosure = predicatesAndClosures.remove(null);
61 final int size = predicatesAndClosures.size();
62 if (size == 0) {
63 return (Closure<E>) (defaultClosure == null ? NOPClosure.<E>nopClosure() : defaultClosure);
64 }
65 final Closure<E>[] closures = new Closure[size];
66 final Predicate<E>[] preds = new Predicate[size];
67 int i = 0;
68 for (final Map.Entry<Predicate<E>, Closure<E>> entry : predicatesAndClosures.entrySet()) {
69 preds[i] = entry.getKey();
70 closures[i] = entry.getValue();
71 i++;
72 }
73 return new SwitchClosure<>(false, preds, closures, defaultClosure);
74 }
75
76
77
78
79
80
81
82
83
84
85
86
87 @SuppressWarnings("unchecked")
88 public static <E> Closure<E> switchClosure(final Predicate<? super E>[] predicates,
89 final Closure<? super E>[] closures,
90 final Closure<? super E> defaultClosure) {
91 FunctorUtils.validate(predicates);
92 FunctorUtils.validate(closures);
93 if (predicates.length != closures.length) {
94 throw new IllegalArgumentException("The predicate and closure arrays must be the same size");
95 }
96 if (predicates.length == 0) {
97 return (Closure<E>) (defaultClosure == null ? NOPClosure.<E>nopClosure() : defaultClosure);
98 }
99 return new SwitchClosure<>(predicates, closures, defaultClosure);
100 }
101
102 private final Predicate<? super T>[] iPredicates;
103
104
105 private final Closure<? super T>[] iClosures;
106
107
108 private final Closure<? super T> iDefault;
109
110
111
112
113
114
115
116
117
118 private SwitchClosure(final boolean clone, final Predicate<? super T>[] predicates,
119 final Closure<? super T>[] closures, final Closure<? super T> defaultClosure) {
120 iPredicates = clone ? FunctorUtils.copy(predicates) : predicates;
121 iClosures = clone ? FunctorUtils.copy(closures) : closures;
122 iDefault = defaultClosure == null ? NOPClosure.<T>nopClosure() : defaultClosure;
123 }
124
125
126
127
128
129
130
131
132
133 public SwitchClosure(final Predicate<? super T>[] predicates, final Closure<? super T>[] closures,
134 final Closure<? super T> defaultClosure) {
135 this(true, predicates, closures, defaultClosure);
136 }
137
138
139
140
141
142
143 @Override
144 public void execute(final T input) {
145 for (int i = 0; i < iPredicates.length; i++) {
146 if (iPredicates[i].test(input)) {
147 iClosures[i].accept(input);
148 return;
149 }
150 }
151 iDefault.accept(input);
152 }
153
154
155
156
157
158
159
160 public Closure<? super T>[] getClosures() {
161 return FunctorUtils.copy(iClosures);
162 }
163
164
165
166
167
168
169
170 public Closure<? super T> getDefaultClosure() {
171 return iDefault;
172 }
173
174
175
176
177
178
179
180 public Predicate<? super T>[] getPredicates() {
181 return FunctorUtils.copy(iPredicates);
182 }
183
184 }