Skip to content

Commit

Permalink
Moving over more types, added tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kpartlow committed Jan 30, 2024
1 parent e305e25 commit 8ab1821
Show file tree
Hide file tree
Showing 9 changed files with 395 additions and 43 deletions.
19 changes: 19 additions & 0 deletions src/main/java/com/cedarsoftware/util/ClassUtilities.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package com.cedarsoftware.util;

import com.cedarsoftware.util.convert.StringConversions;

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
Expand Down Expand Up @@ -290,4 +293,20 @@ else if (className.equals("[C"))
}
return currentClass;
}

public static boolean isClassFinal(Class<?> c) {
return (c.getModifiers() & Modifier.FINAL) != 0;
}

public static boolean areAllConstructorsPrivate(Class<?> c) {
Constructor<?>[] constructors = c.getDeclaredConstructors();

for (Constructor<?> constructor : constructors) {
if ((constructor.getModifiers() & Modifier.PRIVATE) == 0) {
return false;
}
}

return true;
}
}
19 changes: 19 additions & 0 deletions src/main/java/com/cedarsoftware/util/convert/Converter.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import java.time.LocalTime;
import java.time.MonthDay;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.Year;
import java.time.ZonedDateTime;
import java.util.AbstractMap;
Expand Down Expand Up @@ -585,6 +586,17 @@ private static void buildFactoryConversions() {
DEFAULT_FACTORY.put(pair(Map.class, ZonedDateTime.class), MapConversions::toZonedDateTime);
DEFAULT_FACTORY.put(pair(String.class, ZonedDateTime.class), StringConversions::toZonedDateTime);

// toOffsetDateTime
DEFAULT_FACTORY.put(pair(Void.class, OffsetDateTime.class), VoidConversions::toNull);
DEFAULT_FACTORY.put(pair(OffsetDateTime.class, OffsetDateTime.class), Converter::identity);
DEFAULT_FACTORY.put(pair(String.class, OffsetDateTime.class), StringConversions::toOffsetDateTime);

// toOffsetTime
DEFAULT_FACTORY.put(pair(Void.class, OffsetTime.class), VoidConversions::toNull);
DEFAULT_FACTORY.put(pair(OffsetTime.class, OffsetTime.class), Converter::identity);
DEFAULT_FACTORY.put(pair(OffsetDateTime.class, OffsetTime.class), OffsetDateTimeConversions::toOffsetTime);
DEFAULT_FACTORY.put(pair(String.class, OffsetTime.class), StringConversions::toOffsetTime);

// UUID conversions supported
DEFAULT_FACTORY.put(pair(Void.class, UUID.class), VoidConversions::toNull);
DEFAULT_FACTORY.put(pair(UUID.class, UUID.class), Converter::identity);
Expand Down Expand Up @@ -716,6 +728,7 @@ private static void buildFactoryConversions() {

// toCharArray
DEFAULT_FACTORY.put(pair(Void.class, char[].class), VoidConversions::toNull);
DEFAULT_FACTORY.put(pair(Void.class, Character[].class), VoidConversions::toNull);
DEFAULT_FACTORY.put(pair(String.class, char[].class), StringConversions::toCharArray);
DEFAULT_FACTORY.put(pair(StringBuilder.class, char[].class), StringConversions::toCharArray);
DEFAULT_FACTORY.put(pair(StringBuffer.class, char[].class), StringConversions::toCharArray);
Expand Down Expand Up @@ -744,6 +757,12 @@ private static void buildFactoryConversions() {
DEFAULT_FACTORY.put(pair(char[].class, ByteBuffer.class), CharArrayConversions::toByteBuffer);
DEFAULT_FACTORY.put(pair(byte[].class, ByteBuffer.class), ByteArrayConversions::toByteBuffer);

// toYear
DEFAULT_FACTORY.put(pair(Void.class, Year.class), VoidConversions::toNull);
DEFAULT_FACTORY.put(pair(Year.class, Year.class), Converter::identity);
DEFAULT_FACTORY.put(pair(String.class, Year.class), StringConversions::toYear);


// Map conversions supported
DEFAULT_FACTORY.put(pair(Void.class, Map.class), VoidConversions::toNull);
DEFAULT_FACTORY.put(pair(Byte.class, Map.class), MapConversions::initMap);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Stream;

public class OffsetDateTimeConversions {
private OffsetDateTimeConversions() {}
Expand Down Expand Up @@ -81,6 +83,11 @@ static BigDecimal toBigDecimal(Object from, Converter converter, ConverterOption
return BigDecimal.valueOf(toLong(from));
}

static OffsetTime toOffsetTime(Object from, Converter converter, ConverterOptions options) {
OffsetDateTime dateTime = (OffsetDateTime) from;
return dateTime.toOffsetTime();
}

static String toString(Object from, Converter converter, ConverterOptions options) {
OffsetDateTime offsetDateTime = (OffsetDateTime) from;
return offsetDateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.MonthDay;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
import java.time.Year;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
Expand Down Expand Up @@ -328,14 +332,14 @@ static LocalDateTime toLocalDateTime(Object from, Converter converter, Converter
}

static LocalTime toLocalTime(Object from, Converter converter, ConverterOptions options) {
String str = (String) from;
if (StringUtilities.isEmpty(str)) {
String str = StringUtilities.trimToNull(asString(from));
if (str == null) {
return null;
}

try {
return LocalTime.parse(str);
}
catch (Exception e) {
} catch (Exception e) {
ZonedDateTime zdt = DateUtilities.parseDate(str, options.getSourceZoneIdForLocalDates(), true);
return zdt.toLocalTime();
}
Expand All @@ -354,6 +358,32 @@ static ZonedDateTime toZonedDateTime(Object from, Converter converter, Converter
return toZonedDateTime(from, options);
}

static OffsetDateTime toOffsetDateTime(Object from, Converter converter, ConverterOptions options) {
String s = StringUtilities.trimToNull(asString(from));
if (s == null) {
return null;
}

try {
return OffsetDateTime.parse(s, DateTimeFormatter.ISO_OFFSET_DATE_TIME);
} catch (Exception e) {
return toZonedDateTime(from, options).toOffsetDateTime();
}
}

static OffsetTime toOffsetTime(Object from, Converter converter, ConverterOptions options) {
String s = StringUtilities.trimToNull(asString(from));
if (s == null) {
return null;
}

try {
return OffsetTime.parse(s, DateTimeFormatter.ISO_OFFSET_TIME);
} catch (Exception e) {
return toZonedDateTime(from, options).toOffsetDateTime().toOffsetTime();
}
}

static Instant toInstant(Object from, Converter converter, ConverterOptions options) {
String s = StringUtilities.trimToNull(asString(from));
if (s == null) {
Expand Down Expand Up @@ -421,4 +451,14 @@ static StringBuilder toStringBuilder(Object from, Converter converter, Converter
return from == null ? null : new StringBuilder(from.toString());
}

static Year toYear(Object from, Converter converter, ConverterOptions options) {
String s = StringUtilities.trimToNull(asString(from));
if (s == null) {
return null;
}

return Year.parse(s);
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Stream;

import com.cedarsoftware.util.ClassUtilities;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
Expand All @@ -23,15 +24,10 @@ class BooleanConversionsTests {


@Test
public void testClassCompliance() throws Exception {
void testClassCompliance() throws Exception {
Class<?> c = BooleanConversions.class;
assertEquals(Modifier.FINAL, c.getModifiers() & Modifier.FINAL);

Constructor con = c.getDeclaredConstructor();
assertEquals(Modifier.PRIVATE, con.getModifiers() & Modifier.PRIVATE);

con.setAccessible(true);
assertNotNull(con.newInstance());
assertThat(ClassUtilities.isClassFinal(c)).isTrue();
assertThat(ClassUtilities.areAllConstructorsPrivate(c)).isTrue();
}

private static Stream<Arguments> toByteParams() {
Expand Down
34 changes: 3 additions & 31 deletions src/test/java/com/cedarsoftware/util/convert/ConverterTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -866,6 +866,9 @@ void testCalendarToLocalDateTime(long epochMilli, ZoneId zoneId, LocalDateTime e
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(epochMilli);

System.out.println(Instant.ofEpochMilli(epochMilli).atZone(zoneId).toOffsetDateTime());


LocalDateTime localDateTime = this.converter.convert(calendar, LocalDateTime.class, createCustomZones(zoneId, zoneId));

assertThat(localDateTime).isEqualTo(expected);
Expand Down Expand Up @@ -3158,37 +3161,6 @@ void testUnsupportedType()



private static Stream<Arguments> classesThatReturnNull_whenConvertingFromNull() {
return Stream.of(
Arguments.of(Class.class),
Arguments.of(String.class),
Arguments.of(AtomicLong.class),
Arguments.of(AtomicInteger.class),
Arguments.of(AtomicBoolean.class),
Arguments.of(BigDecimal.class),
Arguments.of(BigInteger.class),
Arguments.of(Timestamp.class),
Arguments.of(java.sql.Date.class),
Arguments.of(Date.class),
Arguments.of(Character.class),
Arguments.of(Double.class),
Arguments.of(Float.class),
Arguments.of(Long.class),
Arguments.of(Short.class),
Arguments.of(Integer.class),
Arguments.of(Byte.class),
Arguments.of(Boolean.class),
Arguments.of(Byte.class)
);
}

@ParameterizedTest
@MethodSource("classesThatReturnNull_whenConvertingFromNull")
void testClassesThatReturnNull_whenConvertingFromNull(Class c)
{
assertThat(this.converter.convert(null, c)).isNull();
}

private static Stream<Arguments> classesThatReturnZero_whenConvertingFromNull() {
return Stream.of(
Arguments.of(byte.class, CommonValues.BYTE_ZERO),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package com.cedarsoftware.util.convert;

import org.assertj.core.data.Offset;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.Date;
import java.util.stream.Stream;

import static org.assertj.core.api.Assertions.assertThat;

public class OffsetDateTimeConversionsTests {

private Converter converter;

@BeforeEach
public void beforeEach() {
this.converter = new Converter(new DefaultConverterOptions());
}

// epoch milli 1687622249729L
private static Stream<Arguments> offsetDateTime_asString_withMultipleOffsets_sameEpochMilli() {
return Stream.of(
Arguments.of("2023-06-25T00:57:29.729+09:00"),
Arguments.of("2023-06-24T17:57:29.729+02:00"),
Arguments.of("2023-06-24T15:57:29.729Z"),
Arguments.of("2023-06-24T11:57:29.729-04:00"),
Arguments.of("2023-06-24T10:57:29.729-05:00"),
Arguments.of("2023-06-24T08:57:29.729-07:00")
);
}

@ParameterizedTest
@MethodSource("offsetDateTime_asString_withMultipleOffsets_sameEpochMilli")
void toLong_differentZones_sameEpochMilli(String input) {
OffsetDateTime initial = OffsetDateTime.parse(input);
long actual = converter.convert(initial, long.class);
assertThat(actual).isEqualTo(1687622249729L);
}

@ParameterizedTest
@MethodSource("offsetDateTime_asString_withMultipleOffsets_sameEpochMilli")
void toDate_differentZones_sameEpochMilli(String input) {
OffsetDateTime initial = OffsetDateTime.parse(input);
Date actual = converter.convert(initial, Date.class);
assertThat(actual.getTime()).isEqualTo(1687622249729L);
}

@ParameterizedTest
@MethodSource("offsetDateTime_asString_withMultipleOffsets_sameEpochMilli")
void toSqlDate_differentZones_sameEpochMilli(String input) {
OffsetDateTime initial = OffsetDateTime.parse(input);
java.sql.Date actual = converter.convert(initial, java.sql.Date.class);
assertThat(actual.getTime()).isEqualTo(1687622249729L);
}

@ParameterizedTest
@MethodSource("offsetDateTime_asString_withMultipleOffsets_sameEpochMilli")
void toTimestamp_differentZones_sameEpochMilli(String input) {
OffsetDateTime initial = OffsetDateTime.parse(input);
Timestamp actual = converter.convert(initial, Timestamp.class);
assertThat(actual.getTime()).isEqualTo(1687622249729L);
}

// epoch milli 1687622249729L
private static Stream<Arguments> offsetDateTime_withMultipleOffset_sameEpochMilli() {
return Stream.of(
Arguments.of(OffsetDateTime.of(2023, 06, 25, 0, 57, 29, 729000000, ZoneOffset.of("+09:00"))),
Arguments.of(OffsetDateTime.of(2023, 06, 24, 17, 57, 29, 729000000, ZoneOffset.of("+02:00"))),
Arguments.of(OffsetDateTime.of(2023, 06, 24, 15, 57, 29, 729000000, ZoneOffset.of("Z"))),
Arguments.of(OffsetDateTime.of(2023, 06, 24, 11, 57, 29, 729000000, ZoneOffset.of("-04:00"))),
Arguments.of(OffsetDateTime.of(2023, 06, 24, 10, 57, 29, 729000000, ZoneOffset.of("-05:00"))),
Arguments.of(OffsetDateTime.of(2023, 06, 24, 8, 57, 29, 729000000, ZoneOffset.of("-07:00")))
);
}

@ParameterizedTest
@MethodSource("offsetDateTime_withMultipleOffset_sameEpochMilli")
void toLong_differentZones_sameEpochMilli(OffsetDateTime initial) {
long actual = converter.convert(initial, long.class);
assertThat(actual).isEqualTo(1687622249729L);
}

@ParameterizedTest
@MethodSource("offsetDateTime_withMultipleOffset_sameEpochMilli")
void toDate_differentZones_sameEpochMilli(OffsetDateTime initial) {
Date actual = converter.convert(initial, Date.class);
assertThat(actual.getTime()).isEqualTo(1687622249729L);
}

@ParameterizedTest
@MethodSource("offsetDateTime_withMultipleOffset_sameEpochMilli")
void toSqlDate_differentZones_sameEpochMilli(OffsetDateTime initial) {
java.sql.Date actual = converter.convert(initial, java.sql.Date.class);
assertThat(actual.getTime()).isEqualTo(1687622249729L);
}

@ParameterizedTest
@MethodSource("offsetDateTime_withMultipleOffset_sameEpochMilli")
void toTimestamp_differentZones_sameEpochMilli(OffsetDateTime initial) {
Timestamp actual = converter.convert(initial, Timestamp.class);
assertThat(actual.getTime()).isEqualTo(1687622249729L);
}



}
Loading

0 comments on commit 8ab1821

Please sign in to comment.