001package com.hfg.util; 002 003 004 005import com.hfg.util.collection.CollectionUtil; 006 007import java.util.List; 008 009//------------------------------------------------------------------------------ 010/** 011 Utility functions for manipulating StackTrace information. 012 013 * @author J. Alex Taylor, hairyfatguy.com 014 */ 015//------------------------------------------------------------------------------ 016// com.hfg XML/HTML Coding Library 017// 018// This library is free software; you can redistribute it and/or 019// modify it under the terms of the GNU Lesser General Public 020// License as published by the Free Software Foundation; either 021// version 2.1 of the License, or (at your option) any later version. 022// 023// This library is distributed in the hope that it will be useful, 024// but WITHOUT ANY WARRANTY; without even the implied warranty of 025// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 026// Lesser General Public License for more details. 027// 028// You should have received a copy of the GNU Lesser General Public 029// License along with this library; if not, write to the Free Software 030// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 031// 032// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com 033// jataylor@hairyfatguy.com 034//------------------------------------------------------------------------------ 035 036public class StackTraceUtil 037{ 038 //########################################################################## 039 // PUBLIC FUNCTIONS 040 //########################################################################## 041 042 //-------------------------------------------------------------------------- 043 public static String getCurrentMethodName() 044 { 045 StackTraceElement e[] = Thread.currentThread().getStackTrace(); 046 return e[2].getMethodName(); 047 } 048 049 //-------------------------------------------------------------------------- 050 public static String getCallingMethodName() 051 { 052 StackTraceElement e[] = Thread.currentThread().getStackTrace(); 053 return e[3].getMethodName(); 054 } 055 056 //-------------------------------------------------------------------------- 057 public static String getCurrentClassName() 058 { 059 StackTraceElement e[] = Thread.currentThread().getStackTrace(); 060 return e[2].getClassName(); 061 } 062 063 //-------------------------------------------------------------------------- 064 public static String getCallingClassName() 065 { 066 StackTraceElement e[] = Thread.currentThread().getStackTrace(); 067 return e[3].getClassName(); 068 } 069 070 //-------------------------------------------------------------------------- 071 public static int getCurrentLineNumber() 072 { 073 StackTraceElement e[] = Thread.currentThread().getStackTrace(); 074 return e[2].getLineNumber(); 075 } 076 077 //-------------------------------------------------------------------------- 078 public static StackTraceElement getCallingStackTraceElement(List<StackTraceElementFilter> inExclusions) 079 { 080 StackTraceElement caller = null; 081 082 StackTraceElement e[] = Thread.currentThread().getStackTrace(); 083 // TODO: Is using Throwable faster? 084// StackTraceElement e[] = new Throwable().getStackTrace(); 085 if (CollectionUtil.hasValues(inExclusions)) 086 { 087 for (int i = 3; i < e.length; i++) 088 { 089 StackTraceElement element = e[i]; 090 091 boolean skip = false; 092 for (StackTraceElementFilter exclusionFilter : inExclusions) 093 { 094 if (exclusionFilter.accept(element)) 095 { 096 skip = true; 097 break; 098 } 099 } 100 101 if (! skip) 102 { 103 caller = element; 104 break; 105 } 106 } 107 } 108 else 109 { 110 caller = e[3]; 111// caller = e[2]; // for Throwable version 112 } 113 114 return caller; 115 } 116 117 //-------------------------------------------------------------------------- 118 /** 119 Returns the root exception from an exception. 120 * @param inException the exception from which to find the root exception 121 * @return Throwable the root exception 122 */ 123 public static Throwable getRootException(Throwable inException) 124 { 125 Throwable rootException = inException; 126 while (rootException.getCause() != null) 127 { 128 rootException = rootException.getCause(); 129 } 130 131 return rootException; 132 } 133 134 //-------------------------------------------------------------------------- 135 /** 136 Returns a stack trace formatted similarly to the one produced by e.printStackTrace(). 137 * @param inException the exception from which to get the stack trace 138 * @return String version of the stack trace 139 */ 140 public static String getExceptionStackTrace(Throwable inException) 141 { 142 143 StringBuilderPlus buffer = new StringBuilderPlus().setDelimiter(System.getProperty("line.separator")); 144 145 146 Throwable e = inException; 147 while (e != null) 148 { 149 StackTraceElement[] stackTrace = e.getStackTrace(); 150 151 if (e != inException) 152 { 153 buffer.delimitedAppend("Caused by: "); 154 } 155 156 buffer.append(e.getClass().getName() + ": "); 157 158 if (e.getMessage() != null) 159 { 160 buffer.append(e.getMessage()); 161 } 162 163 for (StackTraceElement element : stackTrace) 164 { 165 buffer.delimitedAppend("\tat "); 166 buffer.append(element.toString()); 167 } 168 169 e = e.getCause(); 170 } 171 172 return buffer.toString(); 173 } 174}