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

org.test4j.mock.faking.util.StackTrace Maven / Gradle / Ivy

package org.test4j.mock.faking.util;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static org.test4j.mock.faking.util.ReflectUtility.doThrow;

/**
 * Provides utility methods to extract and filter stack trace information.
 *
 * @author wudarui
 */
@SuppressWarnings({"unused"})
public final class StackTrace {
    private final Throwable throwable;


    private StackTrace(Throwable throwable) {
        this.throwable = throwable;
    }

    public static void filterStackTrace(Throwable t) {
        if (t == null) {
            return;
        }
        try {
            new StackTrace(t).filter(new HashSet<>());
        } catch (Exception e) {
            doThrow(t);
        }
    }

    /**
     * 过滤异常栈
     *
     * @param hasFilters 已过滤异常
     */
    void filter(Set hasFilters) {
        int objId = System.identityHashCode(this.throwable);
        if (hasFilters.contains(objId) || this.throwable == null) {
            return;
        } else {
            hasFilters.add(objId);
        }
        StackTraceElement[] elements = this.throwable.getStackTrace();
        StackTraceElement[] filtered = new StackTraceElement[elements.length];
        int index = 0;
        for (StackTraceElement ste : elements) {
            if (filter(ste)) {
                continue;
            }
            filtered[index] = ste;
            index++;
        }

        StackTraceElement[] newStackTrace = new StackTraceElement[index];
        System.arraycopy(filtered, 0, newStackTrace, 0, index);
        throwable.setStackTrace(newStackTrace);
        new StackTrace(throwable.getCause()).filter(hasFilters);
    }

    /**
     * 是否被过滤掉
     *
     * @param ste StackTraceElement
     * @return ignore
     */
    private boolean filter(StackTraceElement ste) {
        if (ste.getFileName() == null) {
            return true;
        }
        String className = ste.getClassName();
        return isJDK(ste) || is3rdInternalMethod(className);
    }

    /**
     * JDK
     *
     * @param ste StackTraceElement
     * @return ignore
     */
    private static boolean isJDK(StackTraceElement ste) {
        String className = ste.getClassName();
        return className.startsWith("sun.") && !ste.isNativeMethod() ||
            className.startsWith("jdk.") ||
            className.startsWith("java.util.");
    }

    /**
     * 部分三方工具内部方法
     *
     * @param className class name
     * @return ignore
     */
    private static boolean is3rdInternalMethod(String className) {
        for (String pack : Start_Filters) {
            if (className.startsWith(pack)) {
                return true;
            }
        }
        for (String pack : Contain_Filters) {
            if (className.contains(pack)) {
                return true;
            }
        }
        return false;
    }

    /**
     * package以下列开头的过滤掉
     */
    private static final List Start_Filters = Arrays.asList(
        "org.junit.",
        "org.testng.",
        "junit.framework",
        "org.test4j.integration.",
        "org.test4j.mock.faking.",
        "org.test4j.exception.Exceptions",
        "org.test4j.module.database.operator.",
        "org.test4j.module.spec.internal."
    );
    /**
     * package包含下列路径的过滤掉
     */
    private static final List Contain_Filters = Arrays.asList(
        "$$EnhancerByCGLIB$$",
        ".reflect.",
        ".surefire.",
        ".gradle.",
        ".intellij.",
        ".eclipse.",
        ".jdt."
    );


    /**
     * 将异常日志转换为字符串
     *
     * @param e Throwable
     * @return ignore
     */
    public static String toString(Throwable e) {
        if (e == null) {
            return "";
        }
        try (StringWriter writer = new StringWriter(); PrintWriter print = new PrintWriter(writer)) {
            e.printStackTrace(print);
            return writer.toString();
        } catch (IOException ex) {
            ex.printStackTrace();
            return e.getMessage();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy