From 33ab7eb7a5057e86f66c74e2d7bffcee115ca75a Mon Sep 17 00:00:00 2001 From: rbygrave Date: Thu, 13 Nov 2014 23:13:51 +1300 Subject: [PATCH] Add ScalarTypeLocalDate --- .../server/type/DefaultTypeManager.java | 11 ++++ .../server/type/ScalarTypeLocalDate.java | 56 +++++++++++++++++ .../server/type/ScalarTypeLocalDateTime.java | 44 +++++++++++++ .../server/type/ScalarTypeOffsetDateTime.java | 43 +++++++++++++ .../server/type/ScalarTypeLocalDateTest.java | 50 +++++++++++++++ .../type/ScalarTypeLocalDateTimeTest.java | 58 +++++++++++++++++ .../type/ScalarTypeOffsetDateTimeTest.java | 62 +++++++++++++++++++ 7 files changed, 324 insertions(+) create mode 100644 src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeLocalDate.java create mode 100644 src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeLocalDateTime.java create mode 100644 src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeOffsetDateTime.java create mode 100644 src/test/java/com/avaje/ebeaninternal/server/type/ScalarTypeLocalDateTest.java create mode 100644 src/test/java/com/avaje/ebeaninternal/server/type/ScalarTypeLocalDateTimeTest.java create mode 100644 src/test/java/com/avaje/ebeaninternal/server/type/ScalarTypeOffsetDateTimeTest.java diff --git a/src/main/java/com/avaje/ebeaninternal/server/type/DefaultTypeManager.java b/src/main/java/com/avaje/ebeaninternal/server/type/DefaultTypeManager.java index 9eed017de..bbff03a0c 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/type/DefaultTypeManager.java +++ b/src/main/java/com/avaje/ebeaninternal/server/type/DefaultTypeManager.java @@ -10,6 +10,7 @@ import java.sql.Date; import java.sql.Time; import java.sql.Timestamp; import java.sql.Types; +import java.time.OffsetDateTime; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; @@ -146,6 +147,7 @@ public final class DefaultTypeManager implements TypeManager, KnownImmutable { this.extraTypeFactory = new DefaultTypeFactory(config); initialiseStandard(clobType, blobType, config.isUuidStoreAsBinary()); + initialiseJavaTimeTypes(); initialiseJodaTypes(); if (bootupClasses != null) { @@ -602,6 +604,15 @@ public final class DefaultTypeManager implements TypeManager, KnownImmutable { return propParamTypes[1]; } + protected void initialiseJavaTimeTypes() { + if (ClassUtil.isPresent("java.time.LocalDate", this.getClass())) { + logger.debug("Registering java.time data types"); + typeMap.put(java.time.LocalDate.class, new ScalarTypeLocalDate()); + typeMap.put(java.time.LocalDateTime.class, new ScalarTypeLocalDateTime()); + typeMap.put(OffsetDateTime.class, new ScalarTypeOffsetDateTime()); + } + } + /** * Detect if Joda classes are in the classpath and if so register the Joda * data types. diff --git a/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeLocalDate.java b/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeLocalDate.java new file mode 100644 index 000000000..58685ff8c --- /dev/null +++ b/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeLocalDate.java @@ -0,0 +1,56 @@ +package com.avaje.ebeaninternal.server.type; + +import com.avaje.ebeaninternal.server.core.BasicTypeConverter; + +import java.sql.Date; +import java.sql.Timestamp; +import java.sql.Types; +import java.time.LocalDate; + +/** + * ScalarType for java.time.LocalDate. This maps to a JDBC Date. + */ +public class ScalarTypeLocalDate extends ScalarTypeBaseDate { + + public ScalarTypeLocalDate() { + super(LocalDate.class, false, Types.DATE); + } + + @Override + public long convertToMillis(Object value) { + return convertToDate((LocalDate) value).toInstant().toEpochMilli(); + } + + @Override + public LocalDate convertFromDate(Date ts) { + return ts.toLocalDate(); + } + + @Override + public Date convertToDate(LocalDate t) { + return Date.valueOf(t); + } + + @Override + public Object toJdbcType(Object value) { + if (value instanceof LocalDate) { + return Date.valueOf((LocalDate) value); + } + return BasicTypeConverter.toDate(value); + } + + @Override + public LocalDate toBeanType(Object value) { + if (value instanceof java.sql.Date) { + return ((java.sql.Date) value).toLocalDate(); + } + return (LocalDate) value; + } + + @Override + public LocalDate parseDateTime(long systemTimeMillis) { + return new Timestamp(systemTimeMillis).toLocalDateTime().toLocalDate(); + } + + +} diff --git a/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeLocalDateTime.java b/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeLocalDateTime.java new file mode 100644 index 000000000..3a937910b --- /dev/null +++ b/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeLocalDateTime.java @@ -0,0 +1,44 @@ +package com.avaje.ebeaninternal.server.type; + +import java.sql.Timestamp; +import java.sql.Types; +import java.time.*; + +/** + * ScalarType for java.sql.Timestamp. + */ +public class ScalarTypeLocalDateTime extends ScalarTypeBaseDateTime { + + public ScalarTypeLocalDateTime() { + super(LocalDateTime.class, true, Types.TIMESTAMP); + } + + @Override + public long convertToMillis(Object value) { + return ((LocalDateTime) value).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); + } + + @Override + public LocalDateTime convertFromTimestamp(Timestamp ts) { + return ts.toLocalDateTime(); + } + + @Override + public Timestamp convertToTimestamp(LocalDateTime t) { + + ZonedDateTime zonedDateTime = t.atZone(ZoneId.systemDefault()); + return Timestamp.from(zonedDateTime.toInstant()); + } + + @Override + public Object toJdbcType(Object value) { + if (value instanceof Timestamp) return value; + return convertToTimestamp((LocalDateTime)value); + } + + @Override + public LocalDateTime toBeanType(Object value) { + if (value instanceof LocalDateTime) return (LocalDateTime)value; + return convertFromTimestamp((Timestamp)value); + } +} diff --git a/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeOffsetDateTime.java b/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeOffsetDateTime.java new file mode 100644 index 000000000..8fc004792 --- /dev/null +++ b/src/main/java/com/avaje/ebeaninternal/server/type/ScalarTypeOffsetDateTime.java @@ -0,0 +1,43 @@ +package com.avaje.ebeaninternal.server.type; + +import java.sql.Timestamp; +import java.sql.Types; +import java.time.OffsetDateTime; +import java.time.ZoneId; + +/** + * ScalarType for java.sql.Timestamp. + */ +public class ScalarTypeOffsetDateTime extends ScalarTypeBaseDateTime { + + public ScalarTypeOffsetDateTime() { + super(OffsetDateTime.class, true, Types.TIMESTAMP); + } + + @Override + public long convertToMillis(Object value) { + return ((OffsetDateTime) value).toInstant().toEpochMilli(); + } + + @Override + public OffsetDateTime convertFromTimestamp(Timestamp ts) { + return OffsetDateTime.ofInstant(ts.toInstant(), ZoneId.systemDefault()); + } + + @Override + public Timestamp convertToTimestamp(OffsetDateTime t) { + return Timestamp.from(t.toInstant()); + } + + @Override + public Object toJdbcType(Object value) { + if (value instanceof Timestamp) return value; + return convertToTimestamp((OffsetDateTime)value); + } + + @Override + public OffsetDateTime toBeanType(Object value) { + if (value instanceof OffsetDateTime) return (OffsetDateTime) value; + return convertFromTimestamp((Timestamp)value); + } +} diff --git a/src/test/java/com/avaje/ebeaninternal/server/type/ScalarTypeLocalDateTest.java b/src/test/java/com/avaje/ebeaninternal/server/type/ScalarTypeLocalDateTest.java new file mode 100644 index 000000000..73b48161e --- /dev/null +++ b/src/test/java/com/avaje/ebeaninternal/server/type/ScalarTypeLocalDateTest.java @@ -0,0 +1,50 @@ +package com.avaje.ebeaninternal.server.type; + +import org.junit.Test; + +import java.time.LocalDate; + +import static org.junit.Assert.*; + +public class ScalarTypeLocalDateTest { + + ScalarTypeLocalDate type = new ScalarTypeLocalDate(); + + @Test + public void testConvertToMillis() throws Exception { + + LocalDate date = LocalDate.of(2014, 5, 20); + long millis = type.convertToMillis(date); + + System.out.println(date); + + LocalDate parseDate = type.parseDateTime(millis); + + assertEquals(date, parseDate); + } + + @Test + public void testConvertFromDate() throws Exception { + + } + + @Test + public void testConvertToDate() throws Exception { + + } + + @Test + public void testToJdbcType() throws Exception { + + } + + @Test + public void testToBeanType() throws Exception { + + } + + @Test + public void testParseDateTime() throws Exception { + + } +} \ No newline at end of file diff --git a/src/test/java/com/avaje/ebeaninternal/server/type/ScalarTypeLocalDateTimeTest.java b/src/test/java/com/avaje/ebeaninternal/server/type/ScalarTypeLocalDateTimeTest.java new file mode 100644 index 000000000..492ee9b42 --- /dev/null +++ b/src/test/java/com/avaje/ebeaninternal/server/type/ScalarTypeLocalDateTimeTest.java @@ -0,0 +1,58 @@ +package com.avaje.ebeaninternal.server.type; + +import org.junit.Test; + +import java.sql.Timestamp; +import java.time.LocalDateTime; + +import static org.junit.Assert.*; + +public class ScalarTypeLocalDateTimeTest { + + ScalarTypeLocalDateTime type = new ScalarTypeLocalDateTime(); + + // warm up + LocalDateTime warmUp = LocalDateTime.now(); + + @Test + public void testConvertToMillis() throws Exception { + + warmUp.hashCode(); + + long now = System.currentTimeMillis(); + long toMillis = type.convertToMillis( LocalDateTime.now()); + + assertTrue(toMillis - now < 10); + } + + @Test + public void testConvertFromTimestamp() throws Exception { + + Timestamp now = new Timestamp(System.currentTimeMillis()); + + LocalDateTime localDateTime = type.convertFromTimestamp(now); + Timestamp timestamp = type.convertToTimestamp(localDateTime); + + assertEquals(now, timestamp); + } + + + @Test + public void testToJdbcType() throws Exception { + + Object jdbcType = type.toJdbcType(LocalDateTime.now()); + assertTrue(jdbcType instanceof Timestamp); + } + + @Test + public void testToBeanType() throws Exception { + + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); + LocalDateTime localDateTime = type.toBeanType(timestamp); + + assertNotNull(localDateTime); + + Timestamp timestamp1 = type.convertToTimestamp(localDateTime); + assertEquals(timestamp, timestamp1); + } +} \ No newline at end of file diff --git a/src/test/java/com/avaje/ebeaninternal/server/type/ScalarTypeOffsetDateTimeTest.java b/src/test/java/com/avaje/ebeaninternal/server/type/ScalarTypeOffsetDateTimeTest.java new file mode 100644 index 000000000..50e0a5565 --- /dev/null +++ b/src/test/java/com/avaje/ebeaninternal/server/type/ScalarTypeOffsetDateTimeTest.java @@ -0,0 +1,62 @@ +package com.avaje.ebeaninternal.server.type; + +import org.junit.Test; + +import java.sql.Timestamp; +import java.time.LocalDateTime; +import java.time.OffsetDateTime; + +import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; + +public class ScalarTypeOffsetDateTimeTest { + + + ScalarTypeOffsetDateTime type = new ScalarTypeOffsetDateTime(); + + OffsetDateTime warmUp = OffsetDateTime.now(); + + @Test + public void testConvertToMillis() throws Exception { + + warmUp.hashCode(); + + long now = System.currentTimeMillis(); + long toMillis = type.convertToMillis( OffsetDateTime.now()); + + assertTrue(toMillis - now < 10); + + } + + @Test + public void testConvertFromTimestamp() throws Exception { + + Timestamp now = new Timestamp(System.currentTimeMillis()); + + OffsetDateTime localDateTime = type.convertFromTimestamp(now); + Timestamp timestamp = type.convertToTimestamp(localDateTime); + + assertEquals(now, timestamp); + } + + + @Test + public void testToJdbcType() throws Exception { + + Object jdbcType = type.toJdbcType(OffsetDateTime.now()); + assertTrue(jdbcType instanceof Timestamp); + } + + @Test + public void testToBeanType() throws Exception { + + Timestamp timestamp = new Timestamp(System.currentTimeMillis()); + OffsetDateTime localDateTime = type.toBeanType(timestamp); + + assertNotNull(localDateTime); + + Timestamp timestamp1 = type.convertToTimestamp(localDateTime); + assertEquals(timestamp, timestamp1); + + } +} \ No newline at end of file