mirror of
https://github.com/2003scape/deep-c-rsc.git
synced 2024-03-22 05:49:51 -04:00
167 lines
5.1 KiB
Java
167 lines
5.1 KiB
Java
/*
|
|
* @(#) $(JCGO)/goclsp/vm/sun/reflect/Reflection.java --
|
|
* JSR 166 reflection hooks.
|
|
**
|
|
* Project: JCGO (http://www.ivmaisoft.com/jcgo/)
|
|
* Copyright (C) 2001-2008 Ivan Maidanski <ivmai@ivmaisoft.com>
|
|
* All rights reserved.
|
|
**
|
|
* Class specification origin: GNU Classpath v0.93 vm/reference
|
|
*/
|
|
|
|
/*
|
|
* This is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2, or (at your option)
|
|
* any later version.
|
|
**
|
|
* This software is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License (GPL) for more details.
|
|
**
|
|
* Linking this library statically or dynamically with other modules is
|
|
* making a combined work based on this library. Thus, the terms and
|
|
* conditions of the GNU General Public License cover the whole
|
|
* combination.
|
|
**
|
|
* As a special exception, the copyright holders of this library give you
|
|
* permission to link this library with independent modules to produce an
|
|
* executable, regardless of the license terms of these independent
|
|
* modules, and to copy and distribute the resulting executable under
|
|
* terms of your choice, provided that you also meet, for each linked
|
|
* independent module, the terms and conditions of the license of that
|
|
* module. An independent module is a module which is not derived from
|
|
* or based on this library. If you modify this library, you may extend
|
|
* this exception to your version of the library, but you are not
|
|
* obligated to do so. If you do not wish to do so, delete this
|
|
* exception statement from your version.
|
|
*/
|
|
|
|
package sun.reflect;
|
|
|
|
import gnu.classpath.VMStackWalker;
|
|
|
|
import java.lang.reflect.Modifier;
|
|
|
|
public class Reflection
|
|
{ /* VM class */
|
|
|
|
public Reflection() {}
|
|
|
|
public static Class getCallerClass(int depth)
|
|
{
|
|
Class[] ctx = VMStackWalker.getClassContext();
|
|
return depth >= 0 && ctx.length > depth ? ctx[depth] : null;
|
|
}
|
|
|
|
public static boolean quickCheckMemberAccess(Class memberClass,
|
|
int modifiers)
|
|
{
|
|
return Modifier.isPublic(getClassAccessFlags(memberClass) & modifiers);
|
|
}
|
|
|
|
public static void ensureMemberAccess(Class callerClass, Class declarerClass,
|
|
Object obj, int modifiers)
|
|
throws IllegalAccessException
|
|
{
|
|
if (callerClass == null || declarerClass == null)
|
|
throw new InternalError("ensureMemberAccess");
|
|
if (!verifyMemberAccess(callerClass, declarerClass, obj, modifiers))
|
|
throw new IllegalAccessException("class " + callerClass.getName() +
|
|
" can not access a member of class " + declarerClass.getName() +
|
|
" with modifiers \"" + Modifier.toString(modifiers) + "\"");
|
|
}
|
|
|
|
public static boolean verifyMemberAccess(Class callerClass,
|
|
Class declarerClass, Object obj, int modifiers)
|
|
{
|
|
if (callerClass != declarerClass)
|
|
{
|
|
boolean isPkgChecked = false;
|
|
if (!Modifier.isPublic(getClassAccessFlags(declarerClass)))
|
|
{
|
|
if (!isSameClassPackage(callerClass, declarerClass))
|
|
return false;
|
|
isPkgChecked = true;
|
|
}
|
|
if (!Modifier.isPublic(modifiers))
|
|
{
|
|
if (Modifier.isProtected(modifiers))
|
|
{
|
|
if (!isPkgChecked && !isSubclassOf(callerClass, declarerClass))
|
|
{
|
|
if (!isSameClassPackage(callerClass, declarerClass))
|
|
return false;
|
|
isPkgChecked = true;
|
|
}
|
|
Class aclass = obj != null ? obj.getClass() : declarerClass;
|
|
if (aclass != callerClass && !isPkgChecked &&
|
|
!isSameClassPackage(callerClass, declarerClass) &&
|
|
!isSubclassOf(aclass, callerClass))
|
|
return false;
|
|
}
|
|
else if (Modifier.isPrivate(modifiers) || (!isPkgChecked &&
|
|
!isSameClassPackage(callerClass, declarerClass)))
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static boolean isSubclassOf(Class queryClass, Class ofClass)
|
|
{
|
|
while (queryClass != null)
|
|
{
|
|
if (queryClass == ofClass)
|
|
return true;
|
|
queryClass = queryClass.getSuperclass();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private static boolean isSameClassPackage(Class aclass1, Class aclass2)
|
|
{
|
|
return isSameClassPackage(aclass1.getClassLoader(), aclass1.getName(),
|
|
aclass2.getClassLoader(), aclass2.getName());
|
|
}
|
|
|
|
private static boolean isSameClassPackage(ClassLoader loader1,
|
|
String className1, ClassLoader loader2, String className2)
|
|
{
|
|
if (loader1 != loader2)
|
|
return false;
|
|
int i1 = className1.lastIndexOf('.');
|
|
int i2 = className2.lastIndexOf('.');
|
|
if (i1 == -1 || i2 == -1)
|
|
return i1 == i2;
|
|
int k1 = 0;
|
|
if (className1.charAt(0) == '[')
|
|
{
|
|
do
|
|
{
|
|
k1++;
|
|
} while (className1.charAt(k1) == '[');
|
|
if (className1.charAt(k1) != 'L')
|
|
throw new InternalError("illegal class name " + className1);
|
|
}
|
|
int k2 = 0;
|
|
if (className2.charAt(0) == '[')
|
|
{
|
|
do
|
|
{
|
|
k2++;
|
|
} while (className2.charAt(k2) == '[');
|
|
if (className2.charAt(k2) != 'L')
|
|
throw new InternalError("illegal class name " + className2);
|
|
}
|
|
int len = i1 - k1;
|
|
return i2 - k2 == len && className1.regionMatches(k1, className2, k2, len);
|
|
}
|
|
|
|
private static int getClassAccessFlags(Class aclass)
|
|
{
|
|
return VMAccessorJavaLang.getModifiersVMClass(aclass, true);
|
|
}
|
|
}
|