diff --git a/src/main/java/com/cedarsoftware/util/convert/Converter.java b/src/main/java/com/cedarsoftware/util/convert/Converter.java index b09592b9..e7be99bc 100644 --- a/src/main/java/com/cedarsoftware/util/convert/Converter.java +++ b/src/main/java/com/cedarsoftware/util/convert/Converter.java @@ -17,6 +17,7 @@ import java.time.Period; import java.time.Year; import java.time.YearMonth; +import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.AbstractMap; import java.util.Calendar; @@ -676,6 +677,7 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(MonthDay.class, String.class), StringConversions::toString); DEFAULT_FACTORY.put(pair(YearMonth.class, String.class), StringConversions::toString); DEFAULT_FACTORY.put(pair(Period.class, String.class), StringConversions::toString); + DEFAULT_FACTORY.put(pair(ZoneId.class, String.class), StringConversions::toString); DEFAULT_FACTORY.put(pair(OffsetTime.class, String.class), OffsetTimeConversions::toString); DEFAULT_FACTORY.put(pair(OffsetDateTime.class, String.class), OffsetDateTimeConversions::toString); DEFAULT_FACTORY.put(pair(Year.class, String.class), YearConversions::toString); @@ -710,7 +712,12 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(Map.class, Instant.class), MapConversions::toInstant); DEFAULT_FACTORY.put(pair(OffsetDateTime.class, Instant.class), OffsetDateTimeConversions::toInstant); -// java.time.ZoneId = com.cedarsoftware.util.io.DEFAULT_FACTORY.ZoneIdFactory + // ZoneId conversions supported + DEFAULT_FACTORY.put(pair(Void.class, ZoneId.class), VoidConversions::toNull); + DEFAULT_FACTORY.put(pair(ZoneId.class, ZoneId.class), Converter::identity); + DEFAULT_FACTORY.put(pair(String.class, ZoneId.class), StringConversions::toZoneId); + DEFAULT_FACTORY.put(pair(Map.class, ZoneId.class), MapConversions::toZoneId); + // java.time.ZoneOffset = com.cedarsoftware.util.io.DEFAULT_FACTORY.ZoneOffsetFactory // java.time.ZoneRegion = com.cedarsoftware.util.io.DEFAULT_FACTORY.ZoneIdFactory @@ -830,6 +837,7 @@ private static void buildFactoryConversions() { DEFAULT_FACTORY.put(pair(MonthDay.class, Map.class), MonthDayConversions::toMap); DEFAULT_FACTORY.put(pair(YearMonth.class, Map.class), YearMonthConversions::toMap); DEFAULT_FACTORY.put(pair(Period.class, Map.class), PeriodConversions::toMap); + DEFAULT_FACTORY.put(pair(ZoneId.class, Map.class), ZoneIdConversions::toMap); DEFAULT_FACTORY.put(pair(Class.class, Map.class), MapConversions::initMap); DEFAULT_FACTORY.put(pair(UUID.class, Map.class), MapConversions::initMap); DEFAULT_FACTORY.put(pair(Calendar.class, Map.class), MapConversions::initMap); diff --git a/src/main/java/com/cedarsoftware/util/convert/MapConversions.java b/src/main/java/com/cedarsoftware/util/convert/MapConversions.java index ea178f3b..d1fb44dd 100644 --- a/src/main/java/com/cedarsoftware/util/convert/MapConversions.java +++ b/src/main/java/com/cedarsoftware/util/convert/MapConversions.java @@ -14,6 +14,7 @@ import java.time.Period; import java.time.Year; import java.time.YearMonth; +import java.time.ZoneId; import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.util.Calendar; @@ -325,6 +326,16 @@ static Period toPeriod(Object from, Converter converter, ConverterOptions option } } + static ZoneId toZoneId(Object from, Converter converter, ConverterOptions options) { + Map map = (Map) from; + if (map.containsKey(ZONE)) { + ZoneId zoneId = converter.convert(map.get(ZONE), ZoneId.class, options); + return zoneId; + } else { + return fromSingleKey(from, converter, options, ZONE, ZoneId.class); + } + } + static Year toYear(Object from, Converter converter, ConverterOptions options) { return fromSingleKey(from, converter, options, YEAR, Year.class); } diff --git a/src/main/java/com/cedarsoftware/util/convert/StringConversions.java b/src/main/java/com/cedarsoftware/util/convert/StringConversions.java index 08d72d2a..5ed8c4f2 100644 --- a/src/main/java/com/cedarsoftware/util/convert/StringConversions.java +++ b/src/main/java/com/cedarsoftware/util/convert/StringConversions.java @@ -17,6 +17,7 @@ import java.time.Period; import java.time.Year; import java.time.YearMonth; +import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; @@ -393,6 +394,19 @@ static ZonedDateTime toZonedDateTime(Object from, Converter converter, Converter return toZonedDateTime(from, options); } + static ZoneId toZoneId(Object from, Converter converter, ConverterOptions options) { + String s = StringUtilities.trimToNull(asString(from)); + if (s == null) { + return null; + } + try { + return ZoneId.of(s); + } + catch (Exception e) { + throw new IllegalArgumentException("Unknown time-zone ID: '" + s + "'"); + } + } + static OffsetDateTime toOffsetDateTime(Object from, Converter converter, ConverterOptions options) { String s = StringUtilities.trimToNull(asString(from)); if (s == null) { @@ -465,7 +479,6 @@ static byte[] toByteArray(Object from, ConverterOptions options) { return s.getBytes(options.getCharset()); } - static byte[] toByteArray(Object from, Converter converter, ConverterOptions options) { return toByteArray(from, options); } diff --git a/src/main/java/com/cedarsoftware/util/convert/ZoneIdConversions.java b/src/main/java/com/cedarsoftware/util/convert/ZoneIdConversions.java new file mode 100644 index 00000000..ef2bb81c --- /dev/null +++ b/src/main/java/com/cedarsoftware/util/convert/ZoneIdConversions.java @@ -0,0 +1,35 @@ +package com.cedarsoftware.util.convert; + +import java.time.ZoneId; +import java.util.Map; + +import com.cedarsoftware.util.CompactLinkedMap; + +/** + * @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. + */ +public final class ZoneIdConversions { + + private ZoneIdConversions() {} + + static Map toMap(Object from, Converter converter, ConverterOptions options) { + ZoneId zoneID = (ZoneId) from; + Map target = new CompactLinkedMap<>(); + target.put("zone", zoneID.toString()); + return target; + } +} diff --git a/src/test/java/com/cedarsoftware/util/convert/ConverterEverythingTest.java b/src/test/java/com/cedarsoftware/util/convert/ConverterEverythingTest.java index 24602b2f..a0a1d508 100644 --- a/src/test/java/com/cedarsoftware/util/convert/ConverterEverythingTest.java +++ b/src/test/java/com/cedarsoftware/util/convert/ConverterEverythingTest.java @@ -6,6 +6,7 @@ import java.time.Period; import java.time.Year; import java.time.YearMonth; +import java.time.ZoneId; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -173,7 +174,7 @@ class ConverterEverythingTest { new BigDecimal("128"), (byte)-128 }, }); TEST_FACTORY.put(pair(Number.class, Byte.class), new Object[][] { - + { -2L, (byte) -2 }, }); TEST_FACTORY.put(pair(Map.class, Byte.class), new Object[][] { { mapOf("_v", "-1"), (byte) -1 }, @@ -337,6 +338,31 @@ class ConverterEverythingTest }); TEST_FACTORY.put(pair(Number.class, Year.class), new Object[][] { { (byte)101, new IllegalArgumentException("Unsupported conversion, source type [Byte (101)] target type 'Year'") }, + { (short)2024, Year.of(2024) }, + }); + + // ZoneId + ZoneId NY_Z = ZoneId.of("America/New_York"); + ZoneId TOKYO_Z = ZoneId.of("Asia/Tokyo"); + TEST_FACTORY.put(pair(Void.class, ZoneId.class), new Object[][] { + { null, null }, + }); + TEST_FACTORY.put(pair(ZoneId.class, ZoneId.class), new Object[][] { + { NY_Z, NY_Z }, + { TOKYO_Z, TOKYO_Z }, + }); + TEST_FACTORY.put(pair(String.class, ZoneId.class), new Object[][] { + { "America/New_York", NY_Z }, + { "Asia/Tokyo", TOKYO_Z }, + { "America/Cincinnati", new IllegalArgumentException("Unknown time-zone ID: 'America/Cincinnati'") }, + }); + TEST_FACTORY.put(pair(Map.class, ZoneId.class), new Object[][] { + { mapOf("_v", "America/New_York"), NY_Z }, + { mapOf("_v", NY_Z), NY_Z }, + { mapOf("zone", NY_Z), NY_Z }, + { mapOf("_v", "Asia/Tokyo"), TOKYO_Z }, + { mapOf("_v", TOKYO_Z), TOKYO_Z }, + { mapOf("zone", mapOf("_v", TOKYO_Z)), TOKYO_Z }, }); } @@ -388,7 +414,9 @@ void testEverything() { System.err.println("{ " + getShortName(sourceClass) + ".class ==> " + getShortName(targetClass) + ".class }"); System.err.print("testPair[" + i + "] = "); if (testPair.length == 2) { - System.err.println("{ " + testPair[0].toString() + ", " + testPair[1].toString() + " }"); + String pair0 = testPair[0] == null ? "null" : testPair[0].toString(); + String pair1 = testPair[1] == null ? "null" : testPair[1].toString(); + System.err.println("{ " + pair0 + ", " + pair1 + " }"); } System.err.println(); e.printStackTrace(); @@ -401,7 +429,7 @@ void testEverything() { } if (neededTests > 0) { - System.err.println("Conversions needing tests: " + neededTests); + System.err.println(neededTests + " tests need to be added."); System.err.flush(); } if (failed) {