All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.avh4.util.reflection.StackUtils Maven / Gradle / Ivy

package net.avh4.util.reflection;

import org.junit.Test;

import java.lang.reflect.Method;

public abstract class StackUtils {

    public static Class getCallingClass(final Class... alsoSkippable) {
        final StackTraceElement callingStackTraceElement = getCallingStackTraceElement(
                alsoSkippable);
        return getClass(callingStackTraceElement);
    }

    public static Class getClass(final StackTraceElement stackTraceElement) {
        final Class sourceClass;
        try {
            sourceClass = Class.forName(stackTraceElement.getClassName());
        } catch (final ClassNotFoundException e) {
            throw new RuntimeException(
                    "Could not load resources for test class: "
                            + stackTraceElement.getClassName(), e);
        }
        return sourceClass;
    }

    public static StackTraceElement getCallingStackTraceElement(
            final Class... alsoSkippable) {
        final StackTraceElement[] stackTrace = Thread.currentThread()
                .getStackTrace();
        int i = 0;
        while (isSkippable(stackTrace[i], alsoSkippable)) {
            i++;
        }
        i++;
        while (isSkippable(stackTrace[i], alsoSkippable)) {
            i++;
        }
        return stackTrace[i];
    }

    private static boolean isSkippable(
            final StackTraceElement stackTraceElement,
            final Class... alsoSkippable) {
        if (stackTraceElement.getClassName()
                .equals(Thread.class.getCanonicalName())) {
            return true;
        } else if (stackTraceElement.getClassName().equals(StackUtils.class
                .getCanonicalName())) {
            return true;
        } else {
            for (final Class skippable : alsoSkippable) {
                if (stackTraceElement.getClassName()
                        .equals(skippable.getCanonicalName())) {
                    return true;
                }
            }
            return false;
        }
    }

    public static StackTraceElement getCallingTestMethodStackTraceElement() {
        final StackTraceElement[] stackTrace = Thread.currentThread()
                .getStackTrace();
        int i = 0;
        while (!isTestMethod(stackTrace[i])) {
            i++;
        }
        return stackTrace[i];
    }

    private static boolean isTestMethod(
            final StackTraceElement stackTraceElement) {
        final Class clazz = getClass(stackTraceElement);
        try {
            final Method method = clazz
                    .getMethod(stackTraceElement.getMethodName());
            return isJUnit4TestMethod(method) || isJUnit3TestMethod(method);
        } catch (final SecurityException e) {
            throw new RuntimeException("Couldn't read stack trace information",
                    e);
        } catch (final NoSuchMethodException e) {
            // This will happen often since we are trying to get a method with
            // the method name take from the stack trace with no parameters. So
            // any method calls in the stack trace that do take parameters will
            // trigger this exception. (But this is safe to silently ignore,
            // since any method that has parameters will not be a test method.)
            return false;
        }
    }

    private static boolean isJUnit4TestMethod(final Method method) {
        final Test annotation = method.getAnnotation(Test.class);
        if (annotation == null) {
            return false;
        } else {
            return true;
        }
    }

    private static boolean isJUnit3TestMethod(final Method method) {
        if (method.getName().startsWith("test")) {
            return true;
        } else {
            return false;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy