001 /* 002 * Licensed under the Apache License, Version 2.0 (the "License"); 003 * you may not use this file except in compliance with the License. 004 * You may obtain a copy of the License at 005 * 006 * http://www.apache.org/licenses/LICENSE-2.0 007 * 008 * Unless required by applicable law or agreed to in writing, software 009 * distributed under the License is distributed on an "AS IS" BASIS, 010 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 011 * See the License for the specific language governing permissions and 012 * limitations under the License. 013 */ 014 package org.apache.commons.classscan.util; 015 016 public abstract class CallStack { 017 018 interface GetCallerStrategy { 019 Class<?> getCallerClass(int callStackDepth); 020 } 021 022 private static GetCallerStrategy strategy; 023 024 static class SunReflection implements GetCallerStrategy { 025 SunReflection() { 026 // cause load of sun.reflect.Reflection class 027 sun.reflect.Reflection.getCallerClass(0); 028 } 029 030 @Override 031 public Class<?> getCallerClass(int callStackDepth) { 032 return sun.reflect.Reflection.getCallerClass(callStackDepth); 033 } 034 } 035 036 static class SecurityManagerMethod extends SecurityManager implements GetCallerStrategy { 037 @Override 038 public Class<?> getCallerClass(int callStackDepth) { 039 return getClassContext()[callStackDepth]; 040 } 041 } 042 043 static { 044 try { 045 strategy= new SunReflection(); 046 } 047 catch(Throwable t) { 048 strategy= new SecurityManagerMethod(); 049 } 050 } 051 052 /** 053 * Return the Class of the caller. 054 * @param callStackDepth The number of stack frames to skip. 055 * A value of 0 will return the calling Class of this method. 056 * A value of 1 will return the calling Class of the caller of this method. 057 * @return The Class at callStackDepth down the call stack 058 */ 059 public static Class<?> getCallerClass(int callStackDepth) { 060 return strategy.getCallerClass(callStackDepth+3); 061 } 062 063 /** 064 * Return the ClassLoader of the caller. 065 * @param callStackDepth The number of stack frames to skip. 066 * A value of 0 will return the ClassLoader of the calling Class of this method. 067 * A value of 1 will return the ClassLoader of the calling Class of the caller of this method. 068 * @return The ClassLoader of the Class at callStackDepth down the call stack 069 */ 070 public static ClassLoader getClassLoader(int callStackDepth) { 071 Class<?> rc= strategy.getCallerClass(callStackDepth+3); 072 return rc.getClassLoader(); 073 } 074 }