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

net.thucydides.core.reflection.StackTraceAnalyser Maven / Gradle / Ivy

There is a newer version: 2.0.7
Show newest version
package net.thucydides.core.reflection;

import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Method;
import java.util.List;


public class StackTraceAnalyser {

    private final StackTraceElement stackTraceElement;
    private final Logger logger = LoggerFactory.getLogger(StackTraceAnalyser.class);

    private StackTraceAnalyser(StackTraceElement stackTraceElement) {
        this.stackTraceElement = stackTraceElement;
    }

    public static StackTraceAnalyser forStackTraceElement(StackTraceElement stackTraceElement) {
        return new StackTraceAnalyser(stackTraceElement);
    }

    public Method getMethod() {
        try {
            if (allowedClassName(stackTraceElement.getClassName()) && !lambda(stackTraceElement.getClassName()) ) {
                Class callingClass = Class.forName(stackTraceElement.getClassName());
                Method matchingMethod = extractMethod(stackTraceElement, callingClass);
                if (matchingMethod != null) {
                    return matchingMethod;
                }
            }
        } catch (ClassNotFoundException classNotFoundIgnored) {
            logger.debug("Couldn't find class during Stack analysis: " + classNotFoundIgnored.getLocalizedMessage());
        } catch (NoClassDefFoundError noClassDefFoundErrorIgnored) {
            logger.debug("Couldn't find class definition during Stack analysis: " + noClassDefFoundErrorIgnored.getLocalizedMessage());
        }
        return null;
    }

    private boolean lambda(String className) {
        return className.contains("$$Lambda$");
    }

    public static Method extractMethod(StackTraceElement stackTraceElement, Class callingClass)  {
        Class targetClass;
        if (isInstrumentedMethod(stackTraceElement)) {
            targetClass = callingClass.getSuperclass();
        } else {
            targetClass = callingClass;
        }
        try {
            return targetClass.getMethod(stackTraceElement.getMethodName());
        } catch (NoSuchMethodException e) {
            return null;
        }
    }

    private static boolean isInstrumentedMethod(StackTraceElement stackTraceElement) {
        return StringUtils.isNotEmpty(stackTraceElement.getFileName()) && (stackTraceElement.getFileName().equals(""));
    }

    private boolean allowedClassName(String className) {
        return !((className.startsWith("sun.")) || (className.startsWith("java.")) || (className.contains("$")));
    }

    public static List inscopeMethodsIn(StackTraceElement[] stackTrace) {
        List methods = Lists.newArrayList();
        for(StackTraceElement stackTraceElement : stackTrace) {
            Method method = StackTraceAnalyser.forStackTraceElement(stackTraceElement).getMethod();
            if (method != null) {
                methods.add(method);
            }
        }
        return methods;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy