Home | History | Annotate | Download | only in matchers
      1 package org.junit.internal.matchers;
      2 
      3 import java.lang.reflect.Method;
      4 
      5 import org.hamcrest.BaseMatcher;
      6 import org.junit.internal.MethodSorter;
      7 
      8 /**
      9  * Convenient base class for Matchers that require a non-null value of a specific type.
     10  * This simply implements the null check, checks the type and then casts.
     11  *
     12  * @author Joe Walnes
     13  * @deprecated Please use {@link org.hamcrest.TypeSafeMatcher}.
     14  */
     15 @Deprecated
     16 public abstract class TypeSafeMatcher<T> extends BaseMatcher<T> {
     17 
     18     private Class<?> expectedType;
     19 
     20     /**
     21      * Subclasses should implement this. The item will already have been checked for
     22      * the specific type and will never be null.
     23      */
     24     public abstract boolean matchesSafely(T item);
     25 
     26     protected TypeSafeMatcher() {
     27         expectedType = findExpectedType(getClass());
     28     }
     29 
     30     private static Class<?> findExpectedType(Class<?> fromClass) {
     31         for (Class<?> c = fromClass; c != Object.class; c = c.getSuperclass()) {
     32             for (Method method : MethodSorter.getDeclaredMethods(c)) {
     33                 if (isMatchesSafelyMethod(method)) {
     34                     return method.getParameterTypes()[0];
     35                 }
     36             }
     37         }
     38 
     39         throw new Error("Cannot determine correct type for matchesSafely() method.");
     40     }
     41 
     42     private static boolean isMatchesSafelyMethod(Method method) {
     43         return method.getName().equals("matchesSafely")
     44                 && method.getParameterTypes().length == 1
     45                 && !method.isSynthetic();
     46     }
     47 
     48     protected TypeSafeMatcher(Class<T> expectedType) {
     49         this.expectedType = expectedType;
     50     }
     51 
     52     /**
     53      * Method made final to prevent accidental override.
     54      * If you need to override this, there's no point on extending TypeSafeMatcher.
     55      * Instead, extend the {@link BaseMatcher}.
     56      */
     57     @SuppressWarnings({"unchecked"})
     58     public final boolean matches(Object item) {
     59         return item != null
     60                 && expectedType.isInstance(item)
     61                 && matchesSafely((T) item);
     62     }
     63 }
     64