Skip to content

Commit

Permalink
- Moved all the map conversions to MapConversions
Browse files Browse the repository at this point in the history
- Moved the static Map helper functions to MapConversions from Converter
  • Loading branch information
jdereg committed Jan 27, 2024
1 parent 99d9d6f commit cb58bcd
Show file tree
Hide file tree
Showing 2 changed files with 154 additions and 137 deletions.
150 changes: 16 additions & 134 deletions src/main/java/com/cedarsoftware/util/convert/Converter.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.cedarsoftware.util.convert;


import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
Expand All @@ -13,7 +12,6 @@
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.MonthDay;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.AbstractMap;
Expand All @@ -23,7 +21,6 @@
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.UUID;
Expand All @@ -34,7 +31,6 @@
import java.util.concurrent.atomic.AtomicLong;

import com.cedarsoftware.util.ClassUtilities;
import com.cedarsoftware.util.CollectionUtilities;
import com.cedarsoftware.util.DateUtilities;
import com.cedarsoftware.util.StringUtilities;

Expand Down Expand Up @@ -74,9 +70,9 @@
*/

public final class Converter {
public static final String NOPE = "~nope!";
public static final String VALUE = "_v";
private static final String VALUE2 = "value";
static final String NOPE = "~nope!";
static final String VALUE = "_v";
static final String VALUE2 = "value";

private final Map<Map.Entry<Class<?>, Class<?>>, Convert<?>> factory;
private final ConverterOptions options;
Expand Down Expand Up @@ -284,7 +280,7 @@ private static void buildFactoryConversions() {
DEFAULT_FACTORY.put(pair(BigInteger.class, Character.class), NumberConversions::toCharacter);
DEFAULT_FACTORY.put(pair(BigDecimal.class, Character.class), NumberConversions::toCharacter);
DEFAULT_FACTORY.put(pair(Number.class, Character.class), NumberConversions::toCharacter);
DEFAULT_FACTORY.put(pair(Map.class, Character.class), (fromInstance, converter, options) -> converter.fromValueMap((Map<?, ?>) fromInstance, char.class, null, options));
DEFAULT_FACTORY.put(pair(Map.class, Character.class), MapConversions::toCharacter);
DEFAULT_FACTORY.put(pair(String.class, Character.class), StringConversions::toCharacter);

// BigInteger versions supported
Expand Down Expand Up @@ -489,26 +485,7 @@ private static void buildFactoryConversions() {
DEFAULT_FACTORY.put(pair(ZonedDateTime.class, Calendar.class), ZonedDateTimeConversions::toCalendar);
DEFAULT_FACTORY.put(pair(Calendar.class, Calendar.class), CalendarConversions::clone);
DEFAULT_FACTORY.put(pair(Number.class, Calendar.class), NumberConversions::toCalendar);
DEFAULT_FACTORY.put(pair(Map.class, Calendar.class), (fromInstance, converter, options) -> {
Map<?, ?> map = (Map<?, ?>) fromInstance;
if (map.containsKey("time")) {
Object zoneRaw = map.get("zone");
TimeZone tz;
if (zoneRaw instanceof String) {
String zone = (String) zoneRaw;
tz = TimeZone.getTimeZone(zone);
} else {
tz = TimeZone.getTimeZone(options.getZoneId());
}
Calendar cal = Calendar.getInstance();
cal.setTimeZone(tz);
Date epochInMillis = converter.convert(map.get("time"), Date.class, options);
cal.setTimeInMillis(epochInMillis.getTime());
return cal;
} else {
return converter.fromValueMap(map, Calendar.class, CollectionUtilities.setOf("time", "zone"), options);
}
});
DEFAULT_FACTORY.put(pair(Map.class, Calendar.class), MapConversions::toCalendar);
DEFAULT_FACTORY.put(pair(String.class, Calendar.class), (fromInstance, converter, options) -> {
String str = ((String) fromInstance).trim();
Date date = DateUtilities.parseDate(str);
Expand All @@ -518,31 +495,6 @@ private static void buildFactoryConversions() {
return CalendarConversions.create(date.getTime(), options);
});


// LocalTime conversions supported
DEFAULT_FACTORY.put(pair(Void.class, LocalTime.class), VoidConversions::toNull);
DEFAULT_FACTORY.put(pair(LocalTime.class, LocalTime.class), Converter::identity);
DEFAULT_FACTORY.put(pair(String.class, LocalTime.class), (fromInstance, converter, options) -> {
String strTime = (String) fromInstance;
try {
return LocalTime.parse(strTime);
} catch (Exception e) {
return DateUtilities.parseDate(strTime).toInstant().atZone(ZoneId.systemDefault()).toLocalTime();
}
});
DEFAULT_FACTORY.put(pair(Map.class, LocalTime.class), (fromInstance, converter, options) -> {
Map<?, ?> map = (Map<?, ?>) fromInstance;
if (map.containsKey("hour") && map.containsKey("minute")) {
int hour = converter.convert(map.get("hour"), int.class, options);
int minute = converter.convert(map.get("minute"), int.class, options);
int second = converter.convert(map.get("second"), int.class, options);
int nano = converter.convert(map.get("nano"), int.class, options);
return LocalTime.of(hour, minute, second, nano);
} else {
return converter.fromValueMap(map, LocalTime.class, CollectionUtilities.setOf("hour", "minute", "second", "nano"), options);
}
});

// LocalDate conversions supported
DEFAULT_FACTORY.put(pair(Void.class, LocalDate.class), VoidConversions::toNull);
DEFAULT_FACTORY.put(pair(Long.class, LocalDate.class), NumberConversions::toLocalDate);
Expand All @@ -559,17 +511,7 @@ private static void buildFactoryConversions() {
DEFAULT_FACTORY.put(pair(ZonedDateTime.class, LocalDate.class), ZonedDateTimeConversions::toLocalDate);
DEFAULT_FACTORY.put(pair(Calendar.class, LocalDate.class), CalendarConversions::toLocalDate);
DEFAULT_FACTORY.put(pair(Number.class, LocalDate.class), NumberConversions::toLocalDate);
DEFAULT_FACTORY.put(pair(Map.class, LocalDate.class), (fromInstance, converter, options) -> {
Map<?, ?> map = (Map<?, ?>) fromInstance;
if (map.containsKey("month") && map.containsKey("day") && map.containsKey("year")) {
int month = converter.convert(map.get("month"), int.class, options);
int day = converter.convert(map.get("day"), int.class, options);
int year = converter.convert(map.get("year"), int.class, options);
return LocalDate.of(year, month, day);
} else {
return converter.fromValueMap(map, LocalDate.class, CollectionUtilities.setOf("year", "month", "day"), options);
}
});
DEFAULT_FACTORY.put(pair(Map.class, LocalDate.class), MapConversions::toLocalDate);
DEFAULT_FACTORY.put(pair(String.class, LocalDate.class), (fromInstance, converter, options) -> {
String str = ((String) fromInstance).trim();
Date date = DateUtilities.parseDate(str);
Expand All @@ -595,10 +537,7 @@ private static void buildFactoryConversions() {
DEFAULT_FACTORY.put(pair(ZonedDateTime.class, LocalDateTime.class), ZonedDateTimeConversions::toLocalDateTime);
DEFAULT_FACTORY.put(pair(Calendar.class, LocalDateTime.class), CalendarConversions::toLocalDateTime);
DEFAULT_FACTORY.put(pair(Number.class, LocalDateTime.class), NumberConversions::toLocalDateTime);
DEFAULT_FACTORY.put(pair(Map.class, LocalDateTime.class), (fromInstance, converter, options) -> {
Map<?, ?> map = (Map<?, ?>) fromInstance;
return converter.fromValueMap(map, LocalDateTime.class, null, options);
});
DEFAULT_FACTORY.put(pair(Map.class, LocalDateTime.class), MapConversions::toLocalDateTime);
DEFAULT_FACTORY.put(pair(String.class, LocalDateTime.class), (fromInstance, converter, options) -> {
String str = ((String) fromInstance).trim();
Date date = DateUtilities.parseDate(str);
Expand All @@ -608,6 +547,7 @@ private static void buildFactoryConversions() {
return date.toInstant().atZone(options.getZoneId()).toLocalDateTime();
});

// LocalTime conversions supported
DEFAULT_FACTORY.put(pair(Void.class, LocalTime.class), VoidConversions::toNull);
DEFAULT_FACTORY.put(pair(Long.class, LocalTime.class), NumberConversions::toLocalTime);
DEFAULT_FACTORY.put(pair(Double.class, LocalTime.class), NumberConversions::toLocalTime);
Expand All @@ -624,10 +564,7 @@ private static void buildFactoryConversions() {
DEFAULT_FACTORY.put(pair(ZonedDateTime.class, LocalTime.class), ZonedDateTimeConversions::toLocalTime);
DEFAULT_FACTORY.put(pair(Calendar.class, LocalTime.class), CalendarConversions::toLocalTime);
DEFAULT_FACTORY.put(pair(Number.class, LocalTime.class), NumberConversions::toLocalTime);
DEFAULT_FACTORY.put(pair(Map.class, LocalTime.class), (fromInstance, converter, options) -> {
Map<?, ?> map = (Map<?, ?>) fromInstance;
return converter.fromValueMap(map, LocalTime.class, null, options);
});
DEFAULT_FACTORY.put(pair(Map.class, LocalTime.class), MapConversions::toLocalTime);
DEFAULT_FACTORY.put(pair(String.class, LocalTime.class), (fromInstance, converter, options) -> {
String str = StringUtilities.trimToEmpty((String)fromInstance);
Date date = DateUtilities.parseDate(str);
Expand All @@ -636,8 +573,7 @@ private static void buildFactoryConversions() {
}
return converter.convert(date, LocalTime.class, options);
});



// ZonedDateTime conversions supported
DEFAULT_FACTORY.put(pair(Void.class, ZonedDateTime.class), VoidConversions::toNull);
DEFAULT_FACTORY.put(pair(Long.class, ZonedDateTime.class), NumberConversions::toZonedDateTime);
Expand All @@ -654,10 +590,7 @@ private static void buildFactoryConversions() {
DEFAULT_FACTORY.put(pair(ZonedDateTime.class, ZonedDateTime.class), Converter::identity);
DEFAULT_FACTORY.put(pair(Calendar.class, ZonedDateTime.class), CalendarConversions::toZonedDateTime);
DEFAULT_FACTORY.put(pair(Number.class, ZonedDateTime.class), NumberConversions::toZonedDateTime);
DEFAULT_FACTORY.put(pair(Map.class, ZonedDateTime.class), (fromInstance, converter, options) -> {
Map<?, ?> map = (Map<?, ?>) fromInstance;
return converter.fromValueMap(map, ZonedDateTime.class, null, options);
});
DEFAULT_FACTORY.put(pair(Map.class, ZonedDateTime.class), MapConversions::toZonedDateTime);
DEFAULT_FACTORY.put(pair(String.class, ZonedDateTime.class), (fromInstance, converter, options) -> {
String str = ((String) fromInstance).trim();
Date date = DateUtilities.parseDate(str);
Expand Down Expand Up @@ -689,7 +622,7 @@ private static void buildFactoryConversions() {
// Class conversions supported
DEFAULT_FACTORY.put(pair(Void.class, Class.class), VoidConversions::toNull);
DEFAULT_FACTORY.put(pair(Class.class, Class.class), Converter::identity);
DEFAULT_FACTORY.put(pair(Map.class, Class.class), (fromInstance, converter, options) -> converter.fromValueMap((Map<?, ?>) fromInstance, AtomicLong.class, null, options));
DEFAULT_FACTORY.put(pair(Map.class, Class.class), MapConversions::toClass);
DEFAULT_FACTORY.put(pair(String.class, Class.class), (fromInstance, converter, options) -> {
String str = ((String) fromInstance).trim();
Class<?> clazz = ClassUtilities.forName(str, options.getClassLoader());
Expand Down Expand Up @@ -758,16 +691,7 @@ private static void buildFactoryConversions() {
DEFAULT_FACTORY.put(pair(Void.class, Duration.class), VoidConversions::toNull);
DEFAULT_FACTORY.put(pair(Duration.class, Duration.class), Converter::identity);
DEFAULT_FACTORY.put(pair(String.class, Duration.class), (fromInstance, converter, options) -> Duration.parse((String) fromInstance));
DEFAULT_FACTORY.put(pair(Map.class, Duration.class), (fromInstance, converter, options) -> {
Map<String, Object> map = (Map<String, Object>) fromInstance;
if (map.containsKey("seconds")) {
long sec = converter.convert(map.get("seconds"), long.class, options);
long nanos = converter.convert(map.get("nanos"), long.class, options);
return Duration.ofSeconds(sec, nanos);
} else {
return converter.fromValueMap(map, Duration.class, CollectionUtilities.setOf("seconds", "nanos"), options);
}
});
DEFAULT_FACTORY.put(pair(Map.class, Duration.class), MapConversions::toDuration);

// Instant conversions supported
DEFAULT_FACTORY.put(pair(Void.class, Instant.class), VoidConversions::toNull);
Expand All @@ -787,16 +711,7 @@ private static void buildFactoryConversions() {
DEFAULT_FACTORY.put(pair(Number.class, Instant.class), NumberConversions::toInstant);

DEFAULT_FACTORY.put(pair(String.class, Instant.class), StringConversions::toInstant);
DEFAULT_FACTORY.put(pair(Map.class, Instant.class), (fromInstance, converter, options) -> {
Map<String, Object> map = (Map<String, Object>) fromInstance;
if (map.containsKey("seconds")) {
long sec = converter.convert(map.get("seconds"), long.class, options);
long nanos = converter.convert(map.get("nanos"), long.class, options);
return Instant.ofEpochSecond(sec, nanos);
} else {
return converter.fromValueMap(map, Instant.class, CollectionUtilities.setOf("seconds", "nanos"), options);
}
});
DEFAULT_FACTORY.put(pair(Map.class, Instant.class), MapConversions::toInstant);

// java.time.OffsetDateTime = com.cedarsoftware.util.io.DEFAULT_FACTORY.OffsetDateTimeFactory
// java.time.OffsetTime = com.cedarsoftware.util.io.DEFAULT_FACTORY.OffsetTimeFactory
Expand All @@ -814,16 +729,7 @@ private static void buildFactoryConversions() {
String monthDay = (String) fromInstance;
return MonthDay.parse(monthDay);
});
DEFAULT_FACTORY.put(pair(Map.class, MonthDay.class), (fromInstance, converter, options) -> {
Map<String, Object> map = (Map<String, Object>) fromInstance;
if (map.containsKey("month")) {
int month = converter.convert(map.get("month"), int.class, options);
int day = converter.convert(map.get("day"), int.class, options);
return MonthDay.of(month, day);
} else {
return converter.fromValueMap(map, MonthDay.class, CollectionUtilities.setOf("month", "day"), options);
}
});
DEFAULT_FACTORY.put(pair(Map.class, MonthDay.class), MapConversions::toMonthDay);

// Map conversions supported
DEFAULT_FACTORY.put(pair(Void.class, Map.class), VoidConversions::toNull);
Expand Down Expand Up @@ -1106,31 +1012,7 @@ private String name(Object fromInstance) {
map.put(VALUE, from);
return map;
}

private Object fromValueMap(Map<?, ?> map, Class<?> type, Set<String> set, ConverterOptions options) {
Object ret = fromMap(map, VALUE, type, this.options);
if (ret != NOPE) {
return ret;
}

ret = fromMap(map, VALUE2, type, this.options);
if (ret == NOPE) {
if (set == null || set.isEmpty()) {
throw new IllegalArgumentException("To convert from Map to " + getShortName(type) + ", the map must include keys: '_v' or 'value' an associated value to convert from.");
} else {
throw new IllegalArgumentException("To convert from Map to " + getShortName(type) + ", the map must include keys: " + set + ", or '_v' or 'value' an associated value to convert from.");
}
}
return ret;
}

private Object fromMap(Map<?, ?> map, String key, Class<?> type, ConverterOptions options) {
if (map.containsKey(key)) {
return convert(map.get(key), type, options);
}
return NOPE;
}


/**
* Check to see if a direct-conversion from type to another type is supported.
*
Expand Down
Loading

0 comments on commit cb58bcd

Please sign in to comment.