001/* java.lang.reflect.AccessibleObject 002 Copyright (C) 2001, 2005, 2006 Free Software Foundation, Inc. 003 004This file is part of GNU Classpath. 005 006GNU Classpath is free software; you can redistribute it and/or modify 007it under the terms of the GNU General Public License as published by 008the Free Software Foundation; either version 2, or (at your option) 009any later version. 010 011GNU Classpath is distributed in the hope that it will be useful, but 012WITHOUT ANY WARRANTY; without even the implied warranty of 013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014General Public License for more details. 015 016You should have received a copy of the GNU General Public License 017along with GNU Classpath; see the file COPYING. If not, write to the 018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 01902110-1301 USA. 020 021Linking this library statically or dynamically with other modules is 022making a combined work based on this library. Thus, the terms and 023conditions of the GNU General Public License cover the whole 024combination. 025 026As a special exception, the copyright holders of this library give you 027permission to link this library with independent modules to produce an 028executable, regardless of the license terms of these independent 029modules, and to copy and distribute the resulting executable under 030terms of your choice, provided that you also meet, for each linked 031independent module, the terms and conditions of the license of that 032module. An independent module is a module which is not derived from 033or based on this library. If you modify this library, you may extend 034this exception to your version of the library, but you are not 035obligated to do so. If you do not wish to do so, delete this 036exception statement from your version. */ 037 038 039package java.lang.reflect; 040 041import java.lang.annotation.Annotation; 042 043/** 044 * This class is the superclass of various reflection classes, and 045 * allows sufficiently trusted code to bypass normal restrictions to 046 * do necessary things like invoke private methods outside of the 047 * class during Serialization. If you don't have a good reason 048 * to mess with this, don't try. Fortunately, there are adequate 049 * security checks before you can set a reflection object as accessible. 050 * 051 * @author Tom Tromey (tromey@cygnus.com) 052 * @author Eric Blake (ebb9@email.byu.edu) 053 * @see Field 054 * @see Constructor 055 * @see Method 056 * @see ReflectPermission 057 * @since 1.2 058 * @status updated to 1.5 059 */ 060public class AccessibleObject 061 implements AnnotatedElement 062{ 063 /** 064 * True if this object is marked accessible, which means the reflected 065 * object bypasses normal security checks. 066 */ 067 // default visibility for use by inherited classes 068 boolean flag = false; 069 070 /** 071 * Only the three reflection classes that extend this can create an 072 * accessible object. This is not serializable for security reasons. 073 */ 074 protected AccessibleObject() 075 { 076 } 077 078 /** 079 * Return the accessibility status of this object. 080 * 081 * @return true if this object bypasses security checks 082 */ 083 public boolean isAccessible() 084 { 085 return flag; 086 } 087 088 /** 089 * Convenience method to set the flag on a number of objects with a single 090 * security check. If a security manager exists, it is checked for 091 * <code>ReflectPermission("suppressAccessChecks")</code>.<p> 092 * 093 * It is forbidden to set the accessibility flag to true on any constructor 094 * for java.lang.Class. This will result in a SecurityException. If the 095 * SecurityException is thrown for any of the passed AccessibleObjects, 096 * the accessibility flag will be set on AccessibleObjects in the array prior 097 * to the one which resulted in the exception. 098 * 099 * @param array the array of accessible objects 100 * @param flag the desired state of accessibility, true to bypass security 101 * @throws NullPointerException if array is null 102 * @throws SecurityException if the request is denied 103 * @see SecurityManager#checkPermission(java.security.Permission) 104 * @see RuntimePermission 105 */ 106 public static void setAccessible(AccessibleObject[] array, boolean flag) 107 { 108 checkPermission(); 109 for (int i = 0; i < array.length; i++) 110 array[i].secureSetAccessible(flag); 111 } 112 113 /** 114 * Sets the accessibility flag for this reflection object. If a security 115 * manager exists, it is checked for 116 * <code>ReflectPermission("suppressAccessChecks")</code>.<p> 117 * 118 * It is forbidden to set the accessibility flag to true on any constructor for 119 * java.lang.Class. This will result in a SecurityException. 120 * 121 * @param flag the desired state of accessibility, true to bypass security 122 * @throws NullPointerException if array is null 123 * @throws SecurityException if the request is denied 124 * @see SecurityManager#checkPermission(java.security.Permission) 125 * @see RuntimePermission 126 */ 127 public void setAccessible(boolean flag) 128 { 129 checkPermission(); 130 secureSetAccessible(flag); 131 } 132 133 /** 134 * Performs the specified security check, for 135 * <code>ReflectPermission("suppressAccessChecks")</code>. 136 * 137 * @throws SecurityException if permission is denied 138 */ 139 private static void checkPermission() 140 { 141 SecurityManager sm = System.getSecurityManager(); 142 if (sm != null) 143 sm.checkPermission(new ReflectPermission("suppressAccessChecks")); 144 } 145 146 /** 147 * Performs the actual accessibility change, this must always be invoked 148 * after calling checkPermission. 149 * 150 * @param flag the desired status 151 * @throws SecurityException if flag is true and this is a constructor 152 * for <code>java.lang.Class</code>. 153 */ 154 private void secureSetAccessible(boolean flag) 155 { 156 if (flag && 157 (this instanceof Constructor 158 && ((Constructor) this).getDeclaringClass() == Class.class)) 159 throw new SecurityException("Cannot make object accessible: " + this); 160 this.flag = flag; 161 } 162 163 /** 164 * <p> 165 * Returns the element's annotation for the specified annotation type, 166 * or <code>null</code> if no such annotation exists. 167 * </p> 168 * <p> 169 * <strong>This method must be overridden by subclasses to provide 170 * appropriate behaviour.</strong> 171 * </p> 172 * 173 * @param annotationClass the type of annotation to look for. 174 * @return this element's annotation for the specified type, or 175 * <code>null</code> if no such annotation exists. 176 * @throws NullPointerException if the annotation class is <code>null</code>. 177 */ 178 public <T extends Annotation> T getAnnotation(Class<T> annotationClass) 179 { 180 throw new AssertionError("Subclass must override this method"); 181 } 182 183 /** 184 * Returns all annotations associated with the element. If there are 185 * no annotations associated with the element, then a zero-length array 186 * will be returned. The returned array may be modified by the client 187 * code, but this will have no effect on the annotation content of the 188 * element, and hence no effect on the return value of this method for 189 * future callers. 190 * 191 * @return this element's annotations. 192 */ 193 public Annotation[] getAnnotations() 194 { 195 return getDeclaredAnnotations(); 196 } 197 198 /** 199 * <p> 200 * Returns all annotations directly defined by the element. If there are 201 * no annotations directly associated with the element, then a zero-length 202 * array will be returned. The returned array may be modified by the client 203 * code, but this will have no effect on the annotation content of this 204 * class, and hence no effect on the return value of this method for 205 * future callers. 206 * </p> 207 * <p> 208 * <strong>This method must be overridden by subclasses to provide 209 * appropriate behaviour.</strong> 210 * </p> 211 * 212 * @return the annotations directly defined by the element. 213 * @since 1.5 214 */ 215 public Annotation[] getDeclaredAnnotations() 216 { 217 throw new AssertionError("Subclass must override this method"); 218 } 219 220 /** 221 * Returns true if an annotation for the specified type is associated 222 * with the element. This is primarily a short-hand for using marker 223 * annotations. 224 * 225 * @param annotationClass the type of annotation to look for. 226 * @return true if an annotation exists for the specified type. 227 * @since 1.5 228 */ 229 public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) 230 { 231 return getAnnotation(annotationClass) != null; 232 } 233}