Skip to content

Commit

Permalink
Merge pull request #692 from Netflix/uri-locale-converters
Browse files Browse the repository at this point in the history
Add TypeConverters for URI and Locale
  • Loading branch information
rgallardo-netflix authored Nov 29, 2023
2 parents e14dc80 + 20eadb4 commit cd49592
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@

@Singleton
public class DefaultDecoder implements Decoder, TypeConverter.Registry {
private final Map<Type, TypeConverter> cache = new ConcurrentHashMap<>();
private final Map<Type, TypeConverter<?>> cache = new ConcurrentHashMap<>();

private final List<TypeConverter.Factory> factories = new ArrayList<>();

public static DefaultDecoder INSTANCE = new DefaultDecoder();
public static final DefaultDecoder INSTANCE = new DefaultDecoder();

private DefaultDecoder() {
factories.add(DefaultTypeConverterFactory.INSTANCE);
Expand All @@ -60,7 +60,7 @@ public <T> T decode(Type type, String encoded) {
if (encoded == null) {
return null;
}
return (T)getOrCreateConverter(type).convert(encoded);
return (T) getOrCreateConverter(type).convert(encoded);
} catch (Exception e) {
throw new ParseException("Error decoding type `" + type.getTypeName() + "`", e);
}
Expand All @@ -78,7 +78,10 @@ private TypeConverter<?> getOrCreateConverter(Type type) {
if (converter == null) {
throw new RuntimeException("No converter found for type '" + type + "'");
}
cache.put(type, converter);
TypeConverter<?> existing = cache.putIfAbsent(type, converter);
if (existing != null) {
converter = existing;
}
}
return converter;
}
Expand Down Expand Up @@ -106,27 +109,28 @@ private static <T> TypeConverter<T> findValueOfTypeConverter(Type type) {
return null;
}

Class cls = (Class)type;
@SuppressWarnings("unchecked")
Class<T> cls = (Class<T>) type;

// Next look a valueOf(String) static method
Method method;
try {
method = cls.getMethod("valueOf", String.class);
return value -> {
try {
return (T)method.invoke(null, value);
return (T) method.invoke(null, value);
} catch (Exception e) {
throw new ParseException("Error converting value '" + value + "' to '" + type.getTypeName() + "'", e);
}
};
} catch (NoSuchMethodException e1) {
// Next look for a T(String) constructor
Constructor c;
Constructor<T> c;
try {
c = cls.getConstructor(String.class);
return value -> {
try {
return (T)c.newInstance(value);
return (T) c.newInstance(value);
} catch (Exception e) {
throw new ParseException("Error converting value", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URI;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
Expand All @@ -22,6 +23,7 @@
import java.util.Currency;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
Expand Down Expand Up @@ -76,6 +78,8 @@ private DefaultTypeConverterFactory() {
converters.put(Instant.class, v -> Instant.from(OffsetDateTime.parse(v)));
converters.put(Date.class, v -> new Date(Long.parseLong(v)));
converters.put(Currency.class, Currency::getInstance);
converters.put(URI.class, URI::create);
converters.put(Locale.class, Locale::forLanguageTag);

converters.put(BitSet.class, v -> {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URI;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
Expand All @@ -30,6 +31,7 @@
import java.util.BitSet;
import java.util.Currency;
import java.util.Date;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

Expand Down Expand Up @@ -84,5 +86,7 @@ public void testJavaMiscellaneous() throws DecoderException {
Assert.assertEquals(Currency.getInstance("USD"), decoder.decode(Currency.class, "USD"));
Assert.assertEquals(BitSet.valueOf(Hex.decodeHex("DEADBEEF00DEADBEEF")), decoder.decode(BitSet.class, "DEADBEEF00DEADBEEF"));
Assert.assertEquals("testString", decoder.decode(String.class, "testString"));
Assert.assertEquals(URI.create("https://netflix.com"), decoder.decode(URI.class, "https://netflix.com"));
Assert.assertEquals(Locale.ENGLISH, decoder.decode(Locale.class, "en"));
}
}

0 comments on commit cd49592

Please sign in to comment.