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.Predicate;
24 import org.apache.commons.collections4.Transformer;
25
26
27
28
29
30
31
32
33
34 public class SwitchTransformer<T, R> implements Transformer<T, R>, Serializable {
35
36
37 private static final long serialVersionUID = -6404460890903469332L;
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 @SuppressWarnings("unchecked")
59 public static <I, O> Transformer<I, O> switchTransformer(
60 final Map<? extends Predicate<? super I>, ? extends Transformer<? super I, ? extends O>> map) {
61
62 Objects.requireNonNull(map, "map");
63 if (map.isEmpty()) {
64 return ConstantTransformer.<I, O>nullTransformer();
65 }
66
67 final Transformer<? super I, ? extends O> defaultTransformer = map.remove(null);
68 final int size = map.size();
69 if (size == 0) {
70 return (Transformer<I, O>) (defaultTransformer == null ? ConstantTransformer.<I, O>nullTransformer() :
71 defaultTransformer);
72 }
73 final Transformer<? super I, ? extends O>[] transformers = new Transformer[size];
74 final Predicate<? super I>[] preds = new Predicate[size];
75 int i = 0;
76 for (final Map.Entry<? extends Predicate<? super I>,
77 ? extends Transformer<? super I, ? extends O>> entry : map.entrySet()) {
78 preds[i] = entry.getKey();
79 transformers[i] = entry.getValue();
80 i++;
81 }
82 return new SwitchTransformer<>(false, preds, transformers, defaultTransformer);
83 }
84
85
86
87
88
89
90
91
92
93
94
95
96
97 @SuppressWarnings("unchecked")
98 public static <I, O> Transformer<I, O> switchTransformer(final Predicate<? super I>[] predicates,
99 final Transformer<? super I, ? extends O>[] transformers,
100 final Transformer<? super I, ? extends O> defaultTransformer) {
101 FunctorUtils.validate(predicates);
102 FunctorUtils.validate(transformers);
103 if (predicates.length != transformers.length) {
104 throw new IllegalArgumentException("The predicate and transformer arrays must be the same size");
105 }
106 if (predicates.length == 0) {
107 return (Transformer<I, O>) (defaultTransformer == null ? ConstantTransformer.<I, O>nullTransformer() :
108 defaultTransformer);
109 }
110 return new SwitchTransformer<>(predicates, transformers, defaultTransformer);
111 }
112
113 private final Predicate<? super T>[] iPredicates;
114
115
116 private final Transformer<? super T, ? extends R>[] iTransformers;
117
118
119 private final Transformer<? super T, ? extends R> iDefault;
120
121
122
123
124
125
126
127
128
129 private SwitchTransformer(final boolean clone, final Predicate<? super T>[] predicates,
130 final Transformer<? super T, ? extends R>[] transformers,
131 final Transformer<? super T, ? extends R> defaultTransformer) {
132 iPredicates = clone ? FunctorUtils.copy(predicates) : predicates;
133 iTransformers = clone ? FunctorUtils.copy(transformers) : transformers;
134 iDefault = defaultTransformer == null ?
135 ConstantTransformer.<T, R>nullTransformer() : defaultTransformer;
136 }
137
138
139
140
141
142
143
144
145
146 public SwitchTransformer(final Predicate<? super T>[] predicates,
147 final Transformer<? super T, ? extends R>[] transformers,
148 final Transformer<? super T, ? extends R> defaultTransformer) {
149 this(true, predicates, transformers, defaultTransformer);
150 }
151
152
153
154
155
156
157
158 public Transformer<? super T, ? extends R> getDefaultTransformer() {
159 return iDefault;
160 }
161
162
163
164
165
166
167
168 public Predicate<? super T>[] getPredicates() {
169 return FunctorUtils.copy(iPredicates);
170 }
171
172
173
174
175
176
177
178 public Transformer<? super T, ? extends R>[] getTransformers() {
179 return FunctorUtils.copy(iTransformers);
180 }
181
182
183
184
185
186
187
188
189 @Override
190 public R transform(final T input) {
191 for (int i = 0; i < iPredicates.length; i++) {
192 if (iPredicates[i].test(input)) {
193 return iTransformers[i].apply(input);
194 }
195 }
196 return iDefault.apply(input);
197 }
198
199 }