diff --git a/src/main/java/com/cedarsoftware/util/convert/AtomicBooleanConversion.java b/src/main/java/com/cedarsoftware/util/convert/AtomicBooleanConversion.java new file mode 100644 index 000000000..bffd761c3 --- /dev/null +++ b/src/main/java/com/cedarsoftware/util/convert/AtomicBooleanConversion.java @@ -0,0 +1,64 @@ +package com.cedarsoftware.util.convert; + +import java.math.BigDecimal; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; + +public class AtomicBooleanConversion { + + public static Byte toByte(Object from, Converter converter, ConverterOptions options) { + AtomicBoolean b = (AtomicBoolean) from; + return b.get() ? CommonValues.BYTE_ONE : CommonValues.BYTE_ZERO; + } + + public static Short toShort(Object from, Converter converter, ConverterOptions options) { + AtomicBoolean b = (AtomicBoolean) from; + return b.get() ? CommonValues.SHORT_ONE : CommonValues.SHORT_ZERO; + } + + public static Integer toInteger(Object from, Converter converter, ConverterOptions options) { + AtomicBoolean b = (AtomicBoolean) from; + return b.get() ? CommonValues.INTEGER_ONE : CommonValues.INTEGER_ZERO; + } + + public static Long toLong(Object from, Converter converter, ConverterOptions options) { + AtomicBoolean b = (AtomicBoolean) from; + return b.get() ? CommonValues.LONG_ONE : CommonValues.LONG_ZERO; + } + + public static Float toFloat(Object from, Converter converter, ConverterOptions options) { + AtomicBoolean b = (AtomicBoolean) from; + return b.get() ? CommonValues.FLOAT_ONE : CommonValues.FLOAT_ZERO; + } + + public static Double toDouble(Object from, Converter converter, ConverterOptions options) { + AtomicBoolean b = (AtomicBoolean) from; + return b.get() ? CommonValues.DOUBLE_ONE : CommonValues.DOUBLE_ZERO; + } + + public static boolean toBoolean(Object from, Converter converter, ConverterOptions options) { + AtomicBoolean b = (AtomicBoolean) from; + return b.get(); + } + + public static AtomicInteger toAtomicInteger(Object from, Converter converter, ConverterOptions options) { + AtomicBoolean b = (AtomicBoolean) from; + return b.get() ? new AtomicInteger(1) : new AtomicInteger (0); + } + + public static AtomicLong toAtomicLong(Object from, Converter converter, ConverterOptions options) { + AtomicBoolean b = (AtomicBoolean) from; + return b.get() ? new AtomicLong(1) : new AtomicLong(0); + } + + public static Character toCharacter(Object from, Converter converter, ConverterOptions options) { + AtomicBoolean b = (AtomicBoolean) from; + return b.get() ? CommonValues.CHARACTER_ONE : CommonValues.CHARACTER_ZERO; + } + + public static BigDecimal toBigDecimal(Object from, Converter converter, ConverterOptions options) { + AtomicBoolean b = (AtomicBoolean) from; + return b.get() ? BigDecimal.ONE : BigDecimal.ZERO; + } +} diff --git a/src/main/java/com/cedarsoftware/util/convert/BooleanConversion.java b/src/main/java/com/cedarsoftware/util/convert/BooleanConversion.java index 817d18abd..372503b18 100644 --- a/src/main/java/com/cedarsoftware/util/convert/BooleanConversion.java +++ b/src/main/java/com/cedarsoftware/util/convert/BooleanConversion.java @@ -1,6 +1,8 @@ package com.cedarsoftware.util.convert; +import java.math.BigDecimal; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicLong; /** * @author John DeRegnaucourt (jdereg@gmail.com) @@ -23,71 +25,51 @@ public class BooleanConversion { public static Byte toByte(Object from, Converter converter, ConverterOptions options) { Boolean b = (Boolean) from; - return b.booleanValue() ? CommonValues.BYTE_ONE : CommonValues.BYTE_ZERO; + return b ? CommonValues.BYTE_ONE : CommonValues.BYTE_ZERO; } public static Short toShort(Object from, Converter converter, ConverterOptions options) { Boolean b = (Boolean) from; - return b.booleanValue() ? CommonValues.SHORT_ONE : CommonValues.SHORT_ZERO; + return b ? CommonValues.SHORT_ONE : CommonValues.SHORT_ZERO; } public static Integer toInteger(Object from, Converter converter, ConverterOptions options) { Boolean b = (Boolean) from; - return b.booleanValue() ? CommonValues.INTEGER_ONE : CommonValues.INTEGER_ZERO; + return b ? CommonValues.INTEGER_ONE : CommonValues.INTEGER_ZERO; } - public static Long toLong(Object from, Converter converter, ConverterOptions options) { + public static AtomicLong toAtomicLong(Object from, Converter converter, ConverterOptions options) { Boolean b = (Boolean) from; - return b.booleanValue() ? CommonValues.LONG_ONE : CommonValues.LONG_ZERO; - } - - public static AtomicBoolean numberToAtomicBoolean(Object from, Converter converter, ConverterOptions options) { - Number number = (Number) from; - return new AtomicBoolean(number.longValue() != 0); - } - - public static Byte atomicToByte(Object from, Converter converter, ConverterOptions options) { - AtomicBoolean b = (AtomicBoolean) from; - return b.get() ? CommonValues.BYTE_ONE : CommonValues.BYTE_ZERO; - } - - public static Short atomicToShort(Object from, Converter converter, ConverterOptions options) { - AtomicBoolean b = (AtomicBoolean) from; - return b.get() ? CommonValues.SHORT_ONE : CommonValues.SHORT_ZERO; + return new AtomicLong(b ? 1 : 0); } - public static Integer atomicToInteger(Object from, Converter converter, ConverterOptions options) { - AtomicBoolean b = (AtomicBoolean) from; - return b.get() ? CommonValues.INTEGER_ONE : CommonValues.INTEGER_ZERO; + public static AtomicBoolean toAtomicBoolean(Object from, Converter converter, ConverterOptions options) { + Boolean b = (Boolean) from; + return new AtomicBoolean(b); } - public static Long atomicToLong(Object from, Converter converter, ConverterOptions options) { - AtomicBoolean b = (AtomicBoolean) from; - return b.get() ? CommonValues.LONG_ONE : CommonValues.LONG_ZERO; + public static Long toLong(Object from, Converter converter, ConverterOptions options) { + Boolean b = (Boolean) from; + return b.booleanValue() ? CommonValues.LONG_ONE : CommonValues.LONG_ZERO; } - public static Long atomicToCharacter(Object from, Converter converter, ConverterOptions options) { - AtomicBoolean b = (AtomicBoolean) from; - return b.get() ? CommonValues.LONG_ONE : CommonValues.LONG_ZERO; + public static BigDecimal toBigDecimal(Object from, Converter converter, ConverterOptions options) { + Boolean b = (Boolean)from; + return b ? BigDecimal.ONE : BigDecimal.ZERO; } public static Float toFloat(Object from, Converter converter, ConverterOptions options) { Boolean b = (Boolean) from; - return b.booleanValue() ? CommonValues.FLOAT_ONE : CommonValues.FLOAT_ZERO; + return b ? CommonValues.FLOAT_ONE : CommonValues.FLOAT_ZERO; } public static Double toDouble(Object from, Converter converter, ConverterOptions options) { Boolean b = (Boolean) from; - return b.booleanValue() ? CommonValues.DOUBLE_ONE : CommonValues.DOUBLE_ZERO; + return b ? CommonValues.DOUBLE_ONE : CommonValues.DOUBLE_ZERO; } - public static Float atomicToFloat(Object from, Converter converter, ConverterOptions options) { - AtomicBoolean b = (AtomicBoolean) from; - return b.get() ? CommonValues.FLOAT_ONE : CommonValues.FLOAT_ZERO; - } - - public static Double atomicToDouble(Object from, Converter converter, ConverterOptions options) { - AtomicBoolean b = (AtomicBoolean) from; - return b.get() ? CommonValues.DOUBLE_ONE : CommonValues.DOUBLE_ZERO; + public static char toCharacter(Object from, Converter converter, ConverterOptions options) { + Boolean b = (Boolean) from; + return b ? CommonValues.CHARACTER_ONE : CommonValues.CHARACTER_ZERO; } } diff --git a/src/main/java/com/cedarsoftware/util/convert/CalendarConversion.java b/src/main/java/com/cedarsoftware/util/convert/CalendarConversion.java new file mode 100644 index 000000000..012922c47 --- /dev/null +++ b/src/main/java/com/cedarsoftware/util/convert/CalendarConversion.java @@ -0,0 +1,30 @@ +package com.cedarsoftware.util.convert; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Calendar; +import java.util.Date; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicLong; + +public class CalendarConversion { + public static Date toDate(Object fromInstance, Converter converter, ConverterOptions options) { + Calendar from = (Calendar)fromInstance; + return from.getTime(); + } + + public static AtomicLong toAtomicLong(Object fromInstance, Converter converter, ConverterOptions options) { + Calendar from = (Calendar)fromInstance; + return new AtomicLong(from.getTime().getTime()); + } + + public static BigDecimal toBigDecimal(Object fromInstance, Converter converter, ConverterOptions options) { + Calendar from = (Calendar)fromInstance; + return BigDecimal.valueOf(from.getTime().getTime()); + } + + public static BigInteger toBigInteger(Object fromInstance, Converter converter, ConverterOptions options) { + Calendar from = (Calendar)fromInstance; + return BigInteger.valueOf(from.getTime().getTime()); + } +} diff --git a/src/main/java/com/cedarsoftware/util/convert/CharacterConversion.java b/src/main/java/com/cedarsoftware/util/convert/CharacterConversion.java new file mode 100644 index 000000000..11c0501c6 --- /dev/null +++ b/src/main/java/com/cedarsoftware/util/convert/CharacterConversion.java @@ -0,0 +1,18 @@ +package com.cedarsoftware.util.convert; + +import java.util.concurrent.atomic.AtomicBoolean; + +public class CharacterConversion { + public static boolean toBoolean(Object from, Converter converter, ConverterOptions options) { + Character c = (Character) from; + return c != CommonValues.CHARACTER_ZERO; + } + + public static double toDouble(Object from, Converter converter, ConverterOptions options) { + return (char) from; + } + + public static float toFloat(Object from, Converter converter, ConverterOptions options) { + return (char) from; + } +} diff --git a/src/main/java/com/cedarsoftware/util/convert/CommonValues.java b/src/main/java/com/cedarsoftware/util/convert/CommonValues.java index c3352cd97..3b2370f20 100644 --- a/src/main/java/com/cedarsoftware/util/convert/CommonValues.java +++ b/src/main/java/com/cedarsoftware/util/convert/CommonValues.java @@ -30,4 +30,8 @@ public class CommonValues { public static final Float FLOAT_ONE = 1.0f; public static final Double DOUBLE_ZERO = 0.0d; public static final Double DOUBLE_ONE = 1.0d; + + public static final Character CHARACTER_ZERO = (char)0; + + public static final Character CHARACTER_ONE = (char)1; } diff --git a/src/main/java/com/cedarsoftware/util/convert/Converter.java b/src/main/java/com/cedarsoftware/util/convert/Converter.java index 6eb90fec1..0a1244110 100644 --- a/src/main/java/com/cedarsoftware/util/convert/Converter.java +++ b/src/main/java/com/cedarsoftware/util/convert/Converter.java @@ -83,7 +83,7 @@ public final class Converter { private static final Map, Set> cacheParentTypes = new ConcurrentHashMap<>(); private static final Map, Class> primitiveToWrapper = new HashMap<>(20, .8f); private static final Map, Class>, Convert> DEFAULT_FACTORY = new ConcurrentHashMap<>(500, .8f); - + // Create a Map.Entry (pair) of source class to target class. private static Map.Entry, Class> pair(Class source, Class target) { return new AbstractMap.SimpleImmutableEntry<>(source, target); @@ -108,7 +108,7 @@ private static void buildPrimitiveWrappers() { private static void buildFactoryConversions() { // Byte/byte Conversions supported - DEFAULT_FACTORY.put(pair(Void.class, byte.class), (fromInstance, converter, options) -> (byte) 0); + DEFAULT_FACTORY.put(pair(Void.class, byte.class), NumberConversion::toByteZero); DEFAULT_FACTORY.put(pair(Void.class, Byte.class), VoidConversion::toNull); DEFAULT_FACTORY.put(pair(Byte.class, Byte.class), Converter::identity); DEFAULT_FACTORY.put(pair(Short.class, Byte.class), NumberConversion::toByte); @@ -119,17 +119,17 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(Boolean.class, Byte.class), BooleanConversion::toByte); DEFAULT_FACTORY.put(pair(Character.class, Byte.class), (fromInstance, converter, options) -> (byte) ((Character) fromInstance).charValue()); DEFAULT_FACTORY.put(pair(Calendar.class, Byte.class), NumberConversion::toByte); - DEFAULT_FACTORY.put(pair(AtomicBoolean.class, Byte.class), BooleanConversion::atomicToByte); + DEFAULT_FACTORY.put(pair(AtomicBoolean.class, Byte.class), AtomicBooleanConversion::toByte); DEFAULT_FACTORY.put(pair(AtomicInteger.class, Byte.class), NumberConversion::toByte); DEFAULT_FACTORY.put(pair(AtomicLong.class, Byte.class), NumberConversion::toByte); DEFAULT_FACTORY.put(pair(BigInteger.class, Byte.class), NumberConversion::toByte); DEFAULT_FACTORY.put(pair(BigDecimal.class, Byte.class), NumberConversion::toByte); DEFAULT_FACTORY.put(pair(Number.class, Byte.class), NumberConversion::toByte); - DEFAULT_FACTORY.put(pair(Map.class, Byte.class), (fromInstance, converter, options) -> converter.fromValueMap((Map) fromInstance, byte.class, null, options)); - DEFAULT_FACTORY.put(pair(String.class, Byte.class), StringConversion::stringToByte); + DEFAULT_FACTORY.put(pair(Map.class, Byte.class), MapConversion::toByte); + DEFAULT_FACTORY.put(pair(String.class, Byte.class), StringConversion::toByte); // Short/short conversions supported - DEFAULT_FACTORY.put(pair(Void.class, short.class), (fromInstance, converter, options) -> (short) 0); + DEFAULT_FACTORY.put(pair(Void.class, short.class), NumberConversion::toShortZero); DEFAULT_FACTORY.put(pair(Void.class, Short.class), VoidConversion::toNull); DEFAULT_FACTORY.put(pair(Byte.class, Short.class), NumberConversion::toShort); DEFAULT_FACTORY.put(pair(Short.class, Short.class), Converter::identity); @@ -139,7 +139,7 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(Double.class, Short.class), NumberConversion::toShort); DEFAULT_FACTORY.put(pair(Boolean.class, Short.class), BooleanConversion::toShort); DEFAULT_FACTORY.put(pair(Character.class, Short.class), (fromInstance, converter, options) -> (short) ((Character) fromInstance).charValue()); - DEFAULT_FACTORY.put(pair(AtomicBoolean.class, Short.class), BooleanConversion::atomicToShort); + DEFAULT_FACTORY.put(pair(AtomicBoolean.class, Short.class), AtomicBooleanConversion::toShort); DEFAULT_FACTORY.put(pair(AtomicInteger.class, Short.class), NumberConversion::toShort); DEFAULT_FACTORY.put(pair(AtomicLong.class, Short.class), NumberConversion::toShort); DEFAULT_FACTORY.put(pair(BigInteger.class, Short.class), NumberConversion::toShort); @@ -147,10 +147,10 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(LocalDate.class, Short.class), (fromInstance, converter, options) -> ((LocalDate) fromInstance).toEpochDay()); DEFAULT_FACTORY.put(pair(Number.class, Short.class), NumberConversion::toShort); DEFAULT_FACTORY.put(pair(Map.class, Short.class), (fromInstance, converter, options) -> converter.fromValueMap((Map) fromInstance, short.class, null, options)); - DEFAULT_FACTORY.put(pair(String.class, Short.class), StringConversion::stringToShort); + DEFAULT_FACTORY.put(pair(String.class, Short.class), StringConversion::toShort); // Integer/int conversions supported - DEFAULT_FACTORY.put(pair(Void.class, int.class), (fromInstance, converter, options) -> 0); + DEFAULT_FACTORY.put(pair(Void.class, int.class), NumberConversion::toIntZero); DEFAULT_FACTORY.put(pair(Void.class, Integer.class), VoidConversion::toNull); DEFAULT_FACTORY.put(pair(Byte.class, Integer.class), NumberConversion::toInt); DEFAULT_FACTORY.put(pair(Short.class, Integer.class), NumberConversion::toInt); @@ -160,18 +160,18 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(Double.class, Integer.class), NumberConversion::toInt); DEFAULT_FACTORY.put(pair(Boolean.class, Integer.class), BooleanConversion::toInteger); DEFAULT_FACTORY.put(pair(Character.class, Integer.class), (fromInstance, converter, options) -> (int) (Character) fromInstance); - DEFAULT_FACTORY.put(pair(AtomicBoolean.class, Integer.class), BooleanConversion::atomicToInteger); + DEFAULT_FACTORY.put(pair(AtomicBoolean.class, Integer.class), AtomicBooleanConversion::toInteger); DEFAULT_FACTORY.put(pair(AtomicInteger.class, Integer.class), NumberConversion::toInt); DEFAULT_FACTORY.put(pair(AtomicLong.class, Integer.class), NumberConversion::toInt); DEFAULT_FACTORY.put(pair(BigInteger.class, Integer.class), NumberConversion::toInt); DEFAULT_FACTORY.put(pair(BigDecimal.class, Integer.class), NumberConversion::toInt); DEFAULT_FACTORY.put(pair(LocalDate.class, Integer.class), (fromInstance, converter, options) -> (int) ((LocalDate) fromInstance).toEpochDay()); DEFAULT_FACTORY.put(pair(Number.class, Integer.class), NumberConversion::toInt); - DEFAULT_FACTORY.put(pair(Map.class, Integer.class), (fromInstance, converter, options) -> converter.fromValueMap((Map) fromInstance, int.class, null, options)); - DEFAULT_FACTORY.put(pair(String.class, Integer.class), StringConversion::stringToInteger); + DEFAULT_FACTORY.put(pair(Map.class, Integer.class), MapConversion::toInt); + DEFAULT_FACTORY.put(pair(String.class, Integer.class), StringConversion::toInt); // Long/long conversions supported - DEFAULT_FACTORY.put(pair(Void.class, long.class), (fromInstance, converter, options) -> 0L); + DEFAULT_FACTORY.put(pair(Void.class, long.class), NumberConversion::toLongZero); DEFAULT_FACTORY.put(pair(Void.class, Long.class), VoidConversion::toNull); DEFAULT_FACTORY.put(pair(Byte.class, Long.class), NumberConversion::toLong); DEFAULT_FACTORY.put(pair(Short.class, Long.class), NumberConversion::toLong); @@ -181,7 +181,7 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(Double.class, Long.class), NumberConversion::toLong); DEFAULT_FACTORY.put(pair(Boolean.class, Long.class), BooleanConversion::toLong); DEFAULT_FACTORY.put(pair(Character.class, Long.class), (fromInstance, converter, options) -> (long) ((char) fromInstance)); - DEFAULT_FACTORY.put(pair(AtomicBoolean.class, Long.class), BooleanConversion::atomicToLong); + DEFAULT_FACTORY.put(pair(AtomicBoolean.class, Long.class), AtomicBooleanConversion::toLong); DEFAULT_FACTORY.put(pair(AtomicInteger.class, Long.class), NumberConversion::toLong); DEFAULT_FACTORY.put(pair(AtomicLong.class, Long.class), NumberConversion::toLong); DEFAULT_FACTORY.put(pair(BigInteger.class, Long.class), NumberConversion::toLong); @@ -194,11 +194,11 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(ZonedDateTime.class, Long.class), (fromInstance, converter, options) -> zonedDateTimeToMillis((ZonedDateTime) fromInstance)); DEFAULT_FACTORY.put(pair(Calendar.class, Long.class), (fromInstance, converter, options) -> ((Calendar) fromInstance).getTime().getTime()); DEFAULT_FACTORY.put(pair(Number.class, Long.class), NumberConversion::toLong); - DEFAULT_FACTORY.put(pair(Map.class, Long.class), (fromInstance, converter, options) -> converter.fromValueMap((Map) fromInstance, long.class, null, options)); - DEFAULT_FACTORY.put(pair(String.class, Long.class), StringConversion::stringToLong); + DEFAULT_FACTORY.put(pair(Map.class, Long.class), MapConversion::toLong); + DEFAULT_FACTORY.put(pair(String.class, Long.class), StringConversion::toLong); // Float/float conversions supported - DEFAULT_FACTORY.put(pair(Void.class, float.class), (fromInstance, converter, options) -> 0.0f); + DEFAULT_FACTORY.put(pair(Void.class, float.class), NumberConversion::toFloatZero); DEFAULT_FACTORY.put(pair(Void.class, Float.class), VoidConversion::toNull); DEFAULT_FACTORY.put(pair(Byte.class, Float.class), NumberConversion::toFloat); DEFAULT_FACTORY.put(pair(Short.class, Float.class), NumberConversion::toFloat); @@ -207,16 +207,16 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(Float.class, Float.class), Converter::identity); DEFAULT_FACTORY.put(pair(Double.class, Float.class), NumberConversion::toFloat); DEFAULT_FACTORY.put(pair(Boolean.class, Float.class), BooleanConversion::toFloat); - DEFAULT_FACTORY.put(pair(Character.class, Float.class), (fromInstance, converter, options) -> (float) ((char) fromInstance)); + DEFAULT_FACTORY.put(pair(Character.class, Float.class), CharacterConversion::toFloat); DEFAULT_FACTORY.put(pair(LocalDate.class, Float.class), (fromInstance, converter, options) -> ((LocalDate) fromInstance).toEpochDay()); - DEFAULT_FACTORY.put(pair(AtomicBoolean.class, Float.class), BooleanConversion::atomicToFloat); + DEFAULT_FACTORY.put(pair(AtomicBoolean.class, Float.class), AtomicBooleanConversion::toFloat); DEFAULT_FACTORY.put(pair(AtomicInteger.class, Float.class), NumberConversion::toFloat); DEFAULT_FACTORY.put(pair(AtomicLong.class, Float.class), NumberConversion::toFloat); DEFAULT_FACTORY.put(pair(BigInteger.class, Float.class), NumberConversion::toFloat); DEFAULT_FACTORY.put(pair(BigDecimal.class, Float.class), NumberConversion::toFloat); DEFAULT_FACTORY.put(pair(Number.class, Float.class), NumberConversion::toFloat); - DEFAULT_FACTORY.put(pair(Map.class, Float.class), (fromInstance, converter, options) -> converter.fromValueMap((Map) fromInstance, float.class, null, options)); - DEFAULT_FACTORY.put(pair(String.class, Float.class), StringConversion::stringToFloat); + DEFAULT_FACTORY.put(pair(Map.class, Float.class), MapConversion::toFloat); + DEFAULT_FACTORY.put(pair(String.class, Float.class), StringConversion::toFloat); // Double/double conversions supported DEFAULT_FACTORY.put(pair(Void.class, double.class), (fromInstance, converter, options) -> 0.0d); @@ -228,25 +228,25 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(Float.class, Double.class), NumberConversion::toDouble); DEFAULT_FACTORY.put(pair(Double.class, Double.class), Converter::identity); DEFAULT_FACTORY.put(pair(Boolean.class, Double.class), BooleanConversion::toDouble); - DEFAULT_FACTORY.put(pair(Character.class, Double.class), (fromInstance, converter, options) -> (double) ((char) fromInstance)); + DEFAULT_FACTORY.put(pair(Character.class, Double.class), CharacterConversion::toDouble); DEFAULT_FACTORY.put(pair(LocalDate.class, Double.class), (fromInstance, converter, options) -> (double) ((LocalDate) fromInstance).toEpochDay()); DEFAULT_FACTORY.put(pair(LocalDateTime.class, Double.class), (fromInstance, converter, options) -> (double) localDateTimeToMillis((LocalDateTime) fromInstance, options.getSourceZoneId())); DEFAULT_FACTORY.put(pair(ZonedDateTime.class, Double.class), (fromInstance, converter, options) -> (double) zonedDateTimeToMillis((ZonedDateTime) fromInstance)); DEFAULT_FACTORY.put(pair(Date.class, Double.class), (fromInstance, converter, options) -> (double) ((Date) fromInstance).getTime()); DEFAULT_FACTORY.put(pair(java.sql.Date.class, Double.class), (fromInstance, converter, options) -> (double) ((Date) fromInstance).getTime()); DEFAULT_FACTORY.put(pair(Timestamp.class, Double.class), (fromInstance, converter, options) -> (double) ((Date) fromInstance).getTime()); - DEFAULT_FACTORY.put(pair(AtomicBoolean.class, Double.class), BooleanConversion::atomicToDouble); + DEFAULT_FACTORY.put(pair(AtomicBoolean.class, Double.class), AtomicBooleanConversion::toDouble); DEFAULT_FACTORY.put(pair(AtomicInteger.class, Double.class), NumberConversion::toDouble); DEFAULT_FACTORY.put(pair(AtomicLong.class, Double.class), NumberConversion::toDouble); DEFAULT_FACTORY.put(pair(BigInteger.class, Double.class), NumberConversion::toDouble); DEFAULT_FACTORY.put(pair(BigDecimal.class, Double.class), NumberConversion::toDouble); DEFAULT_FACTORY.put(pair(Calendar.class, Double.class), (fromInstance, converter, options) -> (double) ((Calendar) fromInstance).getTime().getTime()); DEFAULT_FACTORY.put(pair(Number.class, Double.class), NumberConversion::toDouble); - DEFAULT_FACTORY.put(pair(Map.class, Double.class), (fromInstance, converter, options) -> converter.fromValueMap((Map) fromInstance, double.class, null, options)); - DEFAULT_FACTORY.put(pair(String.class, Double.class), StringConversion::stringToDouble); + DEFAULT_FACTORY.put(pair(Map.class, Double.class), MapConversion::toDouble); + DEFAULT_FACTORY.put(pair(String.class, Double.class), StringConversion::toDouble); // Boolean/boolean conversions supported - DEFAULT_FACTORY.put(pair(Void.class, boolean.class), (fromInstance, converter, options) -> false); + DEFAULT_FACTORY.put(pair(Void.class, boolean.class), VoidConversion::toBoolean); DEFAULT_FACTORY.put(pair(Void.class, Boolean.class), VoidConversion::toNull); DEFAULT_FACTORY.put(pair(Byte.class, Boolean.class), NumberConversion::isIntTypeNotZero); DEFAULT_FACTORY.put(pair(Short.class, Boolean.class), NumberConversion::isIntTypeNotZero); @@ -255,57 +255,35 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(Float.class, Boolean.class), NumberConversion::isFloatTypeNotZero); DEFAULT_FACTORY.put(pair(Double.class, Boolean.class), NumberConversion::isFloatTypeNotZero); DEFAULT_FACTORY.put(pair(Boolean.class, Boolean.class), Converter::identity); - DEFAULT_FACTORY.put(pair(Character.class, Boolean.class), (fromInstance, converter, options) -> ((char) fromInstance) > 0); - DEFAULT_FACTORY.put(pair(AtomicBoolean.class, Boolean.class), (fromInstance, converter, options) -> ((AtomicBoolean) fromInstance).get()); + DEFAULT_FACTORY.put(pair(Character.class, Boolean.class), CharacterConversion::toBoolean); + DEFAULT_FACTORY.put(pair(AtomicBoolean.class, Boolean.class), AtomicBooleanConversion::toBoolean); DEFAULT_FACTORY.put(pair(AtomicInteger.class, Boolean.class), NumberConversion::isIntTypeNotZero); DEFAULT_FACTORY.put(pair(AtomicLong.class, Boolean.class), NumberConversion::isIntTypeNotZero); - DEFAULT_FACTORY.put(pair(BigInteger.class, Boolean.class), (fromInstance, converter, options) -> ((BigInteger)fromInstance).compareTo(BigInteger.ZERO) != 0); - DEFAULT_FACTORY.put(pair(BigDecimal.class, Boolean.class), (fromInstance, converter, options) -> ((BigDecimal)fromInstance).compareTo(BigDecimal.ZERO) != 0); + DEFAULT_FACTORY.put(pair(BigInteger.class, Boolean.class), NumberConversion::isBigIntegerNotZero); + DEFAULT_FACTORY.put(pair(BigDecimal.class, Boolean.class), NumberConversion::isBigDecimalNotZero); DEFAULT_FACTORY.put(pair(Number.class, Boolean.class), NumberConversion::isIntTypeNotZero); - DEFAULT_FACTORY.put(pair(Map.class, Boolean.class), (fromInstance, converter, options) -> converter.fromValueMap((Map) fromInstance, boolean.class, null, options)); - DEFAULT_FACTORY.put(pair(String.class, Boolean.class), (fromInstance, converter, options) -> { - String str = ((String) fromInstance).trim(); - if (str.isEmpty()) { - return false; - } - // faster equals check "true" and "false" - if ("true".equals(str)) { - return true; - } else if ("false".equals(str)) { - return false; - } - return "true".equalsIgnoreCase(str); - }); + DEFAULT_FACTORY.put(pair(Map.class, Boolean.class), MapConversion::toBoolean); + DEFAULT_FACTORY.put(pair(String.class, Boolean.class), StringConversion::toBoolean); // Character/chat conversions supported - DEFAULT_FACTORY.put(pair(Void.class, char.class), (fromInstance, converter, options) -> (char) 0); + DEFAULT_FACTORY.put(pair(Void.class, char.class), VoidConversion::toChar); DEFAULT_FACTORY.put(pair(Void.class, Character.class), VoidConversion::toNull); - DEFAULT_FACTORY.put(pair(Byte.class, Character.class), NumberConversion::numberToCharacter); - DEFAULT_FACTORY.put(pair(Short.class, Character.class), NumberConversion::numberToCharacter); - DEFAULT_FACTORY.put(pair(Integer.class, Character.class), NumberConversion::numberToCharacter); - DEFAULT_FACTORY.put(pair(Long.class, Character.class), NumberConversion::numberToCharacter); - DEFAULT_FACTORY.put(pair(Float.class, Character.class), NumberConversion::numberToCharacter); - DEFAULT_FACTORY.put(pair(Double.class, Character.class), NumberConversion::numberToCharacter); - DEFAULT_FACTORY.put(pair(Boolean.class, Character.class), (fromInstance, converter, options) -> ((Boolean) fromInstance) ? '1' : '0'); + DEFAULT_FACTORY.put(pair(Byte.class, Character.class), NumberConversion::toCharacter); + DEFAULT_FACTORY.put(pair(Short.class, Character.class), NumberConversion::toCharacter); + DEFAULT_FACTORY.put(pair(Integer.class, Character.class), NumberConversion::toCharacter); + DEFAULT_FACTORY.put(pair(Long.class, Character.class), NumberConversion::toCharacter); + DEFAULT_FACTORY.put(pair(Float.class, Character.class), NumberConversion::toCharacter); + DEFAULT_FACTORY.put(pair(Double.class, Character.class), NumberConversion::toCharacter); + DEFAULT_FACTORY.put(pair(Boolean.class, Character.class), BooleanConversion::toCharacter); DEFAULT_FACTORY.put(pair(Character.class, Character.class), Converter::identity); - DEFAULT_FACTORY.put(pair(AtomicBoolean.class, Character.class), (fromInstance, converter, options) -> ((AtomicBoolean) fromInstance).get() ? '1' : '0'); - DEFAULT_FACTORY.put(pair(AtomicInteger.class, Character.class), NumberConversion::numberToCharacter); - DEFAULT_FACTORY.put(pair(AtomicLong.class, Character.class), NumberConversion::numberToCharacter); - DEFAULT_FACTORY.put(pair(BigInteger.class, Character.class), NumberConversion::numberToCharacter); - DEFAULT_FACTORY.put(pair(BigDecimal.class, Character.class), NumberConversion::numberToCharacter); - DEFAULT_FACTORY.put(pair(Number.class, Character.class), NumberConversion::numberToCharacter); + DEFAULT_FACTORY.put(pair(AtomicBoolean.class, Character.class), AtomicBooleanConversion::toCharacter); + DEFAULT_FACTORY.put(pair(AtomicInteger.class, Character.class), NumberConversion::toCharacter); + DEFAULT_FACTORY.put(pair(AtomicLong.class, Character.class), NumberConversion::toCharacter); + DEFAULT_FACTORY.put(pair(BigInteger.class, Character.class), NumberConversion::toCharacter); + DEFAULT_FACTORY.put(pair(BigDecimal.class, Character.class), NumberConversion::toCharacter); + DEFAULT_FACTORY.put(pair(Number.class, Character.class), NumberConversion::toCharacter); DEFAULT_FACTORY.put(pair(Map.class, Character.class), (fromInstance, converter, options) -> converter.fromValueMap((Map) fromInstance, char.class, null, options)); - DEFAULT_FACTORY.put(pair(String.class, Character.class), (fromInstance, converter, options) -> { - String str = ((String) fromInstance); - if (str.isEmpty()) { - return (char) 0; - } - if (str.length() == 1) { - return str.charAt(0); - } - // Treat as a String number, like "65" = 'A' - return (char) Integer.parseInt(str.trim()); - }); + DEFAULT_FACTORY.put(pair(String.class, Character.class), StringConversion::toCharacter); // BigInteger versions supported DEFAULT_FACTORY.put(pair(Void.class, BigInteger.class), VoidConversion::toNull); @@ -335,9 +313,9 @@ private static void buildFactoryConversions() { // Shift the most significant bits to the left and add the least significant bits return mostSignificant.shiftLeft(64).add(leastSignificant); }); - DEFAULT_FACTORY.put(pair(Calendar.class, BigInteger.class), (fromInstance, converter, options) -> BigInteger.valueOf(((Calendar) fromInstance).getTime().getTime())); + DEFAULT_FACTORY.put(pair(Calendar.class, BigInteger.class), CalendarConversion::toBigInteger); DEFAULT_FACTORY.put(pair(Number.class, BigInteger.class), (fromInstance, converter, options) -> new BigInteger(fromInstance.toString())); - DEFAULT_FACTORY.put(pair(Map.class, BigInteger.class), (fromInstance, converter, options) -> converter.fromValueMap((Map) fromInstance, BigInteger.class, null, options)); + DEFAULT_FACTORY.put(pair(Map.class, BigInteger.class), MapConversion::toBigInteger); DEFAULT_FACTORY.put(pair(String.class, BigInteger.class), (fromInstance, converter, options) -> { String str = ((String) fromInstance).trim(); if (str.isEmpty()) { @@ -351,24 +329,26 @@ private static void buildFactoryConversions() { } }); + + // BigDecimal conversions supported DEFAULT_FACTORY.put(pair(Void.class, BigDecimal.class), VoidConversion::toNull); - DEFAULT_FACTORY.put(pair(Byte.class, BigDecimal.class), NumberConversion::longToBigDecimal); - DEFAULT_FACTORY.put(pair(Short.class, BigDecimal.class), NumberConversion::longToBigDecimal); - DEFAULT_FACTORY.put(pair(Integer.class, BigDecimal.class), NumberConversion::longToBigDecimal); - DEFAULT_FACTORY.put(pair(Long.class, BigDecimal.class), NumberConversion::longToBigDecimal); - DEFAULT_FACTORY.put(pair(Float.class, BigDecimal.class), (fromInstance, converter, options) -> BigDecimal.valueOf((Float) fromInstance)); - DEFAULT_FACTORY.put(pair(Double.class, BigDecimal.class), (fromInstance, converter, options) -> BigDecimal.valueOf((Double) fromInstance)); - DEFAULT_FACTORY.put(pair(Boolean.class, BigDecimal.class), (fromInstance, converter, options) -> (Boolean) fromInstance ? BigDecimal.ONE : BigDecimal.ZERO); + DEFAULT_FACTORY.put(pair(Byte.class, BigDecimal.class), NumberConversion::integerTypeToBigDecimal); + DEFAULT_FACTORY.put(pair(Short.class, BigDecimal.class), NumberConversion::integerTypeToBigDecimal); + DEFAULT_FACTORY.put(pair(Integer.class, BigDecimal.class), NumberConversion::integerTypeToBigDecimal); + DEFAULT_FACTORY.put(pair(Long.class, BigDecimal.class), NumberConversion::integerTypeToBigDecimal); + DEFAULT_FACTORY.put(pair(Float.class, BigDecimal.class), NumberConversion::floatingPointToBigDecimal); + DEFAULT_FACTORY.put(pair(Double.class, BigDecimal.class), NumberConversion::floatingPointToBigDecimal); + DEFAULT_FACTORY.put(pair(Boolean.class, BigDecimal.class), BooleanConversion::toBigDecimal); DEFAULT_FACTORY.put(pair(Character.class, BigDecimal.class), (fromInstance, converter, options) -> BigDecimal.valueOf(((char) fromInstance))); DEFAULT_FACTORY.put(pair(BigDecimal.class, BigDecimal.class), Converter::identity); - DEFAULT_FACTORY.put(pair(BigInteger.class, BigDecimal.class), (fromInstance, converter, options) -> new BigDecimal((BigInteger) fromInstance)); - DEFAULT_FACTORY.put(pair(AtomicBoolean.class, BigDecimal.class), (fromInstance, converter, options) -> ((AtomicBoolean) fromInstance).get() ? BigDecimal.ONE : BigDecimal.ZERO); - DEFAULT_FACTORY.put(pair(AtomicInteger.class, BigDecimal.class), NumberConversion::longToBigDecimal); - DEFAULT_FACTORY.put(pair(AtomicLong.class, BigDecimal.class), NumberConversion::longToBigDecimal); - DEFAULT_FACTORY.put(pair(Date.class, BigDecimal.class), (fromInstance, converter, options) -> BigDecimal.valueOf(((Date) fromInstance).getTime())); - DEFAULT_FACTORY.put(pair(java.sql.Date.class, BigDecimal.class), (fromInstance, converter, options) -> BigDecimal.valueOf(((Date) fromInstance).getTime())); - DEFAULT_FACTORY.put(pair(Timestamp.class, BigDecimal.class), (fromInstance, converter, options) -> BigDecimal.valueOf(((Date) fromInstance).getTime())); + DEFAULT_FACTORY.put(pair(BigInteger.class, BigDecimal.class), NumberConversion::bigIntegerToBigDecimal); + DEFAULT_FACTORY.put(pair(AtomicBoolean.class, BigDecimal.class), AtomicBooleanConversion::toBigDecimal); + DEFAULT_FACTORY.put(pair(AtomicInteger.class, BigDecimal.class), NumberConversion::integerTypeToBigDecimal); + DEFAULT_FACTORY.put(pair(AtomicLong.class, BigDecimal.class), NumberConversion::integerTypeToBigDecimal); + DEFAULT_FACTORY.put(pair(Date.class, BigDecimal.class), DateConversion::toBigDecimal); + DEFAULT_FACTORY.put(pair(java.sql.Date.class, BigDecimal.class), DateConversion::toBigDecimal); + DEFAULT_FACTORY.put(pair(Timestamp.class, BigDecimal.class), DateConversion::toBigDecimal); DEFAULT_FACTORY.put(pair(LocalDate.class, BigDecimal.class), (fromInstance, converter, options) -> BigDecimal.valueOf(((LocalDate) fromInstance).toEpochDay())); DEFAULT_FACTORY.put(pair(LocalDateTime.class, BigDecimal.class), (fromInstance, converter, options) -> BigDecimal.valueOf(localDateTimeToMillis((LocalDateTime) fromInstance, options.getSourceZoneId()))); DEFAULT_FACTORY.put(pair(ZonedDateTime.class, BigDecimal.class), (fromInstance, converter, options) -> BigDecimal.valueOf(zonedDateTimeToMillis((ZonedDateTime) fromInstance))); @@ -379,38 +359,28 @@ private static void buildFactoryConversions() { // Shift the most significant bits to the left and add the least significant bits return new BigDecimal(mostSignificant.shiftLeft(64).add(leastSignificant)); }); - DEFAULT_FACTORY.put(pair(Calendar.class, BigDecimal.class), (fromInstance, converter, options) -> BigDecimal.valueOf(((Calendar) fromInstance).getTime().getTime())); + DEFAULT_FACTORY.put(pair(Calendar.class, BigDecimal.class), CalendarConversion::toBigDecimal); DEFAULT_FACTORY.put(pair(Number.class, BigDecimal.class), (fromInstance, converter, options) -> new BigDecimal(fromInstance.toString())); - DEFAULT_FACTORY.put(pair(Map.class, BigDecimal.class), (fromInstance, converter, options) -> converter.fromValueMap((Map) fromInstance, BigDecimal.class, null, options)); - DEFAULT_FACTORY.put(pair(String.class, BigDecimal.class), (fromInstance, converter, options) -> { - String str = ((String) fromInstance).trim(); - if (str.isEmpty()) { - return BigDecimal.ZERO; - } - try { - return new BigDecimal(str); - } catch (NumberFormatException e) { - throw new IllegalArgumentException("Value: " + fromInstance + " not parseable as a BigDecimal value."); - } - }); + DEFAULT_FACTORY.put(pair(Map.class, BigDecimal.class), MapConversion::toBigDecimal); + DEFAULT_FACTORY.put(pair(String.class, BigDecimal.class), StringConversion::toBigDecimal); // AtomicBoolean conversions supported DEFAULT_FACTORY.put(pair(Void.class, AtomicBoolean.class), VoidConversion::toNull); - DEFAULT_FACTORY.put(pair(Byte.class, AtomicBoolean.class), BooleanConversion::numberToAtomicBoolean); - DEFAULT_FACTORY.put(pair(Short.class, AtomicBoolean.class), BooleanConversion::numberToAtomicBoolean); - DEFAULT_FACTORY.put(pair(Integer.class, AtomicBoolean.class), BooleanConversion::numberToAtomicBoolean); - DEFAULT_FACTORY.put(pair(Long.class, AtomicBoolean.class), BooleanConversion::numberToAtomicBoolean); - DEFAULT_FACTORY.put(pair(Float.class, AtomicBoolean.class), BooleanConversion::numberToAtomicBoolean); - DEFAULT_FACTORY.put(pair(Double.class, AtomicBoolean.class), BooleanConversion::numberToAtomicBoolean); - DEFAULT_FACTORY.put(pair(Boolean.class, AtomicBoolean.class), (fromInstance, converter, options) -> new AtomicBoolean((Boolean) fromInstance)); + DEFAULT_FACTORY.put(pair(Byte.class, AtomicBoolean.class), NumberConversion::toAtomicBoolean); + DEFAULT_FACTORY.put(pair(Short.class, AtomicBoolean.class), NumberConversion::toAtomicBoolean); + DEFAULT_FACTORY.put(pair(Integer.class, AtomicBoolean.class), NumberConversion::toAtomicBoolean); + DEFAULT_FACTORY.put(pair(Long.class, AtomicBoolean.class), NumberConversion::toAtomicBoolean); + DEFAULT_FACTORY.put(pair(Float.class, AtomicBoolean.class), NumberConversion::toAtomicBoolean); + DEFAULT_FACTORY.put(pair(Double.class, AtomicBoolean.class), NumberConversion::toAtomicBoolean); + DEFAULT_FACTORY.put(pair(Boolean.class, AtomicBoolean.class), BooleanConversion::toAtomicBoolean); DEFAULT_FACTORY.put(pair(Character.class, AtomicBoolean.class), (fromInstance, converter, options) -> new AtomicBoolean((char) fromInstance > 0)); - DEFAULT_FACTORY.put(pair(BigInteger.class, AtomicBoolean.class), BooleanConversion::numberToAtomicBoolean); - DEFAULT_FACTORY.put(pair(BigDecimal.class, AtomicBoolean.class), BooleanConversion::numberToAtomicBoolean); + DEFAULT_FACTORY.put(pair(BigInteger.class, AtomicBoolean.class), NumberConversion::toAtomicBoolean); + DEFAULT_FACTORY.put(pair(BigDecimal.class, AtomicBoolean.class), NumberConversion::toAtomicBoolean); DEFAULT_FACTORY.put(pair(AtomicBoolean.class, AtomicBoolean.class), (fromInstance, converter, options) -> new AtomicBoolean(((AtomicBoolean) fromInstance).get())); // mutable, so dupe - DEFAULT_FACTORY.put(pair(AtomicInteger.class, AtomicBoolean.class), BooleanConversion::numberToAtomicBoolean); - DEFAULT_FACTORY.put(pair(AtomicLong.class, AtomicBoolean.class), BooleanConversion::numberToAtomicBoolean); - DEFAULT_FACTORY.put(pair(Number.class, AtomicBoolean.class), BooleanConversion::numberToAtomicBoolean); - DEFAULT_FACTORY.put(pair(Map.class, AtomicBoolean.class), (fromInstance, converter, options) -> converter.fromValueMap((Map) fromInstance, AtomicBoolean.class, null, options)); + DEFAULT_FACTORY.put(pair(AtomicInteger.class, AtomicBoolean.class), NumberConversion::toAtomicBoolean); + DEFAULT_FACTORY.put(pair(AtomicLong.class, AtomicBoolean.class), NumberConversion::toAtomicBoolean); + DEFAULT_FACTORY.put(pair(Number.class, AtomicBoolean.class), NumberConversion::toAtomicBoolean); + DEFAULT_FACTORY.put(pair(Map.class, AtomicBoolean.class), MapConversion::toAtomicBoolean); DEFAULT_FACTORY.put(pair(String.class, AtomicBoolean.class), (fromInstance, converter, options) -> { String str = ((String) fromInstance).trim(); if (str.isEmpty()) { @@ -421,57 +391,57 @@ private static void buildFactoryConversions() { // AtomicInteger conversions supported DEFAULT_FACTORY.put(pair(Void.class, AtomicInteger.class), VoidConversion::toNull); - DEFAULT_FACTORY.put(pair(Byte.class, AtomicInteger.class), NumberConversion::numberToAtomicInteger); - DEFAULT_FACTORY.put(pair(Short.class, AtomicInteger.class), NumberConversion::numberToAtomicInteger); - DEFAULT_FACTORY.put(pair(Integer.class, AtomicInteger.class), NumberConversion::numberToAtomicInteger); - DEFAULT_FACTORY.put(pair(Long.class, AtomicInteger.class), NumberConversion::numberToAtomicInteger); - DEFAULT_FACTORY.put(pair(Float.class, AtomicInteger.class), NumberConversion::numberToAtomicInteger); - DEFAULT_FACTORY.put(pair(Double.class, AtomicInteger.class), NumberConversion::numberToAtomicInteger); + DEFAULT_FACTORY.put(pair(Byte.class, AtomicInteger.class), NumberConversion::toAtomicInteger); + DEFAULT_FACTORY.put(pair(Short.class, AtomicInteger.class), NumberConversion::toAtomicInteger); + DEFAULT_FACTORY.put(pair(Integer.class, AtomicInteger.class), NumberConversion::toAtomicInteger); + DEFAULT_FACTORY.put(pair(Long.class, AtomicInteger.class), NumberConversion::toAtomicInteger); + DEFAULT_FACTORY.put(pair(Float.class, AtomicInteger.class), NumberConversion::toAtomicInteger); + DEFAULT_FACTORY.put(pair(Double.class, AtomicInteger.class), NumberConversion::toAtomicInteger); DEFAULT_FACTORY.put(pair(Boolean.class, AtomicInteger.class), (fromInstance, converter, options) -> ((Boolean) fromInstance) ? new AtomicInteger(1) : new AtomicInteger(0)); DEFAULT_FACTORY.put(pair(Character.class, AtomicInteger.class), (fromInstance, converter, options) -> new AtomicInteger(((char) fromInstance))); - DEFAULT_FACTORY.put(pair(BigInteger.class, AtomicInteger.class), NumberConversion::numberToAtomicInteger); - DEFAULT_FACTORY.put(pair(BigDecimal.class, AtomicInteger.class), NumberConversion::numberToAtomicInteger); - DEFAULT_FACTORY.put(pair(AtomicInteger.class, AtomicInteger.class), NumberConversion::numberToAtomicInteger); // mutable, so dupe + DEFAULT_FACTORY.put(pair(BigInteger.class, AtomicInteger.class), NumberConversion::toAtomicInteger); + DEFAULT_FACTORY.put(pair(BigDecimal.class, AtomicInteger.class), NumberConversion::toAtomicInteger); + DEFAULT_FACTORY.put(pair(AtomicInteger.class, AtomicInteger.class), NumberConversion::toAtomicInteger); // mutable, so dupe DEFAULT_FACTORY.put(pair(AtomicBoolean.class, AtomicInteger.class), (fromInstance, converter, options) -> ((AtomicBoolean) fromInstance).get() ? new AtomicInteger(1) : new AtomicInteger(0)); - DEFAULT_FACTORY.put(pair(AtomicLong.class, AtomicInteger.class), NumberConversion::numberToAtomicInteger); + DEFAULT_FACTORY.put(pair(AtomicLong.class, AtomicInteger.class), NumberConversion::toAtomicInteger); DEFAULT_FACTORY.put(pair(LocalDate.class, AtomicInteger.class), (fromInstance, converter, options) -> new AtomicInteger((int) ((LocalDate) fromInstance).toEpochDay())); - DEFAULT_FACTORY.put(pair(Number.class, AtomicBoolean.class), NumberConversion::numberToAtomicInteger); - DEFAULT_FACTORY.put(pair(Map.class, AtomicInteger.class), (fromInstance, converter, options) -> converter.fromValueMap((Map) fromInstance, AtomicInteger.class, null, options)); - DEFAULT_FACTORY.put(pair(String.class, AtomicInteger.class), StringConversion::stringToAtomicInteger); + DEFAULT_FACTORY.put(pair(Number.class, AtomicBoolean.class), NumberConversion::toAtomicInteger); + DEFAULT_FACTORY.put(pair(Map.class, AtomicInteger.class), MapConversion::toAtomicInteger); + DEFAULT_FACTORY.put(pair(String.class, AtomicInteger.class), StringConversion::toAtomicInteger); // AtomicLong conversions supported DEFAULT_FACTORY.put(pair(Void.class, AtomicLong.class), VoidConversion::toNull); - DEFAULT_FACTORY.put(pair(Byte.class, AtomicLong.class), NumberConversion::numberToAtomicLong); - DEFAULT_FACTORY.put(pair(Short.class, AtomicLong.class), NumberConversion::numberToAtomicLong); - DEFAULT_FACTORY.put(pair(Integer.class, AtomicLong.class), NumberConversion::numberToAtomicLong); - DEFAULT_FACTORY.put(pair(Long.class, AtomicLong.class), NumberConversion::numberToAtomicLong); - DEFAULT_FACTORY.put(pair(Float.class, AtomicLong.class), NumberConversion::numberToAtomicLong); - DEFAULT_FACTORY.put(pair(Double.class, AtomicLong.class), NumberConversion::numberToAtomicLong); - DEFAULT_FACTORY.put(pair(Boolean.class, AtomicLong.class), (fromInstance, converter, options) -> ((Boolean) fromInstance) ? new AtomicLong(1) : new AtomicLong(0)); + DEFAULT_FACTORY.put(pair(Byte.class, AtomicLong.class), NumberConversion::toAtomicLong); + DEFAULT_FACTORY.put(pair(Short.class, AtomicLong.class), NumberConversion::toAtomicLong); + DEFAULT_FACTORY.put(pair(Integer.class, AtomicLong.class), NumberConversion::toAtomicLong); + DEFAULT_FACTORY.put(pair(Long.class, AtomicLong.class), NumberConversion::toAtomicLong); + DEFAULT_FACTORY.put(pair(Float.class, AtomicLong.class), NumberConversion::toAtomicLong); + DEFAULT_FACTORY.put(pair(Double.class, AtomicLong.class), NumberConversion::toAtomicLong); + DEFAULT_FACTORY.put(pair(Boolean.class, AtomicLong.class), BooleanConversion::toAtomicLong); DEFAULT_FACTORY.put(pair(Character.class, AtomicLong.class), (fromInstance, converter, options) -> new AtomicLong(((char) fromInstance))); - DEFAULT_FACTORY.put(pair(BigInteger.class, AtomicLong.class), NumberConversion::numberToAtomicLong); - DEFAULT_FACTORY.put(pair(BigDecimal.class, AtomicLong.class), NumberConversion::numberToAtomicLong); - DEFAULT_FACTORY.put(pair(AtomicBoolean.class, AtomicLong.class), (fromInstance, converter, options) -> ((AtomicBoolean) fromInstance).get() ? new AtomicLong(1) : new AtomicLong(0)); - DEFAULT_FACTORY.put(pair(AtomicInteger.class, AtomicLong.class), NumberConversion::numberToAtomicLong); - DEFAULT_FACTORY.put(pair(AtomicLong.class, AtomicLong.class), NumberConversion::numberToAtomicLong); // mutable, so dupe - DEFAULT_FACTORY.put(pair(Date.class, AtomicLong.class), (fromInstance, converter, options) -> new AtomicLong(((Date) fromInstance).getTime())); - DEFAULT_FACTORY.put(pair(java.sql.Date.class, AtomicLong.class), (fromInstance, converter, options) -> new AtomicLong(((Date) fromInstance).getTime())); - DEFAULT_FACTORY.put(pair(Timestamp.class, AtomicLong.class), (fromInstance, converter, options) -> new AtomicLong(((Date) fromInstance).getTime())); + DEFAULT_FACTORY.put(pair(BigInteger.class, AtomicLong.class), NumberConversion::toAtomicLong); + DEFAULT_FACTORY.put(pair(BigDecimal.class, AtomicLong.class), NumberConversion::toAtomicLong); + DEFAULT_FACTORY.put(pair(AtomicBoolean.class, AtomicLong.class), AtomicBooleanConversion::toAtomicLong); + DEFAULT_FACTORY.put(pair(AtomicLong.class, AtomicLong.class), Converter::identity); // mutable, so dupe + DEFAULT_FACTORY.put(pair(AtomicInteger.class, AtomicLong.class), NumberConversion::toAtomicLong); + DEFAULT_FACTORY.put(pair(Date.class, AtomicLong.class), DateConversion::toAtomicLong); + DEFAULT_FACTORY.put(pair(java.sql.Date.class, AtomicLong.class), DateConversion::toAtomicLong); + DEFAULT_FACTORY.put(pair(Timestamp.class, AtomicLong.class), DateConversion::toAtomicLong); DEFAULT_FACTORY.put(pair(LocalDate.class, AtomicLong.class), (fromInstance, converter, options) -> new AtomicLong(((LocalDate) fromInstance).toEpochDay())); DEFAULT_FACTORY.put(pair(LocalDateTime.class, AtomicLong.class), (fromInstance, converter, options) -> new AtomicLong(localDateTimeToMillis((LocalDateTime) fromInstance, options.getSourceZoneId()))); DEFAULT_FACTORY.put(pair(ZonedDateTime.class, AtomicLong.class), (fromInstance, converter, options) -> new AtomicLong(zonedDateTimeToMillis((ZonedDateTime) fromInstance))); - DEFAULT_FACTORY.put(pair(Calendar.class, AtomicLong.class), (fromInstance, converter, options) -> new AtomicLong(((Calendar) fromInstance).getTime().getTime())); - DEFAULT_FACTORY.put(pair(Number.class, AtomicLong.class), NumberConversion::numberToAtomicLong); - DEFAULT_FACTORY.put(pair(Map.class, AtomicLong.class), (fromInstance, converter, options) -> converter.fromValueMap((Map) fromInstance, AtomicLong.class, null, options)); - DEFAULT_FACTORY.put(pair(String.class, AtomicLong.class), StringConversion::stringToAtomicLong); + DEFAULT_FACTORY.put(pair(Calendar.class, AtomicLong.class), CalendarConversion::toAtomicLong); + DEFAULT_FACTORY.put(pair(Number.class, AtomicLong.class), NumberConversion::toAtomicLong); + DEFAULT_FACTORY.put(pair(Map.class, AtomicLong.class), MapConversion::toAtomicLong); + DEFAULT_FACTORY.put(pair(String.class, AtomicLong.class), StringConversion::toAtomicLong); // Date conversions supported DEFAULT_FACTORY.put(pair(Void.class, Date.class), VoidConversion::toNull); - DEFAULT_FACTORY.put(pair(Long.class, Date.class), NumberConversion::numberToDate); - DEFAULT_FACTORY.put(pair(Double.class, Date.class), NumberConversion::numberToDate); - DEFAULT_FACTORY.put(pair(BigInteger.class, Date.class), NumberConversion::numberToDate); - DEFAULT_FACTORY.put(pair(BigDecimal.class, Date.class), NumberConversion::numberToDate); - DEFAULT_FACTORY.put(pair(AtomicLong.class, Date.class), NumberConversion::numberToDate); + DEFAULT_FACTORY.put(pair(Long.class, Date.class), NumberConversion::toDate); + DEFAULT_FACTORY.put(pair(Double.class, Date.class), NumberConversion::toDate); + DEFAULT_FACTORY.put(pair(BigInteger.class, Date.class), NumberConversion::toDate); + DEFAULT_FACTORY.put(pair(BigDecimal.class, Date.class), NumberConversion::toDate); + DEFAULT_FACTORY.put(pair(AtomicLong.class, Date.class), NumberConversion::toDate); DEFAULT_FACTORY.put(pair(Date.class, Date.class), (fromInstance, converter, options) -> new Date(((Date) fromInstance).getTime())); DEFAULT_FACTORY.put(pair(java.sql.Date.class, Date.class), (fromInstance, converter, options) -> new Date(((Date) fromInstance).getTime())); DEFAULT_FACTORY.put(pair(Timestamp.class, Date.class), (fromInstance, converter, options) -> new Date(((Date) fromInstance).getTime())); @@ -479,7 +449,7 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(LocalDateTime.class, Date.class), (fromInstance, converter, options) -> new Date(localDateTimeToMillis((LocalDateTime) fromInstance, options.getSourceZoneId()))); DEFAULT_FACTORY.put(pair(ZonedDateTime.class, Date.class), (fromInstance, converter, options) -> new Date(zonedDateTimeToMillis((ZonedDateTime) fromInstance))); DEFAULT_FACTORY.put(pair(Calendar.class, Date.class), (fromInstance, converter, options) -> ((Calendar) fromInstance).getTime()); - DEFAULT_FACTORY.put(pair(Number.class, Date.class), NumberConversion::numberToDate); + DEFAULT_FACTORY.put(pair(Number.class, Date.class), NumberConversion::toDate); DEFAULT_FACTORY.put(pair(Map.class, Date.class), (fromInstance, converter, options) -> { Map map = (Map) fromInstance; if (map.containsKey("time")) { @@ -492,19 +462,20 @@ private static void buildFactoryConversions() { // java.sql.Date conversion supported DEFAULT_FACTORY.put(pair(Void.class, java.sql.Date.class), VoidConversion::toNull); - DEFAULT_FACTORY.put(pair(Long.class, java.sql.Date.class), NumberConversion::numberToSqlDate); - DEFAULT_FACTORY.put(pair(Double.class, java.sql.Date.class), NumberConversion::numberToSqlDate); - DEFAULT_FACTORY.put(pair(BigInteger.class, java.sql.Date.class), NumberConversion::numberToSqlDate); - DEFAULT_FACTORY.put(pair(BigDecimal.class, java.sql.Date.class), NumberConversion::numberToSqlDate); - DEFAULT_FACTORY.put(pair(AtomicLong.class, java.sql.Date.class), NumberConversion::numberToSqlDate); + DEFAULT_FACTORY.put(pair(Long.class, java.sql.Date.class), NumberConversion::toSqlDate); + DEFAULT_FACTORY.put(pair(Double.class, java.sql.Date.class), NumberConversion::toSqlDate); + DEFAULT_FACTORY.put(pair(BigInteger.class, java.sql.Date.class), NumberConversion::toSqlDate); + DEFAULT_FACTORY.put(pair(BigDecimal.class, java.sql.Date.class), NumberConversion::toSqlDate); + DEFAULT_FACTORY.put(pair(AtomicLong.class, java.sql.Date.class), NumberConversion::toSqlDate); + // why not use identity? (no conversion needed) DEFAULT_FACTORY.put(pair(java.sql.Date.class, java.sql.Date.class), (fromInstance, converter, options) -> new java.sql.Date(((java.sql.Date) fromInstance).getTime())); // java.sql.Date is mutable - DEFAULT_FACTORY.put(pair(Date.class, java.sql.Date.class), (fromInstance, converter, options) -> new java.sql.Date(((Date) fromInstance).getTime())); + DEFAULT_FACTORY.put(pair(Date.class, java.sql.Date.class), DateConversion::toSqlDate); DEFAULT_FACTORY.put(pair(Timestamp.class, java.sql.Date.class), (fromInstance, converter, options) -> new java.sql.Date(((Date) fromInstance).getTime())); DEFAULT_FACTORY.put(pair(LocalDate.class, java.sql.Date.class), (fromInstance, converter, options) -> new java.sql.Date(localDateToMillis((LocalDate) fromInstance, options.getSourceZoneId()))); DEFAULT_FACTORY.put(pair(LocalDateTime.class, java.sql.Date.class), (fromInstance, converter, options) -> new java.sql.Date(localDateTimeToMillis((LocalDateTime) fromInstance, options.getSourceZoneId()))); DEFAULT_FACTORY.put(pair(ZonedDateTime.class, java.sql.Date.class), (fromInstance, converter, options) -> new java.sql.Date(zonedDateTimeToMillis((ZonedDateTime) fromInstance))); DEFAULT_FACTORY.put(pair(Calendar.class, java.sql.Date.class), (fromInstance, converter, options) -> new java.sql.Date(((Calendar) fromInstance).getTime().getTime())); - DEFAULT_FACTORY.put(pair(Number.class, java.sql.Date.class), NumberConversion::numberToSqlDate); + DEFAULT_FACTORY.put(pair(Number.class, java.sql.Date.class), NumberConversion::toSqlDate); DEFAULT_FACTORY.put(pair(Map.class, java.sql.Date.class), (fromInstance, converter, options) -> { Map map = (Map) fromInstance; if (map.containsKey("time")) { @@ -524,11 +495,11 @@ private static void buildFactoryConversions() { // Timestamp conversions supported DEFAULT_FACTORY.put(pair(Void.class, Timestamp.class), VoidConversion::toNull); - DEFAULT_FACTORY.put(pair(Long.class, Timestamp.class), NumberConversion::numberToTimestamp); - DEFAULT_FACTORY.put(pair(Double.class, Timestamp.class), NumberConversion::numberToTimestamp); - DEFAULT_FACTORY.put(pair(BigInteger.class, Timestamp.class), NumberConversion::numberToTimestamp); - DEFAULT_FACTORY.put(pair(BigDecimal.class, Timestamp.class), NumberConversion::numberToTimestamp); - DEFAULT_FACTORY.put(pair(AtomicLong.class, Timestamp.class), NumberConversion::numberToTimestamp); + DEFAULT_FACTORY.put(pair(Long.class, Timestamp.class), NumberConversion::toTimestamp); + DEFAULT_FACTORY.put(pair(Double.class, Timestamp.class), NumberConversion::toTimestamp); + DEFAULT_FACTORY.put(pair(BigInteger.class, Timestamp.class), NumberConversion::toTimestamp); + DEFAULT_FACTORY.put(pair(BigDecimal.class, Timestamp.class), NumberConversion::toTimestamp); + DEFAULT_FACTORY.put(pair(AtomicLong.class, Timestamp.class), NumberConversion::toTimestamp); DEFAULT_FACTORY.put(pair(Timestamp.class, Timestamp.class), (fromInstance, converter, options) -> new Timestamp(((Timestamp) fromInstance).getTime())); DEFAULT_FACTORY.put(pair(java.sql.Date.class, Timestamp.class), (fromInstance, converter, options) -> new Timestamp(((Date) fromInstance).getTime())); DEFAULT_FACTORY.put(pair(Date.class, Timestamp.class), (fromInstance, converter, options) -> new Timestamp(((Date) fromInstance).getTime())); @@ -536,7 +507,7 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(LocalDateTime.class, Timestamp.class), (fromInstance, converter, options) -> new Timestamp(localDateTimeToMillis((LocalDateTime) fromInstance, options.getSourceZoneId()))); DEFAULT_FACTORY.put(pair(ZonedDateTime.class, Timestamp.class), (fromInstance, converter, options) -> new Timestamp(zonedDateTimeToMillis((ZonedDateTime) fromInstance))); DEFAULT_FACTORY.put(pair(Calendar.class, Timestamp.class), (fromInstance, converter, options) -> new Timestamp(((Calendar) fromInstance).getTime().getTime())); - DEFAULT_FACTORY.put(pair(Number.class, Timestamp.class), NumberConversion::numberToTimestamp); + DEFAULT_FACTORY.put(pair(Number.class, Timestamp.class), NumberConversion::toTimestamp); DEFAULT_FACTORY.put(pair(Map.class, Timestamp.class), (fromInstance, converter, options) -> { Map map = (Map) fromInstance; if (map.containsKey("time")) { @@ -560,11 +531,11 @@ private static void buildFactoryConversions() { // Calendar conversions supported DEFAULT_FACTORY.put(pair(Void.class, Calendar.class), VoidConversion::toNull); - DEFAULT_FACTORY.put(pair(Long.class, Calendar.class), NumberConversion::numberToCalendar); - DEFAULT_FACTORY.put(pair(Double.class, Calendar.class), NumberConversion::numberToCalendar); - DEFAULT_FACTORY.put(pair(BigInteger.class, Calendar.class), NumberConversion::numberToCalendar); - DEFAULT_FACTORY.put(pair(BigDecimal.class, Calendar.class), NumberConversion::numberToCalendar); - DEFAULT_FACTORY.put(pair(AtomicLong.class, Calendar.class), NumberConversion::numberToCalendar); + DEFAULT_FACTORY.put(pair(Long.class, Calendar.class), NumberConversion::toCalendar); + DEFAULT_FACTORY.put(pair(Double.class, Calendar.class), NumberConversion::toCalendar); + DEFAULT_FACTORY.put(pair(BigInteger.class, Calendar.class), NumberConversion::toCalendar); + DEFAULT_FACTORY.put(pair(BigDecimal.class, Calendar.class), NumberConversion::toCalendar); + DEFAULT_FACTORY.put(pair(AtomicLong.class, Calendar.class), NumberConversion::toCalendar); DEFAULT_FACTORY.put(pair(Date.class, Calendar.class), (fromInstance, converter, options) -> initCal(((Date) fromInstance).getTime())); DEFAULT_FACTORY.put(pair(java.sql.Date.class, Calendar.class), (fromInstance, converter, options) -> initCal(((Date) fromInstance).getTime())); DEFAULT_FACTORY.put(pair(Timestamp.class, Calendar.class), (fromInstance, converter, options) -> initCal(((Date) fromInstance).getTime())); @@ -572,7 +543,7 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(LocalDateTime.class, Calendar.class), (fromInstance, converter, options) -> initCal(localDateTimeToMillis((LocalDateTime) fromInstance, options.getSourceZoneId()))); DEFAULT_FACTORY.put(pair(ZonedDateTime.class, Calendar.class), (fromInstance, converter, options) -> initCal(zonedDateTimeToMillis((ZonedDateTime) fromInstance))); DEFAULT_FACTORY.put(pair(Calendar.class, Calendar.class), (fromInstance, converter, options) -> ((Calendar) fromInstance).clone()); - DEFAULT_FACTORY.put(pair(Number.class, Calendar.class), NumberConversion::numberToCalendar); + DEFAULT_FACTORY.put(pair(Number.class, Calendar.class), NumberConversion::toCalendar); DEFAULT_FACTORY.put(pair(Map.class, Calendar.class), (fromInstance, converter, options) -> { Map map = (Map) fromInstance; if (map.containsKey("time")) { @@ -628,15 +599,15 @@ private static void buildFactoryConversions() { // LocalDate conversions supported DEFAULT_FACTORY.put(pair(Void.class, LocalDate.class), VoidConversion::toNull); - DEFAULT_FACTORY.put(pair(Short.class, LocalDate.class), NumberConversion::numberToLocalDate); - DEFAULT_FACTORY.put(pair(Integer.class, LocalDate.class), NumberConversion::numberToLocalDate); - DEFAULT_FACTORY.put(pair(Long.class, LocalDate.class), NumberConversion::numberToLocalDate); - DEFAULT_FACTORY.put(pair(Float.class, LocalDate.class), NumberConversion::numberToLocalDate); - DEFAULT_FACTORY.put(pair(Double.class, LocalDate.class), NumberConversion::numberToLocalDate); - DEFAULT_FACTORY.put(pair(BigInteger.class, LocalDate.class), NumberConversion::numberToLocalDate); - DEFAULT_FACTORY.put(pair(BigDecimal.class, LocalDate.class), NumberConversion::numberToLocalDate); - DEFAULT_FACTORY.put(pair(AtomicInteger.class, LocalDate.class), NumberConversion::numberToLocalDate); - DEFAULT_FACTORY.put(pair(AtomicLong.class, LocalDate.class), NumberConversion::numberToLocalDate); + DEFAULT_FACTORY.put(pair(Short.class, LocalDate.class), NumberConversion::toLocalDate); + DEFAULT_FACTORY.put(pair(Integer.class, LocalDate.class), NumberConversion::toLocalDate); + DEFAULT_FACTORY.put(pair(Long.class, LocalDate.class), NumberConversion::toLocalDate); + DEFAULT_FACTORY.put(pair(Float.class, LocalDate.class), NumberConversion::toLocalDate); + DEFAULT_FACTORY.put(pair(Double.class, LocalDate.class), NumberConversion::toLocalDate); + DEFAULT_FACTORY.put(pair(BigInteger.class, LocalDate.class), NumberConversion::toLocalDate); + DEFAULT_FACTORY.put(pair(BigDecimal.class, LocalDate.class), NumberConversion::toLocalDate); + DEFAULT_FACTORY.put(pair(AtomicInteger.class, LocalDate.class), NumberConversion::toLocalDate); + DEFAULT_FACTORY.put(pair(AtomicLong.class, LocalDate.class), NumberConversion::toLocalDate); DEFAULT_FACTORY.put(pair(java.sql.Date.class, LocalDate.class), (fromInstance, converter, options) -> ((java.sql.Date) fromInstance).toLocalDate()); DEFAULT_FACTORY.put(pair(Timestamp.class, LocalDate.class), (fromInstance, converter, options) -> ((Timestamp) fromInstance).toLocalDateTime().toLocalDate()); DEFAULT_FACTORY.put(pair(Date.class, LocalDate.class), (fromInstance, converter, options) -> ((Date) fromInstance).toInstant().atZone(ZoneId.systemDefault()).toLocalDate()); @@ -644,7 +615,7 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(LocalDateTime.class, LocalDate.class), (fromInstance, converter, options) -> ((LocalDateTime) fromInstance).toLocalDate()); DEFAULT_FACTORY.put(pair(ZonedDateTime.class, LocalDate.class), (fromInstance, converter, options) -> ((ZonedDateTime) fromInstance).toLocalDate()); DEFAULT_FACTORY.put(pair(Calendar.class, LocalDate.class), (fromInstance, converter, options) -> ((Calendar) fromInstance).toInstant().atZone(ZoneId.systemDefault()).toLocalDate()); - DEFAULT_FACTORY.put(pair(Number.class, LocalDate.class), NumberConversion::numberToLocalDate); + DEFAULT_FACTORY.put(pair(Number.class, LocalDate.class), NumberConversion::toLocalDate); DEFAULT_FACTORY.put(pair(Map.class, LocalDate.class), (fromInstance, converter, options) -> { Map map = (Map) fromInstance; if (map.containsKey("month") && map.containsKey("day") && map.containsKey("year")) { @@ -667,11 +638,11 @@ private static void buildFactoryConversions() { // LocalDateTime conversions supported DEFAULT_FACTORY.put(pair(Void.class, LocalDateTime.class), VoidConversion::toNull); - DEFAULT_FACTORY.put(pair(Long.class, LocalDateTime.class), NumberConversion::numberToLocalDateTime); - DEFAULT_FACTORY.put(pair(Double.class, LocalDateTime.class), NumberConversion::numberToLocalDateTime); - DEFAULT_FACTORY.put(pair(BigInteger.class, LocalDateTime.class), NumberConversion::numberToLocalDateTime); - DEFAULT_FACTORY.put(pair(BigDecimal.class, LocalDateTime.class), NumberConversion::numberToLocalDateTime); - DEFAULT_FACTORY.put(pair(AtomicLong.class, LocalDateTime.class), NumberConversion::numberToLocalDateTime); + DEFAULT_FACTORY.put(pair(Long.class, LocalDateTime.class), NumberConversion::toLocalDateTime); + DEFAULT_FACTORY.put(pair(Double.class, LocalDateTime.class), NumberConversion::toLocalDateTime); + DEFAULT_FACTORY.put(pair(BigInteger.class, LocalDateTime.class), NumberConversion::toLocalDateTime); + DEFAULT_FACTORY.put(pair(BigDecimal.class, LocalDateTime.class), NumberConversion::toLocalDateTime); + DEFAULT_FACTORY.put(pair(AtomicLong.class, LocalDateTime.class), NumberConversion::toLocalDateTime); DEFAULT_FACTORY.put(pair(java.sql.Date.class, LocalDateTime.class), (fromInstance, converter, options) -> ((java.sql.Date) fromInstance).toLocalDate().atStartOfDay()); DEFAULT_FACTORY.put(pair(Timestamp.class, LocalDateTime.class), (fromInstance, converter, options) -> ((Timestamp) fromInstance).toLocalDateTime()); DEFAULT_FACTORY.put(pair(Date.class, LocalDateTime.class), (fromInstance, converter, options) -> ((Date) fromInstance).toInstant().atZone(options.getSourceZoneId()).toLocalDateTime()); @@ -679,7 +650,7 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(LocalDate.class, LocalDateTime.class), (fromInstance, converter, options) -> ((LocalDate) fromInstance).atStartOfDay()); DEFAULT_FACTORY.put(pair(ZonedDateTime.class, LocalDateTime.class), (fromInstance, converter, options) -> ((ZonedDateTime) fromInstance).toLocalDateTime()); DEFAULT_FACTORY.put(pair(Calendar.class, LocalDateTime.class), (fromInstance, converter, options) -> ((Calendar) fromInstance).toInstant().atZone(options.getSourceZoneId()).toLocalDateTime()); - DEFAULT_FACTORY.put(pair(Number.class, LocalDateTime.class), NumberConversion::numberToLocalDateTime); + DEFAULT_FACTORY.put(pair(Number.class, LocalDateTime.class), NumberConversion::toLocalDateTime); DEFAULT_FACTORY.put(pair(Map.class, LocalDateTime.class), (fromInstance, converter, options) -> { Map map = (Map) fromInstance; return converter.fromValueMap(map, LocalDateTime.class, null, options); @@ -695,11 +666,11 @@ private static void buildFactoryConversions() { // ZonedDateTime conversions supported DEFAULT_FACTORY.put(pair(Void.class, ZonedDateTime.class), VoidConversion::toNull); - DEFAULT_FACTORY.put(pair(Long.class, ZonedDateTime.class), NumberConversion::numberToZonedDateTime); - DEFAULT_FACTORY.put(pair(Double.class, ZonedDateTime.class), NumberConversion::numberToZonedDateTime); - DEFAULT_FACTORY.put(pair(BigInteger.class, ZonedDateTime.class), NumberConversion::numberToZonedDateTime); - DEFAULT_FACTORY.put(pair(BigDecimal.class, ZonedDateTime.class), NumberConversion::numberToZonedDateTime); - DEFAULT_FACTORY.put(pair(AtomicLong.class, ZonedDateTime.class), NumberConversion::numberToZonedDateTime); + DEFAULT_FACTORY.put(pair(Long.class, ZonedDateTime.class), NumberConversion::toZonedDateTime); + DEFAULT_FACTORY.put(pair(Double.class, ZonedDateTime.class), NumberConversion::toZonedDateTime); + DEFAULT_FACTORY.put(pair(BigInteger.class, ZonedDateTime.class), NumberConversion::toZonedDateTime); + DEFAULT_FACTORY.put(pair(BigDecimal.class, ZonedDateTime.class), NumberConversion::toZonedDateTime); + DEFAULT_FACTORY.put(pair(AtomicLong.class, ZonedDateTime.class), NumberConversion::toZonedDateTime); DEFAULT_FACTORY.put(pair(java.sql.Date.class, ZonedDateTime.class), (fromInstance, converter, options) -> ((java.sql.Date) fromInstance).toLocalDate().atStartOfDay(options.getSourceZoneId())); DEFAULT_FACTORY.put(pair(Timestamp.class, ZonedDateTime.class), (fromInstance, converter, options) -> ((Timestamp) fromInstance).toInstant().atZone(options.getSourceZoneId())); DEFAULT_FACTORY.put(pair(Date.class, ZonedDateTime.class), (fromInstance, converter, options) -> ((Date) fromInstance).toInstant().atZone(options.getSourceZoneId())); @@ -707,7 +678,7 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(LocalDateTime.class, ZonedDateTime.class), (fromInstance, converter, options) -> ((LocalDateTime) fromInstance).atZone(options.getSourceZoneId())); DEFAULT_FACTORY.put(pair(ZonedDateTime.class, ZonedDateTime.class), Converter::identity); DEFAULT_FACTORY.put(pair(Calendar.class, ZonedDateTime.class), (fromInstance, converter, options) -> ((Calendar) fromInstance).toInstant().atZone(options.getSourceZoneId())); - DEFAULT_FACTORY.put(pair(Number.class, ZonedDateTime.class), NumberConversion::numberToZonedDateTime); + DEFAULT_FACTORY.put(pair(Number.class, ZonedDateTime.class), NumberConversion::toZonedDateTime); DEFAULT_FACTORY.put(pair(Map.class, ZonedDateTime.class), (fromInstance, converter, options) -> { Map map = (Map) fromInstance; return converter.fromValueMap(map, ZonedDateTime.class, null, options); @@ -738,17 +709,7 @@ private static void buildFactoryConversions() { long leastSigBits = bigInt.and(new BigInteger("FFFFFFFFFFFFFFFF", 16)).longValue(); return new UUID(mostSigBits, leastSigBits); }); - DEFAULT_FACTORY.put(pair(Map.class, UUID.class), (fromInstance, converter, options) -> { - Map map = (Map) fromInstance; - Object ret = converter.fromMap(map, "mostSigBits", long.class, options); - if (ret != NOPE) { - Object ret2 = converter.fromMap(map, "leastSigBits", long.class, options); - if (ret2 != NOPE) { - return new UUID((Long) ret, (Long) ret2); - } - } - throw new IllegalArgumentException("To convert Map to UUID, the Map must contain both 'mostSigBits' and 'leastSigBits' keys"); - }); + DEFAULT_FACTORY.put(pair(Map.class, UUID.class), MapConversion::toUUID); // Class conversions supported DEFAULT_FACTORY.put(pair(Void.class, Class.class), VoidConversion::toNull); @@ -810,7 +771,7 @@ private static void buildFactoryConversions() { return simpleDateFormat.format(((Calendar) fromInstance).getTime()); }); DEFAULT_FACTORY.put(pair(Number.class, String.class), Converter::toString); - DEFAULT_FACTORY.put(pair(Map.class, String.class), (fromInstance, converter, options) -> converter.fromValueMap((Map) fromInstance, String.class, null, options)); + DEFAULT_FACTORY.put(pair(Map.class, String.class), MapConversion::toString); DEFAULT_FACTORY.put(pair(Enum.class, String.class), (fromInstance, converter, options) -> ((Enum) fromInstance).name()); DEFAULT_FACTORY.put(pair(String.class, String.class), Converter::identity); DEFAULT_FACTORY.put(pair(Duration.class, String.class), Converter::toString); @@ -1267,7 +1228,7 @@ public Convert addConversion(Class source, Class target, Convert con target = toPrimitiveWrapperClass(target); return factory.put(pair(source, target), conversionFunction); } - + public static long localDateToMillis(LocalDate localDate, ZoneId zoneId) { return localDate.atStartOfDay(zoneId).toInstant().toEpochMilli(); } @@ -1279,7 +1240,7 @@ public static long localDateTimeToMillis(LocalDateTime localDateTime, ZoneId zon public static long zonedDateTimeToMillis(ZonedDateTime zonedDateTime) { return zonedDateTime.toInstant().toEpochMilli(); } - + /** * Given a primitive class, return the Wrapper class equivalent. */ diff --git a/src/main/java/com/cedarsoftware/util/convert/ConverterOptions.java b/src/main/java/com/cedarsoftware/util/convert/ConverterOptions.java index 42b28a843..fabee345b 100644 --- a/src/main/java/com/cedarsoftware/util/convert/ConverterOptions.java +++ b/src/main/java/com/cedarsoftware/util/convert/ConverterOptions.java @@ -1,6 +1,7 @@ package com.cedarsoftware.util.convert; import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.time.ZoneId; import java.util.Locale; import java.util.TimeZone; @@ -27,32 +28,32 @@ public interface ConverterOptions { /** * @return zoneId to use for source conversion when on is not provided on the source (Date, Instant, etc.) */ - ZoneId getSourceZoneId(); + default ZoneId getSourceZoneId() { return ZoneId.systemDefault(); } /** * @return zoneId expected on the target when finished (only for types that support ZoneId or TimeZone) */ - ZoneId getTargetZoneId(); + default ZoneId getTargetZoneId() { return ZoneId.systemDefault(); } /** * @return Locale to use as source locale when converting between types that require a Locale */ - Locale getSourceLocale(); + default Locale getSourceLocale() { return Locale.getDefault(); } /** * @return Locale to use as target when converting between types that require a Locale. */ - Locale getTargetLocale(); + default Locale getTargetLocale() { return Locale.getDefault(); } /** * @return Charset to use as source CharSet on types that require a Charset during conversion (if required). */ - Charset getSourceCharset(); + default Charset getSourceCharset() { return StandardCharsets.UTF_8; } /** * @return Charset to use os target Charset on types that require a Charset during conversion (if required). */ - Charset getTargetCharset(); + default Charset getTargetCharset() { return StandardCharsets.UTF_8; } /** @@ -66,12 +67,12 @@ public interface ConverterOptions { T getCustomOption(String name); /** - * @return zoneId to use for source conversion when on is not provided on the source (Date, Instant, etc.) + * @return TimeZone to use for source conversion when on is not provided on the source (Date, Instant, etc.) */ default TimeZone getSourceTimeZone() { return TimeZone.getTimeZone(this.getSourceZoneId()); } /** - * @return zoneId expected on the target when finished (only for types that support ZoneId or TimeZone) + * @return TimeZone expected on the target when finished (only for types that support ZoneId or TimeZone) */ default TimeZone getTargetTimeZone() { return TimeZone.getTimeZone(this.getTargetZoneId()); } } diff --git a/src/main/java/com/cedarsoftware/util/convert/DateConversion.java b/src/main/java/com/cedarsoftware/util/convert/DateConversion.java new file mode 100644 index 000000000..24ea3300b --- /dev/null +++ b/src/main/java/com/cedarsoftware/util/convert/DateConversion.java @@ -0,0 +1,23 @@ +package com.cedarsoftware.util.convert; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicLong; + +public class DateConversion { + public static Date toSqlDate(Object fromInstance, Converter converter, ConverterOptions options) { + Date from = (Date)fromInstance; + return new java.sql.Date(from.getTime()); + } + + public static BigDecimal toBigDecimal(Object fromInstance, Converter converter, ConverterOptions options) { + Date from = (Date)fromInstance; + return BigDecimal.valueOf(from.getTime()); + } + + public static AtomicLong toAtomicLong(Object fromInstance, Converter converter, ConverterOptions options) { + Date from = (Date)fromInstance; + return new AtomicLong(from.getTime()); + } +} diff --git a/src/main/java/com/cedarsoftware/util/convert/DefaultConverterOptions.java b/src/main/java/com/cedarsoftware/util/convert/DefaultConverterOptions.java index 667b09c81..2e9d23ecd 100644 --- a/src/main/java/com/cedarsoftware/util/convert/DefaultConverterOptions.java +++ b/src/main/java/com/cedarsoftware/util/convert/DefaultConverterOptions.java @@ -27,45 +27,9 @@ public class DefaultConverterOptions implements ConverterOptions { private final Map customOptions; - private final ZoneId zoneId; - private final Locale locale; - private final Charset charset; public DefaultConverterOptions() { this.customOptions = new ConcurrentHashMap<>(); - this.zoneId = ZoneId.systemDefault(); - this.locale = Locale.getDefault(); - this.charset = StandardCharsets.UTF_8; - } - - @Override - public ZoneId getSourceZoneId() { - return zoneId; - } - - @Override - public ZoneId getTargetZoneId() { - return zoneId; - } - - @Override - public Locale getSourceLocale() { - return locale; - } - - @Override - public Locale getTargetLocale() { - return locale; - } - - @Override - public Charset getSourceCharset() { - return charset; - } - - @Override - public Charset getTargetCharset() { - return charset; } @SuppressWarnings("unchecked") diff --git a/src/main/java/com/cedarsoftware/util/convert/MapConversion.java b/src/main/java/com/cedarsoftware/util/convert/MapConversion.java new file mode 100644 index 000000000..dc2544993 --- /dev/null +++ b/src/main/java/com/cedarsoftware/util/convert/MapConversion.java @@ -0,0 +1,108 @@ +package com.cedarsoftware.util.convert; + +import com.cedarsoftware.util.CollectionUtilities; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Date; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; + +public class MapConversion { + + private static final String V = "_v"; + private static final String VALUE = "value"; + + public static Object toUUID(Object fromInstance, Converter converter, ConverterOptions options) { + Map map = (Map) fromInstance; + + if (map.containsKey("mostSigBits") && map.containsKey("leastSigBits")) { + long most = converter.convert(map.get("mostSigBits"), long.class, options); + long least = converter.convert(map.get("leastSigBits"), long.class, options); + + return new UUID(most, least); + } + + throw new IllegalArgumentException("To convert Map to UUID, the Map must contain both 'mostSigBits' and 'leastSigBits' keys"); + } + + public static Byte toByte(Object fromInstance, Converter converter, ConverterOptions options) { + return fromMapValue(fromInstance, converter, options, Byte.class); + } + + public static Short toShort(Object fromInstance, Converter converter, ConverterOptions options) { + return fromMapValue(fromInstance, converter, options, Short.class); + } + + public static Integer toInt(Object fromInstance, Converter converter, ConverterOptions options) { + return fromMapValue(fromInstance, converter, options, Integer.class); + } + + public static Long toLong(Object fromInstance, Converter converter, ConverterOptions options) { + return fromMapValue(fromInstance, converter, options, Long.class); + } + + public static Float toFloat(Object fromInstance, Converter converter, ConverterOptions options) { + return fromMapValue(fromInstance, converter, options, Float.class); + } + + public static Double toDouble(Object fromInstance, Converter converter, ConverterOptions options) { + return fromMapValue(fromInstance, converter, options, Double.class); + } + + public static Boolean toBoolean(Object fromInstance, Converter converter, ConverterOptions options) { + return fromMapValue(fromInstance, converter, options, Boolean.class); + } + + public static BigDecimal toBigDecimal(Object fromInstance, Converter converter, ConverterOptions options) { + return fromMapValue(fromInstance, converter, options, BigDecimal.class); + } + + public static BigInteger toBigInteger(Object fromInstance, Converter converter, ConverterOptions options) { + return fromMapValue(fromInstance, converter, options, BigInteger.class); + } + + public static String toString(Object fromInstance, Converter converter, ConverterOptions options) { + return fromMapValue(fromInstance, converter, options, String.class); + } + + + public static AtomicInteger toAtomicInteger(Object fromInstance, Converter converter, ConverterOptions options) { + return fromMapValue(fromInstance, converter, options, AtomicInteger.class); + } + + public static AtomicLong toAtomicLong(Object fromInstance, Converter converter, ConverterOptions options) { + return fromMapValue(fromInstance, converter, options, AtomicLong.class); + } + + public static AtomicBoolean toAtomicBoolean(Object fromInstance, Converter converter, ConverterOptions options) { + return fromMapValue(fromInstance, converter, options, AtomicBoolean.class); + } + + public static T fromMapValue(Object fromInstance, Converter converter, ConverterOptions options, Class type) { + Map map = (Map) fromInstance; + + if (map.containsKey(V)) { + return converter.convert(map.get(V), type); + } + + if (map.containsKey(VALUE)) { + return converter.convert(map.get(VALUE), type); + } + + throw new IllegalArgumentException("To convert from Map to " + getShortName(type) + ", the map must include keys: '_v' or 'value' an associated value to convert from."); + } + + + private static T getConvertedValue(Map map, String key, Class type, Converter converter, ConverterOptions options) { + // NOPE STUFF? + return converter.convert(map.get(key), type, options); + } + + private static String getShortName(Class type) { + return java.sql.Date.class.equals(type) ? type.getName() : type.getSimpleName(); + } +} diff --git a/src/main/java/com/cedarsoftware/util/convert/NumberConversion.java b/src/main/java/com/cedarsoftware/util/convert/NumberConversion.java index 23e356aea..d7674553f 100644 --- a/src/main/java/com/cedarsoftware/util/convert/NumberConversion.java +++ b/src/main/java/com/cedarsoftware/util/convert/NumberConversion.java @@ -1,6 +1,10 @@ package com.cedarsoftware.util.convert; import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; import java.sql.Timestamp; import java.time.Instant; import java.time.LocalDate; @@ -8,8 +12,6 @@ import java.time.ZonedDateTime; import java.util.Calendar; import java.util.Date; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; /** * @author Kenny Partlow (kpartlow@gmail.com) @@ -34,30 +36,82 @@ public static byte toByte(Object from, Converter converter, ConverterOptions opt return ((Number) from).byteValue(); } + public static Byte toByteZero(Object from, Converter converter, ConverterOptions options) { + return CommonValues.BYTE_ZERO; + } + + public static short toShort(Object from, Converter converter, ConverterOptions options) { return ((Number) from).shortValue(); } + public static Short toShortZero(Object from, Converter converter, ConverterOptions options) { + return CommonValues.SHORT_ZERO; + } + public static int toInt(Object from, Converter converter, ConverterOptions options) { return ((Number) from).intValue(); } + public static Integer toIntZero(Object from, Converter converter, ConverterOptions options) { + return CommonValues.INTEGER_ZERO; + } + + public static long toLong(Object from, Converter converter, ConverterOptions options) { return ((Number) from).longValue(); } + public static Long toLongZero(Object from, Converter converter, ConverterOptions options) { + return CommonValues.LONG_ZERO; + } + + public static float toFloat(Object from, Converter converter, ConverterOptions options) { return ((Number) from).floatValue(); } + public static Float toFloatZero(Object from, Converter converter, ConverterOptions options) { + return CommonValues.FLOAT_ZERO; + } + + public static double toDouble(Object from, Converter converter, ConverterOptions options) { return ((Number) from).doubleValue(); } - public static BigDecimal longToBigDecimal(Object from, Converter converter, ConverterOptions options) { + public static Double toDoubleZero(Object from, Converter converter, ConverterOptions options) { + return CommonValues.DOUBLE_ZERO; + } + + public static BigDecimal integerTypeToBigDecimal(Object from, Converter converter, ConverterOptions options) { return BigDecimal.valueOf(((Number) from).longValue()); } + public static AtomicLong toAtomicLong(Object from, Converter converter, ConverterOptions options) { + Number n = (Number)from; + return new AtomicLong(n.longValue()); + } + + public static AtomicInteger toAtomicInteger(Object from, Converter converter, ConverterOptions options) { + Number n = (Number)from; + return new AtomicInteger(n.intValue()); + } + + public static BigDecimal bigIntegerToBigDecimal(Object from, Converter converter, ConverterOptions options) { + return new BigDecimal((BigInteger)from); + } + + public static AtomicBoolean toAtomicBoolean(Object from, Converter converter, ConverterOptions options) { + Number number = (Number) from; + return new AtomicBoolean(number.longValue() != 0); + } + + public static BigDecimal floatingPointToBigDecimal(Object from, Converter converter, ConverterOptions options) { + Number n = (Number)from; + return BigDecimal.valueOf(n.doubleValue()); + } + public static boolean isIntTypeNotZero(Object from, Converter converter, ConverterOptions options) { return ((Number) from).longValue() != 0; } @@ -66,13 +120,23 @@ public static boolean isFloatTypeNotZero(Object from, Converter converter, Conve return ((Number) from).doubleValue() != 0; } + public static boolean isBigIntegerNotZero(Object from, Converter converter, ConverterOptions options) { + BigInteger bi = (BigInteger) from; + return bi.compareTo(BigInteger.ZERO) != 0; + } + + public static boolean isBigDecimalNotZero(Object from, Converter converter, ConverterOptions options) { + BigDecimal bd = (BigDecimal) from; + return bd.compareTo(BigDecimal.ZERO) != 0; + } + /** * @param number Number instance to convert to char. * @return char that best represents the Number. The result will always be a value between * 0 and Character.MAX_VALUE. * @throws IllegalArgumentException if the value exceeds the range of a char. */ - public static char numberToCharacter(Number number) { + public static char toCharacter(Number number) { long value = number.longValue(); if (value >= 0 && value <= Character.MAX_VALUE) { return (char) value; @@ -88,52 +152,42 @@ public static char numberToCharacter(Number number) { * 0 and Character.MAX_VALUE. * @throws IllegalArgumentException if the value exceeds the range of a char. */ - public static char numberToCharacter(Object from, Converter converter, ConverterOptions options) { - return numberToCharacter((Number) from); - } - - public static AtomicInteger numberToAtomicInteger(Object from, Converter converter, ConverterOptions options) { - Number number = (Number) from; - return new AtomicInteger(number.intValue()); - } - - public static AtomicLong numberToAtomicLong(Object from, Converter converter, ConverterOptions options) { - Number number = (Number) from; - return new AtomicLong(number.longValue()); + public static char toCharacter(Object from, Converter converter, ConverterOptions options) { + return toCharacter((Number) from); } - public static Date numberToDate(Object from, Converter converter, ConverterOptions options) { + public static Date toDate(Object from, Converter converter, ConverterOptions options) { Number number = (Number) from; return new Date(number.longValue()); } - public static java.sql.Date numberToSqlDate(Object from, Converter converter, ConverterOptions options) { + public static java.sql.Date toSqlDate(Object from, Converter converter, ConverterOptions options) { Number number = (Number) from; return new java.sql.Date(number.longValue()); } - public static Timestamp numberToTimestamp(Object from, Converter converter, ConverterOptions options) { + public static Timestamp toTimestamp(Object from, Converter converter, ConverterOptions options) { Number number = (Number) from; return new Timestamp(number.longValue()); } - public static Calendar numberToCalendar(Object from, Converter converter, ConverterOptions options) { + public static Calendar toCalendar(Object from, Converter converter, ConverterOptions options) { Number number = (Number) from; return Converter.initCal(number.longValue()); } - public static LocalDate numberToLocalDate(Object from, Converter converter, ConverterOptions options) { + public static LocalDate toLocalDate(Object from, Converter converter, ConverterOptions options) { Number number = (Number) from; return LocalDate.ofEpochDay(number.longValue()); } - public static LocalDateTime numberToLocalDateTime(Object from, Converter converter, ConverterOptions options) { + public static LocalDateTime toLocalDateTime(Object from, Converter converter, ConverterOptions options) { Number number = (Number) from; return Instant.ofEpochMilli(number.longValue()).atZone(options.getSourceZoneId()).toLocalDateTime(); } - public static ZonedDateTime numberToZonedDateTime(Object from, Converter converter, ConverterOptions options) { + public static ZonedDateTime toZonedDateTime(Object from, Converter converter, ConverterOptions options) { Number number = (Number) from; return Instant.ofEpochMilli(number.longValue()).atZone(options.getSourceZoneId()); } -} \ No newline at end of file +} diff --git a/src/main/java/com/cedarsoftware/util/convert/StringConversion.java b/src/main/java/com/cedarsoftware/util/convert/StringConversion.java index af0d334a2..bc17587ac 100644 --- a/src/main/java/com/cedarsoftware/util/convert/StringConversion.java +++ b/src/main/java/com/cedarsoftware/util/convert/StringConversion.java @@ -32,7 +32,7 @@ public class StringConversion { private static final BigDecimal bigDecimalMaxLong = BigDecimal.valueOf(Long.MAX_VALUE); private static final BigDecimal bigDecimalMinLong = BigDecimal.valueOf(Long.MIN_VALUE); - static Byte stringToByte(Object from, Converter converter, ConverterOptions options) { + static Byte toByte(Object from, Converter converter, ConverterOptions options) { String str = ((String) from).trim(); if (str.isEmpty()) { return CommonValues.BYTE_ZERO; @@ -40,7 +40,7 @@ static Byte stringToByte(Object from, Converter converter, ConverterOptions opti try { return Byte.valueOf(str); } catch (NumberFormatException e) { - Byte value = stringToByte(str); + Byte value = toByte(str); if (value == null) { throw new IllegalArgumentException("Value: " + from + " not parseable as a byte value or outside " + Byte.MIN_VALUE + " to " + Byte.MAX_VALUE); } @@ -48,15 +48,15 @@ static Byte stringToByte(Object from, Converter converter, ConverterOptions opti } } - private static Byte stringToByte(String s) { - Long value = stringToLong(s, bigDecimalMinByte, bigDecimalMaxByte); + private static Byte toByte(String s) { + Long value = toLong(s, bigDecimalMinByte, bigDecimalMaxByte); if (value == null) { return null; } return value.byteValue(); } - static Short stringToShort(Object from, Converter converter, ConverterOptions options) { + static Short toShort(Object from, Converter converter, ConverterOptions options) { String str = ((String) from).trim(); if (str.isEmpty()) { return CommonValues.SHORT_ZERO; @@ -64,7 +64,7 @@ static Short stringToShort(Object from, Converter converter, ConverterOptions op try { return Short.valueOf(str); } catch (NumberFormatException e) { - Short value = stringToShort(str); + Short value = toShort(str); if (value == null) { throw new IllegalArgumentException("Value: " + from + " not parseable as a short value or outside " + Short.MIN_VALUE + " to " + Short.MAX_VALUE); } @@ -72,15 +72,15 @@ static Short stringToShort(Object from, Converter converter, ConverterOptions op } } - private static Short stringToShort(String s) { - Long value = stringToLong(s, bigDecimalMinShort, bigDecimalMaxShort); + private static Short toShort(String s) { + Long value = toLong(s, bigDecimalMinShort, bigDecimalMaxShort); if (value == null) { return null; } return value.shortValue(); } - static Integer stringToInteger(Object from, Converter converter, ConverterOptions options) { + static Integer toInt(Object from, Converter converter, ConverterOptions options) { String str = ((String) from).trim(); if (str.isEmpty()) { return CommonValues.INTEGER_ZERO; @@ -88,7 +88,7 @@ static Integer stringToInteger(Object from, Converter converter, ConverterOption try { return Integer.valueOf(str); } catch (NumberFormatException e) { - Integer value = stringToInteger(str); + Integer value = toInt(str); if (value == null) { throw new IllegalArgumentException("Value: " + from + " not parseable as an int value or outside " + Integer.MIN_VALUE + " to " + Integer.MAX_VALUE); } @@ -96,15 +96,15 @@ static Integer stringToInteger(Object from, Converter converter, ConverterOption } } - private static Integer stringToInteger(String s) { - Long value = stringToLong(s, bigDecimalMinInteger, bigDecimalMaxInteger); + private static Integer toInt(String s) { + Long value = toLong(s, bigDecimalMinInteger, bigDecimalMaxInteger); if (value == null) { return null; } return value.intValue(); } - static Long stringToLong(Object from, Converter converter, ConverterOptions options) { + static Long toLong(Object from, Converter converter, ConverterOptions options) { String str = ((String) from).trim(); if (str.isEmpty()) { return CommonValues.LONG_ZERO; @@ -112,7 +112,7 @@ static Long stringToLong(Object from, Converter converter, ConverterOptions opti try { return Long.valueOf(str); } catch (NumberFormatException e) { - Long value = stringToLong(str, bigDecimalMinLong, bigDecimalMaxLong); + Long value = toLong(str, bigDecimalMinLong, bigDecimalMaxLong); if (value == null) { throw new IllegalArgumentException("Value: " + from + " not parseable as a long value or outside " + Long.MIN_VALUE + " to " + Long.MAX_VALUE); } @@ -120,7 +120,7 @@ static Long stringToLong(Object from, Converter converter, ConverterOptions opti } } - private static Long stringToLong(String s, BigDecimal low, BigDecimal high) { + private static Long toLong(String s, BigDecimal low, BigDecimal high) { try { BigDecimal big = new BigDecimal(s); big = big.setScale(0, RoundingMode.DOWN); @@ -133,7 +133,7 @@ private static Long stringToLong(String s, BigDecimal low, BigDecimal high) { } } - static Float stringToFloat(Object from, Converter converter, ConverterOptions options) { + static Float toFloat(Object from, Converter converter, ConverterOptions options) { String str = ((String) from).trim(); if (str.isEmpty()) { return CommonValues.FLOAT_ZERO; @@ -145,7 +145,7 @@ static Float stringToFloat(Object from, Converter converter, ConverterOptions op } } - static Double stringToDouble(Object from, Converter converter, ConverterOptions options) { + static Double toDouble(Object from, Converter converter, ConverterOptions options) { String str = ((String) from).trim(); if (str.isEmpty()) { return CommonValues.DOUBLE_ZERO; @@ -157,28 +157,66 @@ static Double stringToDouble(Object from, Converter converter, ConverterOptions } } - static AtomicInteger stringToAtomicInteger(Object from, Converter converter, ConverterOptions options) { + static AtomicInteger toAtomicInteger(Object from, Converter converter, ConverterOptions options) { String str = ((String) from).trim(); if (str.isEmpty()) { return new AtomicInteger(0); } - Integer integer = stringToInteger(str); + Integer integer = toInt(str); if (integer == null) { throw new IllegalArgumentException("Value: " + from + " not parseable as an AtomicInteger value or outside " + Integer.MIN_VALUE + " to " + Integer.MAX_VALUE); } return new AtomicInteger(integer); } - static AtomicLong stringToAtomicLong(Object from, Converter converter, ConverterOptions options) { + static AtomicLong toAtomicLong(Object from, Converter converter, ConverterOptions options) { String str = ((String) from).trim(); if (str.isEmpty()) { return new AtomicLong(0L); } - Long value = stringToLong(str, bigDecimalMinLong, bigDecimalMaxLong); + Long value = toLong(str, bigDecimalMinLong, bigDecimalMaxLong); if (value == null) { throw new IllegalArgumentException("Value: " + from + " not parseable as an AtomicLong value or outside " + Long.MIN_VALUE + " to " + Long.MAX_VALUE); } return new AtomicLong(value); } + + public static Boolean toBoolean(Object from, Converter converter, ConverterOptions options) { + String str = ((String) from).trim(); + if (str.isEmpty()) { + return false; + } + // faster equals check "true" and "false" + if ("true".equals(str)) { + return true; + } else if ("false".equals(str)) { + return false; + } + return "true".equalsIgnoreCase(str); + } + + public static char toCharacter(Object from, Converter converter, ConverterOptions options) { + String str = ((String) from); + if (str.isEmpty()) { + return (char) 0; + } + if (str.length() == 1) { + return str.charAt(0); + } + // Treat as a String number, like "65" = 'A' + return (char) Integer.parseInt(str.trim()); + } + + public static BigDecimal toBigDecimal(Object from, Converter converter, ConverterOptions options) { + String str = ((String) from).trim(); + if (str.isEmpty()) { + return BigDecimal.ZERO; + } + try { + return new BigDecimal(str); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Value: " + from + " not parseable as a BigDecimal value."); + } + } } diff --git a/src/main/java/com/cedarsoftware/util/convert/VoidConversion.java b/src/main/java/com/cedarsoftware/util/convert/VoidConversion.java index 247014d78..646b9b7c0 100644 --- a/src/main/java/com/cedarsoftware/util/convert/VoidConversion.java +++ b/src/main/java/com/cedarsoftware/util/convert/VoidConversion.java @@ -18,7 +18,16 @@ * limitations under the License. */ public class VoidConversion { + public static Object toNull(Object from, Converter converter, ConverterOptions options) { return null; } + + public static Boolean toBoolean(Object from, Converter converter, ConverterOptions options) { + return Boolean.FALSE; + } + + public static Character toChar(Object from, Converter converter, ConverterOptions options) { + return Character.MIN_VALUE; + } } diff --git a/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java b/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java index 541dad80d..1671736c6 100644 --- a/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java +++ b/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java @@ -318,11 +318,12 @@ void testConvertToShort_whenEmptyString(String s) assertThat(converted).isZero(); } - private static Stream testIntParams() { return Stream.of( Arguments.of("-32768", -32768), + Arguments.of("-45000", -45000), Arguments.of("32767", 32767), + Arguments.of(new BigInteger("8675309"), 8675309), Arguments.of(Byte.MIN_VALUE,-128), Arguments.of(Byte.MAX_VALUE, 127), Arguments.of(Short.MIN_VALUE, -32768), @@ -331,14 +332,17 @@ private static Stream testIntParams() { Arguments.of(Integer.MAX_VALUE, Integer.MAX_VALUE), Arguments.of(-128L, -128), Arguments.of(127L, 127), + Arguments.of(3.14, 3), Arguments.of(-128.0f, -128), Arguments.of(127.0f, 127), Arguments.of(-128.0d, -128), Arguments.of(127.0d, 127), Arguments.of( new BigDecimal("100"),100), Arguments.of( new BigInteger("120"), 120), - Arguments.of( new AtomicInteger(25), 25), - Arguments.of( new AtomicLong(100L), 100) + Arguments.of( new AtomicInteger(75), 75), + Arguments.of( new AtomicInteger(1), 1), + Arguments.of( new AtomicInteger(0), 0), + Arguments.of( new AtomicLong(Integer.MAX_VALUE), Integer.MAX_VALUE) ); } @@ -741,141 +745,234 @@ void testString_fromLocalDate() assertThat(converted).isEqualTo("2015-09-03"); } - @Test - void testBigDecimal() + + private static Stream testBigDecimalParams() { + return Stream.of( + Arguments.of("-45000", BigDecimal.valueOf(-45000L)), + Arguments.of("-32768", BigDecimal.valueOf(-32768L)), + Arguments.of("32767", BigDecimal.valueOf(32767L)), + Arguments.of(Byte.MIN_VALUE, BigDecimal.valueOf((-128L)), + Arguments.of(Byte.MAX_VALUE, BigDecimal.valueOf(127L)), + Arguments.of(Short.MIN_VALUE, BigDecimal.valueOf(-32768L)), + Arguments.of(Short.MAX_VALUE, BigDecimal.valueOf(32767L)), + Arguments.of(Integer.MIN_VALUE, BigDecimal.valueOf(-2147483648L)), + Arguments.of(Integer.MAX_VALUE, BigDecimal.valueOf(2147483647L)), + Arguments.of(Long.MIN_VALUE, BigDecimal.valueOf(-9223372036854775808L)), + Arguments.of(Long.MAX_VALUE, BigDecimal.valueOf(9223372036854775807L)), + Arguments.of(3.14, BigDecimal.valueOf(3.14)), + Arguments.of(-128.0f, BigDecimal.valueOf(-128.0f)), + Arguments.of(127.0f, BigDecimal.valueOf(127.0f)), + Arguments.of(-128.0d, BigDecimal.valueOf(-128.0d))), + Arguments.of(127.0d, BigDecimal.valueOf(127.0d)), + Arguments.of( new BigDecimal("100"), new BigDecimal("100")), + Arguments.of( new BigInteger("8675309"), new BigDecimal("8675309")), + Arguments.of( new BigInteger("120"), new BigDecimal("120")), + Arguments.of( new AtomicInteger(25), new BigDecimal(25)), + Arguments.of( new AtomicLong(100L), new BigDecimal(100)) + ); + } + + @ParameterizedTest + @MethodSource("testBigDecimalParams") + void testBigDecimal(Object value, BigDecimal expectedResult) { - Object o = converter.convert("", BigDecimal.class); - assertEquals(o, BigDecimal.ZERO); - BigDecimal x = this.converter.convert("-450000", BigDecimal.class); - assertEquals(new BigDecimal("-450000"), x); + BigDecimal converted = this.converter.convert(value, BigDecimal.class); + assertThat(converted).isEqualTo(expectedResult); + } - assertEquals(new BigDecimal("3.14"), this.converter.convert(new BigDecimal("3.14"), BigDecimal.class)); - assertEquals(new BigDecimal("8675309"), this.converter.convert(new BigInteger("8675309"), BigDecimal.class)); - assertEquals(new BigDecimal("75"), this.converter.convert((short) 75, BigDecimal.class)); - assertEquals(BigDecimal.ONE, this.converter.convert(true, BigDecimal.class)); - assertSame(BigDecimal.ONE, this.converter.convert(true, BigDecimal.class)); - assertEquals(BigDecimal.ZERO, this.converter.convert(false, BigDecimal.class)); - assertSame(BigDecimal.ZERO, this.converter.convert(false, BigDecimal.class)); + private static Stream testBigDecimalParams_withObjectsShouldBeSame() { + return Stream.of( + Arguments.of(new AtomicBoolean(true), BigDecimal.ONE), + Arguments.of(new AtomicBoolean(false), BigDecimal.ZERO), + Arguments.of(true, BigDecimal.ONE), + Arguments.of(false, BigDecimal.ZERO), + Arguments.of(Boolean.TRUE, BigDecimal.ONE), + Arguments.of(Boolean.FALSE, BigDecimal.ZERO), + Arguments.of("", BigDecimal.ZERO) + ); + } + @ParameterizedTest + @MethodSource("testBigDecimalParams_withObjectsShouldBeSame") + void testBigDecimal_withObjectsThatShouldBeSameAs(Object value, BigDecimal expected) { + BigDecimal converted = this.converter.convert(value, BigDecimal.class); + assertThat(converted).isSameAs(expected); + } + + @Test + void testBigDecimal_withDate() { Date now = new Date(); - BigDecimal now70 = new BigDecimal(now.getTime()); - assertEquals(now70, this.converter.convert(now, BigDecimal.class)); + BigDecimal bd = new BigDecimal(now.getTime()); + assertEquals(bd, this.converter.convert(now, BigDecimal.class)); + } + @Test + void testBigDecimal_witCalendar() { Calendar today = Calendar.getInstance(); - now70 = new BigDecimal(today.getTime().getTime()); - assertEquals(now70, this.converter.convert(today, BigDecimal.class)); + BigDecimal bd = new BigDecimal(today.getTime().getTime()); + assertEquals(bd, this.converter.convert(today, BigDecimal.class)); + } - assertEquals(new BigDecimal(25), this.converter.convert(new AtomicInteger(25), BigDecimal.class)); - assertEquals(new BigDecimal(100), this.converter.convert(new AtomicLong(100L), BigDecimal.class)); - assertEquals(BigDecimal.ONE, this.converter.convert(new AtomicBoolean(true), BigDecimal.class)); - assertEquals(BigDecimal.ZERO, this.converter.convert(new AtomicBoolean(false), BigDecimal.class)); - assertEquals(converter.convert(BigDecimal.ZERO, Boolean.class), false); - assertEquals(converter.convert(BigDecimal.ONE, Boolean.class), true); - assertEquals(converter.convert(new BigDecimal("3.14159"), Boolean.class), true); + private static Stream testConvertToBigDecimalParams_withIllegalArguments() { + return Stream.of( + Arguments.of("45badNumber", "not parseable"), + Arguments.of(ZoneId.systemDefault(), "Unsupported conversion"), + Arguments.of( TimeZone.getDefault(), "Unsupported conversion")); + } - try - { - this.converter.convert(TimeZone.getDefault(), BigDecimal.class); - fail(); - } - catch (IllegalArgumentException e) - { - assertTrue(e.getMessage().toLowerCase().contains("unsupported conversion, source type [zoneinfo")); - } + @ParameterizedTest + @MethodSource("testConvertToBigDecimalParams_withIllegalArguments") + void testConvertToBigDecimal_withIllegalArguments(Object value, String partialMessage) { + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> this.converter.convert(value, BigDecimal.class)) + .withMessageContaining(partialMessage); + } - try - { - this.converter.convert("45badNumber", BigDecimal.class); - fail(); - } - catch (IllegalArgumentException e) - { - assertTrue(e.getMessage().toLowerCase().contains("value: 45badnumber not parseable as a bigdecimal value")); - } + /** + * + * assertEquals(new BigInteger("3"), this.converter.convert(new BigDecimal("3.14"), BigInteger.class)); + * assertEquals(new BigInteger("8675309"), this.converter.convert(new BigInteger("8675309"), BigInteger.class)); + * assertEquals(new BigInteger("75"), this.converter.convert((short) 75, BigInteger.class)); + * assertEquals(BigInteger.ONE, this.converter.convert(true, BigInteger.class)); + * assertSame(BigInteger.ONE, this.converter.convert(true, BigInteger.class)); + * assertEquals(BigInteger.ZERO, this.converter.convert(false, BigInteger.class)); + * assertSame(BigInteger.ZERO, this.converter.convert(false, BigInteger.class)); + * assertEquals(converter.convert(new BigInteger("314159"), Boolean.class), true); + * assertEquals(new BigInteger("11"), converter.convert("11.5", BigInteger.class)); + */ + private static Stream testBigIntegerParams() { + return Stream.of( + Arguments.of("-32768", BigInteger.valueOf(-32768L)), + Arguments.of("32767", BigInteger.valueOf(32767L)), + Arguments.of(Byte.MIN_VALUE, BigInteger.valueOf((-128L)), + Arguments.of(Byte.MAX_VALUE, BigInteger.valueOf(127L)), + Arguments.of(Short.MIN_VALUE, BigInteger.valueOf(-32768L)), + Arguments.of(Short.MAX_VALUE, BigInteger.valueOf(32767L)), + Arguments.of(Integer.MIN_VALUE, BigInteger.valueOf(-2147483648L)), + Arguments.of(Integer.MAX_VALUE, BigInteger.valueOf(2147483647L)), + Arguments.of(Long.MIN_VALUE, BigInteger.valueOf(-9223372036854775808L)), + Arguments.of(Long.MAX_VALUE, BigInteger.valueOf(9223372036854775807L)), + Arguments.of(-128.0f, BigInteger.valueOf(-128)), + Arguments.of(127.0f, BigInteger.valueOf(127)), + Arguments.of(-128.0d, BigInteger.valueOf(-128))), + Arguments.of(127.0d, BigInteger.valueOf(127)), + Arguments.of( new BigDecimal("100"), new BigInteger("100")), + Arguments.of( new BigInteger("120"), new BigInteger("120")), + Arguments.of( new AtomicInteger(25), BigInteger.valueOf(25)), + Arguments.of( new AtomicLong(100L), BigInteger.valueOf(100)) + ); } - @Test - void testBigInteger() + @ParameterizedTest + @MethodSource("testBigIntegerParams") + void testBigInteger(Object value, BigInteger expectedResult) { - BigInteger x = this.converter.convert("-450000", BigInteger.class); - assertEquals(new BigInteger("-450000"), x); + BigInteger converted = this.converter.convert(value, BigInteger.class); + assertThat(converted).isEqualTo(expectedResult); + } + - assertEquals(new BigInteger("3"), this.converter.convert(new BigDecimal("3.14"), BigInteger.class)); - assertEquals(new BigInteger("8675309"), this.converter.convert(new BigInteger("8675309"), BigInteger.class)); - assertEquals(new BigInteger("75"), this.converter.convert((short) 75, BigInteger.class)); - assertEquals(BigInteger.ONE, this.converter.convert(true, BigInteger.class)); - assertSame(BigInteger.ONE, this.converter.convert(true, BigInteger.class)); - assertEquals(BigInteger.ZERO, this.converter.convert(false, BigInteger.class)); - assertSame(BigInteger.ZERO, this.converter.convert(false, BigInteger.class)); - assertEquals(converter.convert(new BigInteger("314159"), Boolean.class), true); - assertEquals(new BigInteger("11"), converter.convert("11.5", BigInteger.class)); + private static Stream testBigIntegerParams_withObjectsShouldBeSameAs() { + return Stream.of( + Arguments.of(CommonValues.INTEGER_ZERO, BigInteger.ZERO), + Arguments.of(CommonValues.INTEGER_ONE, BigInteger.ONE), + Arguments.of(CommonValues.LONG_ZERO, BigInteger.ZERO), + Arguments.of(CommonValues.LONG_ONE, BigInteger.ONE), + Arguments.of(new AtomicBoolean(true), BigInteger.ONE), + Arguments.of(new AtomicBoolean(false), BigInteger.ZERO), + Arguments.of(true, BigInteger.ONE), + Arguments.of(false, BigInteger.ZERO), + Arguments.of(Boolean.TRUE, BigInteger.ONE), + Arguments.of(Boolean.FALSE, BigInteger.ZERO), + Arguments.of("", BigInteger.ZERO), + Arguments.of(BigInteger.ZERO, BigInteger.ZERO), + Arguments.of(BigInteger.ONE, BigInteger.ONE), + Arguments.of(BigInteger.TEN, BigInteger.TEN) + ); + } + @ParameterizedTest + @MethodSource("testBigIntegerParams_withObjectsShouldBeSameAs") + void testBigInteger_withObjectsShouldBeSameAs(Object value, BigInteger expected) { + BigInteger converted = this.converter.convert(value, BigInteger.class); + assertThat(converted).isSameAs(expected); + } + @Test + void testBigInteger_withDate() { Date now = new Date(); - BigInteger now70 = new BigInteger(Long.toString(now.getTime())); - assertEquals(now70, this.converter.convert(now, BigInteger.class)); + BigInteger bd = BigInteger.valueOf(now.getTime()); + assertEquals(bd, this.converter.convert(now, BigInteger.class)); + } + @Test + void testBigInteger_withCalendar() { Calendar today = Calendar.getInstance(); - now70 = new BigInteger(Long.toString(today.getTime().getTime())); - assertEquals(now70, this.converter.convert(today, BigInteger.class)); - - assertEquals(new BigInteger("25"), this.converter.convert(new AtomicInteger(25), BigInteger.class)); - assertEquals(new BigInteger("100"), this.converter.convert(new AtomicLong(100L), BigInteger.class)); - assertEquals(BigInteger.ONE, this.converter.convert(new AtomicBoolean(true), BigInteger.class)); - assertEquals(BigInteger.ZERO, this.converter.convert(new AtomicBoolean(false), BigInteger.class)); + BigInteger bd = BigInteger.valueOf(today.getTime().getTime()); + assertEquals(bd, this.converter.convert(today, BigInteger.class)); + } - try { - this.converter.convert(TimeZone.getDefault(), BigInteger.class); - fail(); - } catch (IllegalArgumentException e) { - assertTrue(e.getMessage().toLowerCase().contains("unsupported conversion, source type [zoneinfo")); - } + private static Stream testConvertToBigIntegerParams_withIllegalArguments() { + return Stream.of( + Arguments.of("45badNumber", "not parseable"), + Arguments.of(ZoneId.systemDefault(), "Unsupported conversion"), + Arguments.of( TimeZone.getDefault(), "Unsupported conversion")); + } - try { - this.converter.convert("45badNumber", BigInteger.class); - fail(); - } catch (IllegalArgumentException e) { - assertTrue(e.getMessage().toLowerCase().contains("value: 45badnumber not parseable as a biginteger value")); - } + @ParameterizedTest + @MethodSource("testConvertToBigIntegerParams_withIllegalArguments") + void testConvertToBigInteger_withIllegalArguments(Object value, String partialMessage) { + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> this.converter.convert(value, BigInteger.class)) + .withMessageContaining(partialMessage); } - @Test - void testAtomicInteger() + + @ParameterizedTest + @MethodSource("testIntParams") + void testAtomicInteger(Object value, int expectedResult) { - AtomicInteger x = this.converter.convert("-450000", AtomicInteger.class); - assertEquals(-450000, x.get()); + AtomicInteger converted = this.converter.convert(value, AtomicInteger.class); + assertThat(converted.get()).isEqualTo(new AtomicInteger(expectedResult).get()); + } - assertEquals(3, (this.converter.convert(new BigDecimal("3.14"), AtomicInteger.class)).get()); - assertEquals(8675309, (this.converter.convert(new BigInteger("8675309"), AtomicInteger.class)).get()); - assertEquals(75, (this.converter.convert((short) 75, AtomicInteger.class)).get()); - assertEquals(1, (this.converter.convert(true, AtomicInteger.class)).get()); - assertEquals(0, (this.converter.convert(false, AtomicInteger.class)).get()); - assertEquals(new AtomicInteger(11).get(), converter.convert("11.5", AtomicInteger.class).get()); + @Test + void testAtomicInteger_withEmptyString() { + AtomicInteger converted = this.converter.convert("", AtomicInteger.class); + //TODO: Do we want nullable types to default to zero + assertThat(converted.get()).isEqualTo(0); + } - assertEquals(25, (this.converter.convert(new AtomicInteger(25), AtomicInteger.class)).get()); - assertEquals(100, (this.converter.convert(new AtomicLong(100L), AtomicInteger.class)).get()); - assertEquals(1, (this.converter.convert(new AtomicBoolean(true), AtomicInteger.class)).get()); - assertEquals(0, (this.converter.convert(new AtomicBoolean(false), AtomicInteger.class)).get()); + private static Stream testAtomicIntegerParams_withBooleanTypes() { + return Stream.of( + Arguments.of(new AtomicBoolean(true), new AtomicInteger(1)), + Arguments.of(new AtomicBoolean(false), new AtomicInteger(0)), + Arguments.of(true, new AtomicInteger(1)), + Arguments.of(false, new AtomicInteger(0)), + Arguments.of(Boolean.TRUE, new AtomicInteger(1)), + Arguments.of(Boolean.FALSE, new AtomicInteger(0)) + ); + } + @ParameterizedTest + @MethodSource("testAtomicIntegerParams_withBooleanTypes") + void testAtomicInteger_withBooleanTypes(Object value, AtomicInteger expected) { + AtomicInteger converted = this.converter.convert(value, AtomicInteger.class); + assertThat(converted.get()).isEqualTo(expected.get()); + } - try - { - this.converter.convert(TimeZone.getDefault(), AtomicInteger.class); - fail(); - } - catch (IllegalArgumentException e) - { - assertTrue(e.getMessage().toLowerCase().contains("unsupported conversion, source type [zoneinfo")); - } + private static Stream testAtomicinteger_withIllegalArguments_params() { + return Stream.of( + Arguments.of("45badNumber", "not parseable"), + Arguments.of(ZoneId.systemDefault(), "Unsupported conversion"), + Arguments.of( TimeZone.getDefault(), "Unsupported conversion")); + } - try - { - this.converter.convert("45badNumber", AtomicInteger.class); - fail(); - } - catch (IllegalArgumentException e) - { - assertTrue(e.getMessage().toLowerCase().contains("45badnumber")); - } + @ParameterizedTest + @MethodSource("testAtomicinteger_withIllegalArguments_params") + void testAtomicinteger_withIllegalArguments(Object value, String partialMessage) { + assertThatExceptionOfType(IllegalArgumentException.class) + .isThrownBy(() -> this.converter.convert(value, BigInteger.class)) + .withMessageContaining(partialMessage); } @Test @@ -2167,7 +2264,7 @@ void testConvert2() void testNullType() { assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(() -> this.converter.convert("123", null)) - // No Message was coming through here and receiving NullPointerException -- changed to convention over in convert -- hopefully that's what you had in mind. + // TOTO: in case you didn't see, No Message was coming through here and receiving NullPointerException -- changed to convention over in convert -- hopefully that's what you had in mind. .withMessageContaining("toType cannot be null"); } @@ -2210,10 +2307,10 @@ void testCharacterSupport() assert 65 == this.converter.convert('A', BigInteger.class).longValue(); assert 65 == this.converter.convert('A', BigDecimal.class).longValue(); - assert '1' == this.converter.convert(true, char.class); - assert '0' == this.converter.convert(false, char.class); - assert '1' == this.converter.convert(new AtomicBoolean(true), char.class); - assert '0' == this.converter.convert(new AtomicBoolean(false), char.class); + assert 1 == this.converter.convert(true, char.class); + assert 0 == this.converter.convert(false, char.class); + assert 1 == this.converter.convert(new AtomicBoolean(true), char.class); + assert 0 == this.converter.convert(new AtomicBoolean(false), char.class); assert 'z' == this.converter.convert('z', char.class); assert 0 == this.converter.convert("", char.class); assert 0 == this.converter.convert("", Character.class); @@ -3101,4 +3198,28 @@ void testNormieToWeirdoAndBack() assert this.converter.isConversionSupportedFor(Normie.class, Weirdo.class); assert this.converter.isConversionSupportedFor(Weirdo.class, Normie.class); } + + private static Stream emptyStringToType_params() { + return Stream.of( + Arguments.of("", byte.class, (byte)0), + Arguments.of("", Byte.class, (byte)0), + Arguments.of("", short.class, (short)0), + Arguments.of("", Short.class, (short)0), + Arguments.of("", int.class, 0), + Arguments.of("", Integer.class, 0), + Arguments.of("", long.class, 0L), + Arguments.of("", Long.class, 0L), + Arguments.of("", float.class, 0.0f), + Arguments.of("", Float.class, 0.0f), + Arguments.of("", double.class, 0.0d), + Arguments.of("", Double.class, 0.0d)); + } + + @ParameterizedTest + @MethodSource("emptyStringToType_params") + void emptyStringToType(Object value, Class type, Object expected) + { + Object converted = this.converter.convert(value, type); + assertThat(converted).isEqualTo(expected); + } }