diff options
Diffstat (limited to 'src/main/java/org/junit/experimental/theories/ParameterSignature.java')
-rw-r--r-- | src/main/java/org/junit/experimental/theories/ParameterSignature.java | 202 |
1 files changed, 123 insertions, 79 deletions
diff --git a/src/main/java/org/junit/experimental/theories/ParameterSignature.java b/src/main/java/org/junit/experimental/theories/ParameterSignature.java index e7150fc..cf22583 100644 --- a/src/main/java/org/junit/experimental/theories/ParameterSignature.java +++ b/src/main/java/org/junit/experimental/theories/ParameterSignature.java @@ -1,6 +1,3 @@ -/** - * - */ package org.junit.experimental.theories; import java.lang.annotation.Annotation; @@ -8,83 +5,130 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; public class ParameterSignature { - public static ArrayList<ParameterSignature> signatures(Method method) { - return signatures(method.getParameterTypes(), method - .getParameterAnnotations()); - } - - public static List<ParameterSignature> signatures(Constructor<?> constructor) { - return signatures(constructor.getParameterTypes(), constructor - .getParameterAnnotations()); - } - - private static ArrayList<ParameterSignature> signatures( - Class<?>[] parameterTypes, Annotation[][] parameterAnnotations) { - ArrayList<ParameterSignature> sigs= new ArrayList<ParameterSignature>(); - for (int i= 0; i < parameterTypes.length; i++) { - sigs.add(new ParameterSignature(parameterTypes[i], - parameterAnnotations[i])); - } - return sigs; - } - - private final Class<?> type; - - private final Annotation[] annotations; - - private ParameterSignature(Class<?> type, Annotation[] annotations) { - this.type= type; - this.annotations= annotations; - } - - public boolean canAcceptType(Class<?> candidate) { - return type.isAssignableFrom(candidate); - } - - public Class<?> getType() { - return type; - } - - public List<Annotation> getAnnotations() { - return Arrays.asList(annotations); - } - - public boolean canAcceptArrayType(Class<?> type) { - return type.isArray() && canAcceptType(type.getComponentType()); - } - - public boolean hasAnnotation(Class<? extends Annotation> type) { - return getAnnotation(type) != null; - } - - public <T extends Annotation> T findDeepAnnotation(Class<T> annotationType) { - Annotation[] annotations2= annotations; - return findDeepAnnotation(annotations2, annotationType, 3); - } - - private <T extends Annotation> T findDeepAnnotation( - Annotation[] annotations, Class<T> 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 extends Annotation> T getAnnotation(Class<T> annotationType) { - for (Annotation each : getAnnotations()) - if (annotationType.isInstance(each)) - return annotationType.cast(each); - return null; - } + + private static final Map<Class<?>, Class<?>> CONVERTABLE_TYPES_MAP = buildConvertableTypesMap(); + + private static Map<Class<?>, Class<?>> buildConvertableTypesMap() { + Map<Class<?>, Class<?>> map = new HashMap<Class<?>, Class<?>>(); + + 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 <T> void putSymmetrically(Map<T, T> map, T a, T b) { + map.put(a, b); + map.put(b, a); + } + + public static ArrayList<ParameterSignature> signatures(Method method) { + return signatures(method.getParameterTypes(), method + .getParameterAnnotations()); + } + + public static List<ParameterSignature> signatures(Constructor<?> constructor) { + return signatures(constructor.getParameterTypes(), constructor + .getParameterAnnotations()); + } + + private static ArrayList<ParameterSignature> signatures( + Class<?>[] parameterTypes, Annotation[][] parameterAnnotations) { + ArrayList<ParameterSignature> sigs = new ArrayList<ParameterSignature>(); + for (int i = 0; i < parameterTypes.length; i++) { + sigs.add(new ParameterSignature(parameterTypes[i], + parameterAnnotations[i])); + } + return sigs; + } + + private final Class<?> type; + + private final Annotation[] annotations; + + private ParameterSignature(Class<?> type, Annotation[] annotations) { + this.type = type; + this.annotations = annotations; + } + + public boolean canAcceptValue(Object candidate) { + return (candidate == null) ? !type.isPrimitive() : canAcceptType(candidate.getClass()); + } + + public boolean canAcceptType(Class<?> candidate) { + return type.isAssignableFrom(candidate) || + isAssignableViaTypeConversion(type, candidate); + } + + public boolean canPotentiallyAcceptType(Class<?> candidate) { + return candidate.isAssignableFrom(type) || + isAssignableViaTypeConversion(candidate, type) || + canAcceptType(candidate); + } + + private boolean isAssignableViaTypeConversion(Class<?> targetType, Class<?> candidate) { + if (CONVERTABLE_TYPES_MAP.containsKey(candidate)) { + Class<?> wrapperClass = CONVERTABLE_TYPES_MAP.get(candidate); + return targetType.isAssignableFrom(wrapperClass); + } else { + return false; + } + } + + public Class<?> getType() { + return type; + } + + public List<Annotation> getAnnotations() { + return Arrays.asList(annotations); + } + + public boolean hasAnnotation(Class<? extends Annotation> type) { + return getAnnotation(type) != null; + } + + public <T extends Annotation> T findDeepAnnotation(Class<T> annotationType) { + Annotation[] annotations2 = annotations; + return findDeepAnnotation(annotations2, annotationType, 3); + } + + private <T extends Annotation> T findDeepAnnotation( + Annotation[] annotations, Class<T> 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 extends Annotation> T getAnnotation(Class<T> annotationType) { + for (Annotation each : getAnnotations()) { + if (annotationType.isInstance(each)) { + return annotationType.cast(each); + } + } + return null; + } }
\ No newline at end of file |