1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.beanutils2;
19
20 import java.awt.Color;
21 import java.awt.Dimension;
22 import java.awt.Point;
23 import java.io.File;
24 import java.lang.reflect.Array;
25 import java.math.BigDecimal;
26 import java.math.BigInteger;
27 import java.net.InetAddress;
28 import java.net.URI;
29 import java.net.URL;
30 import java.nio.file.Path;
31 import java.sql.Timestamp;
32 import java.time.Duration;
33 import java.time.LocalDate;
34 import java.time.LocalDateTime;
35 import java.time.LocalTime;
36 import java.time.MonthDay;
37 import java.time.OffsetDateTime;
38 import java.time.OffsetTime;
39 import java.time.Period;
40 import java.time.Year;
41 import java.time.YearMonth;
42 import java.time.ZoneId;
43 import java.time.ZoneOffset;
44 import java.time.ZonedDateTime;
45 import java.util.Calendar;
46 import java.util.Collection;
47 import java.util.Locale;
48 import java.util.Map;
49 import java.util.Objects;
50 import java.util.UUID;
51 import java.util.regex.Pattern;
52
53 import org.apache.commons.beanutils2.converters.ArrayConverter;
54 import org.apache.commons.beanutils2.converters.BigDecimalConverter;
55 import org.apache.commons.beanutils2.converters.BigIntegerConverter;
56 import org.apache.commons.beanutils2.converters.BooleanConverter;
57 import org.apache.commons.beanutils2.converters.ByteConverter;
58 import org.apache.commons.beanutils2.converters.CalendarConverter;
59 import org.apache.commons.beanutils2.converters.CharacterConverter;
60 import org.apache.commons.beanutils2.converters.ClassConverter;
61 import org.apache.commons.beanutils2.converters.ColorConverter;
62 import org.apache.commons.beanutils2.converters.ConverterFacade;
63 import org.apache.commons.beanutils2.converters.DateConverter;
64 import org.apache.commons.beanutils2.converters.DimensionConverter;
65 import org.apache.commons.beanutils2.converters.DoubleConverter;
66 import org.apache.commons.beanutils2.converters.DurationConverter;
67 import org.apache.commons.beanutils2.converters.EnumConverter;
68 import org.apache.commons.beanutils2.converters.FileConverter;
69 import org.apache.commons.beanutils2.converters.FloatConverter;
70 import org.apache.commons.beanutils2.converters.InetAddressConverter;
71 import org.apache.commons.beanutils2.converters.IntegerConverter;
72 import org.apache.commons.beanutils2.converters.LocalDateConverter;
73 import org.apache.commons.beanutils2.converters.LocalDateTimeConverter;
74 import org.apache.commons.beanutils2.converters.LocalTimeConverter;
75 import org.apache.commons.beanutils2.converters.LocaleConverter;
76 import org.apache.commons.beanutils2.converters.LongConverter;
77 import org.apache.commons.beanutils2.converters.MonthDayConverter;
78 import org.apache.commons.beanutils2.converters.OffsetDateTimeConverter;
79 import org.apache.commons.beanutils2.converters.OffsetTimeConverter;
80 import org.apache.commons.beanutils2.converters.PathConverter;
81 import org.apache.commons.beanutils2.converters.PatternConverter;
82 import org.apache.commons.beanutils2.converters.PeriodConverter;
83 import org.apache.commons.beanutils2.converters.PointConverter;
84 import org.apache.commons.beanutils2.converters.ShortConverter;
85 import org.apache.commons.beanutils2.converters.StringConverter;
86 import org.apache.commons.beanutils2.converters.URIConverter;
87 import org.apache.commons.beanutils2.converters.URLConverter;
88 import org.apache.commons.beanutils2.converters.UUIDConverter;
89 import org.apache.commons.beanutils2.converters.YearConverter;
90 import org.apache.commons.beanutils2.converters.YearMonthConverter;
91 import org.apache.commons.beanutils2.converters.ZoneIdConverter;
92 import org.apache.commons.beanutils2.converters.ZoneOffsetConverter;
93 import org.apache.commons.beanutils2.converters.ZonedDateTimeConverter;
94 import org.apache.commons.beanutils2.sql.converters.SqlDateConverter;
95 import org.apache.commons.beanutils2.sql.converters.SqlTimeConverter;
96 import org.apache.commons.beanutils2.sql.converters.SqlTimestampConverter;
97 import org.apache.commons.logging.Log;
98 import org.apache.commons.logging.LogFactory;
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197 public class ConvertUtilsBean {
198
199 private static final Integer ZERO = Integer.valueOf(0);
200 private static final Character SPACE = Character.valueOf(' ');
201
202
203
204
205 private static final Log LOG = LogFactory.getLog(ConvertUtilsBean.class);
206
207
208
209
210
211
212 protected static ConvertUtilsBean getInstance() {
213 return BeanUtilsBean.getInstance().getConvertUtils();
214 }
215
216
217
218
219 private final Map<Class<?>, Converter<?>> converters = BeanUtils.createCache();
220
221
222 public ConvertUtilsBean() {
223 deregister();
224 }
225
226
227
228
229
230
231
232
233 public String convert(final Object value) {
234 return (String) convert(value, String.class);
235 }
236
237
238
239
240
241
242
243
244
245
246
247 public <T> Object convert(final Object value, final Class<T> targetType) {
248 final boolean nullValue = value == null;
249 final Class<?> sourceType = nullValue ? null : value.getClass();
250
251 if (LOG.isDebugEnabled()) {
252 if (nullValue) {
253 LOG.debug("Convert null value to type '" + targetType.getName() + "'");
254 } else {
255 LOG.debug("Convert type '" + sourceType.getName() + "' value '" + value + "' to type '" + targetType.getName() + "'");
256 }
257 }
258
259 Object converted = value;
260 final Converter<T> converter = lookup(sourceType, targetType);
261 if (converter != null) {
262 if (LOG.isTraceEnabled()) {
263 LOG.trace(" Using converter " + converter);
264 }
265 converted = converter.convert(targetType, value);
266 }
267 if (String.class.equals(targetType) && converted != null && !(converted instanceof String)) {
268
269
270
271
272 final Converter<String> strConverter = lookup(String.class);
273 if (strConverter != null) {
274 if (LOG.isTraceEnabled()) {
275 LOG.trace(" Using converter " + converter);
276 }
277 converted = strConverter.convert(String.class, converted);
278 }
279
280
281 if (converted != null && !(converted instanceof String)) {
282 converted = converted.toString();
283 }
284
285 }
286 return converted;
287 }
288
289
290
291
292
293
294
295
296
297
298 public <R> Object convert(final String value, final Class<R> clazz) {
299 return convert((Object) value, clazz);
300 }
301
302
303
304
305
306
307
308
309
310
311 public <T> Object convert(final String[] value, final Class<T> clazz) {
312 return convert((Object) value, clazz);
313 }
314
315 private <T> Object convert(final String[] values, final Class<T> type, final Converter<T> converter) {
316 if (LOG.isTraceEnabled()) {
317 LOG.trace(" Using converter " + converter);
318 }
319 final Object array = Array.newInstance(type, values.length);
320 for (int i = 0; i < values.length; i++) {
321 Array.set(array, i, converter.convert(type, values[i]));
322 }
323 return array;
324 }
325
326
327
328
329 public void deregister() {
330
331 converters.clear();
332
333 registerPrimitives(false);
334 registerStandard(false, false);
335 registerOther(true);
336 registerArrays(false, 0);
337 register(BigDecimal.class, new BigDecimalConverter());
338 register(BigInteger.class, new BigIntegerConverter());
339 }
340
341
342
343
344
345
346 public void deregister(final Class<?> clazz) {
347 converters.remove(clazz);
348 }
349
350
351
352
353
354
355
356
357
358
359 public <T> Converter<T> lookup(final Class<?> sourceType, final Class<T> targetType) {
360 Objects.requireNonNull(targetType, "targetType");
361 if (sourceType == null) {
362 return lookup(targetType);
363 }
364 Converter converter = null;
365
366 if (targetType == String.class) {
367 converter = lookup(sourceType);
368 if (converter == null && (sourceType.isArray() || Collection.class.isAssignableFrom(sourceType))) {
369 converter = lookup(String[].class);
370 }
371 if (converter == null) {
372 converter = lookup(String.class);
373 }
374 return converter;
375 }
376
377
378 if (targetType == String[].class) {
379 if (sourceType.isArray() || Collection.class.isAssignableFrom(sourceType)) {
380 converter = lookup(sourceType);
381 }
382 if (converter == null) {
383 converter = lookup(String[].class);
384 }
385 return converter;
386 }
387
388 return lookup(targetType);
389
390 }
391
392
393
394
395
396
397
398
399 @SuppressWarnings("unchecked")
400 public <T> Converter<T> lookup(final Class<T> clazz) {
401 return (Converter<T>) converters.get(clazz);
402 }
403
404
405
406
407
408
409
410
411
412
413
414
415
416 public void register(final boolean throwException, final boolean defaultNull, final int defaultArraySize) {
417 registerPrimitives(throwException);
418 registerStandard(throwException, defaultNull);
419 registerOther(throwException);
420 registerArrays(throwException, defaultArraySize);
421 }
422
423
424 private <T> void register(final Class<?> clazz, final Converter<T> converter) {
425 register(new ConverterFacade<>(converter), clazz);
426 }
427
428
429
430
431
432
433
434 public void register(final Converter converter, final Class<?> clazz) {
435 converters.put(clazz, converter);
436 }
437
438
439
440
441
442
443
444
445
446
447 private <T> void registerArrayConverter(final Class<T> componentType, final Converter<T> componentConverter, final boolean throwException,
448 final int defaultArraySize) {
449 final Class<T[]> arrayType = (Class<T[]>) Array.newInstance(componentType, 0).getClass();
450 final Converter<T[]> arrayConverter;
451 if (throwException) {
452 arrayConverter = new ArrayConverter<>(arrayType, componentConverter);
453 } else {
454 arrayConverter = new ArrayConverter<>(arrayType, componentConverter, defaultArraySize);
455 }
456 register(arrayType, arrayConverter);
457 }
458
459
460
461
462
463
464
465
466
467
468 private void registerArrays(final boolean throwException, final int defaultArraySize) {
469
470
471
472 registerArrayConverter(Boolean.TYPE, new BooleanConverter(), throwException, defaultArraySize);
473 registerArrayConverter(Byte.TYPE, new ByteConverter(), throwException, defaultArraySize);
474 registerArrayConverter(Character.TYPE, new CharacterConverter(), throwException, defaultArraySize);
475 registerArrayConverter(Double.TYPE, new DoubleConverter(), throwException, defaultArraySize);
476 registerArrayConverter(Float.TYPE, new FloatConverter(), throwException, defaultArraySize);
477 registerArrayConverter(Integer.TYPE, new IntegerConverter(), throwException, defaultArraySize);
478 registerArrayConverter(Long.TYPE, new LongConverter(), throwException, defaultArraySize);
479 registerArrayConverter(Short.TYPE, new ShortConverter(), throwException, defaultArraySize);
480
481
482 registerArrayConverter(BigDecimal.class, new BigDecimalConverter(), throwException, defaultArraySize);
483 registerArrayConverter(BigInteger.class, new BigIntegerConverter(), throwException, defaultArraySize);
484 registerArrayConverter(Boolean.class, new BooleanConverter(), throwException, defaultArraySize);
485 registerArrayConverter(Byte.class, new ByteConverter(), throwException, defaultArraySize);
486 registerArrayConverter(Character.class, new CharacterConverter(), throwException, defaultArraySize);
487 registerArrayConverter(Double.class, new DoubleConverter(), throwException, defaultArraySize);
488 registerArrayConverter(Float.class, new FloatConverter(), throwException, defaultArraySize);
489 registerArrayConverter(Integer.class, new IntegerConverter(), throwException, defaultArraySize);
490 registerArrayConverter(Long.class, new LongConverter(), throwException, defaultArraySize);
491 registerArrayConverter(Short.class, new ShortConverter(), throwException, defaultArraySize);
492 registerArrayConverter(String.class, new StringConverter(), throwException, defaultArraySize);
493
494
495 registerArrayConverter(Class.class, new ClassConverter(), throwException, defaultArraySize);
496 registerArrayConverter(Color.class, new ColorConverter(), throwException, defaultArraySize);
497 registerArrayConverter(Enum.class, new EnumConverter(), throwException, defaultArraySize);
498 registerArrayConverter(java.util.Date.class, new DateConverter(), throwException, defaultArraySize);
499 registerArrayConverter(Calendar.class, new CalendarConverter(), throwException, defaultArraySize);
500 registerArrayConverter(Dimension.class, new DimensionConverter(), throwException, defaultArraySize);
501 registerArrayConverter(File.class, new FileConverter(), throwException, defaultArraySize);
502 registerArrayConverter(InetAddress.class, new InetAddressConverter(), throwException, defaultArraySize);
503 registerArrayConverter(Path.class, new PathConverter(), throwException, defaultArraySize);
504 registerArrayConverter(java.sql.Date.class, new SqlDateConverter(), throwException, defaultArraySize);
505 registerArrayConverter(java.sql.Time.class, new SqlTimeConverter(), throwException, defaultArraySize);
506 registerArrayConverter(Timestamp.class, new SqlTimestampConverter(), throwException, defaultArraySize);
507 registerArrayConverter(URL.class, new URLConverter(), throwException, defaultArraySize);
508 registerArrayConverter(URI.class, new URIConverter(), throwException, defaultArraySize);
509 registerArrayConverter(UUID.class, new UUIDConverter(), throwException, defaultArraySize);
510 registerArrayConverter(LocalDate.class, new LocalDateConverter(), throwException, defaultArraySize);
511 registerArrayConverter(LocalDateTime.class, new LocalDateTimeConverter(), throwException, defaultArraySize);
512 registerArrayConverter(LocalTime.class, new LocalTimeConverter(), throwException, defaultArraySize);
513 registerArrayConverter(Locale.class, new LocaleConverter(), throwException, defaultArraySize);
514 registerArrayConverter(OffsetDateTime.class, new OffsetDateTimeConverter(),throwException, defaultArraySize);
515 registerArrayConverter(OffsetTime.class, new OffsetTimeConverter(), throwException, defaultArraySize);
516 registerArrayConverter(ZonedDateTime.class, new ZonedDateTimeConverter(), throwException, defaultArraySize);
517 registerArrayConverter(Duration.class, new DurationConverter(), throwException, defaultArraySize);
518 registerArrayConverter(MonthDay.class, new MonthDayConverter(), throwException, defaultArraySize);
519 registerArrayConverter(Pattern.class, new PatternConverter(), throwException, defaultArraySize);
520 registerArrayConverter(Period.class, new PeriodConverter(), throwException, defaultArraySize);
521 registerArrayConverter(Point.class, new PointConverter(), throwException, defaultArraySize);
522 registerArrayConverter(Year.class, new YearConverter(), throwException, defaultArraySize);
523 registerArrayConverter(YearMonth.class, new YearMonthConverter(), throwException, defaultArraySize);
524 registerArrayConverter(ZoneId.class, new ZoneIdConverter(), throwException, defaultArraySize);
525 registerArrayConverter(ZoneOffset.class, new ZoneOffsetConverter(), throwException, defaultArraySize);
526
527 }
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564 private void registerOther(final boolean throwException) {
565
566 register(Class.class, throwException ? new ClassConverter<>() : new ClassConverter<>(null));
567 register(Color.class, throwException ? new ColorConverter() : new ColorConverter(null));
568 register(Enum.class, throwException ? new EnumConverter() : new EnumConverter(null));
569 register(java.util.Date.class, throwException ? new DateConverter() : new DateConverter(null));
570 register(Dimension.class, throwException ? new DimensionConverter() : new DimensionConverter(null));
571 register(Calendar.class, throwException ? new CalendarConverter() : new CalendarConverter(null));
572 register(File.class, throwException ? new FileConverter() : new FileConverter(null));
573 register(InetAddress.class, throwException ? new InetAddressConverter() : new InetAddressConverter(null));
574 register(Path.class, throwException ? new PathConverter() : new PathConverter(null));
575 register(java.sql.Date.class, throwException ? new SqlDateConverter() : new SqlDateConverter(null));
576 register(java.sql.Time.class, throwException ? new SqlTimeConverter() : new SqlTimeConverter(null));
577 register(Timestamp.class, throwException ? new SqlTimestampConverter() : new SqlTimestampConverter(null));
578 register(URL.class, throwException ? new URLConverter() : new URLConverter(null));
579 register(URI.class, throwException ? new URIConverter() : new URIConverter(null));
580 register(UUID.class, throwException ? new UUIDConverter() : new UUIDConverter(null));
581 register(LocalDate.class, throwException ? new LocalDateConverter() : new LocalDateConverter(null));
582 register(LocalDateTime.class, throwException ? new LocalDateTimeConverter() : new LocalDateTimeConverter(null));
583 register(LocalTime.class, throwException ? new LocalTimeConverter() : new LocalTimeConverter(null));
584 register(Locale.class, throwException ? new LocaleConverter() : new LocaleConverter(null));
585 register(OffsetDateTime.class, throwException ? new OffsetDateTimeConverter() : new OffsetDateTimeConverter(null));
586 register(OffsetTime.class, throwException ? new OffsetTimeConverter() : new OffsetTimeConverter(null));
587 register(ZonedDateTime.class, throwException ? new ZonedDateTimeConverter() : new ZonedDateTimeConverter(null));
588 register(Duration.class, throwException ? new DurationConverter() : new DurationConverter(null));
589 register(MonthDay.class, throwException ? new MonthDayConverter() : new MonthDayConverter(null));
590 register(Pattern.class, throwException ? new PatternConverter() : new PatternConverter(null));
591 register(Period.class, throwException ? new PeriodConverter() : new PeriodConverter(null));
592 register(Point.class, throwException ? new PointConverter() : new PointConverter(null));
593 register(Year.class, throwException ? new YearConverter() : new YearConverter(null));
594 register(YearMonth.class, throwException ? new YearMonthConverter() : new YearMonthConverter(null));
595 register(ZoneId.class, throwException ? new ZoneIdConverter() : new ZoneIdConverter(null));
596 register(ZoneOffset.class, throwException ? new ZoneOffsetConverter() : new ZoneOffsetConverter(null));
597
598 }
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618 private void registerPrimitives(final boolean throwException) {
619 register(Boolean.TYPE, throwException ? new BooleanConverter() : new BooleanConverter(Boolean.FALSE));
620 register(Byte.TYPE, throwException ? new ByteConverter() : new ByteConverter(ZERO));
621 register(Character.TYPE, throwException ? new CharacterConverter() : new CharacterConverter(SPACE));
622 register(Double.TYPE, throwException ? new DoubleConverter() : new DoubleConverter(ZERO));
623 register(Float.TYPE, throwException ? new FloatConverter() : new FloatConverter(ZERO));
624 register(Integer.TYPE, throwException ? new IntegerConverter() : new IntegerConverter(ZERO));
625 register(Long.TYPE, throwException ? new LongConverter() : new LongConverter(ZERO));
626 register(Short.TYPE, throwException ? new ShortConverter() : new ShortConverter(ZERO));
627 }
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654 private void registerStandard(final boolean throwException, final boolean defaultNull) {
655
656 final Number defaultNumber = defaultNull ? null : ZERO;
657 final BigDecimal bigDecDeflt = defaultNull ? null : new BigDecimal("0.0");
658 final BigInteger bigIntDeflt = defaultNull ? null : new BigInteger("0");
659 final Boolean booleanDefault = defaultNull ? null : Boolean.FALSE;
660 final Character charDefault = defaultNull ? null : SPACE;
661 final String stringDefault = defaultNull ? null : "";
662
663 register(BigDecimal.class, throwException ? new BigDecimalConverter() : new BigDecimalConverter(bigDecDeflt));
664 register(BigInteger.class, throwException ? new BigIntegerConverter() : new BigIntegerConverter(bigIntDeflt));
665 register(Boolean.class, throwException ? new BooleanConverter() : new BooleanConverter(booleanDefault));
666 register(Byte.class, throwException ? new ByteConverter() : new ByteConverter(defaultNumber));
667 register(Character.class, throwException ? new CharacterConverter() : new CharacterConverter(charDefault));
668 register(Double.class, throwException ? new DoubleConverter() : new DoubleConverter(defaultNumber));
669 register(Float.class, throwException ? new FloatConverter() : new FloatConverter(defaultNumber));
670 register(Integer.class, throwException ? new IntegerConverter() : new IntegerConverter(defaultNumber));
671 register(Long.class, throwException ? new LongConverter() : new LongConverter(defaultNumber));
672 register(Short.class, throwException ? new ShortConverter() : new ShortConverter(defaultNumber));
673 register(String.class, throwException ? new StringConverter() : new StringConverter(stringDefault));
674
675 }
676 }