001: /*
002: * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.reflect.misc;
027:
028: import java.lang.reflect.Modifier;
029: import sun.reflect.Reflection;
030:
031: public final class ReflectUtil {
032:
033: private ReflectUtil() {
034: }
035:
036: public static Class forName(String name)
037: throws ClassNotFoundException {
038: checkPackageAccess(name);
039: return Class.forName(name);
040: }
041:
042: public static Object newInstance(Class cls)
043: throws InstantiationException, IllegalAccessException {
044: checkPackageAccess(cls);
045: return cls.newInstance();
046: }
047:
048: /*
049: * Reflection.ensureMemberAccess is overly-restrictive
050: * due to a bug. We awkwardly work around it for now.
051: */
052: public static void ensureMemberAccess(Class currentClass,
053: Class memberClass, Object target, int modifiers)
054: throws IllegalAccessException {
055: if (target == null && Modifier.isProtected(modifiers)) {
056: int mods = modifiers;
057: mods = mods & (~Modifier.PROTECTED);
058: mods = mods | Modifier.PUBLIC;
059:
060: /*
061: * See if we fail because of class modifiers
062: */
063: Reflection.ensureMemberAccess(currentClass, memberClass,
064: target, mods);
065: try {
066: /*
067: * We're still here so class access was ok.
068: * Now try with default field access.
069: */
070: mods = mods & (~Modifier.PUBLIC);
071: Reflection.ensureMemberAccess(currentClass,
072: memberClass, target, mods);
073: /*
074: * We're still here so access is ok without
075: * checking for protected.
076: */
077: return;
078: } catch (IllegalAccessException e) {
079: /*
080: * Access failed but we're 'protected' so
081: * if the test below succeeds then we're ok.
082: */
083: if (isSubclassOf(currentClass, memberClass)) {
084: return;
085: } else {
086: throw e;
087: }
088: }
089: } else {
090: Reflection.ensureMemberAccess(currentClass, memberClass,
091: target, modifiers);
092: }
093: }
094:
095: private static boolean isSubclassOf(Class queryClass, Class ofClass) {
096: while (queryClass != null) {
097: if (queryClass == ofClass) {
098: return true;
099: }
100: queryClass = queryClass.getSuperclass();
101: }
102: return false;
103: }
104:
105: public static void checkPackageAccess(Class clazz) {
106: checkPackageAccess(clazz.getName());
107: }
108:
109: public static void checkPackageAccess(String name) {
110: SecurityManager s = System.getSecurityManager();
111: if (s != null) {
112: String cname = name.replace('/', '.');
113: if (cname.startsWith("[")) {
114: int b = cname.lastIndexOf('[') + 2;
115: if (b > 1 && b < cname.length()) {
116: cname = cname.substring(b);
117: }
118: }
119: int i = cname.lastIndexOf('.');
120: if (i != -1) {
121: s.checkPackageAccess(cname.substring(0, i));
122: }
123: }
124: }
125:
126: public static boolean isPackageAccessible(Class clazz) {
127: try {
128: checkPackageAccess(clazz);
129: } catch (SecurityException e) {
130: return false;
131: }
132: return true;
133: }
134: }
|