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