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

clime.messadmin.utils.StackIntrospector Maven / Gradle / Ivy

Go to download

Notification system and Session administration for J2EE Web Applications

The newest version!
/**
 * 
 */
package clime.messadmin.utils;


/**
 * A set of utilities to inspect current stack frame.
 * Heavily inspired by, and based on, Apache LogKit's org.apache.log.util.StackIntrospector
 * 
 * Note: this information is also available since Java 1.4 via
 * {@link Throwable#getStackTrace()}
 * 
 * @author Cédrik LIME
 */
public final class StackIntrospector {
	/* Magic number CALL_CONTEXT_OFFSET identifies our caller */
	private static final int CALL_CONTEXT_OFFSET = 2; // may need to change if this class is redesigned

	/**
	 * Hack to get the call stack as an array of classes.
	 * The SecurityManager class provides this information as a protected method,
	 * so all we have to do is violate OO encapsulation principles and
	 * permit its access through a new public method!
	 */
	private static final class ClassContext extends SecurityManager {
		/**
		 * @throws SecurityException if an existing SecurityManager disallows construction of another SecurityManager
		 */
		ClassContext() {
			super();
		}
		/**
		 * Returns the current execution stack as an array of classes.
* The length of the array is the number of methods on the execution * stack. The element at index 0 is the class of the * currently executing method, the element at index 1 is * the class of that method's caller, and so on. * * @return the execution stack. * @see @link SecurityManager#getClassContext() */ public Class[] get() { return getClassContext(); } } /** * Create Hack SecurityManager to get ClassContext * @throws SecurityException if an existing SecurityManager disallows construction of another SecurityManager */ private static final ClassContext CLASS_CONTEXT = new ClassContext(); /** * Private constructor to block instantiation. */ private StackIntrospector() { /* assert false; */ } /** * Find our caller's caller. * May return null if caller not found on execution stack. */ public static Class getCallerClass() { Class[] stack = CLASS_CONTEXT.get(); if (stack.length <= CALL_CONTEXT_OFFSET + 1) { return null; } Class c = stack[CALL_CONTEXT_OFFSET + 1]; return c; } /** * Find the caller of the passed in Class. * May return null if caller not found on execution stack. * * @param clazz the Class to search for on stack to find caller of * @return the Class of object that called parrameter class */ public static Class getCallerClass(final Class clazz) throws SecurityException { // return getCallerClass(clazz, 0); // can't do that, as this adds a stack frame... final Class[] stack = CLASS_CONTEXT.get(); if (stack.length <= CALL_CONTEXT_OFFSET) { return null; } // Traverse the call stack until we find clazz for (int i = CALL_CONTEXT_OFFSET; i < stack.length; ++i) { if (clazz.isAssignableFrom(stack[i])) { // Found: the caller is the previous stack element return i+1 >= stack.length ? null : stack[i + 1]; } } //Unable to locate class in call stack return null; } /** * Find the caller of the passed in Class. * May return null if caller not found on execution stack. * * @param clazz the Class to search for on stack to find caller of * @param stackDepthOffset Offset call-stack depth to find caller * @return the Class of object that called parrameter class */ public static Class getCallerClass(final Class clazz, final int stackDepthOffset) { final Class[] stack = CLASS_CONTEXT.get(); if (stack.length <= stackDepthOffset + CALL_CONTEXT_OFFSET) { return null; } // Traverse the call stack until we find clazz for (int i = stackDepthOffset + CALL_CONTEXT_OFFSET; i < stack.length; ++i) { if (clazz.isAssignableFrom(stack[i])) { // Found: the caller is the previous stack element return i+1 >= stack.length ? null : stack[i + 1]; } } //Unable to locate class in call stack return null; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy