diff --git a/src/main/java/com/cedarsoftware/util/convert/Converter.java b/src/main/java/com/cedarsoftware/util/convert/Converter.java index d3f837e8..06f97b77 100644 --- a/src/main/java/com/cedarsoftware/util/convert/Converter.java +++ b/src/main/java/com/cedarsoftware/util/convert/Converter.java @@ -718,12 +718,14 @@ private static void buildFactoryConversions() { // URL conversions CONVERSION_DB.put(pair(Void.class, URL.class), VoidConversions::toNull); CONVERSION_DB.put(pair(URL.class, URL.class), Converter::identity); + CONVERSION_DB.put(pair(URI.class, URL.class), UriConversions::toURL); CONVERSION_DB.put(pair(String.class, URL.class), StringConversions::toURL); CONVERSION_DB.put(pair(Map.class, URL.class), MapConversions::toURL); // URI Conversions CONVERSION_DB.put(pair(Void.class, URI.class), VoidConversions::toNull); CONVERSION_DB.put(pair(URI.class, URI.class), Converter::identity); + CONVERSION_DB.put(pair(URL.class, URI.class), UrlConversions::toURI); CONVERSION_DB.put(pair(String.class, URI.class), StringConversions::toURI); CONVERSION_DB.put(pair(Map.class, URI.class), MapConversions::toURI); @@ -897,7 +899,7 @@ private static void buildFactoryConversions() { CONVERSION_DB.put(pair(Timestamp.class, Map.class), TimestampConversions::toMap); CONVERSION_DB.put(pair(LocalDate.class, Map.class), LocalDateConversions::toMap); CONVERSION_DB.put(pair(LocalDateTime.class, Map.class), LocalDateTimeConversions::toMap); - CONVERSION_DB.put(pair(ZonedDateTime.class, Map.class), MapConversions::initMap); + CONVERSION_DB.put(pair(ZonedDateTime.class, Map.class), ZonedDateTimeConversions::toMap); CONVERSION_DB.put(pair(Duration.class, Map.class), DurationConversions::toMap); CONVERSION_DB.put(pair(Instant.class, Map.class), InstantConversions::toMap); CONVERSION_DB.put(pair(LocalTime.class, Map.class), LocalTimeConversions::toMap); diff --git a/src/main/java/com/cedarsoftware/util/convert/MapConversions.java b/src/main/java/com/cedarsoftware/util/convert/MapConversions.java index bf8fcba6..f187ae9f 100644 --- a/src/main/java/com/cedarsoftware/util/convert/MapConversions.java +++ b/src/main/java/com/cedarsoftware/util/convert/MapConversions.java @@ -373,12 +373,21 @@ static LocalDateTime toLocalDateTime(Object from, Converter converter) { static ZonedDateTime toZonedDateTime(Object from, Converter converter) { Map map = (Map) from; + if (map.containsKey(EPOCH_MILLIS)) { + return converter.convert(map.get(EPOCH_MILLIS), ZonedDateTime.class); + } + if (map.containsKey(DATE) && map.containsKey(TIME) && map.containsKey(ZONE)) { + LocalDate localDate = converter.convert(map.get(DATE), LocalDate.class); + LocalTime localTime = converter.convert(map.get(TIME), LocalTime.class); + ZoneId zoneId = converter.convert(map.get(ZONE), ZoneId.class); + return ZonedDateTime.of(localDate, localTime, zoneId); + } if (map.containsKey(ZONE) && map.containsKey(DATE_TIME)) { ZoneId zoneId = converter.convert(map.get(ZONE), ZoneId.class); LocalDateTime localDateTime = converter.convert(map.get(DATE_TIME), LocalDateTime.class); return ZonedDateTime.of(localDateTime, zoneId); } - return fromMap(from, converter, ZonedDateTime.class, ZONE, DATE_TIME); + return fromMap(from, converter, ZonedDateTime.class, DATE, TIME, ZONE); } static Class toClass(Object from, Converter converter) { diff --git a/src/main/java/com/cedarsoftware/util/convert/UriConversions.java b/src/main/java/com/cedarsoftware/util/convert/UriConversions.java index fe607321..2c72b3df 100644 --- a/src/main/java/com/cedarsoftware/util/convert/UriConversions.java +++ b/src/main/java/com/cedarsoftware/util/convert/UriConversions.java @@ -1,6 +1,7 @@ package com.cedarsoftware.util.convert; import java.net.URI; +import java.net.URL; import java.util.Map; import com.cedarsoftware.util.CompactLinkedMap; @@ -34,4 +35,13 @@ static Map toMap(Object from, Converter converter) { target.put(URI_KEY, uri.toString()); return target; } + + static URL toURL(Object from, Converter converter) { + URI uri = (URI) from; + try { + return uri.toURL(); + } catch (Exception e) { + throw new IllegalArgumentException("Unable to convert URI to URL, input URI: " + uri, e); + } + } } diff --git a/src/main/java/com/cedarsoftware/util/convert/UrlConversions.java b/src/main/java/com/cedarsoftware/util/convert/UrlConversions.java index 99f6da67..7271ed02 100644 --- a/src/main/java/com/cedarsoftware/util/convert/UrlConversions.java +++ b/src/main/java/com/cedarsoftware/util/convert/UrlConversions.java @@ -1,5 +1,6 @@ package com.cedarsoftware.util.convert; +import java.net.URI; import java.net.URL; import java.util.Map; @@ -28,10 +29,19 @@ final class UrlConversions { private UrlConversions() {} - static Map toMap(Object from, Converter converter) { + static Map toMap(Object from, Converter converter) { URL url = (URL) from; Map target = new CompactLinkedMap<>(); target.put(URL_KEY, url.toString()); return target; } + + static URI toURI(Object from, Converter converter) { + URL url = (URL) from; + try { + return url.toURI(); + } catch (Exception e) { + throw new IllegalArgumentException("Unable to convert URL to URI, input URL: " + url, e); + } + } } diff --git a/src/main/java/com/cedarsoftware/util/convert/ZonedDateTimeConversions.java b/src/main/java/com/cedarsoftware/util/convert/ZonedDateTimeConversions.java index 7b9d44f8..5a97eb82 100644 --- a/src/main/java/com/cedarsoftware/util/convert/ZonedDateTimeConversions.java +++ b/src/main/java/com/cedarsoftware/util/convert/ZonedDateTimeConversions.java @@ -12,8 +12,15 @@ import java.time.format.DateTimeFormatter; import java.util.Calendar; import java.util.Date; +import java.util.Map; import java.util.concurrent.atomic.AtomicLong; +import com.cedarsoftware.util.CompactLinkedMap; + +import static com.cedarsoftware.util.convert.MapConversions.DATE; +import static com.cedarsoftware.util.convert.MapConversions.TIME; +import static com.cedarsoftware.util.convert.MapConversions.ZONE; + /** * @author Kenny Partlow (kpartlow@gmail.com) *
@@ -109,4 +116,13 @@ static String toString(Object from, Converter converter) { ZonedDateTime zonedDateTime = (ZonedDateTime) from; return zonedDateTime.format(DateTimeFormatter.ISO_DATE_TIME); } + + static Map toMap(Object from, Converter converter) { + ZonedDateTime zdt = (ZonedDateTime) from; + Map target = new CompactLinkedMap<>(); + target.put(DATE, zdt.toLocalDate().toString()); + target.put(TIME, zdt.toLocalTime().toString()); + target.put(ZONE, zdt.getZone().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 43cb5d6b..e1c6720e 100644 --- a/src/test/java/com/cedarsoftware/util/convert/ConverterEverythingTest.java +++ b/src/test/java/com/cedarsoftware/util/convert/ConverterEverythingTest.java @@ -56,6 +56,7 @@ import static com.cedarsoftware.util.convert.Converter.pair; import static com.cedarsoftware.util.convert.MapConversions.COUNTRY; import static com.cedarsoftware.util.convert.MapConversions.DATE; +import static com.cedarsoftware.util.convert.MapConversions.DATE_TIME; import static com.cedarsoftware.util.convert.MapConversions.EPOCH_MILLIS; import static com.cedarsoftware.util.convert.MapConversions.LANGUAGE; import static com.cedarsoftware.util.convert.MapConversions.NANOS; @@ -94,6 +95,7 @@ // TODO: Enum and EnumSet conversions need to be added // TODO: URL to URI, URI to URL // TODO: MapConversions --> Var args of Object[]'s - show as 'OR' in message: [DATE, TIME], [epochMillis], [dateTime], [_V], or [VALUE] +// TODO: MapConversions --> Performance - containsKey() + get() ==> get() and null checks class ConverterEverythingTest { private static final String TOKYO = "Asia/Tokyo"; private static final ZoneId TOKYO_Z = ZoneId.of(TOKYO); @@ -317,6 +319,11 @@ private static void loadUriTests() { { mapOf(URI_KEY, "https://domain.com"), toURI("https://domain.com"), true}, { mapOf(URI_KEY, "bad uri"), new IllegalArgumentException("Cannot convert Map to URI. Malformed URI: 'bad uri'")}, }); + TEST_DB.put(pair(URL.class, URI.class), new Object[][]{ + { (Supplier) () -> { + try {return new URL("https://domain.com");} catch(Exception e){return null;} + }, toURI("https://domain.com"), true}, + }); } /** @@ -932,6 +939,14 @@ private static void loadZoneDateTimeTests() { {ldt("1970-01-01T09:00:00"), zdt("1970-01-01T00:00:00Z"), true}, {ldt("1970-01-01T09:00:00.000000001"), zdt("1970-01-01T00:00:00.000000001Z"), true}, }); + TEST_DB.put(pair(Map.class, ZonedDateTime.class), new Object[][]{ + {mapOf(VALUE, new AtomicLong(now)), Instant.ofEpochMilli(now).atZone(TOKYO_Z)}, + {mapOf(EPOCH_MILLIS, now), Instant.ofEpochMilli(now).atZone(TOKYO_Z)}, + {mapOf(DATE_TIME, "1970-01-01T00:00:00", ZONE, TOKYO), zdt("1970-01-01T00:00:00+09:00")}, + {mapOf(DATE, "1969-12-31", TIME, "23:59:59.999999999", ZONE, TOKYO), zdt("1969-12-31T23:59:59.999999999+09:00"), true}, + {mapOf(DATE, "1970-01-01", TIME, "00:00", ZONE, TOKYO), zdt("1970-01-01T00:00:00+09:00"), true}, + {mapOf(DATE, "1970-01-01", TIME, "00:00:00.000000001", ZONE, TOKYO), zdt("1970-01-01T00:00:00.000000001+09:00"), true}, + }); } /** diff --git a/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java b/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java index ea83284f..6f7d30ef 100644 --- a/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java +++ b/src/test/java/com/cedarsoftware/util/convert/ConverterTest.java @@ -48,6 +48,8 @@ import static com.cedarsoftware.util.convert.ConverterTest.fubar.foo; import static com.cedarsoftware.util.convert.MapConversions.DATE; import static com.cedarsoftware.util.convert.MapConversions.EPOCH_MILLIS; +import static com.cedarsoftware.util.convert.MapConversions.TIME; +import static com.cedarsoftware.util.convert.MapConversions.ZONE; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -3057,7 +3059,7 @@ void testMapToZonedDateTime() map.clear(); assertThatThrownBy(() -> this.converter.convert(map, ZonedDateTime.class)) .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("To convert from Map to ZonedDateTime the map must include one of the following: [zone, dateTime], [_v], or [value] with associated values"); + .hasMessageContaining("To convert from Map to ZonedDateTime the map must include one of the following: [date, time, zone], [_v], or [value] with associated values"); } @@ -3774,9 +3776,10 @@ void testZonedDateTimeToMap() { ZonedDateTime now = ZonedDateTime.now(); Map map = this.converter.convert(now, Map.class); - assert map.size() == 1; - assertEquals(map.get(VALUE), now); - assert map.get(VALUE).getClass().equals(ZonedDateTime.class); + assert map.size() == 3; + assert map.containsKey(DATE); + assert map.containsKey(TIME); + assert map.containsKey(ZONE); } @Test