diff --git a/src/main/java/com/cedarsoftware/util/ClassUtilities.java b/src/main/java/com/cedarsoftware/util/ClassUtilities.java index 819b48d74..58285ac4b 100644 --- a/src/main/java/com/cedarsoftware/util/ClassUtilities.java +++ b/src/main/java/com/cedarsoftware/util/ClassUtilities.java @@ -1,9 +1,12 @@ package com.cedarsoftware.util; +import com.cedarsoftware.util.convert.StringConversions; + import java.lang.reflect.Array; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -290,4 +293,20 @@ else if (className.equals("[C")) } return currentClass; } + + public static boolean isClassFinal(Class c) { + return (c.getModifiers() & Modifier.FINAL) != 0; + } + + public static boolean areAllConstructorsPrivate(Class c) { + Constructor[] constructors = c.getDeclaredConstructors(); + + for (Constructor constructor : constructors) { + if ((constructor.getModifiers() & Modifier.PRIVATE) == 0) { + return false; + } + } + + return true; + } } diff --git a/src/main/java/com/cedarsoftware/util/convert/CalendarConversions.java b/src/main/java/com/cedarsoftware/util/convert/CalendarConversions.java index 34e0e2f55..693ea1d3f 100644 --- a/src/main/java/com/cedarsoftware/util/convert/CalendarConversions.java +++ b/src/main/java/com/cedarsoftware/util/convert/CalendarConversions.java @@ -3,6 +3,7 @@ import java.math.BigDecimal; import java.math.BigInteger; import java.sql.Timestamp; +import java.text.SimpleDateFormat; import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; @@ -115,4 +116,9 @@ static Calendar create(long epochMilli, ConverterOptions options) { cal.setTimeInMillis(epochMilli); return cal; } + + static String toString(Object from, Converter converter, ConverterOptions options) { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); + return simpleDateFormat.format(((Calendar) from).getTime()); + } } diff --git a/src/main/java/com/cedarsoftware/util/convert/Converter.java b/src/main/java/com/cedarsoftware/util/convert/Converter.java index 37322e402..70205b5fb 100644 --- a/src/main/java/com/cedarsoftware/util/convert/Converter.java +++ b/src/main/java/com/cedarsoftware/util/convert/Converter.java @@ -12,6 +12,9 @@ import java.time.LocalDateTime; import java.time.LocalTime; import java.time.MonthDay; +import java.time.OffsetDateTime; +import java.time.OffsetTime; +import java.time.Year; import java.time.ZonedDateTime; import java.util.AbstractMap; import java.util.Calendar; @@ -156,6 +159,8 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(Number.class, Integer.class), NumberConversions::toInt); DEFAULT_FACTORY.put(pair(Map.class, Integer.class), MapConversions::toInt); DEFAULT_FACTORY.put(pair(String.class, Integer.class), StringConversions::toInt); + DEFAULT_FACTORY.put(pair(Year.class, Integer.class), YearConversions::toInt); + // toLong DEFAULT_FACTORY.put(pair(Void.class, long.class), NumberConversions::toLongZero); @@ -184,6 +189,9 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(Number.class, Long.class), NumberConversions::toLong); DEFAULT_FACTORY.put(pair(Map.class, Long.class), MapConversions::toLong); DEFAULT_FACTORY.put(pair(String.class, Long.class), StringConversions::toLong); + DEFAULT_FACTORY.put(pair(OffsetDateTime.class, Long.class), OffsetDateTimeConversions::toLong); + DEFAULT_FACTORY.put(pair(Year.class, Long.class), YearConversions::toLong); + // toFloat DEFAULT_FACTORY.put(pair(Void.class, float.class), NumberConversions::toFloatZero); @@ -234,6 +242,8 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(Number.class, Double.class), NumberConversions::toDouble); DEFAULT_FACTORY.put(pair(Map.class, Double.class), MapConversions::toDouble); DEFAULT_FACTORY.put(pair(String.class, Double.class), StringConversions::toDouble); + DEFAULT_FACTORY.put(pair(Year.class, Double.class), YearConversions::toDouble); + // Boolean/boolean conversions supported DEFAULT_FACTORY.put(pair(Void.class, boolean.class), VoidConversions::toBoolean); @@ -254,6 +264,8 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(Number.class, Boolean.class), NumberConversions::isIntTypeNotZero); DEFAULT_FACTORY.put(pair(Map.class, Boolean.class), MapConversions::toBoolean); DEFAULT_FACTORY.put(pair(String.class, Boolean.class), StringConversions::toBoolean); + DEFAULT_FACTORY.put(pair(Year.class, Boolean.class), YearConversions::toBoolean); + // Character/chat conversions supported DEFAULT_FACTORY.put(pair(Void.class, char.class), VoidConversions::toChar); @@ -302,6 +314,9 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(Number.class, BigInteger.class), NumberConversions::toBigInteger); DEFAULT_FACTORY.put(pair(Map.class, BigInteger.class), MapConversions::toBigInteger); DEFAULT_FACTORY.put(pair(String.class, BigInteger.class), StringConversions::toBigInteger); + DEFAULT_FACTORY.put(pair(OffsetDateTime.class, BigInteger.class), OffsetDateTimeConversions::toBigInteger); + DEFAULT_FACTORY.put(pair(Year.class, BigInteger.class), YearConversions::toBigInteger); + // BigDecimal conversions supported DEFAULT_FACTORY.put(pair(Void.class, BigDecimal.class), VoidConversions::toNull); @@ -330,6 +345,9 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(Number.class, BigDecimal.class), NumberConversions::toBigDecimal); DEFAULT_FACTORY.put(pair(Map.class, BigDecimal.class), MapConversions::toBigDecimal); DEFAULT_FACTORY.put(pair(String.class, BigDecimal.class), StringConversions::toBigDecimal); + DEFAULT_FACTORY.put(pair(OffsetDateTime.class, BigDecimal.class), OffsetDateTimeConversions::toBigDecimal); + DEFAULT_FACTORY.put(pair(Year.class, BigDecimal.class), YearConversions::toBigDecimal); + // AtomicBoolean conversions supported DEFAULT_FACTORY.put(pair(Void.class, AtomicBoolean.class), VoidConversions::toNull); @@ -349,6 +367,7 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(Number.class, AtomicBoolean.class), NumberConversions::toAtomicBoolean); DEFAULT_FACTORY.put(pair(Map.class, AtomicBoolean.class), MapConversions::toAtomicBoolean); DEFAULT_FACTORY.put(pair(String.class, AtomicBoolean.class), StringConversions::toAtomicBoolean); + DEFAULT_FACTORY.put(pair(Year.class, AtomicBoolean.class), YearConversions::toAtomicBoolean); // AtomicInteger conversions supported DEFAULT_FACTORY.put(pair(Void.class, AtomicInteger.class), VoidConversions::toNull); @@ -369,6 +388,7 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(Number.class, AtomicBoolean.class), NumberConversions::toAtomicInteger); DEFAULT_FACTORY.put(pair(Map.class, AtomicInteger.class), MapConversions::toAtomicInteger); DEFAULT_FACTORY.put(pair(String.class, AtomicInteger.class), StringConversions::toAtomicInteger); + DEFAULT_FACTORY.put(pair(Year.class, AtomicInteger.class), YearConversions::toAtomicInteger); // AtomicLong conversions supported DEFAULT_FACTORY.put(pair(Void.class, AtomicLong.class), VoidConversions::toNull); @@ -396,6 +416,9 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(Number.class, AtomicLong.class), NumberConversions::toAtomicLong); DEFAULT_FACTORY.put(pair(Map.class, AtomicLong.class), MapConversions::toAtomicLong); DEFAULT_FACTORY.put(pair(String.class, AtomicLong.class), StringConversions::toAtomicLong); + DEFAULT_FACTORY.put(pair(OffsetDateTime.class, AtomicLong.class), OffsetDateTimeConversions::toAtomicLong); + DEFAULT_FACTORY.put(pair(Year.class, AtomicLong.class), YearConversions::toAtomicLong); + // Date conversions supported DEFAULT_FACTORY.put(pair(Void.class, Date.class), VoidConversions::toNull); @@ -415,6 +438,8 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(Number.class, Date.class), NumberConversions::toDate); DEFAULT_FACTORY.put(pair(Map.class, Date.class), MapConversions::toDate); DEFAULT_FACTORY.put(pair(String.class, Date.class), StringConversions::toDate); + DEFAULT_FACTORY.put(pair(OffsetDateTime.class, Date.class), OffsetDateTimeConversions::toDate); + // java.sql.Date conversion supported DEFAULT_FACTORY.put(pair(Void.class, java.sql.Date.class), VoidConversions::toNull); @@ -434,6 +459,7 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(Number.class, java.sql.Date.class), NumberConversions::toSqlDate); DEFAULT_FACTORY.put(pair(Map.class, java.sql.Date.class), MapConversions::toSqlDate); DEFAULT_FACTORY.put(pair(String.class, java.sql.Date.class), StringConversions::toSqlDate); + DEFAULT_FACTORY.put(pair(OffsetDateTime.class, java.sql.Date.class), OffsetDateTimeConversions::toSqlDate); // Timestamp conversions supported DEFAULT_FACTORY.put(pair(Void.class, Timestamp.class), VoidConversions::toNull); @@ -453,6 +479,8 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(Number.class, Timestamp.class), NumberConversions::toTimestamp); DEFAULT_FACTORY.put(pair(Map.class, Timestamp.class), MapConversions::toTimestamp); DEFAULT_FACTORY.put(pair(String.class, Timestamp.class), StringConversions::toTimestamp); + DEFAULT_FACTORY.put(pair(OffsetDateTime.class, Timestamp.class), OffsetDateTimeConversions::toTimestamp); + // Calendar conversions supported DEFAULT_FACTORY.put(pair(Void.class, Calendar.class), VoidConversions::toNull); @@ -472,6 +500,8 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(Number.class, Calendar.class), NumberConversions::toCalendar); DEFAULT_FACTORY.put(pair(Map.class, Calendar.class), MapConversions::toCalendar); DEFAULT_FACTORY.put(pair(String.class, Calendar.class), StringConversions::toCalendar); + DEFAULT_FACTORY.put(pair(OffsetDateTime.class, Calendar.class), OffsetDateTimeConversions::toCalendar); + // LocalDate conversions supported DEFAULT_FACTORY.put(pair(Void.class, LocalDate.class), VoidConversions::toNull); @@ -491,6 +521,8 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(Number.class, LocalDate.class), NumberConversions::toLocalDate); DEFAULT_FACTORY.put(pair(Map.class, LocalDate.class), MapConversions::toLocalDate); DEFAULT_FACTORY.put(pair(String.class, LocalDate.class), StringConversions::toLocalDate); + DEFAULT_FACTORY.put(pair(OffsetDateTime.class, LocalDate.class), OffsetDateTimeConversions::toLocalDate); + // LocalDateTime conversions supported DEFAULT_FACTORY.put(pair(Void.class, LocalDateTime.class), VoidConversions::toNull); @@ -510,6 +542,8 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(Number.class, LocalDateTime.class), NumberConversions::toLocalDateTime); DEFAULT_FACTORY.put(pair(Map.class, LocalDateTime.class), MapConversions::toLocalDateTime); DEFAULT_FACTORY.put(pair(String.class, LocalDateTime.class), StringConversions::toLocalDateTime); + DEFAULT_FACTORY.put(pair(OffsetDateTime.class, LocalDateTime.class), OffsetDateTimeConversions::toLocalDateTime); + // LocalTime conversions supported DEFAULT_FACTORY.put(pair(Void.class, LocalTime.class), VoidConversions::toNull); @@ -530,7 +564,9 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(Number.class, LocalTime.class), NumberConversions::toLocalTime); DEFAULT_FACTORY.put(pair(Map.class, LocalTime.class), MapConversions::toLocalTime); DEFAULT_FACTORY.put(pair(String.class, LocalTime.class), StringConversions::toLocalTime); - + DEFAULT_FACTORY.put(pair(OffsetDateTime.class, LocalTime.class), OffsetDateTimeConversions::toLocalTime); + + // ZonedDateTime conversions supported DEFAULT_FACTORY.put(pair(Void.class, ZonedDateTime.class), VoidConversions::toNull); DEFAULT_FACTORY.put(pair(Long.class, ZonedDateTime.class), NumberConversions::toZonedDateTime); @@ -550,6 +586,17 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(Map.class, ZonedDateTime.class), MapConversions::toZonedDateTime); DEFAULT_FACTORY.put(pair(String.class, ZonedDateTime.class), StringConversions::toZonedDateTime); + // toOffsetDateTime + DEFAULT_FACTORY.put(pair(Void.class, OffsetDateTime.class), VoidConversions::toNull); + DEFAULT_FACTORY.put(pair(OffsetDateTime.class, OffsetDateTime.class), Converter::identity); + DEFAULT_FACTORY.put(pair(String.class, OffsetDateTime.class), StringConversions::toOffsetDateTime); + + // toOffsetTime + DEFAULT_FACTORY.put(pair(Void.class, OffsetTime.class), VoidConversions::toNull); + DEFAULT_FACTORY.put(pair(OffsetTime.class, OffsetTime.class), Converter::identity); + DEFAULT_FACTORY.put(pair(OffsetDateTime.class, OffsetTime.class), OffsetDateTimeConversions::toOffsetTime); + DEFAULT_FACTORY.put(pair(String.class, OffsetTime.class), StringConversions::toOffsetTime); + // UUID conversions supported DEFAULT_FACTORY.put(pair(Void.class, UUID.class), VoidConversions::toNull); DEFAULT_FACTORY.put(pair(UUID.class, UUID.class), Converter::identity); @@ -588,12 +635,12 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(Date.class, String.class), DateConversions::dateToString); DEFAULT_FACTORY.put(pair(java.sql.Date.class, String.class), DateConversions::sqlDateToString); DEFAULT_FACTORY.put(pair(Timestamp.class, String.class), DateConversions::timestampToString); - DEFAULT_FACTORY.put(pair(LocalDate.class, String.class), DateConversions::localDateToString); - DEFAULT_FACTORY.put(pair(LocalTime.class, String.class), DateConversions::localTimeToString); - DEFAULT_FACTORY.put(pair(LocalDateTime.class, String.class), DateConversions::localDateTimeToString); - DEFAULT_FACTORY.put(pair(ZonedDateTime.class, String.class), DateConversions::zonedDateTimeToString); + DEFAULT_FACTORY.put(pair(LocalDate.class, String.class), LocalDateConversions::toString); + DEFAULT_FACTORY.put(pair(LocalTime.class, String.class), LocalTimeConversions::toString); + DEFAULT_FACTORY.put(pair(LocalDateTime.class, String.class), LocalDateTimeConversions::toString); + DEFAULT_FACTORY.put(pair(ZonedDateTime.class, String.class), ZonedDateTimeConversions::toString); DEFAULT_FACTORY.put(pair(UUID.class, String.class), StringConversions::toString); - DEFAULT_FACTORY.put(pair(Calendar.class, String.class), DateConversions::calendarToString); + DEFAULT_FACTORY.put(pair(Calendar.class, String.class), CalendarConversions::toString); DEFAULT_FACTORY.put(pair(Number.class, String.class), StringConversions::toString); DEFAULT_FACTORY.put(pair(Map.class, String.class), MapConversions::toString); DEFAULT_FACTORY.put(pair(Enum.class, String.class), StringConversions::enumToString); @@ -602,6 +649,9 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(Instant.class, String.class), StringConversions::toString); DEFAULT_FACTORY.put(pair(LocalTime.class, String.class), StringConversions::toString); DEFAULT_FACTORY.put(pair(MonthDay.class, String.class), StringConversions::toString); + DEFAULT_FACTORY.put(pair(OffsetDateTime.class, String.class), OffsetDateTimeConversions::toString); + DEFAULT_FACTORY.put(pair(Year.class, String.class), YearConversions::toString); + // Duration conversions supported DEFAULT_FACTORY.put(pair(Void.class, Duration.class), VoidConversions::toNull); @@ -627,6 +677,7 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(Number.class, Instant.class), NumberConversions::toInstant); DEFAULT_FACTORY.put(pair(String.class, Instant.class), StringConversions::toInstant); DEFAULT_FACTORY.put(pair(Map.class, Instant.class), MapConversions::toInstant); + DEFAULT_FACTORY.put(pair(OffsetDateTime.class, Instant.class), OffsetDateTimeConversions::toInstant); // java.time.OffsetDateTime = com.cedarsoftware.util.io.DEFAULT_FACTORY.OffsetDateTimeFactory // java.time.OffsetTime = com.cedarsoftware.util.io.DEFAULT_FACTORY.OffsetTimeFactory @@ -677,6 +728,7 @@ private static void buildFactoryConversions() { // toCharArray DEFAULT_FACTORY.put(pair(Void.class, char[].class), VoidConversions::toNull); + DEFAULT_FACTORY.put(pair(Void.class, Character[].class), VoidConversions::toNull); DEFAULT_FACTORY.put(pair(String.class, char[].class), StringConversions::toCharArray); DEFAULT_FACTORY.put(pair(StringBuilder.class, char[].class), StringConversions::toCharArray); DEFAULT_FACTORY.put(pair(StringBuffer.class, char[].class), StringConversions::toCharArray); @@ -705,6 +757,12 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(char[].class, ByteBuffer.class), CharArrayConversions::toByteBuffer); DEFAULT_FACTORY.put(pair(byte[].class, ByteBuffer.class), ByteArrayConversions::toByteBuffer); + // toYear + DEFAULT_FACTORY.put(pair(Void.class, Year.class), VoidConversions::toNull); + DEFAULT_FACTORY.put(pair(Year.class, Year.class), Converter::identity); + DEFAULT_FACTORY.put(pair(String.class, Year.class), StringConversions::toYear); + + // Map conversions supported DEFAULT_FACTORY.put(pair(Void.class, Map.class), VoidConversions::toNull); DEFAULT_FACTORY.put(pair(Byte.class, Map.class), MapConversions::initMap); diff --git a/src/main/java/com/cedarsoftware/util/convert/DateConversions.java b/src/main/java/com/cedarsoftware/util/convert/DateConversions.java index 168f2dd18..f59440b1b 100644 --- a/src/main/java/com/cedarsoftware/util/convert/DateConversions.java +++ b/src/main/java/com/cedarsoftware/util/convert/DateConversions.java @@ -114,28 +114,4 @@ static String timestampToString(Object from, Converter converter, ConverterOptio return simpleDateFormat.format(((Date) from)); } - static String calendarToString(Object from, Converter converter, ConverterOptions options) { - SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); - return simpleDateFormat.format(((Calendar) from).getTime()); - } - - static String localDateToString(Object from, Converter converter, ConverterOptions options) { - LocalDate localDate = (LocalDate) from; - return localDate.format(DateTimeFormatter.ISO_LOCAL_DATE); - } - - static String localTimeToString(Object from, Converter converter, ConverterOptions options) { - LocalTime localTime = (LocalTime) from; - return localTime.format(DateTimeFormatter.ISO_LOCAL_TIME); - } - - static String localDateTimeToString(Object from, Converter converter, ConverterOptions options) { - LocalDateTime localDateTime = (LocalDateTime) from; - return localDateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME); - } - - static String zonedDateTimeToString(Object from, Converter converter, ConverterOptions options) { - ZonedDateTime zonedDateTime = (ZonedDateTime) from; - return zonedDateTime.format(DateTimeFormatter.ISO_DATE_TIME); - } } diff --git a/src/main/java/com/cedarsoftware/util/convert/LocalDateConversions.java b/src/main/java/com/cedarsoftware/util/convert/LocalDateConversions.java index e20d562c1..942f7fda6 100644 --- a/src/main/java/com/cedarsoftware/util/convert/LocalDateConversions.java +++ b/src/main/java/com/cedarsoftware/util/convert/LocalDateConversions.java @@ -8,6 +8,7 @@ import java.time.LocalDateTime; import java.time.LocalTime; import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; @@ -116,4 +117,11 @@ static BigInteger toBigInteger(Object from, Converter converter, ConverterOption static BigDecimal toBigDecimal(Object from, Converter converter, ConverterOptions options) { return BigDecimal.valueOf(toLong(from, options)); } + + static String toString(Object from, Converter converter, ConverterOptions options) { + LocalDate localDate = (LocalDate) from; + return localDate.format(DateTimeFormatter.ISO_LOCAL_DATE); + } + + } diff --git a/src/main/java/com/cedarsoftware/util/convert/LocalDateTimeConversions.java b/src/main/java/com/cedarsoftware/util/convert/LocalDateTimeConversions.java index 44aed4f35..a714d795d 100644 --- a/src/main/java/com/cedarsoftware/util/convert/LocalDateTimeConversions.java +++ b/src/main/java/com/cedarsoftware/util/convert/LocalDateTimeConversions.java @@ -8,6 +8,7 @@ import java.time.LocalDateTime; import java.time.LocalTime; import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; @@ -100,4 +101,9 @@ static BigInteger toBigInteger(Object from, Converter converter, ConverterOption static BigDecimal toBigDecimal(Object from, Converter converter, ConverterOptions options) { return BigDecimal.valueOf(toLong(from, options)); } + + static String toString(Object from, Converter converter, ConverterOptions options) { + LocalDateTime localDateTime = (LocalDateTime) from; + return localDateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME); + } } diff --git a/src/main/java/com/cedarsoftware/util/convert/LocalTimeConversions.java b/src/main/java/com/cedarsoftware/util/convert/LocalTimeConversions.java index 1d9c4236e..0bac08623 100644 --- a/src/main/java/com/cedarsoftware/util/convert/LocalTimeConversions.java +++ b/src/main/java/com/cedarsoftware/util/convert/LocalTimeConversions.java @@ -1,6 +1,7 @@ package com.cedarsoftware.util.convert; import java.time.LocalTime; +import java.time.format.DateTimeFormatter; import java.util.Map; import com.cedarsoftware.util.CompactLinkedMap; @@ -41,4 +42,9 @@ static Map toMap(Object from, Converter converter, ConverterOpti } return target; } + + static String toString(Object from, Converter converter, ConverterOptions options) { + LocalTime localTime = (LocalTime) from; + return localTime.format(DateTimeFormatter.ISO_LOCAL_TIME); + } } diff --git a/src/main/java/com/cedarsoftware/util/convert/OffsetDateTimeConversions.java b/src/main/java/com/cedarsoftware/util/convert/OffsetDateTimeConversions.java new file mode 100644 index 000000000..9146f691b --- /dev/null +++ b/src/main/java/com/cedarsoftware/util/convert/OffsetDateTimeConversions.java @@ -0,0 +1,95 @@ +package com.cedarsoftware.util.convert; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.sql.Timestamp; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.OffsetDateTime; +import java.time.OffsetTime; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.concurrent.atomic.AtomicLong; +import java.util.stream.Stream; + +public class OffsetDateTimeConversions { + private OffsetDateTimeConversions() {} + + static OffsetDateTime toDifferentZone(Object from, ConverterOptions options) { + OffsetDateTime offsetDateTime = (OffsetDateTime) from; + return offsetDateTime.toInstant().atZone(options.getZoneId()).toOffsetDateTime(); + } + + static Instant toInstant(Object from) { + return ((OffsetDateTime)from).toInstant(); + } + + static long toLong(Object from) { + return toInstant(from).toEpochMilli(); + } + + static long toLong(Object from, Converter converter, ConverterOptions options) { + return toLong(from); + } + + static Instant toInstant(Object from, Converter converter, ConverterOptions options) { + return toInstant(from); + } + + static LocalDateTime toLocalDateTime(Object from, Converter converter, ConverterOptions options) { + return toDifferentZone(from, options).toLocalDateTime(); + } + + static LocalDate toLocalDate(Object from, Converter converter, ConverterOptions options) { + return toDifferentZone(from, options).toLocalDate(); + } + + static LocalTime toLocalTime(Object from, Converter converter, ConverterOptions options) { + return toDifferentZone(from, options).toLocalTime(); + } + + static AtomicLong toAtomicLong(Object from, Converter converter, ConverterOptions options) { + return new AtomicLong(toLong(from)); + } + + static Timestamp toTimestamp(Object from, Converter converter, ConverterOptions options) { + return new Timestamp(toLong(from)); + } + + static Calendar toCalendar(Object from, Converter converter, ConverterOptions options) { + Calendar calendar = Calendar.getInstance(options.getTimeZone()); + calendar.setTimeInMillis(toLong(from)); + return calendar; + } + + static java.sql.Date toSqlDate(Object from, Converter converter, ConverterOptions options) { + return new java.sql.Date(toLong(from)); + } + + static Date toDate(Object from, Converter converter, ConverterOptions options) { + return new Date(toLong(from)); + } + + static BigInteger toBigInteger(Object from, Converter converter, ConverterOptions options) { + return BigInteger.valueOf(toLong(from)); + } + + static BigDecimal toBigDecimal(Object from, Converter converter, ConverterOptions options) { + return BigDecimal.valueOf(toLong(from)); + } + + static OffsetTime toOffsetTime(Object from, Converter converter, ConverterOptions options) { + OffsetDateTime dateTime = (OffsetDateTime) from; + return dateTime.toOffsetTime(); + } + + static String toString(Object from, Converter converter, ConverterOptions options) { + OffsetDateTime offsetDateTime = (OffsetDateTime) from; + return offsetDateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME); + } +} diff --git a/src/main/java/com/cedarsoftware/util/convert/StringConversions.java b/src/main/java/com/cedarsoftware/util/convert/StringConversions.java index 19d515107..50774e2b9 100644 --- a/src/main/java/com/cedarsoftware/util/convert/StringConversions.java +++ b/src/main/java/com/cedarsoftware/util/convert/StringConversions.java @@ -12,7 +12,11 @@ import java.time.LocalDateTime; import java.time.LocalTime; import java.time.MonthDay; +import java.time.OffsetDateTime; +import java.time.OffsetTime; +import java.time.Year; import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; @@ -328,14 +332,14 @@ static LocalDateTime toLocalDateTime(Object from, Converter converter, Converter } static LocalTime toLocalTime(Object from, Converter converter, ConverterOptions options) { - String str = (String) from; - if (StringUtilities.isEmpty(str)) { + String str = StringUtilities.trimToNull(asString(from)); + if (str == null) { return null; } + try { return LocalTime.parse(str); - } - catch (Exception e) { + } catch (Exception e) { ZonedDateTime zdt = DateUtilities.parseDate(str, options.getSourceZoneIdForLocalDates(), true); return zdt.toLocalTime(); } @@ -354,6 +358,32 @@ static ZonedDateTime toZonedDateTime(Object from, Converter converter, Converter return toZonedDateTime(from, options); } + static OffsetDateTime toOffsetDateTime(Object from, Converter converter, ConverterOptions options) { + String s = StringUtilities.trimToNull(asString(from)); + if (s == null) { + return null; + } + + try { + return OffsetDateTime.parse(s, DateTimeFormatter.ISO_OFFSET_DATE_TIME); + } catch (Exception e) { + return toZonedDateTime(from, options).toOffsetDateTime(); + } + } + + static OffsetTime toOffsetTime(Object from, Converter converter, ConverterOptions options) { + String s = StringUtilities.trimToNull(asString(from)); + if (s == null) { + return null; + } + + try { + return OffsetTime.parse(s, DateTimeFormatter.ISO_OFFSET_TIME); + } catch (Exception e) { + return toZonedDateTime(from, options).toOffsetDateTime().toOffsetTime(); + } + } + static Instant toInstant(Object from, Converter converter, ConverterOptions options) { String s = StringUtilities.trimToNull(asString(from)); if (s == null) { @@ -421,4 +451,14 @@ static StringBuilder toStringBuilder(Object from, Converter converter, Converter return from == null ? null : new StringBuilder(from.toString()); } + static Year toYear(Object from, Converter converter, ConverterOptions options) { + String s = StringUtilities.trimToNull(asString(from)); + if (s == null) { + return null; + } + + return Year.of(Integer.parseInt(s)); + } + + } diff --git a/src/main/java/com/cedarsoftware/util/convert/YearConversions.java b/src/main/java/com/cedarsoftware/util/convert/YearConversions.java new file mode 100644 index 000000000..05052e7e7 --- /dev/null +++ b/src/main/java/com/cedarsoftware/util/convert/YearConversions.java @@ -0,0 +1,66 @@ +package com.cedarsoftware.util.convert; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.sql.Timestamp; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.Year; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; + +public class YearConversions { + private YearConversions() {} + + static int toInt(Object from) { + return ((Year)from).getValue(); + } + + static long toLong(Object from, Converter converter, ConverterOptions options) { + return toInt(from); + } + + static int toInt(Object from, Converter converter, ConverterOptions options) { + return toInt(from); + } + + static AtomicInteger toAtomicInteger(Object from, Converter converter, ConverterOptions options) { + return new AtomicInteger(toInt(from)); + } + + static AtomicLong toAtomicLong(Object from, Converter converter, ConverterOptions options) { + return new AtomicLong(toInt(from)); + } + + static double toDouble(Object from, Converter converter, ConverterOptions options) { + return toInt(from); + } + + static boolean toBoolean(Object from, Converter converter, ConverterOptions options) { + return toInt(from) == 0; + } + + static AtomicBoolean toAtomicBoolean(Object from, Converter converter, ConverterOptions options) { + return new AtomicBoolean(toInt(from) == 0); + } + + static BigInteger toBigInteger(Object from, Converter converter, ConverterOptions options) { + return BigInteger.valueOf(toInt(from)); + } + + static BigDecimal toBigDecimal(Object from, Converter converter, ConverterOptions options) { + return BigDecimal.valueOf(toInt(from)); + } + + static String toString(Object from, Converter converter, ConverterOptions options) { + return ((Year)from).toString(); + } +} diff --git a/src/main/java/com/cedarsoftware/util/convert/ZonedDateTimeConversions.java b/src/main/java/com/cedarsoftware/util/convert/ZonedDateTimeConversions.java index ff77edd16..e891a56f1 100644 --- a/src/main/java/com/cedarsoftware/util/convert/ZonedDateTimeConversions.java +++ b/src/main/java/com/cedarsoftware/util/convert/ZonedDateTimeConversions.java @@ -8,6 +8,7 @@ import java.time.LocalDateTime; import java.time.LocalTime; import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; @@ -94,4 +95,10 @@ static BigInteger toBigInteger(Object from, Converter converter, ConverterOption static BigDecimal toBigDecimal(Object from, Converter converter, ConverterOptions options) { return BigDecimal.valueOf(toLong(from)); } + + static String toString(Object from, Converter converter, ConverterOptions options) { + ZonedDateTime zonedDateTime = (ZonedDateTime) from; + return zonedDateTime.format(DateTimeFormatter.ISO_DATE_TIME); + } + } diff --git a/src/test/java/com/cedarsoftware/util/convert/BooleanConversionsTests.java b/src/test/java/com/cedarsoftware/util/convert/BooleanConversionsTests.java index 208b0c72d..29d64c1be 100644 --- a/src/test/java/com/cedarsoftware/util/convert/BooleanConversionsTests.java +++ b/src/test/java/com/cedarsoftware/util/convert/BooleanConversionsTests.java @@ -10,6 +10,7 @@ import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Stream; +import com.cedarsoftware.util.ClassUtilities; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -23,15 +24,10 @@ class BooleanConversionsTests { @Test - public void testClassCompliance() throws Exception { + void testClassCompliance() throws Exception { Class c = BooleanConversions.class; - assertEquals(Modifier.FINAL, c.getModifiers() & Modifier.FINAL); - - Constructor con = c.getDeclaredConstructor(); - assertEquals(Modifier.PRIVATE, con.getModifiers() & Modifier.PRIVATE); - - con.setAccessible(true); - assertNotNull(con.newInstance()); + assertThat(ClassUtilities.isClassFinal(c)).isTrue(); + assertThat(ClassUtilities.areAllConstructorsPrivate(c)).isTrue(); } private static Stream toByteParams() { diff --git a/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java b/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java index 700942565..4e46d61db 100644 --- a/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java +++ b/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java @@ -866,6 +866,9 @@ void testCalendarToLocalDateTime(long epochMilli, ZoneId zoneId, LocalDateTime e Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(epochMilli); + System.out.println(Instant.ofEpochMilli(epochMilli).atZone(zoneId).toOffsetDateTime()); + + LocalDateTime localDateTime = this.converter.convert(calendar, LocalDateTime.class, createCustomZones(zoneId, zoneId)); assertThat(localDateTime).isEqualTo(expected); @@ -3158,37 +3161,6 @@ void testUnsupportedType() - private static Stream classesThatReturnNull_whenConvertingFromNull() { - return Stream.of( - Arguments.of(Class.class), - Arguments.of(String.class), - Arguments.of(AtomicLong.class), - Arguments.of(AtomicInteger.class), - Arguments.of(AtomicBoolean.class), - Arguments.of(BigDecimal.class), - Arguments.of(BigInteger.class), - Arguments.of(Timestamp.class), - Arguments.of(java.sql.Date.class), - Arguments.of(Date.class), - Arguments.of(Character.class), - Arguments.of(Double.class), - Arguments.of(Float.class), - Arguments.of(Long.class), - Arguments.of(Short.class), - Arguments.of(Integer.class), - Arguments.of(Byte.class), - Arguments.of(Boolean.class), - Arguments.of(Byte.class) - ); - } - - @ParameterizedTest - @MethodSource("classesThatReturnNull_whenConvertingFromNull") - void testClassesThatReturnNull_whenConvertingFromNull(Class c) - { - assertThat(this.converter.convert(null, c)).isNull(); - } - private static Stream classesThatReturnZero_whenConvertingFromNull() { return Stream.of( Arguments.of(byte.class, CommonValues.BYTE_ZERO), diff --git a/src/test/java/com/cedarsoftware/util/convert/MapConversionTests.java b/src/test/java/com/cedarsoftware/util/convert/MapConversionTests.java new file mode 100644 index 000000000..a01f14449 --- /dev/null +++ b/src/test/java/com/cedarsoftware/util/convert/MapConversionTests.java @@ -0,0 +1,14 @@ +package com.cedarsoftware.util.convert; + +import org.junit.jupiter.params.provider.Arguments; + +import javax.swing.text.Segment; +import java.util.stream.Stream; + +public class MapConversionTests { + + private static Stream toByteTests() { + return Stream.of( + ); + } +} diff --git a/src/test/java/com/cedarsoftware/util/convert/OffsetDateTimeConversionsTests.java b/src/test/java/com/cedarsoftware/util/convert/OffsetDateTimeConversionsTests.java new file mode 100644 index 000000000..8ca7b3f14 --- /dev/null +++ b/src/test/java/com/cedarsoftware/util/convert/OffsetDateTimeConversionsTests.java @@ -0,0 +1,113 @@ +package com.cedarsoftware.util.convert; + +import org.assertj.core.data.Offset; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.sql.Timestamp; +import java.time.LocalDateTime; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; +import java.util.Date; +import java.util.stream.Stream; + +import static org.assertj.core.api.Assertions.assertThat; + +public class OffsetDateTimeConversionsTests { + + private Converter converter; + + @BeforeEach + public void beforeEach() { + this.converter = new Converter(new DefaultConverterOptions()); + } + + // epoch milli 1687622249729L + private static Stream offsetDateTime_asString_withMultipleOffsets_sameEpochMilli() { + return Stream.of( + Arguments.of("2023-06-25T00:57:29.729+09:00"), + Arguments.of("2023-06-24T17:57:29.729+02:00"), + Arguments.of("2023-06-24T15:57:29.729Z"), + Arguments.of("2023-06-24T11:57:29.729-04:00"), + Arguments.of("2023-06-24T10:57:29.729-05:00"), + Arguments.of("2023-06-24T08:57:29.729-07:00") + ); + } + + @ParameterizedTest + @MethodSource("offsetDateTime_asString_withMultipleOffsets_sameEpochMilli") + void toLong_differentZones_sameEpochMilli(String input) { + OffsetDateTime initial = OffsetDateTime.parse(input); + long actual = converter.convert(initial, long.class); + assertThat(actual).isEqualTo(1687622249729L); + } + + @ParameterizedTest + @MethodSource("offsetDateTime_asString_withMultipleOffsets_sameEpochMilli") + void toDate_differentZones_sameEpochMilli(String input) { + OffsetDateTime initial = OffsetDateTime.parse(input); + Date actual = converter.convert(initial, Date.class); + assertThat(actual.getTime()).isEqualTo(1687622249729L); + } + + @ParameterizedTest + @MethodSource("offsetDateTime_asString_withMultipleOffsets_sameEpochMilli") + void toSqlDate_differentZones_sameEpochMilli(String input) { + OffsetDateTime initial = OffsetDateTime.parse(input); + java.sql.Date actual = converter.convert(initial, java.sql.Date.class); + assertThat(actual.getTime()).isEqualTo(1687622249729L); + } + + @ParameterizedTest + @MethodSource("offsetDateTime_asString_withMultipleOffsets_sameEpochMilli") + void toTimestamp_differentZones_sameEpochMilli(String input) { + OffsetDateTime initial = OffsetDateTime.parse(input); + Timestamp actual = converter.convert(initial, Timestamp.class); + assertThat(actual.getTime()).isEqualTo(1687622249729L); + } + + // epoch milli 1687622249729L + private static Stream offsetDateTime_withMultipleOffset_sameEpochMilli() { + return Stream.of( + Arguments.of(OffsetDateTime.of(2023, 06, 25, 0, 57, 29, 729000000, ZoneOffset.of("+09:00"))), + Arguments.of(OffsetDateTime.of(2023, 06, 24, 17, 57, 29, 729000000, ZoneOffset.of("+02:00"))), + Arguments.of(OffsetDateTime.of(2023, 06, 24, 15, 57, 29, 729000000, ZoneOffset.of("Z"))), + Arguments.of(OffsetDateTime.of(2023, 06, 24, 11, 57, 29, 729000000, ZoneOffset.of("-04:00"))), + Arguments.of(OffsetDateTime.of(2023, 06, 24, 10, 57, 29, 729000000, ZoneOffset.of("-05:00"))), + Arguments.of(OffsetDateTime.of(2023, 06, 24, 8, 57, 29, 729000000, ZoneOffset.of("-07:00"))) + ); + } + + @ParameterizedTest + @MethodSource("offsetDateTime_withMultipleOffset_sameEpochMilli") + void toLong_differentZones_sameEpochMilli(OffsetDateTime initial) { + long actual = converter.convert(initial, long.class); + assertThat(actual).isEqualTo(1687622249729L); + } + + @ParameterizedTest + @MethodSource("offsetDateTime_withMultipleOffset_sameEpochMilli") + void toDate_differentZones_sameEpochMilli(OffsetDateTime initial) { + Date actual = converter.convert(initial, Date.class); + assertThat(actual.getTime()).isEqualTo(1687622249729L); + } + + @ParameterizedTest + @MethodSource("offsetDateTime_withMultipleOffset_sameEpochMilli") + void toSqlDate_differentZones_sameEpochMilli(OffsetDateTime initial) { + java.sql.Date actual = converter.convert(initial, java.sql.Date.class); + assertThat(actual.getTime()).isEqualTo(1687622249729L); + } + + @ParameterizedTest + @MethodSource("offsetDateTime_withMultipleOffset_sameEpochMilli") + void toTimestamp_differentZones_sameEpochMilli(OffsetDateTime initial) { + Timestamp actual = converter.convert(initial, Timestamp.class); + assertThat(actual.getTime()).isEqualTo(1687622249729L); + } + + + +} diff --git a/src/test/java/com/cedarsoftware/util/convert/StringConversionsTests.java b/src/test/java/com/cedarsoftware/util/convert/StringConversionsTests.java new file mode 100644 index 000000000..43689ed8a --- /dev/null +++ b/src/test/java/com/cedarsoftware/util/convert/StringConversionsTests.java @@ -0,0 +1,103 @@ +package com.cedarsoftware.util.convert; + +import com.cedarsoftware.util.ClassUtilities; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Modifier; +import java.time.Instant; +import java.time.Year; +import java.util.stream.Stream; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +class StringConversionsTests { + + private Converter converter; + + @BeforeEach + public void beforeEach() { + this.converter = new Converter(new DefaultConverterOptions()); + } + + @Test + void testClassCompliance() throws Exception { + Class c = StringConversions.class; + + assertThat(ClassUtilities.isClassFinal(c)).isTrue(); + assertThat(ClassUtilities.areAllConstructorsPrivate(c)).isTrue(); + } + + private static Stream toYear_withParseableParams() { + return Stream.of( + Arguments.of("1999"), + Arguments.of("\t1999\r\n"), + Arguments.of(" 1999 ") + ); + } + + @ParameterizedTest + @MethodSource("toYear_withParseableParams") + void toYear_withParseableParams_returnsValue(String source) { + Year year = this.converter.convert(source, Year.class); + assertThat(year.getValue()).isEqualTo(1999); + } + + private static Stream toYear_nullReturn() { + return Stream.of( + Arguments.of(" "), + Arguments.of("\t\r\n"), + Arguments.of("") + ); + } + + @ParameterizedTest + @MethodSource("toYear_nullReturn") + void toYear_withNullableStrings_returnsNull(String source) { + Year year = this.converter.convert(source, Year.class); + assertThat(year).isNull(); + } + + private static Stream toYear_extremeParams() { + return Stream.of( + // don't know why MIN_ and MAX_ values don't on GitHub???? + //Arguments.of(String.valueOf(Year.MAX_VALUE), Year.MAX_VALUE), + //Arguments.of(String.valueOf(Year.MIN_VALUE), Year.MIN_VALUE), + Arguments.of("9999999", 9999999), + Arguments.of("-99999999", -99999999), + Arguments.of("0", 0) + ); + } + + @ParameterizedTest + @MethodSource("toYear_extremeParams") + void toYear_withExtremeParams_returnsValue(String source, int value) { + Year expected = Year.of(value); + Year actual = this.converter.convert(source, Year.class); + assertThat(actual).isEqualTo(expected); + } + + private static Stream toCharSequenceTypes() { + return Stream.of( + Arguments.of(StringBuffer.class), + Arguments.of(StringBuilder.class), + Arguments.of(String.class) + ); + } + + @ParameterizedTest + @MethodSource("toCharSequenceTypes") + void toCharSequenceTypes_doesNotTrim_returnsValue(Class c) { + String s = "\t foobar \r\n"; + CharSequence actual = this.converter.convert(s, c); + assertThat(actual.toString()).isEqualTo(s); + } + + +} diff --git a/src/test/java/com/cedarsoftware/util/convert/VoidConversionsTests.java b/src/test/java/com/cedarsoftware/util/convert/VoidConversionsTests.java new file mode 100644 index 000000000..a410ddddb --- /dev/null +++ b/src/test/java/com/cedarsoftware/util/convert/VoidConversionsTests.java @@ -0,0 +1,86 @@ +package com.cedarsoftware.util.convert; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.sql.Timestamp; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.OffsetDateTime; +import java.time.OffsetTime; +import java.time.Year; +import java.time.ZonedDateTime; +import java.util.Date; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; +import java.util.stream.Stream; + +import static org.assertj.core.api.Assertions.assertThat; + +public class VoidConversionsTests { + + private Converter converter; + + @BeforeEach + public void beforeEach() { + this.converter = new Converter(new DefaultConverterOptions()); + } + + private static Stream classesThatReturnNull_whenConvertingFromNull() { + return Stream.of( + Arguments.of(char[].class), + Arguments.of(byte[].class), + Arguments.of(Character[].class), + Arguments.of(CharBuffer.class), + Arguments.of(ByteBuffer.class), + Arguments.of(Class.class), + Arguments.of(String.class), + Arguments.of(StringBuffer.class), + Arguments.of(StringBuilder.class), + Arguments.of(Year.class), + Arguments.of(AtomicLong.class), + Arguments.of(AtomicInteger.class), + Arguments.of(AtomicBoolean.class), + Arguments.of(BigDecimal.class), + Arguments.of(BigInteger.class), + Arguments.of(Timestamp.class), + Arguments.of(java.sql.Date.class), + Arguments.of(Date.class), + Arguments.of(Character.class), + Arguments.of(Double.class), + Arguments.of(Float.class), + Arguments.of(Long.class), + Arguments.of(Short.class), + Arguments.of(Integer.class), + Arguments.of(Byte.class), + Arguments.of(Boolean.class), + Arguments.of(Instant.class), + Arguments.of(Date.class), + Arguments.of(java.sql.Date.class), + Arguments.of(Timestamp.class), + Arguments.of(ZonedDateTime.class), + Arguments.of(OffsetDateTime.class), + Arguments.of(OffsetTime.class), + Arguments.of(LocalDateTime.class), + Arguments.of(LocalDate.class), + Arguments.of(LocalTime.class) + ); + } + + + @ParameterizedTest + @MethodSource("classesThatReturnNull_whenConvertingFromNull") + void testClassesThatReturnNull_whenConvertingFromNull(Class c) + { + assertThat(this.converter.convert(null, c)).isNull(); + } +}