1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package fr.inrae.agroclim.indicators.resources;
18
19 import static java.lang.Math.abs;
20
21 import java.util.List;
22 import java.util.Locale;
23 import java.util.Objects;
24 import java.util.Optional;
25 import java.util.ResourceBundle;
26 import java.util.function.BiFunction;
27 import java.util.function.BiPredicate;
28 import java.util.function.Predicate;
29 import java.util.stream.Collectors;
30
31
32
33
34
35
36
37
38
39 public final class I18n {
40
41
42
43 public enum Operator implements BiFunction<Integer, Integer, Boolean> {
44
45
46
47 AEQ("=", Objects::equals),
48
49
50
51 BINFEQ("<=", (a, b) -> a <= b),
52
53
54
55 CINF("<", (a, b) -> a < b),
56
57
58
59 DSUPEQ(">=", (a, b) -> a >= b),
60
61
62
63 ESUP(">", (a, b) -> a > b);
64
65
66
67
68
69
70 static Optional<Operator> extract(final String string) {
71 for (final Operator op : values()) {
72 if (string.startsWith(op.symbol)) {
73 return Optional.of(op);
74 }
75 }
76 return Optional.empty();
77 }
78
79
80
81 private final BiPredicate<Integer, Integer> function;
82
83
84
85 private final String symbol;
86
87
88
89
90
91
92
93 Operator(final String string,
94 final BiPredicate<Integer, Integer> func) {
95 symbol = string;
96 function = func;
97 }
98
99 @Override
100 public Boolean apply(final Integer arg0, final Integer arg1) {
101 return function.test(arg0, arg1);
102 }
103
104
105
106
107 public int getLength() {
108 return symbol.length();
109 }
110 }
111
112
113
114
115
116
117 @SuppressWarnings("checkstyle:MagicNumber")
118 public enum PluralSuffix implements Predicate<Integer> {
119
120
121
122 NONE(nb -> nb == 0),
123
124
125
126 ONE(nb -> nb == 1),
127
128
129
130 TWO(nb -> nb == 2),
131
132
133
134 FEW(nb -> nb % 100 >= 3 && nb % 100 <= 10),
135
136
137
138 MANY(nb -> nb % 100 >= 11 && nb % 100 <= 99);
139
140
141
142
143
144
145
146 static Optional<String> getSuffix(final Integer value) {
147 for (final PluralSuffix suffix : values()) {
148 if (suffix.test(value)) {
149 return Optional.of(suffix.name().toLowerCase());
150 }
151 }
152 return Optional.empty();
153 }
154
155
156
157
158 private final Predicate<Integer> predicate;
159
160
161
162
163
164
165 PluralSuffix(final Predicate<Integer> pr) {
166 predicate = pr;
167 }
168
169 @Override
170 public boolean test(final Integer value) {
171 if (value != null) {
172 return predicate.test(abs(value));
173 }
174 return false;
175 }
176
177 }
178
179
180
181
182
183
184
185
186 static boolean matches(final String comparison, final int plural) {
187 final Optional<Operator> operator = Operator.extract(comparison);
188 if (operator.isPresent()) {
189 final Operator op = operator.get();
190 String val = comparison.substring(op.getLength());
191 if (val != null) {
192 val = val.trim();
193 if (!val.isEmpty()) {
194 final Integer value = Integer.valueOf(val);
195 return op.apply(plural, value);
196 }
197 }
198 }
199 return false;
200 }
201
202
203
204
205 private final Resources resources;
206
207
208
209
210
211
212 public I18n(final ResourceBundle bundle) {
213 resources = new Resources(bundle);
214 }
215
216
217
218
219
220
221
222 public I18n(final String bundleName, final Locale locale) {
223 resources = new Resources(bundleName, locale);
224 }
225
226
227
228
229
230
231
232
233
234 public String format(final int plural, final String key,
235 final Object... messageArguments) {
236 String keyWithSuffix;
237
238
239 keyWithSuffix = key + "[=" + plural + "]";
240 if (resources.getKeys().contains(keyWithSuffix)) {
241 return resources.format(keyWithSuffix, messageArguments);
242 }
243
244
245 final Optional<String> suffix = PluralSuffix.getSuffix(plural);
246 if (suffix.isPresent()) {
247 keyWithSuffix = key + "[" + suffix.get() + "]";
248 if (resources.getKeys().contains(keyWithSuffix)) {
249 return resources.format(keyWithSuffix, messageArguments);
250 }
251 }
252
253
254 final List<String> suffixes = resources.getKeys().stream()
255 .filter(k -> k.startsWith(key + "[") && k.endsWith("]"))
256 .map(k -> k.substring(key.length() + 1, k.length() - 1))
257 .collect(Collectors.toList());
258 for (final String suf: suffixes) {
259 if (matches(suf, plural)) {
260 keyWithSuffix = key + "[" + suf + "]";
261 return resources.format(keyWithSuffix, messageArguments);
262 }
263 }
264
265 return resources.format(key, messageArguments);
266 }
267
268
269
270
271
272
273
274
275 public String format(final String key,
276 final Object... messageArguments) {
277 return resources.format(key, messageArguments);
278 }
279
280
281
282
283
284
285
286 public String get(final String key) {
287 return resources.getString(key);
288 }
289
290
291
292
293 public String getBundleName() {
294 return resources.getBundleName();
295 }
296
297
298
299
300 public void setLocale(final Locale locale) {
301 resources.setLocale(locale);
302 }
303 }