1 /* 2 * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Sun designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Sun in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 22 * CA 95054 USA or visit www.sun.com if you need additional information or 23 * have any questions. 24 */ 25 26 package java.lang.reflect; 27 28 import java.security.AccessController; 29 import sun.reflect.ReflectionFactory; 30 import java.lang.annotation.Annotation; 31 32 /** 33 * The AccessibleObject class is the base class for Field, Method and 34 * Constructor objects. It provides the ability to flag a reflected 35 * object as suppressing default Java language access control checks 36 * when it is used. The access checks--for public, default (package) 37 * access, protected, and private members--are performed when Fields, 38 * Methods or Constructors are used to set or get fields, to invoke 39 * methods, or to create and initialize new instances of classes, 40 * respectively. 41 * 42 * <p>Setting the {@code accessible} flag in a reflected object 43 * permits sophisticated applications with sufficient privilege, such 44 * as Java Object Serialization or other persistence mechanisms, to 45 * manipulate objects in a manner that would normally be prohibited. 46 * 47 * @see Field 48 * @see Method 49 * @see Constructor 50 * @see ReflectPermission 51 * 52 * @since 1.2 53 */ 54 public class AccessibleObject implements AnnotatedElement { 55 56 /** 57 * The Permission object that is used to check whether a client 58 * has sufficient privilege to defeat Java language access 59 * control checks. 60 */ 61 static final private java.security.Permission ACCESS_PERMISSION = 62 new ReflectPermission("suppressAccessChecks"); 63 64 /** 65 * Convenience method to set the {@code accessible} flag for an 66 * array of objects with a single security check (for efficiency). 67 * 68 * <p>First, if there is a security manager, its 69 * {@code checkPermission} method is called with a 70 * {@code ReflectPermission("suppressAccessChecks")} permission. 71 * 72 * <p>A {@code SecurityException} is raised if {@code flag} is 73 * {@code true} but accessibility of any of the elements of the input 74 * {@code array} may not be changed (for example, if the element 75 * object is a {@link Constructor} object for the class {@link 76 * java.lang.Class}). In the event of such a SecurityException, the 77 * accessibility of objects is set to {@code flag} for array elements 78 * upto (and excluding) the element for which the exception occurred; the 79 * accessibility of elements beyond (and including) the element for which 80 * the exception occurred is unchanged. 81 * 82 * @param array the array of AccessibleObjects 83 * @param flag the new value for the {@code accessible} flag 84 * in each object 85 * @throws SecurityException if the request is denied. 86 * @see SecurityManager#checkPermission 87 * @see java.lang.RuntimePermission 88 */ 89 public static void setAccessible(AccessibleObject[] array, boolean flag) 90 throws SecurityException { 91 SecurityManager sm = System.getSecurityManager(); 92 if (sm != null) sm.checkPermission(ACCESS_PERMISSION); 93 for (int i = 0; i < array.length; i++) { 94 setAccessible0(array[i], flag); 95 } 96 } 97 98 /** 99 * Set the {@code accessible} flag for this object to 100 * the indicated boolean value. A value of {@code true} indicates that 101 * the reflected object should suppress Java language access 102 * checking when it is used. A value of {@code false} indicates 103 * that the reflected object should enforce Java language access checks. 104 * 105 * <p>First, if there is a security manager, its 106 * {@code checkPermission} method is called with a 107 * {@code ReflectPermission("suppressAccessChecks")} permission. 108 * 109 * <p>A {@code SecurityException} is raised if {@code flag} is 110 * {@code true} but accessibility of this object may not be changed 111 * (for example, if this element object is a {@link Constructor} object for 112 * the class {@link java.lang.Class}). 113 * 114 * <p>A {@code SecurityException} is raised if this object is a {@link 115 * java.lang.reflect.Constructor} object for the class 116 * {@code java.lang.Class}, and {@code flag} is true. 117 * 118 * @param flag the new value for the {@code accessible} flag 119 * @throws SecurityException if the request is denied. 120 * @see SecurityManager#checkPermission 121 * @see java.lang.RuntimePermission 122 */ 123 public void setAccessible(boolean flag) throws SecurityException { 124 SecurityManager sm = System.getSecurityManager(); 125 if (sm != null) sm.checkPermission(ACCESS_PERMISSION); 126 setAccessible0(this, flag); 127 } 128 129 /* Check that you aren't exposing java.lang.Class.<init>. */ 130 private static void setAccessible0(AccessibleObject obj, boolean flag) 131 throws SecurityException 132 { 133 if (obj instanceof Constructor && flag == true) { 134 Constructor<?> c = (Constructor<?>)obj; 135 if (c.getDeclaringClass() == Class.class) { 136 throw new SecurityException("Can not make a java.lang.Class" + 137 " constructor accessible"); 138 } 139 } 140 obj.override = flag; 141 } 142 143 /** 144 * Get the value of the {@code accessible} flag for this object. 145 * 146 * @return the value of the object's {@code accessible} flag 147 */ 148 public boolean isAccessible() { 149 return override; 150 } 151 152 /** 153 * Constructor: only used by the Java Virtual Machine. 154 */ 155 protected AccessibleObject() {} 156 157 // Indicates whether language-level access checks are overridden 158 // by this object. Initializes to "false". This field is used by 159 // Field, Method, and Constructor. 160 // 161 // NOTE: for security purposes, this field must not be visible 162 // outside this package. 163 boolean override; 164 165 // Reflection factory used by subclasses for creating field, 166 // method, and constructor accessors. Note that this is called 167 // very early in the bootstrapping process. 168 static final ReflectionFactory reflectionFactory = 169 AccessController.doPrivileged( 170 new sun.reflect.ReflectionFactory.GetReflectionFactoryAction()); 171 172 /** 173 * @throws NullPointerException {@inheritDoc} 174 * @since 1.5 175 */ 176 public <T extends Annotation> T getAnnotation(Class<T> annotationClass) { 177 throw new AssertionError("All subclasses should override this method"); 178 } 179 180 /** 181 * @throws NullPointerException {@inheritDoc} 182 * @since 1.5 183 */ 184 public boolean isAnnotationPresent( 185 Class<? extends Annotation> annotationClass) { 186 return getAnnotation(annotationClass) != null; 187 } 188 189 /** 190 * @since 1.5 191 */ 192 public Annotation[] getAnnotations() { 193 return getDeclaredAnnotations(); 194 } 195 196 /** 197 * @since 1.5 198 */ 199 public Annotation[] getDeclaredAnnotations() { 200 throw new AssertionError("All subclasses should override this method"); 201 } 202 }