001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package org.apache.commons.beanutils2; 019 020import java.awt.Color; 021import java.awt.Dimension; 022import java.awt.Point; 023import java.io.File; 024import java.lang.reflect.Array; 025import java.math.BigDecimal; 026import java.math.BigInteger; 027import java.net.InetAddress; 028import java.net.URI; 029import java.net.URL; 030import java.nio.file.Path; 031import java.sql.Timestamp; 032import java.time.Duration; 033import java.time.LocalDate; 034import java.time.LocalDateTime; 035import java.time.LocalTime; 036import java.time.MonthDay; 037import java.time.OffsetDateTime; 038import java.time.OffsetTime; 039import java.time.Period; 040import java.time.Year; 041import java.time.YearMonth; 042import java.time.ZoneId; 043import java.time.ZoneOffset; 044import java.time.ZonedDateTime; 045import java.util.Calendar; 046import java.util.Collection; 047import java.util.Locale; 048import java.util.Map; 049import java.util.Objects; 050import java.util.UUID; 051import java.util.regex.Pattern; 052 053import org.apache.commons.beanutils2.converters.ArrayConverter; 054import org.apache.commons.beanutils2.converters.BigDecimalConverter; 055import org.apache.commons.beanutils2.converters.BigIntegerConverter; 056import org.apache.commons.beanutils2.converters.BooleanConverter; 057import org.apache.commons.beanutils2.converters.ByteConverter; 058import org.apache.commons.beanutils2.converters.CalendarConverter; 059import org.apache.commons.beanutils2.converters.CharacterConverter; 060import org.apache.commons.beanutils2.converters.ClassConverter; 061import org.apache.commons.beanutils2.converters.ColorConverter; 062import org.apache.commons.beanutils2.converters.ConverterFacade; 063import org.apache.commons.beanutils2.converters.DateConverter; 064import org.apache.commons.beanutils2.converters.DimensionConverter; 065import org.apache.commons.beanutils2.converters.DoubleConverter; 066import org.apache.commons.beanutils2.converters.DurationConverter; 067import org.apache.commons.beanutils2.converters.EnumConverter; 068import org.apache.commons.beanutils2.converters.FileConverter; 069import org.apache.commons.beanutils2.converters.FloatConverter; 070import org.apache.commons.beanutils2.converters.InetAddressConverter; 071import org.apache.commons.beanutils2.converters.IntegerConverter; 072import org.apache.commons.beanutils2.converters.LocalDateConverter; 073import org.apache.commons.beanutils2.converters.LocalDateTimeConverter; 074import org.apache.commons.beanutils2.converters.LocalTimeConverter; 075import org.apache.commons.beanutils2.converters.LocaleConverter; 076import org.apache.commons.beanutils2.converters.LongConverter; 077import org.apache.commons.beanutils2.converters.MonthDayConverter; 078import org.apache.commons.beanutils2.converters.OffsetDateTimeConverter; 079import org.apache.commons.beanutils2.converters.OffsetTimeConverter; 080import org.apache.commons.beanutils2.converters.PathConverter; 081import org.apache.commons.beanutils2.converters.PatternConverter; 082import org.apache.commons.beanutils2.converters.PeriodConverter; 083import org.apache.commons.beanutils2.converters.PointConverter; 084import org.apache.commons.beanutils2.converters.ShortConverter; 085import org.apache.commons.beanutils2.converters.StringConverter; 086import org.apache.commons.beanutils2.converters.URIConverter; 087import org.apache.commons.beanutils2.converters.URLConverter; 088import org.apache.commons.beanutils2.converters.UUIDConverter; 089import org.apache.commons.beanutils2.converters.YearConverter; 090import org.apache.commons.beanutils2.converters.YearMonthConverter; 091import org.apache.commons.beanutils2.converters.ZoneIdConverter; 092import org.apache.commons.beanutils2.converters.ZoneOffsetConverter; 093import org.apache.commons.beanutils2.converters.ZonedDateTimeConverter; 094import org.apache.commons.beanutils2.sql.converters.SqlDateConverter; 095import org.apache.commons.beanutils2.sql.converters.SqlTimeConverter; 096import org.apache.commons.beanutils2.sql.converters.SqlTimestampConverter; 097import org.apache.commons.logging.Log; 098import org.apache.commons.logging.LogFactory; 099 100/** 101 * TODO DOCS 102 * <p> 103 * 2.0 104 * </p> 105 * 106 * {@link ConvertUtilsBean} implementation that delegates {@code convert()} methods to the new {@link ConvertUtilsBean#convert(Object, Class)} method. 107 * 108 * <p> 109 * To configure this implementation for the current context ClassLoader invoke {@code BeanUtilsBean.setInstance(new BeanUtilsBean2());} 110 * </p> 111 * 112 * <p> 113 * Pre-2.0 114 * </p> 115 * 116 * <p> 117 * Utility methods for converting String scalar values to objects of the specified Class, String arrays to arrays of the specified Class. The actual 118 * {@link Converter} instance to be used can be registered for each possible destination Class. Unless you override them, standard {@link Converter} instances 119 * are provided for all of the following destination Classes: 120 * </p> 121 * <ul> 122 * <li>java.lang.BigDecimal (no default value)</li> 123 * <li>java.lang.BigInteger (no default value)</li> 124 * <li>boolean and java.lang.Boolean (default to false)</li> 125 * <li>byte and java.lang.Byte (default to zero)</li> 126 * <li>char and java.lang.Character (default to a space)</li> 127 * <li>java.lang.Class (no default value)</li> 128 * <li>java.awt.Color (no default value)</li> 129 * <li>java.awt.Dimension (no default value)</li> 130 * <li>double and java.lang.Double (default to zero)</li> 131 * <li>float and java.lang.Float (default to zero)</li> 132 * <li>int and java.lang.Integer (default to zero)</li> 133 * <li>long and java.lang.Long (default to zero)</li> 134 * <li>short and java.lang.Short (default to zero)</li> 135 * <li>java.lang.String (default to null)</li> 136 * <li>java.lang.Enum (default to null)</li> 137 * <li>java.io.File (no default value)</li> 138 * <li>java.net.InetAddress (no default value)</li> 139 * <li>java.util.Locale (no default value)</li> 140 * <li>java.nio.file.Path (no default value)</li> 141 * <li>java.net.URL (no default value)</li> 142 * <li>java.net.URI (no default value)</li> 143 * <li>java.util.UUID (no default value)</li> 144 * <li>java.sql.Date (no default value)</li> 145 * <li>java.sql.Time (no default value)</li> 146 * <li>java.sql.Timestamp (no default value)</li> 147 * <li>java.time.LocalDate (no default value)</li> 148 * <li>java.time.LocalDateTime (no default value)</li> 149 * <li>java.time.LocalTime (no default value)</li> 150 * <li>java.time.OffsetDateTime (no default value)</li> 151 * <li>java.time.OffsetTime (no default value)</li> 152 * <li>java.time.ZonedDateTime (no default value)</li> 153 * <li>java.time.Duration (no default value)</li> 154 * <li>java.time.MonthDay (no default value)</li> 155 * <li>java.util.regex.Pattern (no default value)</li> 156 * <li>java.time.Period (no default value)</li> 157 * <li>java.awt.Point (no default value)</li> 158 * <li>java.time.Year (no default value)</li> 159 * <li>java.time.YearMonth (no default value)</li> 160 * <li>java.time.ZoneId (no default value)</li> 161 * <li>java.time.ZoneOffset (no default value)</li> 162 * </ul> 163 * 164 * <p> 165 * For backwards compatibility, the standard Converters for primitive types (and the corresponding wrapper classes) return a defined default value when a 166 * conversion error occurs. If you prefer to have a {@link ConversionException} thrown instead, replace the standard Converter instances with instances created 167 * with the zero-arguments constructor. For example, to cause the Converters for integers to throw an exception on conversion errors, you could do this: 168 * </p> 169 * 170 * <pre> 171 * // No-args constructor gets the version that throws exceptions 172 * Converter myConverter = new org.apache.commons.beanutils2.converter.IntegerConverter(); 173 * ConvertUtils.register(myConverter, Integer.TYPE); // Native type 174 * ConvertUtils.register(myConverter, Integer.class); // Wrapper class 175 * </pre> 176 * 177 * <p> 178 * Converters generally treat null input as if it were invalid input, that is, they return their default value if one was specified when the converter was 179 * constructed, and throw an exception otherwise. If you prefer nulls to be preserved for converters that are converting to objects (not primitives) then 180 * register a converter as above, passing a default value of null to the converter constructor (and of course registering that converter only for the .class 181 * target). 182 * </p> 183 * 184 * <p> 185 * When a converter is listed above as having no default value, then that converter will throw an exception when passed null or an invalid value as its input. 186 * In particular, by default the BigInteger and BigDecimal converters have no default (and are therefore somewhat inconsistent with the other numerical 187 * converters which all have zero as their default). 188 * </p> 189 * 190 * <p> 191 * Converters that generate <em>arrays</em> of each of the primitive types are also automatically configured (including String[]). When passed null or invalid 192 * input, these return an empty array (not null). See class AbstractArrayConverter for the supported input formats for these converters. 193 * </p> 194 * 195 * @since 1.7 196 */ 197public class ConvertUtilsBean { 198 199 private static final Integer ZERO = Integer.valueOf(0); 200 private static final Character SPACE = Character.valueOf(' '); 201 202 /** 203 * The {@code Log} instance for this class. 204 */ 205 private static final Log LOG = LogFactory.getLog(ConvertUtilsBean.class); 206 207 /** 208 * Gets singleton instance 209 * 210 * @return The singleton instance 211 */ 212 protected static ConvertUtilsBean getInstance() { 213 return BeanUtilsBean.getInstance().getConvertUtils(); 214 } 215 216 /** 217 * The set of {@link Converter}s that can be used to convert Strings into objects of a specified Class, keyed by the destination Class. 218 */ 219 private final Map<Class<?>, Converter<?>> converters = BeanUtils.createCache(); 220 221 /** Constructs a bean with standard converters registered */ 222 public ConvertUtilsBean() { 223 deregister(); 224 } 225 226 /** 227 * Delegates to the new {@link ConvertUtilsBean#convert(Object, Class)} method. 228 * 229 * @param value Value to be converted (may be null) 230 * @return The converted String value or null if value is null 231 * @see ConvertUtilsBean#convert(String[], Class) 232 */ 233 public String convert(final Object value) { 234 return (String) convert(value, String.class); 235 } 236 237 /** 238 * Converts the value to an object of the specified class (if possible). If no converter for the desired target type is registered, the passed in object is 239 * returned unchanged. 240 * 241 * @param <T> The Class type. 242 * @param value Value to be converted (may be null) 243 * @param targetType Class of the value to be converted to (must not be null) 244 * @return The converted value 245 * @throws ConversionException if thrown by an underlying Converter 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 // NOTE: For backwards compatibility, if the Converter 270 // doesn't handle conversion-->String then 271 // use the registered String Converter 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 // If the object still isn't a String, use toString() method 281 if (converted != null && !(converted instanceof String)) { 282 converted = converted.toString(); 283 } 284 285 } 286 return converted; 287 } 288 289 /** 290 * Delegates to the new {@link ConvertUtilsBean#convert(Object, Class)} method. 291 * 292 * @param <R> the type of the class for the return value. 293 * @param value Value to be converted (may be null) 294 * @param clazz Java class to be converted to (must not be null) 295 * @return The converted value or null if value is null 296 * @see ConvertUtilsBean#convert(String[], Class) 297 */ 298 public <R> Object convert(final String value, final Class<R> clazz) { 299 return convert((Object) value, clazz); 300 } 301 302 /** 303 * Delegates to the new {@link ConvertUtilsBean#convert(Object, Class)} method. 304 * 305 * @param <T> the type of the class for the return value. 306 * @param value Array of values to be converted 307 * @param clazz Java array or element class to be converted to (must not be null) 308 * @return The converted value 309 * @see ConvertUtilsBean#convert(String[], Class) 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 * Deregisters all registered {@link Converter}s, and re-establish the standard Converters. 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 * Remove any registered {@link Converter} for the specified destination {@code Class}. 343 * 344 * @param clazz Class for which to remove a registered Converter 345 */ 346 public void deregister(final Class<?> clazz) { 347 converters.remove(clazz); 348 } 349 350 /** 351 * Looks up and return any registered {@link Converter} for the specified source and destination class; if there is no registered Converter, return 352 * {@code null}. 353 * 354 * @param <T> The converter type. 355 * @param sourceType Class of the value being converted 356 * @param targetType Class of the value to be converted to 357 * @return The registered {@link Converter} or {@code null} if not found 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 // Convert --> String 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 // Convert --> String array 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 * Looks up and return any registered {@link Converter} for the specified destination class; if there is no registered Converter, return {@code null}. 394 * 395 * @param <T> The converter type. 396 * @param clazz Class for which to return a registered Converter 397 * @return The registered {@link Converter} or {@code null} if not found 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 * Registers the provided converters with the specified defaults. 406 * 407 * @param throwException {@code true} if the converters should throw an exception when a conversion error occurs, otherwise {@code false} if a default 408 * value should be used. 409 * @param defaultNull {@code true}if the <em>standard</em> converters (see {@link ConvertUtilsBean#registerStandard(boolean, boolean)}) should use a 410 * default value of {@code null</code>, otherwise <code>false}. 411 * N.B. This values is ignored if {@code throwException</code> is <code>true} 412 * @param defaultArraySize The size of the default array value for array converters 413 * (N.B. This values is ignored if {@code throwException</code> is <code>true}). Specifying a value less than zero causes a {@code null} value to be used 414 * for the default. 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 /** Strictly for convenience since it has same parameter order as Map.put */ 424 private <T> void register(final Class<?> clazz, final Converter<T> converter) { 425 register(new ConverterFacade<>(converter), clazz); 426 } 427 428 /** 429 * Registers a custom {@link Converter} for the specified destination {@code Class}, replacing any previously registered Converter. 430 * 431 * @param converter Converter to be registered 432 * @param clazz Destination class for conversions performed by this Converter 433 */ 434 public void register(final Converter converter, final Class<?> clazz) { 435 converters.put(clazz, converter); 436 } 437 438 /** 439 * Registers a new ArrayConverter with the specified element delegate converter that returns a default array of the specified size in the event of 440 * conversion errors. 441 * 442 * @param componentType The component type of the array 443 * @param componentConverter The converter to delegate to for the array elements 444 * @param throwException Whether a conversion exception should be thrown or a default value used in the event of a conversion error 445 * @param defaultArraySize The size of the default array 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 * Registers array converters. 461 * 462 * @param throwException {@code true} if the converters should throw an exception when a conversion error occurs, otherwise {@code false} if a default 463 * value should be used. 464 * @param defaultArraySize The size of the default array value for array converters (N.B. This values is ignored if 465 * {@code throwException</code> is <code>true}). Specifying a value less than zero causes a {@code null} value to be used for the 466 * default. 467 */ 468 private void registerArrays(final boolean throwException, final int defaultArraySize) { 469 // @formatter:off 470 471 // Primitives 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 // Standard 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 // Other 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 // @formatter:on 527 } 528 529 /** 530 * Registers the converters for other types. 531 * </p> 532 * This method registers the following converters: 533 * <ul> 534 * <li>{@code Class.class} - {@link ClassConverter}</li> 535 * <li>{@code Enum.class} - {@link EnumConverter}</li> 536 * <li>{@code java.util.Date.class} - {@link DateConverter}</li> 537 * <li>{@code java.util.Calendar.class} - {@link CalendarConverter}</li> 538 * <li>{@code File.class} - {@link FileConverter}</li> 539 * <li>{@code Path.class} - {@link PathConverter}</li> 540 * <li>{@code java.sql.Date.class} - {@link SqlDateConverter}</li> 541 * <li>{@code java.sql.Time.class} - {@link SqlTimeConverter}</li> 542 * <li>{@code java.sql.Timestamp.class} - {@link SqlTimestampConverter}</li> 543 * <li>{@code URL.class} - {@link URLConverter}</li> 544 * <li>{@code URI.class} - {@link URIConverter}</li> 545 * <li>{@code UUID.class} - {@link UUIDConverter}</li> 546 * <li>{@code LocalDate.class} - {@link LocalDateConverter}</li> 547 * <li>{@code LocalDateTime.class} - {@link LocalDateTimeConverter}</li> 548 * <li>{@code LocalTime.class} - {@link LocalTimeConverter}</li> 549 * <li>{@code OffsetDateTime.class} - {@link OffsetDateTimeConverter}</li> 550 * <li>{@code OffsetTime.class} - {@link OffsetTimeConverter}</li> 551 * <li>{@code ZonedDateTime.class} - {@link ZonedDateTimeConverter}</li> 552 * <li>{@code Duration.class} - {@link DurationConverter}</li> 553 * <li>{@code MonthDay.class} - {@link MonthDayConverter}</li> 554 * <li>{@code Period.class} - {@link PeriodConverter}</li> 555 * <li>{@code Year.class} - {@link YearConverter}</li> 556 * <li>{@code YearMonth.class} - {@link YearMonthConverter}</li> 557 * <li>{@code ZoneId.class} - {@link ZoneIdConverter}</li> 558 * <li>{@code ZoneOffset.class} - {@link ZoneOffsetConverter}</li> 559 * </ul> 560 * 561 * @param throwException {@code true} if the converters should throw an exception when a conversion error occurs, otherwise <code> {@code false} if a 562 * default value should be used. 563 */ 564 private void registerOther(final boolean throwException) { 565 // @formatter:off 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 // @formatter:on 598 } 599 600 /** 601 * Registers the converters for primitive types. 602 * </p> 603 * This method registers the following converters: 604 * <ul> 605 * <li>{@code Boolean.TYPE} - {@link BooleanConverter}</li> 606 * <li>{@code Byte.TYPE} - {@link ByteConverter}</li> 607 * <li>{@code Character.TYPE} - {@link CharacterConverter}</li> 608 * <li>{@code Double.TYPE} - {@link DoubleConverter}</li> 609 * <li>{@code Float.TYPE} - {@link FloatConverter}</li> 610 * <li>{@code Integer.TYPE} - {@link IntegerConverter}</li> 611 * <li>{@code Long.TYPE} - {@link LongConverter}</li> 612 * <li>{@code Short.TYPE} - {@link ShortConverter}</li> 613 * </ul> 614 * 615 * @param throwException {@code true} if the converters should throw an exception when a conversion error occurs, otherwise <code> {@code false} if a 616 * default value should be used. 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 * Registers the converters for standard types. 631 * </p> 632 * This method registers the following converters: 633 * <ul> 634 * <li>{@code BigDecimal.class} - {@link BigDecimalConverter}</li> 635 * <li>{@code BigInteger.class} - {@link BigIntegerConverter}</li> 636 * <li>{@code Boolean.class} - {@link BooleanConverter}</li> 637 * <li>{@code Byte.class} - {@link ByteConverter}</li> 638 * <li>{@code Character.class} - {@link CharacterConverter}</li> 639 * <li>{@code Double.class} - {@link DoubleConverter}</li> 640 * <li>{@code Float.class} - {@link FloatConverter}</li> 641 * <li>{@code Integer.class} - {@link IntegerConverter}</li> 642 * <li>{@code Long.class} - {@link LongConverter}</li> 643 * <li>{@code Short.class} - {@link ShortConverter}</li> 644 * <li>{@code String.class} - {@link StringConverter}</li> 645 * </ul> 646 * 647 * @param throwException {@code true} if the converters should throw an exception when a conversion error occurs, otherwise <code> 648 * {@code false} if a default value should be used. 649 * @param defaultNull {@code true}if the <em>standard</em> converters 650 * (see {@link ConvertUtilsBean#registerStandard(boolean, boolean)}) 651 * should use a default value of {@code null</code>, otherwise <code>false}. 652 * N.B. This values is ignored if {@code throwException</code> is <code>true} 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}