Common utility routines used by both java.lang and
java.lang.reflect
| Method from sun.reflect.Reflection Detail: |
public static void ensureMemberAccess(Class currentClass,
Class memberClass,
Object target,
int modifiers) throws IllegalAccessException {
if (currentClass == null || memberClass == null) {
throw new InternalError();
}
if (!verifyMemberAccess(currentClass, memberClass, target, modifiers)) {
throw new IllegalAccessException("Class " + currentClass.getName() +
" can not access a member of class " +
memberClass.getName() +
" with modifiers \"" +
Modifier.toString(modifiers) +
"\"");
}
}
|
public static Field[] filterFields(Class containingClass,
Field[] fields) {
if (fieldFilterMap == null) {
// Bootstrapping
return fields;
}
return (Field[])filter(fields, fieldFilterMap.get(containingClass));
}
|
public static Method[] filterMethods(Class containingClass,
Method[] methods) {
if (methodFilterMap == null) {
// Bootstrapping
return methods;
}
return (Method[])filter(methods, methodFilterMap.get(containingClass));
}
|
public static native Class getCallerClass(int realFramesToSkip)
Returns the class of the method realFramesToSkip
frames up the stack (zero-based), ignoring frames associated
with java.lang.reflect.Method.invoke() and its implementation.
The first frame is that associated with this method, so
getCallerClass(0) returns the Class object for
sun.reflect.Reflection. Frames associated with
java.lang.reflect.Method.invoke() and its implementation are
completely ignored and do not count toward the number of "real"
frames skipped. |
static boolean isSubclassOf(Class queryClass,
Class ofClass) {
while (queryClass != null) {
if (queryClass == ofClass) {
return true;
}
queryClass = queryClass.getSuperclass();
}
return false;
}
|
public static boolean quickCheckMemberAccess(Class memberClass,
int modifiers) {
Map< Class,String[] > map = new HashMap< Class,String[] >();
map.put(Reflection.class,
new String[] {"fieldFilterMap", "methodFilterMap"});
map.put(System.class, new String[] {"security"});
fieldFilterMap = map;
methodFilterMap = new HashMap< Class,String[] >();
return Modifier.isPublic(getClassAccessFlags(memberClass) & modifiers);
}
A quick "fast-path" check to try to avoid getCallerClass()
calls. |
public static synchronized void registerFieldsToFilter(Class containingClass,
String fieldNames) {
fieldFilterMap =
registerFilter(fieldFilterMap, containingClass, fieldNames);
}
|
public static synchronized void registerMethodsToFilter(Class containingClass,
String methodNames) {
methodFilterMap =
registerFilter(methodFilterMap, containingClass, methodNames);
}
|
public static boolean verifyMemberAccess(Class currentClass,
Class memberClass,
Object target,
int modifiers) {
// Verify that currentClass can access a field, method, or
// constructor of memberClass, where that member's access bits are
// "modifiers".
boolean gotIsSameClassPackage = false;
boolean isSameClassPackage = false;
if (currentClass == memberClass) {
// Always succeeds
return true;
}
if (!Modifier.isPublic(getClassAccessFlags(memberClass))) {
isSameClassPackage = isSameClassPackage(currentClass, memberClass);
gotIsSameClassPackage = true;
if (!isSameClassPackage) {
return false;
}
}
// At this point we know that currentClass can access memberClass.
if (Modifier.isPublic(modifiers)) {
return true;
}
boolean successSoFar = false;
if (Modifier.isProtected(modifiers)) {
// See if currentClass is a subclass of memberClass
if (isSubclassOf(currentClass, memberClass)) {
successSoFar = true;
}
}
if (!successSoFar && !Modifier.isPrivate(modifiers)) {
if (!gotIsSameClassPackage) {
isSameClassPackage = isSameClassPackage(currentClass,
memberClass);
gotIsSameClassPackage = true;
}
if (isSameClassPackage) {
successSoFar = true;
}
}
if (!successSoFar) {
return false;
}
if (Modifier.isProtected(modifiers)) {
// Additional test for protected members: JLS 6.6.2
Class targetClass = (target == null ? memberClass : target.getClass());
if (targetClass != currentClass) {
if (!gotIsSameClassPackage) {
isSameClassPackage = isSameClassPackage(currentClass, memberClass);
gotIsSameClassPackage = true;
}
if (!isSameClassPackage) {
if (!isSubclassOf(targetClass, currentClass)) {
return false;
}
}
}
}
return true;
}
|