org.junit.contrib.theories.ParameterSignature Maven / Gradle / Ivy
package org.junit.contrib.theories;
import org.javaruntype.type.Types;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.AnnotatedType;
import java.lang.reflect.Executable;
import java.lang.reflect.Parameter;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ParameterSignature implements AnnotatedElement {
private static final Map CONVERTIBLE_TYPES_MAP = buildConvertibleTypesMap();
private static Map buildConvertibleTypesMap() {
Map, Class>> map = new HashMap<>();
putSymmetrically(map, boolean.class, Boolean.class);
putSymmetrically(map, byte.class, Byte.class);
putSymmetrically(map, short.class, Short.class);
putSymmetrically(map, char.class, Character.class);
putSymmetrically(map, int.class, Integer.class);
putSymmetrically(map, long.class, Long.class);
putSymmetrically(map, float.class, Float.class);
putSymmetrically(map, double.class, Double.class);
return Collections.unmodifiableMap(map);
}
private static void putSymmetrically(Map map, T a, T b) {
map.put(a, b);
map.put(b, a);
}
public static List signatures(Executable e) {
List sigs = new ArrayList<>();
for (Parameter each : e.getParameters()) {
sigs.add(new ParameterSignature(each));
}
return sigs;
}
private final Parameter parameter;
private ParameterSignature(Parameter parameter) {
this.parameter = parameter;
}
public boolean canAcceptValue(Object candidate) {
return candidate == null
? !Types.forJavaLangReflectType(getType()).getRawClass().isPrimitive()
: canAcceptType(candidate.getClass());
}
public boolean canAcceptType(Type candidate) {
return assignable(getType(), candidate) || isAssignableViaTypeConversion(getType(), candidate);
}
public boolean canPotentiallyAcceptType(Class> candidate) {
return assignable(candidate, getType())
|| isAssignableViaTypeConversion(candidate, getType())
|| canAcceptType(candidate);
}
private static boolean isAssignableViaTypeConversion(Type targetType, Type candidate) {
if (CONVERTIBLE_TYPES_MAP.containsKey(candidate)) {
Type wrapper = CONVERTIBLE_TYPES_MAP.get(candidate);
return assignable(targetType, wrapper);
}
return false;
}
private static boolean assignable(Type first, Type second) {
return Types.forJavaLangReflectType(first).isAssignableFrom(Types.forJavaLangReflectType(second));
}
public Type getType() {
return getAnnotatedType().getType();
}
public AnnotatedType getAnnotatedType() {
return parameter.getAnnotatedType();
}
@Override
public Annotation[] getAnnotations() {
return parameter.getAnnotations();
}
@Override
public Annotation[] getDeclaredAnnotations() {
return parameter.getDeclaredAnnotations();
}
public String getName() {
return parameter.getName();
}
public String getDeclarerName() {
Executable exec = parameter.getDeclaringExecutable();
return exec.getDeclaringClass().getName() + '.' + exec.getName();
}
public boolean hasAnnotation(Class extends Annotation> type) {
return getAnnotation(type) != null;
}
public T findDeepAnnotation(Class annotationType) {
return findDeepAnnotation(parameter.getAnnotations(), annotationType, 3);
}
private T findDeepAnnotation(Annotation[] annotations,
Class annotationType, int depth) {
if (depth == 0) {
return null;
}
for (Annotation each : annotations) {
if (annotationType.isInstance(each)) {
return annotationType.cast(each);
}
Annotation candidate =
findDeepAnnotation(each.annotationType().getAnnotations(), annotationType, depth - 1);
if (candidate != null) {
return annotationType.cast(candidate);
}
}
return null;
}
public T getAnnotation(Class annotationType) {
for (Annotation each : getAnnotations()) {
if (annotationType.isInstance(each)) {
return annotationType.cast(each);
}
}
return null;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy