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