package net.paoding.rose.util;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* 对栈进行简化的工具,去掉递归调用时循环出现的那部分栈。
*
* @author Li Weibo[weibo.leo@gmail.com]
*/
public class StackTraceSimplifier {
protected static Log logger = LogFactory.getLog(StackTraceSimplifier.class);
private static final Pattern EXCLUDED_STACK_TRACE = Pattern
.compile("^net\\.paoding\\.rose\\.web\\.(((ControllerInterceptorAdapter" +
"|InterceptorDelegate|OncePerRequestInterceptorDelegate).*)"
+ "|(impl\\.thread\\.ActionEngine\\$InvocationChainImpl.*))");
/**
* 对指定异常的栈进行简化
* @param e
*/
public static void simplify(Throwable e) {
if (!isSimplifyStackTrace()) {
return;
}
if (e.getCause() != null) {
simplify(e.getCause());
}
StackTraceElement[] trace = e.getStackTrace();
if (trace == null || trace.length == 0) {
return;
}
List<StackTraceElement> simpleTrace = new ArrayList<StackTraceElement>(
trace.length);
simpleTrace.add(trace[0]);
// Remove unnecessary stack trace elements.
for (int i = 1; i < trace.length; i++) {
if (EXCLUDED_STACK_TRACE.matcher(trace[i].getClassName()).matches()) {
continue;
}
simpleTrace.add(trace[i]);
}
e.setStackTrace(simpleTrace.toArray(new StackTraceElement[simpleTrace
.size()]));
}
private static boolean isSimplifyStackTrace() {
return !logger.isDebugEnabled();
}
public static void main(String[] args) {
String[] ss = {
"net.paoding.rose.web.impl.thread.ActionEngine$InvocationChainImpl.doNext(ActionEngine.java:468)",
"net.paoding.rose.web.InterceptorDelegate.roundInvocation(InterceptorDelegate.java:106)",
"net.paoding.rose.web.OncePerRequestInterceptorDelegate.roundInvocation(OncePerRequestInterceptorDelegate.java:67)",
"net.paoding.rose.web.ControllerInterceptorAdapter.round(ControllerInterceptorAdapter.java:136)" };
for (int i = 0; i < ss.length; i++) {
if (!EXCLUDED_STACK_TRACE.matcher(ss[i]).matches()) {
System.out.println(ss[i]);
}
}
System.out.println("done");
}
}