Skip to content

Commit

Permalink
Prevent erroneous validation failure for primitive type conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
geoand committed Dec 19, 2022
1 parent 74e3620 commit 6b1742a
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand All @@ -27,6 +28,22 @@
* Information about a configuration interface.
*/
public final class ConfigMappingInterface implements ConfigMappingMetadata {

private static final Map<Class<?>, Class<?>> PRIMITIVES_TO_WRAPPERS;
static {
Map<Class<?>, Class<?>> map = new HashMap<>();
map.put(boolean.class, Boolean.class);
map.put(char.class, Character.class);
map.put(byte.class, Byte.class);
map.put(short.class, Short.class);
map.put(int.class, Integer.class);
map.put(long.class, Long.class);
map.put(float.class, Float.class);
map.put(double.class, Double.class);

PRIMITIVES_TO_WRAPPERS = Collections.unmodifiableMap(map);
}

static final ConfigMappingInterface[] NO_TYPES = new ConfigMappingInterface[0];
static final Property[] NO_PROPERTIES = new Property[0];
static final ClassValue<ConfigMappingInterface> cv = new ClassValue<ConfigMappingInterface>() {
Expand Down Expand Up @@ -824,8 +841,10 @@ private static Class<? extends Converter<?>> getConvertWith(final AnnotatedType
private static void validateConverter(final Type type, final Class<? extends Converter<?>> convertWith) {
if (type instanceof Class) {
try {
Class<?> classType = (Class<?>) type;
Class<?> effectiveType = classType.isPrimitive() ? PRIMITIVES_TO_WRAPPERS.get(classType) : classType;
Method convertMethod = convertWith.getMethod("convert", String.class);
if (!((Class<?>) type).isAssignableFrom(convertMethod.getReturnType())) {
if (!effectiveType.isAssignableFrom(convertMethod.getReturnType())) {
throw new IllegalArgumentException();
}
} catch (NoSuchMethodException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,13 @@ void converters() {
final Converters converters = config.getConfigMapping(Converters.class);

assertEquals("bar", converters.foo());
assertTrue(converters.bprim());
assertEquals('c', converters.cprim());
assertEquals(-1, converters.iprim());
assertEquals(-1, converters.sprim());
assertEquals(-1L, converters.lprim());
assertEquals(-1.0, converters.fprim());
assertEquals(-1.0, converters.dprim());
}

@Test
Expand Down Expand Up @@ -661,6 +668,27 @@ public interface ComplexSample {
public interface Converters {
@WithConverter(FooBarConverter.class)
String foo();

@WithConverter(BooleanConverter.class)
boolean bprim();

@WithConverter(CharacterConverter.class)
char cprim();

@WithConverter(IntegerConverter.class)
int iprim();

@WithConverter(ShortConverter.class)
short sprim();

@WithConverter(LongConverter.class)
long lprim();

@WithConverter(FloatConverter.class)
float fprim();

@WithConverter(DoubleConverter.class)
double dprim();
}

public static class FooBarConverter implements Converter<String> {
Expand All @@ -670,6 +698,55 @@ public String convert(final String value) {
}
}

public static class BooleanConverter implements Converter<Boolean> {
@Override
public Boolean convert(String value) throws IllegalArgumentException, NullPointerException {
return true;
}
}

public static class CharacterConverter implements Converter<Character> {
@Override
public Character convert(String value) throws IllegalArgumentException, NullPointerException {
return 'c';
}
}

public static class IntegerConverter implements Converter<Integer> {
@Override
public Integer convert(String value) throws IllegalArgumentException, NullPointerException {
return -1;
}
}

public static class ShortConverter implements Converter<Short> {
@Override
public Short convert(String value) throws IllegalArgumentException, NullPointerException {
return -1;
}
}

public static class LongConverter implements Converter<Long> {
@Override
public Long convert(String value) throws IllegalArgumentException, NullPointerException {
return -1L;
}
}

public static class FloatConverter implements Converter<Float> {
@Override
public Float convert(String value) throws IllegalArgumentException, NullPointerException {
return -1.0F;
}
}

public static class DoubleConverter implements Converter<Double> {
@Override
public Double convert(String value) throws IllegalArgumentException, NullPointerException {
return -1.0;
}
}

@ConfigMapping(prefix = "cloud")
public interface ServerAnnotated {
String host();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,27 @@ public Integer convert(final String value) throws IllegalArgumentException, Null
}
}

@ConfigMapping
interface WrongPrimitiveConverterType {
@WithConverter(IntegerConverter.class)
double type();

class IntegerConverter implements Converter<Integer> {

@Override
public Integer convert(final String value) throws IllegalArgumentException, NullPointerException {
return 0;
}

}
}

@Test
void wrongConverter() {
assertThrows(IllegalArgumentException.class, () -> config(WrongConverterType.class));
assertThrows(IllegalArgumentException.class, () -> config(WrongAbstractConverterType.class));
assertThrows(IllegalArgumentException.class, () -> config(WrongSuperConverterType.class));
assertThrows(IllegalArgumentException.class, () -> config(WrongPrimitiveConverterType.class));
}

@ConfigMapping
Expand Down

0 comments on commit 6b1742a

Please sign in to comment.