1 8 package org.apache.avalon.excalibur.util; 9 10 import java.io.PrintWriter ; 11 import java.io.StringWriter ; 12 import java.util.ArrayList ; 13 14 22 public final class StackIntrospector 23 { 24 29 private final static class CallStack 30 extends SecurityManager 31 { 32 39 public Class [] get() 40 { 41 return getClassContext(); 42 } 43 } 44 45 private static CallStack c_callStack; 47 48 52 private StackIntrospector() 53 { 54 } 55 56 63 private synchronized static Class [] getCallStackAsClassArray() 64 throws SecurityException 65 { 66 if( null == c_callStack ) 68 { 69 c_callStack = new CallStack(); 71 } 72 73 return c_callStack.get(); 74 } 75 76 85 public final static Class getCallerClass( final int index ) 86 throws SecurityException 87 { 88 final Class [] stack = getCallStackAsClassArray(); 89 if( index < stack.length ) return stack[ index ]; 90 else return null; 91 } 92 93 102 public final static Class getCallerClass( final Class clazz ) 103 throws SecurityException 104 { 105 final Class [] stack = getCallStackAsClassArray(); 106 107 for( int i = stack.length - 1; i >= 0; i-- ) 109 { 110 if( clazz.isAssignableFrom( stack[ i ] ) ) 111 { 112 return stack[ i + 1 ]; 114 } 115 } 116 117 return null; 119 } 120 121 127 public final static String getCallerMethod( final int index ) 128 { 129 final String [] callStack = getCallStackAsStringArray(); 130 131 int actualIndex = index + 1; 133 if( actualIndex < callStack.length ) return callStack[ actualIndex ]; 134 else return null; 135 } 136 137 143 public final static String getCallerMethod( final Class clazz ) 144 { 145 final String [] callStack = getCallStackAsStringArray(); 146 final int index = getCallerIndex( clazz.getName(), callStack ); 147 148 if( -1 == index ) return null; 149 else 150 { 151 return callStack[ index ]; 152 } 153 } 154 155 168 public final static String [] getCallerStack( final Class clazz, int count ) 169 { 170 final String [] callStack = getCallStackAsStringArray(); 171 final int start = getCallerIndex( clazz.getName(), callStack ); 172 if( -1 == start ) return null; 173 174 final int size = Math.min( count, callStack.length - start ); 175 176 final String [] result = new String [ size ]; 177 for( int i = 0; i < size; i++ ) 178 { 179 result[ i ] = callStack[ start + i ]; 180 } 181 182 return result; 183 } 184 185 194 public final static String [] getCallStackAsStringArray() 195 { 196 final StringWriter sw = new StringWriter (); 198 final Throwable throwable = new Throwable (); 199 throwable.printStackTrace( new PrintWriter ( sw, true ) ); 200 final StringBuffer buffer = sw.getBuffer(); 201 202 final ArrayList stack = new ArrayList (); 204 205 final StringBuffer line = new StringBuffer (); 207 final int length = buffer.length(); 208 209 boolean found = false; 211 int state = 0; 212 213 for( int i = 0; i < length; i++ ) 215 { 216 final char ch = buffer.charAt( i ); 217 218 switch( state ) 219 { 220 case 0: 221 if( '\n' == ch ) state = 1; 223 break; 224 225 case 1: 226 if( 't' == ch ) state = 2; 228 break; 229 230 case 2: 231 line.setLength( 0 ); 233 state = 3; 234 break; 235 236 case 3: 237 if( '\n' != ch ) line.append( ch ); 239 else 240 { 241 final String method = line.toString(); 244 stack.add( method ); 245 246 state = 1; 248 } 249 } 250 } 251 252 return (String [])stack.toArray( new String [ 0 ] ); 253 } 254 255 263 private static int getCallerIndex( final String prefix, final String [] callStack ) 264 { 265 boolean found = false; 266 for( int i = 0; i < callStack.length; i++ ) 267 { 268 final boolean match = callStack[ i ].startsWith( prefix ); 270 if( !match ) continue; 271 272 if( !found ) found = true; 275 else 276 { 277 return i; 279 } 280 } 281 282 return -1; 283 } 284 } 285 | Popular Tags |