001package org.unix4j.util; 002 003/** 004 * Utility class to evaluate the {@link StackTraceElement} corresponding to a 005 * calling method in the caller stack. 006 */ 007public class StackTraceUtil { 008 009 /** 010 * Returns the stack trace element corresponding to the direct caller 011 * method, that is, the method which calls this method. 012 */ 013 public static StackTraceElement getCurrentMethodStackTraceElement() { 014 return internalGetCurrentMethodStackTraceElement(1); 015 } 016 017 /** 018 * Returns the stack trace element belonging to the 019 * <code>callerOffset<sup>th</sup></code> caller of the calling method. 020 * <p> 021 * For example, {@code callerOffset=0} returns the stack trace element of 022 * the direct caller of this method; {@code callerOffset=1} corresponds to 023 * the method calling the direct caller method, etc. 024 * 025 * @param callerOffset 026 * the index of the stack trace element in the caller stack, 027 * where {@code callerOffset=0} corresponds to the direct caller 028 * of this method 029 */ 030 public static StackTraceElement getCurrentMethodStackTraceElement(int callerOffset) { 031 return internalGetCurrentMethodStackTraceElement(callerOffset + 1); 032 } 033 034 private static StackTraceElement internalGetCurrentMethodStackTraceElement(int callerOffset) { 035 // trc[0] Thread.dumpThreads(native) 036 // trc[1] Thread.getStackTrace(..) 037 // trc[2] StackTrace.internalGetCurrentMethodStackTraceElement(..) 038 // trc[3] is what we want for offset == 0! 039 040 // NOTE sometimes also 041 // trc[0] Thread.getStackTrace(..) 042 // trc[1] StackTrace.internalGetCurrentMethodStackTraceElement(..) 043 // trc[2] is what we want for offset == 0! 044 StackTraceElement[] trc = Thread.currentThread().getStackTrace(); 045 for (int i = 0; i < trc.length; i++) { 046 if (trc[i].getClassName().equals(StackTraceUtil.class.getName()) && trc[i].getMethodName().equals("internalGetCurrentMethodStackTraceElement")) { 047 return trc[callerOffset + i + 1]; 048 } 049 } 050 throw new RuntimeException("internal error: current method not found"); 051 } 052 053 // no instances 054 private StackTraceUtil() { 055 } 056}