From a13f581a65bdb8e9472d6e2d2082d4b674baedd4 Mon Sep 17 00:00:00 2001 From: Rob Bygrave Date: Fri, 26 Aug 2022 13:15:55 +1200 Subject: [PATCH] Refactor ScalarTypeBaseDateTime, merge into ScalarTypeUtils both IsoJsonDateTimeParser and DecimalUtils That is, merge the static util methods into ScalarTypeUtils --- .../core/type/IsoJsonDateTimeParser.java | 21 ------- .../core/type/ScalarTypeBaseDateTime.java | 6 +- ...DecimalUtils.java => ScalarTypeUtils.java} | 56 ++++++++++++------- .../io/ebean/core/type/DecimalUtilsTest.java | 8 +-- .../core/type/IsoJsonDateTimeParserTest.java | 6 +- .../server/type/ScalarTypeCalendar.java | 4 +- .../server/type/ScalarTypeDuration.java | 4 +- .../server/type/ScalarTypeOffsetDateTime.java | 4 +- .../server/type/ScalarTypeTimestamp.java | 4 +- .../server/type/ScalarTypeUtilDate.java | 4 +- .../server/type/ScalarTypeCalendarTest.java | 4 +- .../type/ScalarTypeDurationWithNanosTest.java | 6 +- .../type/ScalarTypeOffsetDateTimeTest.java | 4 +- .../server/type/ScalarTypeTimestampTest.java | 4 +- .../server/type/ScalarTypeUtilDateTest.java | 4 +- .../type/ScalarTypeZonedDateTimeTest.java | 4 +- 16 files changed, 69 insertions(+), 74 deletions(-) delete mode 100644 ebean-core-type/src/main/java/io/ebean/core/type/IsoJsonDateTimeParser.java rename ebean-core-type/src/main/java/io/ebean/core/type/{DecimalUtils.java => ScalarTypeUtils.java} (63%) diff --git a/ebean-core-type/src/main/java/io/ebean/core/type/IsoJsonDateTimeParser.java b/ebean-core-type/src/main/java/io/ebean/core/type/IsoJsonDateTimeParser.java deleted file mode 100644 index d269d0b32..000000000 --- a/ebean-core-type/src/main/java/io/ebean/core/type/IsoJsonDateTimeParser.java +++ /dev/null @@ -1,21 +0,0 @@ -package io.ebean.core.type; - -import java.time.Instant; -import java.time.format.DateTimeFormatter; -import java.time.format.DateTimeFormatterBuilder; - -public final class IsoJsonDateTimeParser { - - private static final DateTimeFormatter ISO_MILLIS = new DateTimeFormatterBuilder() - .parseCaseInsensitive() - .appendInstant(3) - .toFormatter(); - - public static Instant parseIso(String jsonDateTime) { - return Instant.parse(jsonDateTime); - } - - public static String formatIso(Instant value) { - return ISO_MILLIS.format(value); - } -} diff --git a/ebean-core-type/src/main/java/io/ebean/core/type/ScalarTypeBaseDateTime.java b/ebean-core-type/src/main/java/io/ebean/core/type/ScalarTypeBaseDateTime.java index a627c7e81..0ee2cb82f 100644 --- a/ebean-core-type/src/main/java/io/ebean/core/type/ScalarTypeBaseDateTime.java +++ b/ebean-core-type/src/main/java/io/ebean/core/type/ScalarTypeBaseDateTime.java @@ -69,7 +69,7 @@ public abstract class ScalarTypeBaseDateTime extends ScalarTypeBase { * Convert the value to ISO8601 format. */ protected T fromJsonISO8601(String value) { - return convertFromInstant(IsoJsonDateTimeParser.parseIso(value)); + return convertFromInstant(ScalarTypeUtils.parseInstant(value)); } @Override @@ -95,7 +95,7 @@ public abstract class ScalarTypeBaseDateTime extends ScalarTypeBase { * Helper method that given epoch seconds and nanos return a JSON nanos formatted string. */ protected String toJsonNanos(long epochSecs, int nanos) { - return DecimalUtils.toDecimal(epochSecs, nanos); + return ScalarTypeUtils.toDecimal(epochSecs, nanos); } @Override @@ -106,7 +106,7 @@ public abstract class ScalarTypeBaseDateTime extends ScalarTypeBase { } case VALUE_NUMBER_FLOAT: { BigDecimal value = parser.getDecimalValue(); - Timestamp timestamp = DecimalUtils.toTimestamp(value); + Timestamp timestamp = ScalarTypeUtils.toTimestamp(value); return convertFromTimestamp(timestamp); } default: { diff --git a/ebean-core-type/src/main/java/io/ebean/core/type/DecimalUtils.java b/ebean-core-type/src/main/java/io/ebean/core/type/ScalarTypeUtils.java similarity index 63% rename from ebean-core-type/src/main/java/io/ebean/core/type/DecimalUtils.java rename to ebean-core-type/src/main/java/io/ebean/core/type/ScalarTypeUtils.java index 9259e05e2..1e7915316 100644 --- a/ebean-core-type/src/main/java/io/ebean/core/type/DecimalUtils.java +++ b/ebean-core-type/src/main/java/io/ebean/core/type/ScalarTypeUtils.java @@ -1,25 +1,11 @@ package io.ebean.core.type; -/* - * Copyright 2013 FasterXML.com - * - * 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 - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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. - */ - import java.math.BigDecimal; import java.sql.Timestamp; import java.time.Duration; import java.time.Instant; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; /** * Utilities to aid in the translation of decimal types to/from multiple parts. @@ -27,26 +13,50 @@ import java.time.Instant; * @author Nick Williams * @since 2.2.0 */ -public final class DecimalUtils { +public final class ScalarTypeUtils { private static final char[] ZEROES = new char[]{'0', '0', '0', '0', '0', '0', '0', '0', '0'}; private static final BigDecimal ONE_BILLION = new BigDecimal(1000000000L); - private DecimalUtils() { - throw new RuntimeException("DecimalUtils cannot be instantiated."); + private static final DateTimeFormatter ISO_MILLIS = new DateTimeFormatterBuilder() + .parseCaseInsensitive() + .appendInstant(3) + .toFormatter(); + + /** + * Parse using ISO8601. + */ + public static Instant parseInstant(String jsonDateTime) { + return Instant.parse(jsonDateTime); } + /** + * Format using ISO8601. + */ + public static String formatInstant(Instant value) { + return ISO_MILLIS.format(value); + } + + /** + * Convert decimal to duration with nanos. + */ public static Duration toDuration(BigDecimal value) { long seconds = value.longValue(); int nanoseconds = extractNanosecondDecimal(value, seconds); return Duration.ofSeconds(seconds, nanoseconds); } + /** + * Convert duration to decimal with nanos. + */ public static BigDecimal toDecimal(Duration instant) { return new BigDecimal(toDecimal(instant.getSeconds(), instant.getNano())); } + /** + * Convert decimal to timestamp with nanos. + */ public static Timestamp toTimestamp(BigDecimal value) { long seconds = value.longValue(); int nanoseconds = extractNanosecondDecimal(value, seconds); @@ -55,12 +65,18 @@ public final class DecimalUtils { return ts; } + /** + * Convert timestamp to decimal with nanos. + */ public static BigDecimal toDecimal(Timestamp instant) { long millis = instant.getTime(); long secs = millis / 1000; return new BigDecimal(toDecimal(secs, instant.getNanos())); } + /** + * Convert to decimal string with nanos. + */ public static String toDecimal(long seconds, int nanoseconds) { StringBuilder string = new StringBuilder(Integer.toString(nanoseconds)); if (string.length() < 9) @@ -68,7 +84,7 @@ public final class DecimalUtils { return seconds + "." + string; } - static int extractNanosecondDecimal(BigDecimal value, long integer) { + private static int extractNanosecondDecimal(BigDecimal value, long integer) { return value.subtract(new BigDecimal(integer)).multiply(ONE_BILLION).intValue(); } } diff --git a/ebean-core-type/src/test/java/io/ebean/core/type/DecimalUtilsTest.java b/ebean-core-type/src/test/java/io/ebean/core/type/DecimalUtilsTest.java index 44bc322f2..91a7c631c 100644 --- a/ebean-core-type/src/test/java/io/ebean/core/type/DecimalUtilsTest.java +++ b/ebean-core-type/src/test/java/io/ebean/core/type/DecimalUtilsTest.java @@ -16,8 +16,8 @@ class DecimalUtilsTest { Instant now = Instant.now(); Timestamp sourceTimestamp = Timestamp.from(now); - BigDecimal decimal = DecimalUtils.toDecimal(sourceTimestamp); - Timestamp timestamp = DecimalUtils.toTimestamp(decimal); + BigDecimal decimal = ScalarTypeUtils.toDecimal(sourceTimestamp); + Timestamp timestamp = ScalarTypeUtils.toTimestamp(decimal); assertEquals(now, timestamp.toInstant()); assertEquals(sourceTimestamp, timestamp); @@ -27,8 +27,8 @@ class DecimalUtilsTest { void testDuration() { Duration duration = Duration.ofSeconds(323, 1500000); - BigDecimal bigDecimal = DecimalUtils.toDecimal(duration); - Duration duration1 = DecimalUtils.toDuration(bigDecimal); + BigDecimal bigDecimal = ScalarTypeUtils.toDecimal(duration); + Duration duration1 = ScalarTypeUtils.toDuration(bigDecimal); assertEquals(duration, duration1); assertEquals("PT5M23.0015S", duration1.toString()); diff --git a/ebean-core-type/src/test/java/io/ebean/core/type/IsoJsonDateTimeParserTest.java b/ebean-core-type/src/test/java/io/ebean/core/type/IsoJsonDateTimeParserTest.java index b854881b8..12740b552 100644 --- a/ebean-core-type/src/test/java/io/ebean/core/type/IsoJsonDateTimeParserTest.java +++ b/ebean-core-type/src/test/java/io/ebean/core/type/IsoJsonDateTimeParserTest.java @@ -8,7 +8,7 @@ import static org.assertj.core.api.Assertions.assertThat; class IsoJsonDateTimeParserTest { - private IsoJsonDateTimeParser parser = new IsoJsonDateTimeParser(); + private ScalarTypeUtils parser = new ScalarTypeUtils(); @Test void parseFormat_when_hasMillis() { @@ -41,8 +41,8 @@ class IsoJsonDateTimeParserTest { } private void parseAndFormat(String input, String expected) { - Instant timestamp = parser.parseIso(input); - String format = parser.formatIso(timestamp); + Instant timestamp = parser.parseInstant(input); + String format = parser.formatInstant(timestamp); assertThat(format).isEqualTo(expected); } } diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeCalendar.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeCalendar.java index 6584d8360..50ee64539 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeCalendar.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeCalendar.java @@ -12,7 +12,7 @@ import java.sql.Types; import java.time.Instant; import java.util.Calendar; -import static io.ebean.core.type.IsoJsonDateTimeParser.formatIso; +import static io.ebean.core.type.ScalarTypeUtils.formatInstant; /** * ScalarType for java.util.Calendar. @@ -66,7 +66,7 @@ final class ScalarTypeCalendar extends ScalarTypeBaseDateTime { @Override protected String toJsonISO8601(Calendar value) { - return formatIso(value.toInstant()); + return formatInstant(value.toInstant()); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeDuration.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeDuration.java index 34899fe68..2e5a29996 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeDuration.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeDuration.java @@ -27,11 +27,11 @@ class ScalarTypeDuration extends ScalarTypeBase { } BigDecimal convertToBigDecimal(Duration value) { - return (value == null) ? null : DecimalUtils.toDecimal(value); + return (value == null) ? null : ScalarTypeUtils.toDecimal(value); } Duration convertFromBigDecimal(BigDecimal value) { - return (value == null) ? null : DecimalUtils.toDuration(value); + return (value == null) ? null : ScalarTypeUtils.toDuration(value); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeOffsetDateTime.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeOffsetDateTime.java index b105f646a..0f0b053cf 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeOffsetDateTime.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeOffsetDateTime.java @@ -9,7 +9,7 @@ import java.time.Instant; import java.time.OffsetDateTime; import java.time.ZoneId; -import static io.ebean.core.type.IsoJsonDateTimeParser.formatIso; +import static io.ebean.core.type.ScalarTypeUtils.formatInstant; /** * ScalarType for java.sql.Timestamp. @@ -30,7 +30,7 @@ final class ScalarTypeOffsetDateTime extends ScalarTypeBaseDateTime { @Override protected String toJsonISO8601(Timestamp value) { - return formatIso(value.toInstant()); + return formatInstant(value.toInstant()); } @Override diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeUtilDate.java b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeUtilDate.java index f171afdef..ae8d670d5 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeUtilDate.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/type/ScalarTypeUtilDate.java @@ -13,7 +13,7 @@ import java.sql.Types; import java.time.Instant; import java.util.Date; -import static io.ebean.core.type.IsoJsonDateTimeParser.formatIso; +import static io.ebean.core.type.ScalarTypeUtils.formatInstant; /** * ScalarType for java.util.Date. @@ -33,7 +33,7 @@ final class ScalarTypeUtilDate { @Override protected String toJsonISO8601(Date value) { - return formatIso(value.toInstant()); + return formatInstant(value.toInstant()); } @Override diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/type/ScalarTypeCalendarTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/type/ScalarTypeCalendarTest.java index 0e6d4a588..1004ce2ac 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/type/ScalarTypeCalendarTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/type/ScalarTypeCalendarTest.java @@ -1,7 +1,7 @@ package io.ebeaninternal.server.type; import io.ebean.config.JsonConfig; -import io.ebean.core.type.IsoJsonDateTimeParser; +import io.ebean.core.type.ScalarTypeUtils; import org.junit.jupiter.api.Test; import java.sql.Types; @@ -18,7 +18,7 @@ public class ScalarTypeCalendarTest { Calendar instance = Calendar.getInstance(); String asUtc = type.toJsonISO8601(instance); - Calendar calendar = type.convertFromInstant(IsoJsonDateTimeParser.parseIso(asUtc)); //type.fromJsonISO8601(asUtc); + Calendar calendar = type.convertFromInstant(ScalarTypeUtils.parseInstant(asUtc)); //type.fromJsonISO8601(asUtc); assertThat(instance).isEqualTo(calendar); } diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/type/ScalarTypeDurationWithNanosTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/type/ScalarTypeDurationWithNanosTest.java index bbe446746..dd94703f2 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/type/ScalarTypeDurationWithNanosTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/type/ScalarTypeDurationWithNanosTest.java @@ -1,6 +1,6 @@ package io.ebeaninternal.server.type; -import io.ebean.core.type.DecimalUtils; +import io.ebean.core.type.ScalarTypeUtils; import org.junit.jupiter.api.Test; import java.io.ByteArrayInputStream; @@ -41,7 +41,7 @@ class ScalarTypeDurationWithNanosTest { @Test void testToJdbcType() throws Exception { Duration duration = Duration.ofSeconds(323, 1500000); - BigDecimal bigDecimal = DecimalUtils.toDecimal(duration); + BigDecimal bigDecimal = ScalarTypeUtils.toDecimal(duration); Object val1 = type.toJdbcType(duration); Object val2 = type.toJdbcType(bigDecimal); @@ -53,7 +53,7 @@ class ScalarTypeDurationWithNanosTest { @Test void testToBeanType() throws Exception { Duration duration = Duration.ofSeconds(323, 1500000); - BigDecimal bigDecimal = DecimalUtils.toDecimal(duration); + BigDecimal bigDecimal = ScalarTypeUtils.toDecimal(duration); Duration val1 = type.toBeanType(duration); Duration val2 = type.toBeanType(bigDecimal); diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/type/ScalarTypeOffsetDateTimeTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/type/ScalarTypeOffsetDateTimeTest.java index 53c02bde7..be8a7aefb 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/type/ScalarTypeOffsetDateTimeTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/type/ScalarTypeOffsetDateTimeTest.java @@ -1,7 +1,7 @@ package io.ebeaninternal.server.type; import io.ebean.config.JsonConfig; -import io.ebean.core.type.IsoJsonDateTimeParser; +import io.ebean.core.type.ScalarTypeUtils; import org.junit.jupiter.api.Test; import java.sql.Timestamp; @@ -123,7 +123,7 @@ public class ScalarTypeOffsetDateTimeTest { OffsetDateTime now = OffsetDateTime.now(); String asJson = typeIso.toJsonISO8601(now); - OffsetDateTime value = typeIso.convertFromInstant(IsoJsonDateTimeParser.parseIso(asJson)); //typeIso.fromJsonISO8601(asJson); + OffsetDateTime value = typeIso.convertFromInstant(ScalarTypeUtils.parseInstant(asJson)); //typeIso.fromJsonISO8601(asJson); assertThat(now).isEqualToIgnoringNanos(value); } } diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/type/ScalarTypeTimestampTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/type/ScalarTypeTimestampTest.java index 176813c48..3b70aef74 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/type/ScalarTypeTimestampTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/type/ScalarTypeTimestampTest.java @@ -1,7 +1,7 @@ package io.ebeaninternal.server.type; import io.ebean.config.JsonConfig; -import io.ebean.core.type.IsoJsonDateTimeParser; +import io.ebean.core.type.ScalarTypeUtils; import org.junit.jupiter.api.Test; import java.sql.Timestamp; @@ -18,7 +18,7 @@ public class ScalarTypeTimestampTest { Timestamp now = new Timestamp(System.currentTimeMillis()); String asJson = typeIso.toJsonISO8601(now); - Timestamp value = typeIso.convertFromInstant(IsoJsonDateTimeParser.parseIso(asJson)); //typeIso.fromJsonISO8601(asJson); + Timestamp value = typeIso.convertFromInstant(ScalarTypeUtils.parseInstant(asJson)); //typeIso.fromJsonISO8601(asJson); assertThat(now).isEqualTo(value); } } diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/type/ScalarTypeUtilDateTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/type/ScalarTypeUtilDateTest.java index 18fe8aac4..4824c1fcb 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/type/ScalarTypeUtilDateTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/type/ScalarTypeUtilDateTest.java @@ -1,7 +1,7 @@ package io.ebeaninternal.server.type; import io.ebean.config.JsonConfig; -import io.ebean.core.type.IsoJsonDateTimeParser; +import io.ebean.core.type.ScalarTypeUtils; import org.junit.jupiter.api.Test; import java.io.IOException; @@ -35,7 +35,7 @@ public class ScalarTypeUtilDateTest { Date now = new Date(); String asJson = typeIso.toJsonISO8601(now); - Instant instant = IsoJsonDateTimeParser.parseIso(asJson); + Instant instant = ScalarTypeUtils.parseInstant(asJson); Date value = new java.util.Date(instant.toEpochMilli()); // typeIso.fromJsonISO8601(asJson); assertThat(now).isEqualTo(value); } diff --git a/ebean-core/src/test/java/io/ebeaninternal/server/type/ScalarTypeZonedDateTimeTest.java b/ebean-core/src/test/java/io/ebeaninternal/server/type/ScalarTypeZonedDateTimeTest.java index 96bc8d7db..6938b0be0 100644 --- a/ebean-core/src/test/java/io/ebeaninternal/server/type/ScalarTypeZonedDateTimeTest.java +++ b/ebean-core/src/test/java/io/ebeaninternal/server/type/ScalarTypeZonedDateTimeTest.java @@ -1,7 +1,7 @@ package io.ebeaninternal.server.type; import io.ebean.config.JsonConfig; -import io.ebean.core.type.IsoJsonDateTimeParser; +import io.ebean.core.type.ScalarTypeUtils; import org.junit.jupiter.api.Test; import java.sql.Timestamp; @@ -125,7 +125,7 @@ public class ScalarTypeZonedDateTimeTest { ZonedDateTime now = ZonedDateTime.now(); String asJson = typeIso.toJsonISO8601(now); - ZonedDateTime value = type.convertFromInstant(IsoJsonDateTimeParser.parseIso(asJson)); //typeIso.fromJsonISO8601(asJson); + ZonedDateTime value = type.convertFromInstant(ScalarTypeUtils.parseInstant(asJson)); //typeIso.fromJsonISO8601(asJson); assertThat(now).isEqualTo(value); } }