CAY-2447 Crypto support for LocalDateTime
Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/63518b81 Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/63518b81 Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/63518b81 Branch: refs/heads/master Commit: 63518b81c6d8455a70558255cc160f91a26ed46d Parents: c9d0fd3 Author: Nikita Timofeev <stari...@gmail.com> Authored: Fri Aug 10 17:32:09 2018 +0300 Committer: Nikita Timofeev <stari...@gmail.com> Committed: Fri Aug 10 17:32:09 2018 +0300 ---------------------------------------------------------------------- RELEASE-NOTES.txt | 2 +- .../value/LocalDateTimeConverter.java | 27 ++++++++---- .../transformer/value/LocalTimeConverter.java | 1 + .../value/LocalDateConverterTest.java | 14 +++---- .../value/LocalDateTimeConverterTest.java | 43 +++++++++++++++----- .../value/LocalTimeConverterTest.java | 20 +++++---- 6 files changed, 71 insertions(+), 36 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cayenne/blob/63518b81/RELEASE-NOTES.txt ---------------------------------------------------------------------- diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt index fff3063..d2e5421 100644 --- a/RELEASE-NOTES.txt +++ b/RELEASE-NOTES.txt @@ -14,12 +14,12 @@ Date: Changes/New Features: CAY-2446 Run Disjoint By Id queries outside of synchronized block +CAY-2447 Crypto support for LocalDateTime Bug Fixes: CAY-2444 Change URI from http:// to https:// in xsi:schemaLocation CAY-2445 Oracle: Problem with ExpressionFactory.notInExp() -CAY-2447 Crypto support for LocalDateTime ---------------------------------- Release: 4.1.M2 http://git-wip-us.apache.org/repos/asf/cayenne/blob/63518b81/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/LocalDateTimeConverter.java ---------------------------------------------------------------------- diff --git a/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/LocalDateTimeConverter.java b/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/LocalDateTimeConverter.java index 91dd318..6307c46 100644 --- a/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/LocalDateTimeConverter.java +++ b/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/LocalDateTimeConverter.java @@ -5,10 +5,13 @@ import java.time.LocalDateTime; import java.time.LocalTime; import java.util.Objects; +import org.apache.cayenne.crypto.CayenneCryptoException; + /** * @since 4.1 */ public class LocalDateTimeConverter implements BytesConverter<LocalDateTime> { + public static final BytesConverter<LocalDateTime> INSTANCE = new LocalDateTimeConverter(LongConverter.INSTANCE); private BytesConverter<Long> longConverter; @@ -20,14 +23,22 @@ public class LocalDateTimeConverter implements BytesConverter<LocalDateTime> { @Override public LocalDateTime fromBytes(byte[] bytes) { - int dateLength = 2; - int timeLength = 8; + if (bytes.length < 2) { + throw new IllegalArgumentException("Unexpected number of bytes: " + bytes.length); + } + + // long values converted to varying length byte arrays, so first byte is length + int dateLength = bytes[0]; + if(dateLength <= 0 || dateLength >= bytes.length - 1) { + throw new CayenneCryptoException("Corrupted data for LocalDateTime: wrong encoded length"); + } + int timeLength = bytes.length - 1 - dateLength; byte[] date = new byte[dateLength]; byte[] time = new byte[timeLength]; - System.arraycopy(bytes, 0, date, 0, dateLength); - System.arraycopy(bytes, dateLength, time, 0, timeLength); + System.arraycopy(bytes, 1, date, 0, dateLength); + System.arraycopy(bytes, dateLength + 1, time, 0, timeLength); LocalDate localDate = LocalDate.ofEpochDay(longConverter.fromBytes(date)); LocalTime localTime = LocalTime.ofNanoOfDay(longConverter.fromBytes(time)); @@ -40,9 +51,11 @@ public class LocalDateTimeConverter implements BytesConverter<LocalDateTime> { byte[] date = longConverter.toBytes(value.toLocalDate().toEpochDay()); byte[] time = longConverter.toBytes(value.toLocalTime().toNanoOfDay()); - byte [] datetime = new byte[date.length + time.length]; - System.arraycopy(date,0, datetime, 0, date.length); - System.arraycopy(time,0, datetime, date.length, time.length); + byte [] datetime = new byte[date.length + time.length + 1]; + // store date part length as first byte + datetime[0] = (byte)date.length; + System.arraycopy(date,0, datetime, 1, date.length); + System.arraycopy(time,0, datetime, date.length + 1, time.length); return datetime; } http://git-wip-us.apache.org/repos/asf/cayenne/blob/63518b81/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/LocalTimeConverter.java ---------------------------------------------------------------------- diff --git a/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/LocalTimeConverter.java b/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/LocalTimeConverter.java index 82908ec..ae49c80 100644 --- a/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/LocalTimeConverter.java +++ b/cayenne-crypto/src/main/java/org/apache/cayenne/crypto/transformer/value/LocalTimeConverter.java @@ -7,6 +7,7 @@ import java.util.Objects; * @since 4.1 */ public class LocalTimeConverter implements BytesConverter<LocalTime> { + public static final BytesConverter<LocalTime> INSTANCE = new LocalTimeConverter(LongConverter.INSTANCE); private BytesConverter<Long> longConverter; http://git-wip-us.apache.org/repos/asf/cayenne/blob/63518b81/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/value/LocalDateConverterTest.java ---------------------------------------------------------------------- diff --git a/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/value/LocalDateConverterTest.java b/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/value/LocalDateConverterTest.java index 9b5458a..7cf6aa8 100644 --- a/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/value/LocalDateConverterTest.java +++ b/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/value/LocalDateConverterTest.java @@ -2,7 +2,6 @@ package org.apache.cayenne.crypto.transformer.value; import org.junit.Test; -import java.text.ParseException; import java.time.LocalDate; import static org.junit.Assert.assertArrayEquals; @@ -10,18 +9,15 @@ import static org.junit.Assert.assertEquals; public class LocalDateConverterTest { - private LocalDate localDate(String dateString) { - return LocalDate.parse(dateString); - } - @Test - public void testFromBytes() throws ParseException { - assertEquals(localDate("2015-01-07"), LocalDateConverter.INSTANCE.fromBytes(new byte[]{64, 58})); + public void testFromBytes() { + assertEquals(LocalDate.of(2015, 1, 7), + LocalDateConverter.INSTANCE.fromBytes(new byte[]{64, 58})); } @Test - public void testToBytes() throws ParseException { + public void testToBytes() { assertArrayEquals(new byte[]{64, 58}, - LocalDateConverter.INSTANCE.toBytes(localDate("2015-01-07"))); + LocalDateConverter.INSTANCE.toBytes(LocalDate.of(2015, 1, 7))); } } http://git-wip-us.apache.org/repos/asf/cayenne/blob/63518b81/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/value/LocalDateTimeConverterTest.java ---------------------------------------------------------------------- diff --git a/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/value/LocalDateTimeConverterTest.java b/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/value/LocalDateTimeConverterTest.java index 1cc9425..6be15e9 100644 --- a/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/value/LocalDateTimeConverterTest.java +++ b/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/value/LocalDateTimeConverterTest.java @@ -2,28 +2,51 @@ package org.apache.cayenne.crypto.transformer.value; import org.junit.Test; -import java.text.ParseException; import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; public class LocalDateTimeConverterTest { - private LocalDateTime localDate(String dateString) { - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); - return LocalDateTime.parse(dateString, formatter); + @Test + public void testFromBytes() { + assertEquals(LocalDateTime.of(2015, 1, 7, 11, 0, 2), + LocalDateTimeConverter.INSTANCE.fromBytes(new byte[]{2, 64, 58, 0, 0, 36, 4, -113, 36, 116, 0})); + } + + @Test + public void testToBytes() { + byte[] bytes = LocalDateTimeConverter.INSTANCE + .toBytes(LocalDateTime.of(2015, 1, 7, 11, 0, 2)); + assertArrayEquals(new byte[]{2, 64, 58, 0, 0, 36, 4, -113, 36, 116, 0}, bytes); + } + + @Test + public void testToBytesBig() { + byte[] bytes = LocalDateTimeConverter.INSTANCE + .toBytes(LocalDateTime.of(123456, 12, 31, 23, 59, 59)); + assertArrayEquals(new byte[]{4, 2, -91, 16, -9, 0, 0, 78, -108, 85, -76, 54, 0}, bytes); + } + + @Test + public void testFromBytesBig() { + LocalDateTime localDateTime = LocalDateTimeConverter.INSTANCE + .fromBytes(new byte[]{4, 2, -91, 16, -9, 0, 0, 78, -108, 85, -76, 54, 0}); + assertEquals(LocalDateTime.of(123456, 12, 31, 23, 59, 59), localDateTime); } @Test - public void testFromBytes() throws ParseException { - assertEquals(localDate("2015-01-07 11:00:02"), LocalDateTimeConverter.INSTANCE.fromBytes(new byte[]{64, 58, 0, 0, 36, 4, -113, 36, 116, 0})); + public void testToBytesSmall() { + byte[] bytes = LocalDateTimeConverter.INSTANCE + .toBytes(LocalDateTime.of(0, 1, 1, 0, 0, 0)); + assertArrayEquals(new byte[]{4, -1, -11, 5, 88, 0}, bytes); } @Test - public void testToBytes() throws ParseException { - assertArrayEquals(new byte[]{64, 58, 0, 0, 36, 4, -113, 36, 116, 0}, - LocalDateTimeConverter.INSTANCE.toBytes(localDate("2015-01-07 11:00:02"))); + public void testFromBytesSmall() { + LocalDateTime localDateTime = LocalDateTimeConverter.INSTANCE + .fromBytes(new byte[]{4, -1, -11, 5, 88, 0}); + assertEquals(LocalDateTime.of(0, 1, 1, 0, 0, 0), localDateTime); } } http://git-wip-us.apache.org/repos/asf/cayenne/blob/63518b81/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/value/LocalTimeConverterTest.java ---------------------------------------------------------------------- diff --git a/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/value/LocalTimeConverterTest.java b/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/value/LocalTimeConverterTest.java index 4743217..e0dca79 100644 --- a/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/value/LocalTimeConverterTest.java +++ b/cayenne-crypto/src/test/java/org/apache/cayenne/crypto/transformer/value/LocalTimeConverterTest.java @@ -2,7 +2,6 @@ package org.apache.cayenne.crypto.transformer.value; import org.junit.Test; -import java.text.ParseException; import java.time.LocalTime; import static org.junit.Assert.assertArrayEquals; @@ -10,19 +9,22 @@ import static org.junit.Assert.assertEquals; public class LocalTimeConverterTest { - private LocalTime localTime(String dateString) { - return LocalTime.parse(dateString); - } - @Test - public void testFromBytes() throws ParseException { - assertEquals(localTime("11:00:02"), LocalTimeConverter.INSTANCE.fromBytes(new byte[]{0, 0, 36, 4, -113, 36, 116, 0})); + public void testFromBytes() { + assertEquals(LocalTime.of(11, 0, 2), + LocalTimeConverter.INSTANCE.fromBytes(new byte[]{0, 0, 36, 4, -113, 36, 116, 0})); + + assertEquals(LocalTime.of(0, 0, 0), + LocalTimeConverter.INSTANCE.fromBytes(new byte[]{0})); } @Test - public void testToBytes() throws ParseException { + public void testToBytes() { assertArrayEquals(new byte[]{0, 0, 36, 4, -113, 36, 116, 0}, - LocalTimeConverter.INSTANCE.toBytes(localTime("11:00:02"))); + LocalTimeConverter.INSTANCE.toBytes(LocalTime.of(11, 0, 2))); + + assertArrayEquals(new byte[]{0}, + LocalTimeConverter.INSTANCE.toBytes(LocalTime.of(0, 0, 0))); } }