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

com.github.phantomthief.util.StackTraceProviderJdk8 Maven / Gradle / Ivy

There is a newer version: 0.1.55
Show newest version
package com.github.phantomthief.util;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Predicate;

import javax.annotation.Nullable;

import org.apache.commons.lang3.StringUtils;

/**
 * @author w.vela
 * Created on 2019-08-01.
 */
class StackTraceProviderJdk8 implements StackTraceProvider {

    static final String[] REFLECTION_PREFIXES = {"sun.reflect.", "java.lang.reflect.", "jdk.internal.reflect."};

    @Nullable
    @Override
    public StackTraceElement getCallerPlace(Predicate locationAwareClassChecker, Predicate ignore) {
        boolean afterSelf = false;
        boolean afterDeprecated = false;
        String deprecatedClass = null;
        // 之所以用异常获取而不是Thread.currentThread().getStackTrace(),是因为它内部实现其实也是判断当前线程了
        for (StackTraceElement stack : (new Exception()).getStackTrace()) {
            String stackClassName = stack.getClassName();
            if (isReflection(stackClassName)) {
                continue;
            }
            if (locationAwareClassChecker.test(stackClassName)) {
                afterSelf = true;
                continue;
            }
            if (afterSelf) {
                if (deprecatedClass == null) {
                    deprecatedClass = stackClassName;
                }
            }
            if (stackClassName.equals(deprecatedClass)) {
                afterDeprecated = true;
                continue;
            }
            if (afterDeprecated) {
                if (ignore.test(stackClassName)) {
                    continue;
                }
                return stack;
            }
        }
        return null;
    }

    /**
     * at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
     * at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
     * at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
     * at java.lang.reflect.Method.invoke(Method.java:498)
     */
    private boolean isReflection(String stackClassName) {
        return StringUtils.startsWithAny(stackClassName, REFLECTION_PREFIXES);
    }

    private Set toString(Class[] locationAwareClasses) {
        int length = locationAwareClasses.length;
        if (length == 1) { // optimize
            return Collections.singleton(locationAwareClasses[0].getName());
        }
        Set result = new HashSet<>(length);
        for (Class locationAwareClass : locationAwareClasses) {
            result.add(locationAwareClass.getName());
        }
        return result;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy