Open Source Repository

Home /junit/junit-4.10 | Repository Home


org/junit/experimental/theories/ParameterSignature.java
/**
 
 */
package org.junit.experimental.theories;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

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;
  }
}