1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.logging.log4j.core.config.plugins.convert;
19
20 import java.io.File;
21 import java.math.BigDecimal;
22 import java.math.BigInteger;
23 import java.net.InetAddress;
24 import java.net.MalformedURLException;
25 import java.net.URI;
26 import java.net.URISyntaxException;
27 import java.net.URL;
28 import java.nio.charset.Charset;
29 import java.nio.file.Path;
30 import java.nio.file.Paths;
31 import java.security.Provider;
32 import java.security.Security;
33 import java.util.UUID;
34 import java.util.regex.Pattern;
35
36 import org.apache.logging.log4j.Level;
37 import org.apache.logging.log4j.Logger;
38 import org.apache.logging.log4j.core.appender.rolling.action.Duration;
39 import org.apache.logging.log4j.core.config.plugins.Plugin;
40 import org.apache.logging.log4j.core.util.CronExpression;
41 import org.apache.logging.log4j.status.StatusLogger;
42 import org.apache.logging.log4j.util.LoaderUtil;
43
44
45
46
47
48
49
50 public final class TypeConverters {
51
52
53
54
55
56
57 public static final String CATEGORY = "TypeConverter";
58
59
60
61
62 @Plugin(name = "BigDecimal", category = CATEGORY)
63 public static class BigDecimalConverter implements TypeConverter<BigDecimal> {
64 @Override
65 public BigDecimal convert(final String s) {
66 return new BigDecimal(s);
67 }
68 }
69
70
71
72
73 @Plugin(name = "BigInteger", category = CATEGORY)
74 public static class BigIntegerConverter implements TypeConverter<BigInteger> {
75 @Override
76 public BigInteger convert(final String s) {
77 return new BigInteger(s);
78 }
79 }
80
81
82
83
84 @Plugin(name = "Boolean", category = CATEGORY)
85 public static class BooleanConverter implements TypeConverter<Boolean> {
86 @Override
87 public Boolean convert(final String s) {
88 return Boolean.valueOf(s);
89 }
90 }
91
92
93
94
95
96
97
98
99
100
101
102 @Plugin(name = "ByteArray", category = CATEGORY)
103 public static class ByteArrayConverter implements TypeConverter<byte[]> {
104
105 private static final String PREFIX_0x = "0x";
106 private static final String PREFIX_BASE64 = "Base64:";
107
108 @Override
109 public byte[] convert(final String value) {
110 byte[] bytes;
111 if (value == null || value.isEmpty()) {
112 bytes = new byte[0];
113 } else if (value.startsWith(PREFIX_BASE64)) {
114 final String lexicalXSDBase64Binary = value.substring(PREFIX_BASE64.length());
115 bytes = Base64Converter.parseBase64Binary(lexicalXSDBase64Binary);
116 } else if (value.startsWith(PREFIX_0x)) {
117 final String lexicalXSDHexBinary = value.substring(PREFIX_0x.length());
118 bytes = HexConverter.parseHexBinary(lexicalXSDHexBinary);
119 } else {
120 bytes = value.getBytes(Charset.defaultCharset());
121 }
122 return bytes;
123 }
124 }
125
126
127
128
129 @Plugin(name = "Byte", category = CATEGORY)
130 public static class ByteConverter implements TypeConverter<Byte> {
131 @Override
132 public Byte convert(final String s) {
133 return Byte.valueOf(s);
134 }
135 }
136
137
138
139
140 @Plugin(name = "Character", category = CATEGORY)
141 public static class CharacterConverter implements TypeConverter<Character> {
142 @Override
143 public Character convert(final String s) {
144 if (s.length() != 1) {
145 throw new IllegalArgumentException("Character string must be of length 1: " + s);
146 }
147 return Character.valueOf(s.toCharArray()[0]);
148 }
149 }
150
151
152
153
154 @Plugin(name = "CharacterArray", category = CATEGORY)
155 public static class CharArrayConverter implements TypeConverter<char[]> {
156 @Override
157 public char[] convert(final String s) {
158 return s.toCharArray();
159 }
160 }
161
162
163
164
165 @Plugin(name = "Charset", category = CATEGORY)
166 public static class CharsetConverter implements TypeConverter<Charset> {
167 @Override
168 public Charset convert(final String s) {
169 return Charset.forName(s);
170 }
171 }
172
173
174
175
176 @Plugin(name = "Class", category = CATEGORY)
177 public static class ClassConverter implements TypeConverter<Class<?>> {
178 @Override
179 public Class<?> convert(final String s) throws ClassNotFoundException {
180 switch (s.toLowerCase()) {
181 case "boolean":
182 return boolean.class;
183 case "byte":
184 return byte.class;
185 case "char":
186 return char.class;
187 case "double":
188 return double.class;
189 case "float":
190 return float.class;
191 case "int":
192 return int.class;
193 case "long":
194 return long.class;
195 case "short":
196 return short.class;
197 case "void":
198 return void.class;
199 default:
200 return LoaderUtil.loadClass(s);
201 }
202
203 }
204 }
205
206 @Plugin(name = "CronExpression", category = CATEGORY)
207 public static class CronExpressionConverter implements TypeConverter<CronExpression> {
208 @Override
209 public CronExpression convert(final String s) throws Exception {
210 return new CronExpression(s);
211 }
212 }
213
214
215
216
217 @Plugin(name = "Double", category = CATEGORY)
218 public static class DoubleConverter implements TypeConverter<Double> {
219 @Override
220 public Double convert(final String s) {
221 return Double.valueOf(s);
222 }
223 }
224
225
226
227
228
229 @Plugin(name = "Duration", category = CATEGORY)
230 public static class DurationConverter implements TypeConverter<Duration> {
231 @Override
232 public Duration convert(final String s) {
233 return Duration.parse(s);
234 }
235 }
236
237
238
239
240 @Plugin(name = "File", category = CATEGORY)
241 public static class FileConverter implements TypeConverter<File> {
242 @Override
243 public File convert(final String s) {
244 return new File(s);
245 }
246 }
247
248
249
250
251 @Plugin(name = "Float", category = CATEGORY)
252 public static class FloatConverter implements TypeConverter<Float> {
253 @Override
254 public Float convert(final String s) {
255 return Float.valueOf(s);
256 }
257 }
258
259
260
261
262 @Plugin(name = "InetAddress", category = CATEGORY)
263 public static class InetAddressConverter implements TypeConverter<InetAddress> {
264 @Override
265 public InetAddress convert(final String s) throws Exception {
266 return InetAddress.getByName(s);
267 }
268 }
269
270
271
272
273 @Plugin(name = "Integer", category = CATEGORY)
274 public static class IntegerConverter implements TypeConverter<Integer> {
275 @Override
276 public Integer convert(final String s) {
277 return Integer.valueOf(s);
278 }
279 }
280
281
282
283
284 @Plugin(name = "Level", category = CATEGORY)
285 public static class LevelConverter implements TypeConverter<Level> {
286 @Override
287 public Level convert(final String s) {
288 return Level.valueOf(s);
289 }
290 }
291
292
293
294
295 @Plugin(name = "Long", category = CATEGORY)
296 public static class LongConverter implements TypeConverter<Long> {
297 @Override
298 public Long convert(final String s) {
299 return Long.valueOf(s);
300 }
301 }
302
303
304
305
306
307 @Plugin(name = "Path", category = CATEGORY)
308 public static class PathConverter implements TypeConverter<Path> {
309 @Override
310 public Path convert(final String s) throws Exception {
311 return Paths.get(s);
312 }
313 }
314
315
316
317
318 @Plugin(name = "Pattern", category = CATEGORY)
319 public static class PatternConverter implements TypeConverter<Pattern> {
320 @Override
321 public Pattern convert(final String s) {
322 return Pattern.compile(s);
323 }
324 }
325
326
327
328
329 @Plugin(name = "SecurityProvider", category = CATEGORY)
330 public static class SecurityProviderConverter implements TypeConverter<Provider> {
331 @Override
332 public Provider convert(final String s) {
333 return Security.getProvider(s);
334 }
335 }
336
337
338
339
340 @Plugin(name = "Short", category = CATEGORY)
341 public static class ShortConverter implements TypeConverter<Short> {
342 @Override
343 public Short convert(final String s) {
344 return Short.valueOf(s);
345 }
346 }
347
348
349
350
351 @Plugin(name = "String", category = CATEGORY)
352 public static class StringConverter implements TypeConverter<String> {
353 @Override
354 public String convert(final String s) {
355 return s;
356 }
357 }
358
359
360
361
362 @Plugin(name = "URI", category = CATEGORY)
363 public static class UriConverter implements TypeConverter<URI> {
364 @Override
365 public URI convert(final String s) throws URISyntaxException {
366 return new URI(s);
367 }
368 }
369
370
371
372
373 @Plugin(name = "URL", category = CATEGORY)
374 public static class UrlConverter implements TypeConverter<URL> {
375 @Override
376 public URL convert(final String s) throws MalformedURLException {
377 return new URL(s);
378 }
379 }
380
381
382
383
384
385 @Plugin(name = "UUID", category = CATEGORY)
386 public static class UuidConverter implements TypeConverter<UUID> {
387 @Override
388 public UUID convert(final String s) throws Exception {
389 return UUID.fromString(s);
390 }
391 }
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410 public static <T> T convert(final String s, final Class<? extends T> clazz, final Object defaultValue) {
411 @SuppressWarnings("unchecked")
412 final TypeConverter<T> converter = (TypeConverter<T>) TypeConverterRegistry.getInstance().findCompatibleConverter(clazz);
413 if (s == null) {
414
415
416 return parseDefaultValue(converter, defaultValue);
417 }
418 try {
419 return converter.convert(s);
420 } catch (final Exception e) {
421 LOGGER.warn("Error while converting string [{}] to type [{}]. Using default value [{}].", s, clazz,
422 defaultValue, e);
423 return parseDefaultValue(converter, defaultValue);
424 }
425 }
426
427 @SuppressWarnings("unchecked")
428 private static <T> T parseDefaultValue(final TypeConverter<T> converter, final Object defaultValue) {
429 if (defaultValue == null) {
430 return null;
431 }
432 if (!(defaultValue instanceof String)) {
433 return (T) defaultValue;
434 }
435 try {
436 return converter.convert((String) defaultValue);
437 } catch (final Exception e) {
438 LOGGER.debug("Can't parse default value [{}] for type [{}].", defaultValue, converter.getClass(), e);
439 return null;
440 }
441 }
442
443 private static final Logger LOGGER = StatusLogger.getLogger();
444
445 }