diff --git a/src/main/java/com/cedarsoftware/util/convert/AtomicBooleanConversions.java b/src/main/java/com/cedarsoftware/util/convert/AtomicBooleanConversions.java
index 1794ae67e..6de33ba29 100644
--- a/src/main/java/com/cedarsoftware/util/convert/AtomicBooleanConversions.java
+++ b/src/main/java/com/cedarsoftware/util/convert/AtomicBooleanConversions.java
@@ -72,7 +72,6 @@ static AtomicInteger toAtomicInteger(Object from, Converter converter) {
return b.get() ? new AtomicInteger(1) : new AtomicInteger (0);
}
-
static AtomicLong toAtomicLong(Object from, Converter converter) {
AtomicBoolean b = (AtomicBoolean) from;
return b.get() ? new AtomicLong(1) : new AtomicLong(0);
diff --git a/src/main/java/com/cedarsoftware/util/convert/AtomicIntegerConversions.java b/src/main/java/com/cedarsoftware/util/convert/AtomicIntegerConversions.java
new file mode 100644
index 000000000..d7ce28b21
--- /dev/null
+++ b/src/main/java/com/cedarsoftware/util/convert/AtomicIntegerConversions.java
@@ -0,0 +1,36 @@
+package com.cedarsoftware.util.convert;
+
+import java.time.LocalTime;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * @author John DeRegnaucourt (jdereg@gmail.com)
+ *
+ * Copyright (c) Cedar Software LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * License
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+final class AtomicIntegerConversions {
+
+ private AtomicIntegerConversions() {}
+
+ static AtomicInteger toAtomicInteger(Object from, Converter converter) {
+ AtomicInteger atomicInt = (AtomicInteger) from;
+ return new AtomicInteger(atomicInt.intValue());
+ }
+
+ static LocalTime toLocalTime(Object from, Converter converter) {
+ AtomicInteger atomicInteger= (AtomicInteger) from;
+ return LongConversions.toLocalTime((long)atomicInteger.get(), converter);
+ }
+}
diff --git a/src/main/java/com/cedarsoftware/util/convert/AtomicLongConversions.java b/src/main/java/com/cedarsoftware/util/convert/AtomicLongConversions.java
new file mode 100644
index 000000000..76b6c6d4f
--- /dev/null
+++ b/src/main/java/com/cedarsoftware/util/convert/AtomicLongConversions.java
@@ -0,0 +1,36 @@
+package com.cedarsoftware.util.convert;
+
+import java.time.LocalTime;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * @author John DeRegnaucourt (jdereg@gmail.com)
+ *
+ * Copyright (c) Cedar Software LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * License
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+final class AtomicLongConversions {
+
+ private AtomicLongConversions() {}
+
+ static AtomicLong toAtomicLong(Object from, Converter converter) {
+ AtomicLong atomicLong = (AtomicLong) from;
+ return new AtomicLong(atomicLong.get());
+ }
+
+ static LocalTime toLocalTime(Object from, Converter converter) {
+ AtomicLong atomicLong = (AtomicLong) from;
+ return LongConversions.toLocalTime(atomicLong.get(), converter);
+ }
+}
diff --git a/src/main/java/com/cedarsoftware/util/convert/BigDecimalConversions.java b/src/main/java/com/cedarsoftware/util/convert/BigDecimalConversions.java
index ace157dc8..c54375c02 100644
--- a/src/main/java/com/cedarsoftware/util/convert/BigDecimalConversions.java
+++ b/src/main/java/com/cedarsoftware/util/convert/BigDecimalConversions.java
@@ -7,6 +7,7 @@
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
+import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.ZonedDateTime;
import java.util.Date;
@@ -46,6 +47,17 @@ static Duration toDuration(Object from, Converter converter) {
return Duration.ofSeconds(seconds.longValue(), nanos.movePointRight(9).longValue());
}
+ static LocalTime toLocalTime(Object from, Converter converter) {
+ BigDecimal seconds = (BigDecimal) from;
+ BigDecimal nanos = seconds.multiply(BigDecimal.valueOf(1_000_000_000));
+ try {
+ return LocalTime.ofNanoOfDay(nanos.longValue());
+ }
+ catch (Exception e) {
+ throw new IllegalArgumentException("Input value [" + seconds.toPlainString() + "] for conversion to LocalTime must be >= 0 && <= 86399.999999999", e);
+ }
+ }
+
static LocalDate toLocalDate(Object from, Converter converter) {
return toZonedDateTime(from, converter).toLocalDate();
}
diff --git a/src/main/java/com/cedarsoftware/util/convert/BigIntegerConversions.java b/src/main/java/com/cedarsoftware/util/convert/BigIntegerConversions.java
index 7a05fd47c..fec623fb2 100644
--- a/src/main/java/com/cedarsoftware/util/convert/BigIntegerConversions.java
+++ b/src/main/java/com/cedarsoftware/util/convert/BigIntegerConversions.java
@@ -7,6 +7,7 @@
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
+import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.ZonedDateTime;
import java.util.Date;
@@ -81,6 +82,15 @@ static ZonedDateTime toZonedDateTime(Object from, Converter converter) {
return toInstant(from, converter).atZone(converter.getOptions().getZoneId());
}
+ static LocalTime toLocalTime(Object from, Converter converter) {
+ BigInteger bigI = (BigInteger) from;
+ try {
+ return LocalTime.ofNanoOfDay(bigI.longValue());
+ } catch (Exception e) {
+ throw new IllegalArgumentException("Input value [" + bigI + "] for conversion to LocalTime must be >= 0 && <= 86399999999999", e);
+ }
+ }
+
static LocalDate toLocalDate(Object from, Converter converter) {
return toZonedDateTime(from, converter).toLocalDate();
}
diff --git a/src/main/java/com/cedarsoftware/util/convert/Converter.java b/src/main/java/com/cedarsoftware/util/convert/Converter.java
index bb23773b0..7e5911c20 100644
--- a/src/main/java/com/cedarsoftware/util/convert/Converter.java
+++ b/src/main/java/com/cedarsoftware/util/convert/Converter.java
@@ -160,6 +160,7 @@ private static void buildFactoryConversions() {
CONVERSION_DB.put(pair(Number.class, Integer.class), NumberConversions::toInt);
CONVERSION_DB.put(pair(Map.class, Integer.class), MapConversions::toInt);
CONVERSION_DB.put(pair(String.class, Integer.class), StringConversions::toInt);
+ CONVERSION_DB.put(pair(LocalTime.class, Integer.class), LocalTimeConversions::toInteger);
CONVERSION_DB.put(pair(Year.class, Integer.class), YearConversions::toInt);
// toLong
@@ -184,6 +185,7 @@ private static void buildFactoryConversions() {
CONVERSION_DB.put(pair(Instant.class, Long.class), InstantConversions::toLong);
CONVERSION_DB.put(pair(Duration.class, Long.class), DurationConversions::toLong);
CONVERSION_DB.put(pair(LocalDate.class, Long.class), LocalDateConversions::toLong);
+ CONVERSION_DB.put(pair(LocalTime.class, Long.class), LocalTimeConversions::toLong);
CONVERSION_DB.put(pair(LocalDateTime.class, Long.class), LocalDateTimeConversions::toLong);
CONVERSION_DB.put(pair(OffsetDateTime.class, Long.class), OffsetDateTimeConversions::toLong);
CONVERSION_DB.put(pair(ZonedDateTime.class, Long.class), ZonedDateTimeConversions::toLong);
@@ -227,6 +229,7 @@ private static void buildFactoryConversions() {
CONVERSION_DB.put(pair(Character.class, Double.class), CharacterConversions::toDouble);
CONVERSION_DB.put(pair(Duration.class, Double.class), DurationConversions::toDouble);
CONVERSION_DB.put(pair(Instant.class, Double.class), InstantConversions::toDouble);
+ CONVERSION_DB.put(pair(LocalTime.class, Double.class), LocalTimeConversions::toDouble);
CONVERSION_DB.put(pair(LocalDate.class, Double.class), LocalDateConversions::toDouble);
CONVERSION_DB.put(pair(LocalDateTime.class, Double.class), LocalDateTimeConversions::toDouble);
CONVERSION_DB.put(pair(ZonedDateTime.class, Double.class), ZonedDateTimeConversions::toDouble);
@@ -305,6 +308,7 @@ private static void buildFactoryConversions() {
CONVERSION_DB.put(pair(Timestamp.class, BigInteger.class), TimestampConversions::toBigInteger);
CONVERSION_DB.put(pair(Duration.class, BigInteger.class), DurationConversions::toBigInteger);
CONVERSION_DB.put(pair(Instant.class, BigInteger.class), InstantConversions::toBigInteger);
+ CONVERSION_DB.put(pair(LocalTime.class, BigInteger.class), LocalTimeConversions::toBigInteger);
CONVERSION_DB.put(pair(LocalDate.class, BigInteger.class), LocalDateConversions::toBigInteger);
CONVERSION_DB.put(pair(LocalDateTime.class, BigInteger.class), LocalDateTimeConversions::toBigInteger);
CONVERSION_DB.put(pair(ZonedDateTime.class, BigInteger.class), ZonedDateTimeConversions::toBigInteger);
@@ -336,6 +340,7 @@ private static void buildFactoryConversions() {
CONVERSION_DB.put(pair(Timestamp.class, BigDecimal.class), TimestampConversions::toBigDecimal);
CONVERSION_DB.put(pair(Instant.class, BigDecimal.class), InstantConversions::toBigDecimal);
CONVERSION_DB.put(pair(Duration.class, BigDecimal.class), DurationConversions::toBigDecimal);
+ CONVERSION_DB.put(pair(LocalTime.class, BigDecimal.class), LocalTimeConversions::toBigDecimal);
CONVERSION_DB.put(pair(LocalDate.class, BigDecimal.class), LocalDateConversions::toBigDecimal);
CONVERSION_DB.put(pair(LocalDateTime.class, BigDecimal.class), LocalDateTimeConversions::toBigDecimal);
CONVERSION_DB.put(pair(ZonedDateTime.class, BigDecimal.class), ZonedDateTimeConversions::toBigDecimal);
@@ -379,9 +384,10 @@ private static void buildFactoryConversions() {
CONVERSION_DB.put(pair(Character.class, AtomicInteger.class), CharacterConversions::toAtomicInteger);
CONVERSION_DB.put(pair(BigInteger.class, AtomicInteger.class), NumberConversions::toAtomicInteger);
CONVERSION_DB.put(pair(BigDecimal.class, AtomicInteger.class), NumberConversions::toAtomicInteger);
- CONVERSION_DB.put(pair(AtomicInteger.class, AtomicInteger.class), NumberConversions::toAtomicInteger);
+ CONVERSION_DB.put(pair(AtomicInteger.class, AtomicInteger.class), AtomicIntegerConversions::toAtomicInteger);
CONVERSION_DB.put(pair(AtomicBoolean.class, AtomicInteger.class), AtomicBooleanConversions::toAtomicInteger);
CONVERSION_DB.put(pair(AtomicLong.class, AtomicInteger.class), NumberConversions::toAtomicInteger);
+ CONVERSION_DB.put(pair(LocalTime.class, AtomicInteger.class), LocalTimeConversions::toAtomicInteger);
CONVERSION_DB.put(pair(LocalDate.class, AtomicInteger.class), LocalDateConversions::toAtomicLong);
CONVERSION_DB.put(pair(Number.class, AtomicBoolean.class), NumberConversions::toAtomicInteger);
CONVERSION_DB.put(pair(Map.class, AtomicInteger.class), MapConversions::toAtomicInteger);
@@ -401,14 +407,15 @@ private static void buildFactoryConversions() {
CONVERSION_DB.put(pair(BigInteger.class, AtomicLong.class), NumberConversions::toAtomicLong);
CONVERSION_DB.put(pair(BigDecimal.class, AtomicLong.class), NumberConversions::toAtomicLong);
CONVERSION_DB.put(pair(AtomicBoolean.class, AtomicLong.class), AtomicBooleanConversions::toAtomicLong);
- CONVERSION_DB.put(pair(AtomicLong.class, AtomicLong.class), Converter::identity);
CONVERSION_DB.put(pair(AtomicInteger.class, AtomicLong.class), NumberConversions::toAtomicLong);
+ CONVERSION_DB.put(pair(AtomicLong.class, AtomicLong.class), AtomicLongConversions::toAtomicLong);
CONVERSION_DB.put(pair(Date.class, AtomicLong.class), DateConversions::toAtomicLong);
CONVERSION_DB.put(pair(java.sql.Date.class, AtomicLong.class), DateConversions::toAtomicLong);
CONVERSION_DB.put(pair(Timestamp.class, AtomicLong.class), DateConversions::toAtomicLong);
CONVERSION_DB.put(pair(Instant.class, AtomicLong.class), InstantConversions::toAtomicLong);
CONVERSION_DB.put(pair(Duration.class, AtomicLong.class), DurationConversions::toAtomicLong);
CONVERSION_DB.put(pair(LocalDate.class, AtomicLong.class), LocalDateConversions::toAtomicLong);
+ CONVERSION_DB.put(pair(LocalTime.class, AtomicLong.class), LocalTimeConversions::toAtomicLong);
CONVERSION_DB.put(pair(LocalDateTime.class, AtomicLong.class), LocalDateTimeConversions::toAtomicLong);
CONVERSION_DB.put(pair(ZonedDateTime.class, AtomicLong.class), ZonedDateTimeConversions::toAtomicLong);
CONVERSION_DB.put(pair(OffsetDateTime.class, AtomicLong.class), OffsetDateTimeConversions::toAtomicLong);
@@ -567,13 +574,13 @@ private static void buildFactoryConversions() {
CONVERSION_DB.put(pair(Void.class, LocalTime.class), VoidConversions::toNull);
CONVERSION_DB.put(pair(Byte.class, LocalTime.class), UNSUPPORTED);
CONVERSION_DB.put(pair(Short.class, LocalTime.class), UNSUPPORTED);
- CONVERSION_DB.put(pair(Integer.class, LocalTime.class), UNSUPPORTED);
- CONVERSION_DB.put(pair(Long.class, LocalTime.class), NumberConversions::toLocalTime);
- CONVERSION_DB.put(pair(Double.class, LocalTime.class), NumberConversions::toLocalTime);
- CONVERSION_DB.put(pair(BigInteger.class, LocalTime.class), NumberConversions::toLocalTime);
- CONVERSION_DB.put(pair(BigDecimal.class, LocalTime.class), NumberConversions::toLocalDateTime);
- CONVERSION_DB.put(pair(AtomicInteger.class, LocalTime.class), UNSUPPORTED);
- CONVERSION_DB.put(pair(AtomicLong.class, LocalTime.class), NumberConversions::toLocalTime);
+ CONVERSION_DB.put(pair(Integer.class, LocalTime.class), IntegerConversions::toLocalTime);
+ CONVERSION_DB.put(pair(Long.class, LocalTime.class), LongConversions::toLocalTime);
+ CONVERSION_DB.put(pair(Double.class, LocalTime.class), DoubleConversions::toLocalTime);
+ CONVERSION_DB.put(pair(BigInteger.class, LocalTime.class), BigIntegerConversions::toLocalTime);
+ CONVERSION_DB.put(pair(BigDecimal.class, LocalTime.class), BigDecimalConversions::toLocalTime);
+ CONVERSION_DB.put(pair(AtomicInteger.class, LocalTime.class), AtomicIntegerConversions::toLocalTime);
+ CONVERSION_DB.put(pair(AtomicLong.class, LocalTime.class), AtomicLongConversions::toLocalTime);
CONVERSION_DB.put(pair(java.sql.Date.class, LocalTime.class), DateConversions::toLocalTime);
CONVERSION_DB.put(pair(Timestamp.class, LocalTime.class), DateConversions::toLocalTime);
CONVERSION_DB.put(pair(Date.class, LocalTime.class), DateConversions::toLocalTime);
@@ -584,7 +591,6 @@ private static void buildFactoryConversions() {
CONVERSION_DB.put(pair(ZonedDateTime.class, LocalTime.class), ZonedDateTimeConversions::toLocalTime);
CONVERSION_DB.put(pair(OffsetDateTime.class, LocalTime.class), OffsetDateTimeConversions::toLocalTime);
CONVERSION_DB.put(pair(Calendar.class, LocalTime.class), CalendarConversions::toLocalTime);
- CONVERSION_DB.put(pair(Number.class, LocalTime.class), NumberConversions::toLocalTime);
CONVERSION_DB.put(pair(Map.class, LocalTime.class), MapConversions::toLocalTime);
CONVERSION_DB.put(pair(String.class, LocalTime.class), StringConversions::toLocalTime);
diff --git a/src/main/java/com/cedarsoftware/util/convert/DoubleConversions.java b/src/main/java/com/cedarsoftware/util/convert/DoubleConversions.java
index b4053b46c..baf205071 100644
--- a/src/main/java/com/cedarsoftware/util/convert/DoubleConversions.java
+++ b/src/main/java/com/cedarsoftware/util/convert/DoubleConversions.java
@@ -5,6 +5,7 @@
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
+import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.ZonedDateTime;
import java.util.Date;
@@ -46,6 +47,17 @@ static Date toSqlDate(Object from, Converter converter) {
return new java.sql.Date((long)(d * 1000));
}
+ static LocalTime toLocalTime(Object from, Converter converter) {
+ double seconds = (double) from;
+ double nanos = seconds * 1_000_000_000.0;
+ try {
+ return LocalTime.ofNanoOfDay((long)nanos);
+ }
+ catch (Exception e) {
+ throw new IllegalArgumentException("Input value [" + seconds + "] for conversion to LocalTime must be >= 0 && <= 86399.999999999", e);
+ }
+ }
+
static LocalDate toLocalDate(Object from, Converter converter) {
return toZonedDateTime(from, converter).toLocalDate();
}
diff --git a/src/main/java/com/cedarsoftware/util/convert/IntegerConversions.java b/src/main/java/com/cedarsoftware/util/convert/IntegerConversions.java
new file mode 100644
index 000000000..600a476e4
--- /dev/null
+++ b/src/main/java/com/cedarsoftware/util/convert/IntegerConversions.java
@@ -0,0 +1,30 @@
+package com.cedarsoftware.util.convert;
+
+import java.time.LocalTime;
+
+/**
+ * @author John DeRegnaucourt (jdereg@gmail.com)
+ *
+ * Copyright (c) Cedar Software LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * License
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+final class IntegerConversions {
+
+ private IntegerConversions() {}
+
+ static LocalTime toLocalTime(Object from, Converter converter) {
+ int ms = (Integer) from;
+ return LongConversions.toLocalTime((long)ms, converter);
+ }
+}
diff --git a/src/main/java/com/cedarsoftware/util/convert/LocalTimeConversions.java b/src/main/java/com/cedarsoftware/util/convert/LocalTimeConversions.java
index c3c6dc3a4..68c27daea 100644
--- a/src/main/java/com/cedarsoftware/util/convert/LocalTimeConversions.java
+++ b/src/main/java/com/cedarsoftware/util/convert/LocalTimeConversions.java
@@ -1,8 +1,13 @@
package com.cedarsoftware.util.convert;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.RoundingMode;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
import com.cedarsoftware.util.CompactLinkedMap;
@@ -24,6 +29,7 @@
* limitations under the License.
*/
final class LocalTimeConversions {
+ static final BigDecimal BILLION = BigDecimal.valueOf(1_000_000_000);
private LocalTimeConversions() {}
@@ -43,6 +49,39 @@ static Map toMap(Object from, Converter converter) {
return target;
}
+ static int toInteger(Object from, Converter converter) {
+ LocalTime lt = (LocalTime) from;
+ return (int) (lt.toNanoOfDay() / 1_000_000); // Convert nanoseconds to milliseconds.
+ }
+
+ static long toLong(Object from, Converter converter) {
+ LocalTime lt = (LocalTime) from;
+ return lt.toNanoOfDay() / 1_000_000; // Convert nanoseconds to milliseconds.
+ }
+
+ static double toDouble(Object from, Converter converter) {
+ LocalTime lt = (LocalTime) from;
+ return lt.toNanoOfDay() / 1_000_000_000.0;
+ }
+
+ static BigInteger toBigInteger(Object from, Converter converter) {
+ LocalTime lt = (LocalTime) from;
+ return BigInteger.valueOf(lt.toNanoOfDay());
+ }
+
+ static BigDecimal toBigDecimal(Object from, Converter converter) {
+ LocalTime lt = (LocalTime) from;
+ return new BigDecimal(lt.toNanoOfDay()).divide(BILLION, 9, RoundingMode.HALF_UP);
+ }
+
+ static AtomicInteger toAtomicInteger(Object from, Converter converter) {
+ return new AtomicInteger((int)toLong(from, converter));
+ }
+
+ static AtomicLong toAtomicLong(Object from, Converter converter) {
+ return new AtomicLong(toLong(from, converter));
+ }
+
static String toString(Object from, Converter converter) {
LocalTime localTime = (LocalTime) from;
return localTime.format(DateTimeFormatter.ISO_LOCAL_TIME);
diff --git a/src/main/java/com/cedarsoftware/util/convert/LongConversions.java b/src/main/java/com/cedarsoftware/util/convert/LongConversions.java
new file mode 100644
index 000000000..3dfdd5458
--- /dev/null
+++ b/src/main/java/com/cedarsoftware/util/convert/LongConversions.java
@@ -0,0 +1,34 @@
+package com.cedarsoftware.util.convert;
+
+import java.time.LocalTime;
+
+/**
+ * @author John DeRegnaucourt (jdereg@gmail.com)
+ *
+ * Copyright (c) Cedar Software LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * License
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+final class LongConversions {
+
+ private LongConversions() {}
+
+ static LocalTime toLocalTime(Object from, Converter converter) {
+ long millis = (Long) from;
+ try {
+ return LocalTime.ofNanoOfDay(millis * 1_000_000);
+ } catch (Exception e) {
+ throw new IllegalArgumentException("Input value [" + millis + "] for conversion to LocalTime must be >= 0 && <= 86399999", e);
+ }
+ }
+}
diff --git a/src/main/java/com/cedarsoftware/util/convert/NumberConversions.java b/src/main/java/com/cedarsoftware/util/convert/NumberConversions.java
index 6ab697a74..d2e447ed2 100644
--- a/src/main/java/com/cedarsoftware/util/convert/NumberConversions.java
+++ b/src/main/java/com/cedarsoftware/util/convert/NumberConversions.java
@@ -7,7 +7,6 @@
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
-import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.Year;
import java.time.ZonedDateTime;
@@ -203,11 +202,7 @@ static LocalDate toLocalDate(Object from, Converter converter) {
static LocalDateTime toLocalDateTime(Object from, Converter converter) {
return toZonedDateTime(from, converter).toLocalDateTime();
}
-
- static LocalTime toLocalTime(Object from, Converter converter) {
- return toZonedDateTime(from, converter).toLocalTime();
- }
-
+
static ZonedDateTime toZonedDateTime(Object from, Converter converter) {
return toInstant(from, converter).atZone(converter.getOptions().getZoneId());
}
diff --git a/src/test/java/com/cedarsoftware/util/convert/ConverterEverythingTest.java b/src/test/java/com/cedarsoftware/util/convert/ConverterEverythingTest.java
index 4f21e8398..6214f7c58 100644
--- a/src/test/java/com/cedarsoftware/util/convert/ConverterEverythingTest.java
+++ b/src/test/java/com/cedarsoftware/util/convert/ConverterEverythingTest.java
@@ -27,6 +27,7 @@
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -76,6 +77,7 @@ class ConverterEverythingTest {
private static final String TOKYO = "Asia/Tokyo";
private static final ZoneId TOKYO_Z = ZoneId.of(TOKYO);
private static final TimeZone TOKYO_TZ = TimeZone.getTimeZone(TOKYO_Z);
+ private static final Set> immutable = new HashSet<>();
private Converter converter;
private final ConverterOptions options = new ConverterOptions() {
public ZoneId getZoneId() {
@@ -89,6 +91,38 @@ public ZoneId getZoneId() {
// Useful values for input
long now = System.currentTimeMillis();
+ // List classes that should be checked for immutability
+ immutable.add(byte.class);
+ immutable.add(Byte.class);
+ immutable.add(short.class);
+ immutable.add(Short.class);
+ immutable.add(int.class);
+ immutable.add(Integer.class);
+ immutable.add(long.class);
+ immutable.add(Long.class);
+ immutable.add(float.class);
+ immutable.add(Float.class);
+ immutable.add(double.class);
+ immutable.add(Double.class);
+ immutable.add(boolean.class);
+ immutable.add(Boolean.class);
+ immutable.add(char.class);
+ immutable.add(Character.class);
+ immutable.add(BigInteger.class);
+ immutable.add(BigDecimal.class);
+ immutable.add(LocalTime.class);
+ immutable.add(LocalDate.class);
+ immutable.add(LocalDateTime.class);
+ immutable.add(ZonedDateTime.class);
+ immutable.add(OffsetDateTime.class);
+ immutable.add(Instant.class);
+ immutable.add(Duration.class);
+ immutable.add(Period.class);
+ immutable.add(Month.class);
+ immutable.add(Year.class);
+ immutable.add(MonthDay.class);
+ immutable.add(YearMonth.class);
+
loadByteTest();
loadShortTests();
loadIntegerTests();
@@ -102,6 +136,7 @@ public ZoneId getZoneId() {
loadInstantTests();
loadDateTests();
loadSqlDateTests();
+ loadCalendarTests();
loadDurationTests();
loadOffsetDateTimeTests();
loadMonthDayTests();
@@ -111,11 +146,81 @@ public ZoneId getZoneId() {
loadZoneIdTests();
loadTimestampTests(now);
loadLocalDateTests();
+ loadLocalTimeTests();
loadLocalDateTimeTests();
loadZoneDateTimeTests();
loadZoneOffsetTests();
loadStringTests();
loadAtomicLongTests();
+ loadAtomicIntegerTests();
+ loadAtomicBooleanTests();
+ loadMapTests();
+ }
+
+ /**
+ * Map
+ */
+ private static void loadMapTests() {
+ TEST_DB.put(pair(Void.class, Map.class), new Object[][]{
+ {null, null}
+ });
+ }
+
+ /**
+ * AtomicBoolean
+ */
+ private static void loadAtomicBooleanTests() {
+ TEST_DB.put(pair(Void.class, AtomicBoolean.class), new Object[][]{
+ {null, null}
+ });
+ TEST_DB.put(pair(AtomicBoolean.class, AtomicBoolean.class), new Object[][] {
+ { new AtomicBoolean(false), new AtomicBoolean(false)},
+ { new AtomicBoolean(true), new AtomicBoolean(true)},
+ });
+ TEST_DB.put(pair(AtomicInteger.class, AtomicBoolean.class), new Object[][] {
+ { new AtomicInteger(-1), new AtomicBoolean(true)},
+ { new AtomicInteger(0), new AtomicBoolean(false), true},
+ { new AtomicInteger(1), new AtomicBoolean(true), true},
+ });
+ TEST_DB.put(pair(AtomicLong.class, AtomicBoolean.class), new Object[][] {
+ { new AtomicLong((byte)-1), new AtomicBoolean(true)},
+ { new AtomicLong((byte)0), new AtomicBoolean(false), true},
+ { new AtomicLong((byte)1), new AtomicBoolean(true), true},
+ });
+ TEST_DB.put(pair(BigDecimal.class, AtomicBoolean.class), new Object[][] {
+ { new BigDecimal("-1.1"), new AtomicBoolean(true)},
+ { BigDecimal.valueOf(-1), new AtomicBoolean(true)},
+ { BigDecimal.ZERO, new AtomicBoolean(false), true},
+ { BigDecimal.valueOf(1), new AtomicBoolean(true), true},
+ { new BigDecimal("1.1"), new AtomicBoolean(true)},
+ });
+ TEST_DB.put(pair(Map.class, AtomicBoolean.class), new Object[][] {
+ { mapOf("_v", "true"), new AtomicBoolean(true)},
+ { mapOf("_v", true), new AtomicBoolean(true)},
+ { mapOf("_v", "false"), new AtomicBoolean(false)},
+ { mapOf("_v", false), new AtomicBoolean(false)},
+ { mapOf("_v", BigInteger.valueOf(1)), new AtomicBoolean(true)},
+ { mapOf("_v", BigDecimal.ZERO), new AtomicBoolean(false)},
+ });
+ }
+
+ /**
+ * AtomicInteger
+ */
+ private static void loadAtomicIntegerTests() {
+ TEST_DB.put(pair(Void.class, AtomicInteger.class), new Object[][]{
+ {null, null}
+ });
+ TEST_DB.put(pair(AtomicInteger.class, AtomicInteger.class), new Object[][] {
+ { new AtomicInteger(1), new AtomicInteger((byte)1), true}
+ });
+ TEST_DB.put(pair(AtomicLong.class, AtomicInteger.class), new Object[][] {
+ { new AtomicLong(Integer.MIN_VALUE), new AtomicInteger(Integer.MIN_VALUE), true},
+ { new AtomicLong(-1), new AtomicInteger((byte)-1), true},
+ { new AtomicLong(0), new AtomicInteger(0), true},
+ { new AtomicLong(1), new AtomicInteger((byte)1), true},
+ { new AtomicLong(Integer.MAX_VALUE), new AtomicInteger(Integer.MAX_VALUE), true},
+ });
}
/**
@@ -125,6 +230,9 @@ private static void loadAtomicLongTests() {
TEST_DB.put(pair(Void.class, AtomicLong.class), new Object[][]{
{null, null}
});
+ TEST_DB.put(pair(AtomicLong.class, AtomicLong.class), new Object[][]{
+ {new AtomicLong(16), new AtomicLong(16)}
+ });
TEST_DB.put(pair(Instant.class, AtomicLong.class), new Object[][]{
{Instant.parse("0000-01-01T00:00:00Z"), new AtomicLong(-62167219200000L), true},
{Instant.parse("0000-01-01T00:00:00.001Z"), new AtomicLong(-62167219199999L), true},
@@ -501,6 +609,11 @@ private static void loadLocalDateTimeTests() {
TEST_DB.put(pair(LocalDateTime.class, LocalDateTime.class), new Object[][]{
{LocalDateTime.of(1970, 1, 1, 0, 0), LocalDateTime.of(1970, 1, 1, 0, 0), true}
});
+ TEST_DB.put(pair(AtomicLong.class, LocalDateTime.class), new Object[][]{
+ {new AtomicLong(-1), LocalDateTime.parse("1969-12-31T23:59:59.999").atZone(ZoneId.of("UTC")).withZoneSameInstant(TOKYO_Z).toLocalDateTime(), true},
+ {new AtomicLong(0), LocalDateTime.parse("1970-01-01T00:00:00").atZone(ZoneId.of("UTC")).withZoneSameInstant(TOKYO_Z).toLocalDateTime(), true},
+ {new AtomicLong(1), LocalDateTime.parse("1970-01-01T00:00:00.001").atZone(ZoneId.of("UTC")).withZoneSameInstant(TOKYO_Z).toLocalDateTime(), true},
+ });
TEST_DB.put(pair(Double.class, LocalDateTime.class), new Object[][]{
{-0.000000001, LocalDateTime.parse("1969-12-31T23:59:59.999999999").atZone(ZoneId.of("UTC")).withZoneSameInstant(TOKYO_Z).toLocalDateTime()}, // IEEE-754 prevents perfect symmetry
{0d, LocalDateTime.parse("1970-01-01T00:00:00").atZone(ZoneId.of("UTC")).withZoneSameInstant(TOKYO_Z).toLocalDateTime(), true},
@@ -515,6 +628,69 @@ private static void loadLocalDateTimeTests() {
});
}
+ /**
+ * LocalTime
+ */
+ private static void loadLocalTimeTests() {
+ TEST_DB.put(pair(Void.class, LocalTime.class), new Object[][]{
+ {null, null},
+ });
+ TEST_DB.put(pair(LocalTime.class, LocalTime.class), new Object[][]{
+ { LocalTime.parse("12:34:56"), LocalTime.parse("12:34:56"), true}
+ });
+ TEST_DB.put(pair(Integer.class, LocalTime.class), new Object[][]{
+ { -1, new IllegalArgumentException("value [-1]")},
+ { 0, LocalTime.parse("00:00:00"), true},
+ { 1, LocalTime.parse("00:00:00.001"), true},
+ { 86399999, LocalTime.parse("23:59:59.999"), true},
+ { 86400000, new IllegalArgumentException("value [86400000]")},
+ });
+ TEST_DB.put(pair(Long.class, LocalTime.class), new Object[][]{
+ { -1L, new IllegalArgumentException("value [-1]")},
+ { 0L, LocalTime.parse("00:00:00"), true},
+ { 1L, LocalTime.parse("00:00:00.001"), true},
+ { 86399999L, LocalTime.parse("23:59:59.999"), true},
+ { 86400000L, new IllegalArgumentException("value [86400000]")},
+ });
+ TEST_DB.put(pair(Double.class, LocalTime.class), new Object[][]{
+ { -0.000000001, new IllegalArgumentException("value [-1.0E-9]")},
+ { 0.0, LocalTime.parse("00:00:00"), true},
+ { 0.000000001, LocalTime.parse("00:00:00.000000001"), true},
+ { 1.0, LocalTime.parse("00:00:01"), true},
+ { 86399.999999999, LocalTime.parse("23:59:59.999999999"), true},
+ { 86400.0, new IllegalArgumentException("value [86400.0]")},
+ });
+ TEST_DB.put(pair(AtomicInteger.class, LocalTime.class), new Object[][]{
+ { new AtomicInteger(-1), new IllegalArgumentException("value [-1]")},
+ { new AtomicInteger(0), LocalTime.parse("00:00:00"), true},
+ { new AtomicInteger(1), LocalTime.parse("00:00:00.001"), true},
+ { new AtomicInteger(86399999), LocalTime.parse("23:59:59.999"), true},
+ { new AtomicInteger(86400000), new IllegalArgumentException("value [86400000]")},
+ });
+ TEST_DB.put(pair(AtomicLong.class, LocalTime.class), new Object[][]{
+ { new AtomicLong(-1), new IllegalArgumentException("value [-1]")},
+ { new AtomicLong(0), LocalTime.parse("00:00:00"), true},
+ { new AtomicLong(1), LocalTime.parse("00:00:00.001"), true},
+ { new AtomicLong(86399999), LocalTime.parse("23:59:59.999"), true},
+ { new AtomicLong(86400000), new IllegalArgumentException("value [86400000]")},
+ });
+ TEST_DB.put(pair(BigInteger.class, LocalTime.class), new Object[][]{
+ { BigInteger.valueOf(-1), new IllegalArgumentException("value [-1]")},
+ { BigInteger.valueOf(0), LocalTime.parse("00:00:00"), true},
+ { BigInteger.valueOf(1), LocalTime.parse("00:00:00.000000001"), true},
+ { BigInteger.valueOf(86399999999999L), LocalTime.parse("23:59:59.999999999"), true},
+ { BigInteger.valueOf(86400000000000L), new IllegalArgumentException("value [86400000000000]")},
+ });
+ TEST_DB.put(pair(BigDecimal.class, LocalTime.class), new Object[][]{
+ { BigDecimal.valueOf(-0.000000001), new IllegalArgumentException("value [-0.0000000010]")},
+ { BigDecimal.valueOf(0), LocalTime.parse("00:00:00"), true},
+ { BigDecimal.valueOf(0.000000001), LocalTime.parse("00:00:00.000000001"), true},
+ { BigDecimal.valueOf(1), LocalTime.parse("00:00:01"), true},
+ { BigDecimal.valueOf(86399.999999999), LocalTime.parse("23:59:59.999999999"), true},
+ { BigDecimal.valueOf(86400.0), new IllegalArgumentException("value [86400.0]")},
+ });
+ }
+
/**
* LocalDate
*/
@@ -532,6 +708,13 @@ private static void loadLocalDateTests() {
{53999.999, LocalDate.parse("1970-01-01")}, // Showing that there is a wide range of numbers that will convert to this date
{54000d, LocalDate.parse("1970-01-02"), true},
});
+ TEST_DB.put(pair(AtomicLong.class, LocalDate.class), new Object[][]{ // options timezone is factored in (86,400 seconds per day)
+ {new AtomicLong(-118800000), LocalDate.parse("1969-12-31"), true},
+ {new AtomicLong(-32400000), LocalDate.parse("1970-01-01"), true},
+ {new AtomicLong(0), LocalDate.parse("1970-01-01")}, // Showing that there is a wide range of numbers that will convert to this date
+ {new AtomicLong(53999999), LocalDate.parse("1970-01-01")}, // Showing that there is a wide range of numbers that will convert to this date
+ {new AtomicLong(54000000), LocalDate.parse("1970-01-02"), true},
+ });
TEST_DB.put(pair(BigInteger.class, LocalDate.class), new Object[][]{ // options timezone is factored in (86,400 seconds per day)
// These are all in the same date range
{BigInteger.ZERO, ZonedDateTime.parse("1970-01-01T00:00:00Z").withZoneSameInstant(TOKYO_Z).toLocalDate() },
@@ -904,6 +1087,31 @@ private static void loadDateTests() {
{null, null}
});
// No identity test for Date, as it is mutable
+ TEST_DB.put(pair(AtomicLong.class, Date.class), new Object[][]{
+ {new AtomicLong(Long.MIN_VALUE), new Date(Long.MIN_VALUE), true},
+ {new AtomicLong(-1), new Date(-1), true},
+ {new AtomicLong(0), new Date(0), true},
+ {new AtomicLong(1), new Date(1), true},
+ {new AtomicLong(Long.MAX_VALUE), new Date(Long.MAX_VALUE), true},
+ });
+ }
+
+ /**
+ * Calendar
+ */
+ private static void loadCalendarTests() {
+ TEST_DB.put(pair(Void.class, Calendar.class), new Object[][]{
+ {null, null}
+ });
+ TEST_DB.put(pair(AtomicLong.class, Calendar.class), new Object[][]{
+ {new AtomicLong(0), (Supplier) () -> {
+ Calendar cal = Calendar.getInstance();
+ cal.clear();
+ cal.setTimeZone(TOKYO_TZ);
+ cal.setTimeInMillis(0);
+ return cal;
+ }, true}
+ });
}
/**
@@ -940,6 +1148,20 @@ private static void loadBigDecimalTests() {
TEST_DB.put(pair(String.class, BigDecimal.class), new Object[][]{
{"3.1415926535897932384626433", new BigDecimal("3.1415926535897932384626433"), true}
});
+ TEST_DB.put(pair(AtomicInteger.class, BigDecimal.class), new Object[][] {
+ { new AtomicInteger(Integer.MIN_VALUE), BigDecimal.valueOf(Integer.MIN_VALUE), true},
+ { new AtomicInteger(-1), BigDecimal.valueOf(-1), true},
+ { new AtomicInteger(0), BigDecimal.ZERO, true},
+ { new AtomicInteger(1), BigDecimal.valueOf(1), true},
+ { new AtomicInteger(Integer.MAX_VALUE), BigDecimal.valueOf(Integer.MAX_VALUE), true},
+ });
+ TEST_DB.put(pair(AtomicLong.class, BigDecimal.class), new Object[][] {
+ { new AtomicLong(Long.MIN_VALUE), BigDecimal.valueOf(Long.MIN_VALUE), true},
+ { new AtomicLong(-1), BigDecimal.valueOf(-1), true},
+ { new AtomicLong(0), BigDecimal.ZERO, true},
+ { new AtomicLong(1), BigDecimal.valueOf(1), true},
+ { new AtomicLong(Long.MAX_VALUE), BigDecimal.valueOf(Long.MAX_VALUE), true},
+ });
TEST_DB.put(pair(Date.class, BigDecimal.class), new Object[][]{
{Date.from(Instant.parse("0000-01-01T00:00:00Z")), new BigDecimal("-62167219200"), true},
{Date.from(Instant.parse("0000-01-01T00:00:00.001Z")), new BigDecimal("-62167219199.999"), true},
@@ -1400,35 +1622,35 @@ private static void loadBooleanTests() {
{'0', false},
});
TEST_DB.put(pair(AtomicBoolean.class, Boolean.class), new Object[][]{
- {new AtomicBoolean(true), true},
- {new AtomicBoolean(false), false},
+ {new AtomicBoolean(true), true, true},
+ {new AtomicBoolean(false), false, true},
});
TEST_DB.put(pair(AtomicInteger.class, Boolean.class), new Object[][]{
{new AtomicInteger(-2), true},
{new AtomicInteger(-1), true},
- {new AtomicInteger(0), false},
- {new AtomicInteger(1), true},
+ {new AtomicInteger(0), false, true},
+ {new AtomicInteger(1), true, true},
{new AtomicInteger(2), true},
});
TEST_DB.put(pair(AtomicLong.class, Boolean.class), new Object[][]{
{new AtomicLong(-2), true},
{new AtomicLong(-1), true},
- {new AtomicLong(0), false},
- {new AtomicLong(1), true},
+ {new AtomicLong(0), false, true},
+ {new AtomicLong(1), true, true},
{new AtomicLong(2), true},
});
TEST_DB.put(pair(BigInteger.class, Boolean.class), new Object[][]{
{BigInteger.valueOf(-2), true},
{BigInteger.valueOf(-1), true},
- {BigInteger.ZERO, false},
- {BigInteger.valueOf(1), true},
+ {BigInteger.ZERO, false, true},
+ {BigInteger.valueOf(1), true, true},
{BigInteger.valueOf(2), true},
});
TEST_DB.put(pair(BigDecimal.class, Boolean.class), new Object[][]{
{BigDecimal.valueOf(-2L), true},
{BigDecimal.valueOf(-1L), true},
- {BigDecimal.valueOf(0L), false},
- {BigDecimal.valueOf(1L), true},
+ {BigDecimal.valueOf(0L), false, true},
+ {BigDecimal.valueOf(1L), true, true},
{BigDecimal.valueOf(2L), true},
});
TEST_DB.put(pair(Number.class, Boolean.class), new Object[][]{
@@ -1447,13 +1669,13 @@ private static void loadBooleanTests() {
});
TEST_DB.put(pair(String.class, Boolean.class), new Object[][]{
{"0", false},
- {"false", false},
+ {"false", false, true},
{"FaLse", false},
{"FALSE", false},
{"F", false},
{"f", false},
{"1", true},
- {"true", true},
+ {"true", true, true},
{"TrUe", true},
{"TRUE", true},
{"T", true},
@@ -2515,109 +2737,105 @@ private static void loadByteTest() {
{Byte.MAX_VALUE, Byte.MAX_VALUE},
});
TEST_DB.put(pair(Short.class, Byte.class), new Object[][]{
- {(short) -1, (byte) -1},
- {(short) 0, (byte) 0},
- {(short) 1, (byte) 1},
- {(short) -128, Byte.MIN_VALUE},
- {(short) 127, Byte.MAX_VALUE},
+ {(short) -1, (byte) -1, true},
+ {(short) 0, (byte) 0, true},
+ {(short) 1, (byte) 1, true},
+ {(short) -128, Byte.MIN_VALUE, true},
+ {(short) 127, Byte.MAX_VALUE, true},
{(short) -129, Byte.MAX_VALUE}, // verify wrap around
{(short) 128, Byte.MIN_VALUE}, // verify wrap around
});
TEST_DB.put(pair(Integer.class, Byte.class), new Object[][]{
- {-1, (byte) -1},
- {0, (byte) 0},
- {1, (byte) 1},
- {-128, Byte.MIN_VALUE},
- {127, Byte.MAX_VALUE},
+ {-1, (byte) -1, true},
+ {0, (byte) 0, true},
+ {1, (byte) 1, true},
+ {-128, Byte.MIN_VALUE, true},
+ {127, Byte.MAX_VALUE, true},
{-129, Byte.MAX_VALUE}, // verify wrap around
{128, Byte.MIN_VALUE}, // verify wrap around
});
TEST_DB.put(pair(Long.class, Byte.class), new Object[][]{
- {-1L, (byte) -1},
- {0L, (byte) 0},
- {1L, (byte) 1},
- {-128L, Byte.MIN_VALUE},
- {127L, Byte.MAX_VALUE},
+ {-1L, (byte) -1, true},
+ {0L, (byte) 0, true},
+ {1L, (byte) 1, true},
+ {-128L, Byte.MIN_VALUE, true},
+ {127L, Byte.MAX_VALUE, true},
{-129L, Byte.MAX_VALUE}, // verify wrap around
{128L, Byte.MIN_VALUE} // verify wrap around
});
TEST_DB.put(pair(Float.class, Byte.class), new Object[][]{
- {-1f, (byte) -1},
+ {-1f, (byte) -1, true},
{-1.99f, (byte) -1},
{-1.1f, (byte) -1},
- {0f, (byte) 0},
- {1f, (byte) 1},
+ {0f, (byte) 0, true},
+ {1f, (byte) 1, true},
{1.1f, (byte) 1},
{1.999f, (byte) 1},
- {-128f, Byte.MIN_VALUE},
- {127f, Byte.MAX_VALUE},
+ {-128f, Byte.MIN_VALUE, true},
+ {127f, Byte.MAX_VALUE, true},
{-129f, Byte.MAX_VALUE}, // verify wrap around
{128f, Byte.MIN_VALUE} // verify wrap around
});
TEST_DB.put(pair(Double.class, Byte.class), new Object[][]{
- {-1d, (byte) -1},
+ {-1d, (byte) -1, true},
{-1.99, (byte) -1},
{-1.1, (byte) -1},
- {0d, (byte) 0},
+ {0d, (byte) 0, true},
{1d, (byte) 1},
{1.1, (byte) 1},
{1.999, (byte) 1},
- {-128d, Byte.MIN_VALUE},
- {127d, Byte.MAX_VALUE},
+ {-128d, Byte.MIN_VALUE, true},
+ {127d, Byte.MAX_VALUE, true},
{-129d, Byte.MAX_VALUE}, // verify wrap around
{128d, Byte.MIN_VALUE} // verify wrap around
});
TEST_DB.put(pair(Boolean.class, Byte.class), new Object[][]{
- {true, (byte) 1},
- {false, (byte) 0},
+ {true, (byte) 1, true},
+ {false, (byte) 0, true},
});
TEST_DB.put(pair(Character.class, Byte.class), new Object[][]{
- {'1', (byte) 49},
- {'0', (byte) 48},
- {(char) 1, (byte) 1},
- {(char) 0, (byte) 0},
+ {'1', (byte) 49, true},
+ {'0', (byte) 48, true},
+ {(char) 1, (byte) 1, true},
+ {(char) 0, (byte) 0, true},
});
TEST_DB.put(pair(AtomicBoolean.class, Byte.class), new Object[][]{
- {new AtomicBoolean(true), (byte) 1},
- {new AtomicBoolean(false), (byte) 0},
+ {new AtomicBoolean(true), (byte) 1, true},
+ {new AtomicBoolean(false), (byte) 0, true},
});
TEST_DB.put(pair(AtomicInteger.class, Byte.class), new Object[][]{
- {new AtomicInteger(-1), (byte) -1},
- {new AtomicInteger(0), (byte) 0},
- {new AtomicInteger(1), (byte) 1},
- {new AtomicInteger(-128), Byte.MIN_VALUE},
- {new AtomicInteger(127), Byte.MAX_VALUE},
- {new AtomicInteger(-129), Byte.MAX_VALUE},
- {new AtomicInteger(128), Byte.MIN_VALUE},
+ {new AtomicInteger(-1), (byte) -1, true},
+ {new AtomicInteger(0), (byte) 0, true},
+ {new AtomicInteger(1), (byte) 1, true},
+ {new AtomicInteger(-128), Byte.MIN_VALUE, true},
+ {new AtomicInteger(127), Byte.MAX_VALUE, true},
});
TEST_DB.put(pair(AtomicLong.class, Byte.class), new Object[][]{
- {new AtomicLong(-1), (byte) -1},
- {new AtomicLong(0), (byte) 0},
- {new AtomicLong(1), (byte) 1},
- {new AtomicLong(-128), Byte.MIN_VALUE},
- {new AtomicLong(127), Byte.MAX_VALUE},
- {new AtomicLong(-129), Byte.MAX_VALUE},
- {new AtomicLong(128), Byte.MIN_VALUE},
+ {new AtomicLong(-1), (byte) -1, true},
+ {new AtomicLong(0), (byte) 0, true},
+ {new AtomicLong(1), (byte) 1, true},
+ {new AtomicLong(-128), Byte.MIN_VALUE, true},
+ {new AtomicLong(127), Byte.MAX_VALUE, true},
});
TEST_DB.put(pair(BigInteger.class, Byte.class), new Object[][]{
- {new BigInteger("-1"), (byte) -1},
- {BigInteger.ZERO, (byte) 0},
- {new BigInteger("1"), (byte) 1},
- {new BigInteger("-128"), Byte.MIN_VALUE},
- {new BigInteger("127"), Byte.MAX_VALUE},
+ {new BigInteger("-1"), (byte) -1, true},
+ {BigInteger.ZERO, (byte) 0, true},
+ {new BigInteger("1"), (byte) 1, true},
+ {new BigInteger("-128"), Byte.MIN_VALUE, true},
+ {new BigInteger("127"), Byte.MAX_VALUE, true},
{new BigInteger("-129"), Byte.MAX_VALUE},
{new BigInteger("128"), Byte.MIN_VALUE},
});
TEST_DB.put(pair(BigDecimal.class, Byte.class), new Object[][]{
- {new BigDecimal("-1"), (byte) -1},
+ {new BigDecimal("-1"), (byte) -1, true},
{new BigDecimal("-1.1"), (byte) -1},
{new BigDecimal("-1.9"), (byte) -1},
- {BigDecimal.ZERO, (byte) 0},
- {new BigDecimal("1"), (byte) 1},
+ {BigDecimal.ZERO, (byte) 0, true},
+ {new BigDecimal("1"), (byte) 1, true},
{new BigDecimal("1.1"), (byte) 1},
{new BigDecimal("1.9"), (byte) 1},
- {new BigDecimal("-128"), Byte.MIN_VALUE},
- {new BigDecimal("127"), Byte.MAX_VALUE},
+ {new BigDecimal("-128"), Byte.MIN_VALUE, true},
+ {new BigDecimal("127"), Byte.MAX_VALUE, true},
{new BigDecimal("-129"), Byte.MAX_VALUE},
{new BigDecimal("128"), Byte.MIN_VALUE},
});
@@ -2650,18 +2868,18 @@ private static void loadByteTest() {
{mapOf("_v", mapOf("_v", 128L)), Byte.MIN_VALUE}, // Prove use of recursive call to .convert()
});
TEST_DB.put(pair(Year.class, Byte.class), new Object[][]{
- {Year.of(2024), new IllegalArgumentException("Unsupported conversion, source type [Year (2024)] target type 'Byte'")},
+ {Year.of(2024), new IllegalArgumentException("Unsupported conversion, source type [Year (2024)] target type 'Byte'") },
});
TEST_DB.put(pair(String.class, Byte.class), new Object[][]{
- {"-1", (byte) -1},
+ {"-1", (byte) -1, true},
{"-1.1", (byte) -1},
{"-1.9", (byte) -1},
- {"0", (byte) 0},
- {"1", (byte) 1},
+ {"0", (byte) 0, true},
+ {"1", (byte) 1, true},
{"1.1", (byte) 1},
{"1.9", (byte) 1},
- {"-128", (byte) -128},
- {"127", (byte) 127},
+ {"-128", (byte) -128, true},
+ {"127", (byte) 127, true},
{"", (byte) 0},
{" ", (byte) 0},
{"crapola", new IllegalArgumentException("Value 'crapola' not parseable as a byte value or outside -128 to 127")},
@@ -2714,6 +2932,11 @@ private static Stream generateTestEverythingParams() {
for (Map.Entry, Class>>, Object[][]> entry : TEST_DB.entrySet()) {
Class> sourceClass = entry.getKey().getKey();
Class> targetClass = entry.getKey().getValue();
+
+ // Skip Atomic's to Map - assertEquals() does not know to call .get() on the value side of the Map.
+ if (isHardCase(sourceClass, targetClass)) {
+ continue;
+ }
String sourceName = Converter.getShortName(sourceClass);
String targetName = Converter.getShortName(targetClass);
Object[][] testData = entry.getValue();
@@ -2735,6 +2958,10 @@ private static Stream generateTestEverythingParamsInReverse() {
for (Map.Entry, Class>>, Object[][]> entry : TEST_DB.entrySet()) {
Class> sourceClass = entry.getKey().getKey();
Class> targetClass = entry.getKey().getValue();
+
+ if (isHardCase(sourceClass, targetClass)) {
+ continue;
+ }
String sourceName = Converter.getShortName(sourceClass);
String targetName = Converter.getShortName(targetClass);
@@ -2771,7 +2998,7 @@ void testConvert(String shortNameSource, String shortNameTarget, Object source,
assert target == null || target instanceof Throwable || ClassUtilities.toPrimitiveWrapperClass(targetClass).isInstance(target) : "target type mismatch ==> Expected: " + shortNameTarget + ", Actual: " + Converter.getShortName(target.getClass());
// if the source/target are the same Class, then ensure identity lambda is used.
- if (sourceClass.equals(targetClass)) {
+ if (sourceClass.equals(targetClass) && immutable.contains(sourceClass)) {
assertSame(source, converter.convert(source, targetClass));
}
@@ -2784,7 +3011,13 @@ void testConvert(String shortNameSource, String shortNameTarget, Object source,
// Assert values are equals
Object actual = converter.convert(source, targetClass);
try {
- if (target instanceof AtomicLong) {
+ if (target instanceof AtomicBoolean) {
+ assertEquals(((AtomicBoolean) target).get(), ((AtomicBoolean) actual).get());
+ updateStat(pair(sourceClass, targetClass), true);
+ } else if (target instanceof AtomicInteger) {
+ assertEquals(((AtomicInteger) target).get(), ((AtomicInteger) actual).get());
+ updateStat(pair(sourceClass, targetClass), true);
+ } else if (target instanceof AtomicLong) {
assertEquals(((AtomicLong) target).get(), ((AtomicLong) actual).get());
updateStat(pair(sourceClass, targetClass), true);
} else if (target instanceof BigDecimal) {
@@ -2793,7 +3026,7 @@ void testConvert(String shortNameSource, String shortNameTarget, Object source,
}
updateStat(pair(sourceClass, targetClass), true);
} else {
- assertEquals(target, actual);
+ assertEquals(actual, target);
updateStat(pair(sourceClass, targetClass), true);
}
}
@@ -2803,11 +3036,17 @@ void testConvert(String shortNameSource, String shortNameTarget, Object source,
}
}
}
-
+
private static void updateStat(Map.Entry, Class>> pair, boolean state) {
STAT_DB.put(pair, state);
}
+ // Rare pairings that cannot be tested without drilling into the class - Atomic's require .get() to be called,
+ // so an Atomic inside a Map is a hard-case.
+ private static boolean isHardCase(Class> sourceClass, Class> targetClass) {
+ return targetClass.equals(Map.class) && (sourceClass.equals(AtomicBoolean.class) || sourceClass.equals(AtomicInteger.class) || sourceClass.equals(AtomicLong.class));
+ }
+
@BeforeAll
static void statPrep() {
Map, Set>> map = com.cedarsoftware.util.Converter.allSupportedConversions();
@@ -2830,6 +3069,11 @@ static void printStats() {
Map.Entry, Class>> pair = entry.getKey();
boolean value = entry.getValue();
if (!value) {
+ Class> sourceClass = pair.getKey();
+ Class> targetClass = pair.getValue();
+ if (isHardCase(sourceClass, targetClass)) {
+ continue;
+ }
missing++;
testPairNames.add("\n " + Converter.getShortName(pair.getKey()) + " ==> " + Converter.getShortName(pair.getValue()));
}
diff --git a/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java b/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java
index 65230c1e8..1e3d05e31 100644
--- a/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java
+++ b/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java
@@ -43,6 +43,7 @@
import static com.cedarsoftware.util.ArrayUtilities.EMPTY_CHAR_ARRAY;
import static com.cedarsoftware.util.Converter.zonedDateTimeToMillis;
import static com.cedarsoftware.util.StringUtilities.EMPTY;
+import static com.cedarsoftware.util.convert.Converter.VALUE;
import static com.cedarsoftware.util.convert.ConverterTest.fubar.bar;
import static com.cedarsoftware.util.convert.ConverterTest.fubar.foo;
import static org.assertj.core.api.Assertions.assertThat;
@@ -1617,16 +1618,6 @@ void testLongToBigInteger(Object source, Number number)
assertThat(actual).isEqualTo(BigInteger.valueOf(expected));
}
-
- @ParameterizedTest
- @MethodSource("epochMillis_withLocalDateInformation")
- void testLongToLocalTime(long epochMilli, ZoneId zoneId, LocalDate expected)
- {
- Converter converter = new Converter(createCustomZones(zoneId));
- LocalTime actual = converter.convert(epochMilli, LocalTime.class);
-
- assertThat(actual).isEqualTo(Instant.ofEpochMilli(epochMilli).atZone(zoneId).toLocalTime());
- }
@ParameterizedTest
@MethodSource("localDateTimeConversion_params")
@@ -3511,14 +3502,14 @@ void testByteToMap()
byte b1 = (byte) 16;
Map, ?> map = this.converter.convert(b1, Map.class);
assert map.size() == 1;
- assertEquals(map.get(Converter.VALUE), (byte)16);
- assert map.get(Converter.VALUE).getClass().equals(Byte.class);
+ assertEquals(map.get(VALUE), (byte)16);
+ assert map.get(VALUE).getClass().equals(Byte.class);
Byte b2 = (byte) 16;
map = this.converter.convert(b2, Map.class);
assert map.size() == 1;
- assertEquals(map.get(Converter.VALUE), (byte)16);
- assert map.get(Converter.VALUE).getClass().equals(Byte.class);
+ assertEquals(map.get(VALUE), (byte)16);
+ assert map.get(VALUE).getClass().equals(Byte.class);
}
@Test
@@ -3527,14 +3518,14 @@ void testShortToMap()
short s1 = (short) 1600;
Map, ?> map = this.converter.convert(s1, Map.class);
assert map.size() == 1;
- assertEquals(map.get(Converter.VALUE), (short)1600);
- assert map.get(Converter.VALUE).getClass().equals(Short.class);
+ assertEquals(map.get(VALUE), (short)1600);
+ assert map.get(VALUE).getClass().equals(Short.class);
Short s2 = (short) 1600;
map = this.converter.convert(s2, Map.class);
assert map.size() == 1;
- assertEquals(map.get(Converter.VALUE), (short)1600);
- assert map.get(Converter.VALUE).getClass().equals(Short.class);
+ assertEquals(map.get(VALUE), (short)1600);
+ assert map.get(VALUE).getClass().equals(Short.class);
}
@Test
@@ -3543,14 +3534,14 @@ void testIntegerToMap()
int s1 = 1234567;
Map, ?> map = this.converter.convert(s1, Map.class);
assert map.size() == 1;
- assertEquals(map.get(Converter.VALUE), 1234567);
- assert map.get(Converter.VALUE).getClass().equals(Integer.class);
+ assertEquals(map.get(VALUE), 1234567);
+ assert map.get(VALUE).getClass().equals(Integer.class);
Integer s2 = 1234567;
map = this.converter.convert(s2, Map.class);
assert map.size() == 1;
- assertEquals(map.get(Converter.VALUE), 1234567);
- assert map.get(Converter.VALUE).getClass().equals(Integer.class);
+ assertEquals(map.get(VALUE), 1234567);
+ assert map.get(VALUE).getClass().equals(Integer.class);
}
@Test
@@ -3559,14 +3550,14 @@ void testLongToMap()
long s1 = 123456789012345L;
Map, ?> map = this.converter.convert(s1, Map.class);
assert map.size() == 1;
- assertEquals(map.get(Converter.VALUE), 123456789012345L);
- assert map.get(Converter.VALUE).getClass().equals(Long.class);
+ assertEquals(map.get(VALUE), 123456789012345L);
+ assert map.get(VALUE).getClass().equals(Long.class);
Long s2 = 123456789012345L;
map = this.converter.convert(s2, Map.class);
assert map.size() == 1;
- assertEquals(map.get(Converter.VALUE), 123456789012345L);
- assert map.get(Converter.VALUE).getClass().equals(Long.class);
+ assertEquals(map.get(VALUE), 123456789012345L);
+ assert map.get(VALUE).getClass().equals(Long.class);
}
@Test
@@ -3575,14 +3566,14 @@ void testFloatToMap()
float s1 = 3.141592f;
Map, ?> map = this.converter.convert(s1, Map.class);
assert map.size() == 1;
- assertEquals(map.get(Converter.VALUE), 3.141592f);
- assert map.get(Converter.VALUE).getClass().equals(Float.class);
+ assertEquals(map.get(VALUE), 3.141592f);
+ assert map.get(VALUE).getClass().equals(Float.class);
Float s2 = 3.141592f;
map = this.converter.convert(s2, Map.class);
assert map.size() == 1;
- assertEquals(map.get(Converter.VALUE), 3.141592f);
- assert map.get(Converter.VALUE).getClass().equals(Float.class);
+ assertEquals(map.get(VALUE), 3.141592f);
+ assert map.get(VALUE).getClass().equals(Float.class);
}
@Test
@@ -3591,14 +3582,14 @@ void testDoubleToMap()
double s1 = 3.14159265358979d;
Map, ?> map = this.converter.convert(s1, Map.class);
assert map.size() == 1;
- assertEquals(map.get(Converter.VALUE), 3.14159265358979d);
- assert map.get(Converter.VALUE).getClass().equals(Double.class);
+ assertEquals(map.get(VALUE), 3.14159265358979d);
+ assert map.get(VALUE).getClass().equals(Double.class);
Double s2 = 3.14159265358979d;
map = this.converter.convert(s2, Map.class);
assert map.size() == 1;
- assertEquals(map.get(Converter.VALUE), 3.14159265358979d);
- assert map.get(Converter.VALUE).getClass().equals(Double.class);
+ assertEquals(map.get(VALUE), 3.14159265358979d);
+ assert map.get(VALUE).getClass().equals(Double.class);
}
@Test
@@ -3607,14 +3598,14 @@ void testBooleanToMap()
boolean s1 = true;
Map, ?> map = this.converter.convert(s1, Map.class);
assert map.size() == 1;
- assertEquals(map.get(Converter.VALUE), true);
- assert map.get(Converter.VALUE).getClass().equals(Boolean.class);
+ assertEquals(map.get(VALUE), true);
+ assert map.get(VALUE).getClass().equals(Boolean.class);
Boolean s2 = true;
map = this.converter.convert(s2, Map.class);
assert map.size() == 1;
- assertEquals(map.get(Converter.VALUE), true);
- assert map.get(Converter.VALUE).getClass().equals(Boolean.class);
+ assertEquals(map.get(VALUE), true);
+ assert map.get(VALUE).getClass().equals(Boolean.class);
}
@Test
@@ -3623,14 +3614,14 @@ void testCharacterToMap()
char s1 = 'e';
Map, ?> map = this.converter.convert(s1, Map.class);
assert map.size() == 1;
- assertEquals(map.get(Converter.VALUE), 'e');
- assert map.get(Converter.VALUE).getClass().equals(Character.class);
+ assertEquals(map.get(VALUE), 'e');
+ assert map.get(VALUE).getClass().equals(Character.class);
Character s2 = 'e';
map = this.converter.convert(s2, Map.class);
assert map.size() == 1;
- assertEquals(map.get(Converter.VALUE), 'e');
- assert map.get(Converter.VALUE).getClass().equals(Character.class);
+ assertEquals(map.get(VALUE), 'e');
+ assert map.get(VALUE).getClass().equals(Character.class);
}
@Test
@@ -3639,8 +3630,8 @@ void testBigIntegerToMap()
BigInteger bi = BigInteger.valueOf(1234567890123456L);
Map, ?> map = this.converter.convert(bi, Map.class);
assert map.size() == 1;
- assertEquals(map.get(Converter.VALUE), bi);
- assert map.get(Converter.VALUE).getClass().equals(BigInteger.class);
+ assertEquals(map.get(VALUE), bi);
+ assert map.get(VALUE).getClass().equals(BigInteger.class);
}
@Test
@@ -3649,8 +3640,8 @@ void testBigDecimalToMap()
BigDecimal bd = new BigDecimal("3.1415926535897932384626433");
Map, ?> map = this.converter.convert(bd, Map.class);
assert map.size() == 1;
- assertEquals(map.get(Converter.VALUE), bd);
- assert map.get(Converter.VALUE).getClass().equals(BigDecimal.class);
+ assertEquals(map.get(VALUE), bd);
+ assert map.get(VALUE).getClass().equals(BigDecimal.class);
}
@Test
@@ -3659,8 +3650,8 @@ void testAtomicBooleanToMap()
AtomicBoolean ab = new AtomicBoolean(true);
Map, ?> map = this.converter.convert(ab, Map.class);
assert map.size() == 1;
- assertEquals(map.get(Converter.VALUE), ab);
- assert map.get(Converter.VALUE).getClass().equals(AtomicBoolean.class);
+ assertEquals(map.get(VALUE), ab);
+ assert map.get(VALUE).getClass().equals(AtomicBoolean.class);
}
@Test
@@ -3669,8 +3660,8 @@ void testAtomicIntegerToMap()
AtomicInteger ai = new AtomicInteger(123456789);
Map, ?> map = this.converter.convert(ai, Map.class);
assert map.size() == 1;
- assertEquals(map.get(Converter.VALUE), ai);
- assert map.get(Converter.VALUE).getClass().equals(AtomicInteger.class);
+ assertEquals(map.get(VALUE), ai);
+ assert map.get(VALUE).getClass().equals(AtomicInteger.class);
}
@Test
@@ -3679,8 +3670,8 @@ void testAtomicLongToMap()
AtomicLong al = new AtomicLong(12345678901234567L);
Map, ?> map = this.converter.convert(al, Map.class);
assert map.size() == 1;
- assertEquals(map.get(Converter.VALUE), al);
- assert map.get(Converter.VALUE).getClass().equals(AtomicLong.class);
+ assertEquals(map.get(VALUE), al);
+ assert map.get(VALUE).getClass().equals(AtomicLong.class);
}
@Test
@@ -3689,7 +3680,7 @@ void testClassToMap()
Class> clazz = ConverterTest.class;
Map, ?> map = this.converter.convert(clazz, Map.class);
assert map.size() == 1;
- assertEquals(map.get(Converter.VALUE), clazz);
+ assertEquals(map.get(VALUE), clazz);
}
@Test
@@ -3698,8 +3689,8 @@ void testUUIDToMap()
UUID uuid = new UUID(1L, 2L);
Map, ?> map = this.converter.convert(uuid, Map.class);
assert map.size() == 1;
- assertEquals(map.get(Converter.VALUE), uuid);
- assert map.get(Converter.VALUE).getClass().equals(UUID.class);
+ assertEquals(map.get(VALUE), uuid);
+ assert map.get(VALUE).getClass().equals(UUID.class);
}
@Test
@@ -3708,8 +3699,8 @@ void testCalendarToMap()
Calendar cal = Calendar.getInstance();
Map, ?> map = this.converter.convert(cal, Map.class);
assert map.size() == 1;
- assertEquals(map.get(Converter.VALUE), cal);
- assert map.get(Converter.VALUE) instanceof Calendar;
+ assertEquals(map.get(VALUE), cal);
+ assert map.get(VALUE) instanceof Calendar;
}
@Test
@@ -3718,8 +3709,8 @@ void testDateToMap()
Date now = new Date();
Map, ?> map = this.converter.convert(now, Map.class);
assert map.size() == 1;
- assertEquals(map.get(Converter.VALUE), now);
- assert map.get(Converter.VALUE).getClass().equals(Date.class);
+ assertEquals(map.get(VALUE), now);
+ assert map.get(VALUE).getClass().equals(Date.class);
}
@Test
@@ -3728,8 +3719,8 @@ void testSqlDateToMap()
java.sql.Date now = new java.sql.Date(System.currentTimeMillis());
Map, ?> map = this.converter.convert(now, Map.class);
assert map.size() == 1;
- assertEquals(map.get(Converter.VALUE), now);
- assert map.get(Converter.VALUE).getClass().equals(java.sql.Date.class);
+ assertEquals(map.get(VALUE), now);
+ assert map.get(VALUE).getClass().equals(java.sql.Date.class);
}
@Test
@@ -3738,8 +3729,8 @@ void testTimestampToMap()
Timestamp now = new Timestamp(System.currentTimeMillis());
Map, ?> map = this.converter.convert(now, Map.class);
assert map.size() == 1;
- assertEquals(map.get(Converter.VALUE), now);
- assert map.get(Converter.VALUE).getClass().equals(Timestamp.class);
+ assertEquals(map.get(VALUE), now);
+ assert map.get(VALUE).getClass().equals(Timestamp.class);
}
@Test
@@ -3748,8 +3739,8 @@ void testLocalDateToMap()
LocalDate now = LocalDate.now();
Map, ?> map = this.converter.convert(now, Map.class);
assert map.size() == 1;
- assertEquals(map.get(Converter.VALUE), now);
- assert map.get(Converter.VALUE).getClass().equals(LocalDate.class);
+ assertEquals(map.get(VALUE), now);
+ assert map.get(VALUE).getClass().equals(LocalDate.class);
}
@Test
@@ -3758,8 +3749,8 @@ void testLocalDateTimeToMap()
LocalDateTime now = LocalDateTime.now();
Map, ?> map = this.converter.convert(now, Map.class);
assert map.size() == 1;
- assertEquals(map.get(Converter.VALUE), now);
- assert map.get(Converter.VALUE).getClass().equals(LocalDateTime.class);
+ assertEquals(map.get(VALUE), now);
+ assert map.get(VALUE).getClass().equals(LocalDateTime.class);
}
@Test
@@ -3768,8 +3759,8 @@ void testZonedDateTimeToMap()
ZonedDateTime now = ZonedDateTime.now();
Map, ?> map = this.converter.convert(now, Map.class);
assert map.size() == 1;
- assertEquals(map.get(Converter.VALUE), now);
- assert map.get(Converter.VALUE).getClass().equals(ZonedDateTime.class);
+ assertEquals(map.get(VALUE), now);
+ assert map.get(VALUE).getClass().equals(ZonedDateTime.class);
}
@Test