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  * <p>By default, a reflected object is <em>not</em> accessible.
  48  *
  49  * @see Field
  50  * @see Method
  51  * @see Constructor
  52  * @see ReflectPermission
  53  *
  54  * @since 1.2
  55  */
  56 public class AccessibleObject implements AnnotatedElement {
  57 
  58     /**
  59      * The Permission object that is used to check whether a client
  60      * has sufficient privilege to defeat Java language access
  61      * control checks.
  62      */
  63     static final private java.security.Permission ACCESS_PERMISSION =
  64         new ReflectPermission("suppressAccessChecks");
  65 
  66     /**
  67      * Convenience method to set the {@code accessible} flag for an
  68      * array of objects with a single security check (for efficiency).
  69      *
  70      * <p>First, if there is a security manager, its
  71      * {@code checkPermission} method is called with a
  72      * {@code ReflectPermission("suppressAccessChecks")} permission.
  73      *
  74      * <p>A {@code SecurityException} is raised if {@code flag} is
  75      * {@code true} but accessibility of any of the elements of the input
  76      * {@code array} may not be changed (for example, if the element
  77      * object is a {@link Constructor} object for the class {@link
  78      * java.lang.Class}).  In the event of such a SecurityException, the
  79      * accessibility of objects is set to {@code flag} for array elements
  80      * upto (and excluding) the element for which the exception occurred; the
  81      * accessibility of elements beyond (and including) the element for which
  82      * the exception occurred is unchanged.
  83      *
  84      * @param array the array of AccessibleObjects
  85      * @param flag  the new value for the {@code accessible} flag
  86      *              in each object
  87      * @throws SecurityException if the request is denied.
  88      * @see SecurityManager#checkPermission
  89      * @see java.lang.RuntimePermission
  90      */
  91     public static void setAccessible(AccessibleObject[] array, boolean flag)
  92         throws SecurityException {
  93         SecurityManager sm = System.getSecurityManager();
  94         if (sm != null) sm.checkPermission(ACCESS_PERMISSION);
  95         for (int i = 0; i < array.length; i++) {
  96             setAccessible0(array[i], flag);
  97         }
  98     }
  99 
 100     /**
 101      * Set the {@code accessible} flag for this object to
 102      * the indicated boolean value.  A value of {@code true} indicates that
 103      * the reflected object should suppress Java language access
 104      * checking when it is used.  A value of {@code false} indicates
 105      * that the reflected object should enforce Java language access checks.
 106      *
 107      * <p>First, if there is a security manager, its
 108      * {@code checkPermission} method is called with a
 109      * {@code ReflectPermission("suppressAccessChecks")} permission.
 110      *
 111      * <p>A {@code SecurityException} is raised if {@code flag} is
 112      * {@code true} but accessibility of this object may not be changed
 113      * (for example, if this element object is a {@link Constructor} object for
 114      * the class {@link java.lang.Class}).
 115      *
 116      * <p>A {@code SecurityException} is raised if this object is a {@link
 117      * java.lang.reflect.Constructor} object for the class
 118      * {@code java.lang.Class}, and {@code flag} is true.
 119      *
 120      * @param flag the new value for the {@code accessible} flag
 121      * @throws SecurityException if the request is denied.
 122      * @see SecurityManager#checkPermission
 123      * @see java.lang.RuntimePermission
 124      */
 125     public void setAccessible(boolean flag) throws SecurityException {
 126         SecurityManager sm = System.getSecurityManager();
 127         if (sm != null) sm.checkPermission(ACCESS_PERMISSION);
 128         setAccessible0(this, flag);
 129     }
 130 
 131     /* Check that you aren't exposing java.lang.Class.<init>. */
 132     private static void setAccessible0(AccessibleObject obj, boolean flag)
 133         throws SecurityException
 134     {
 135         if (obj instanceof Constructor && flag == true) {
 136             Constructor<?> c = (Constructor<?>)obj;
 137             if (c.getDeclaringClass() == Class.class) {
 138                 throw new SecurityException("Can not make a java.lang.Class" +
 139                                             " constructor accessible");
 140             }
 141         }
 142         obj.override = flag;
 143     }
 144 
 145     /**
 146      * Get the value of the {@code accessible} flag for this object.
 147      *
 148      * @return the value of the object's {@code accessible} flag
 149      */
 150     public boolean isAccessible() {
 151         return override;
 152     }
 153 
 154     /**
 155      * Constructor: only used by the Java Virtual Machine.
 156      */
 157     protected AccessibleObject() {}
 158 
 159     // Indicates whether language-level access checks are overridden
 160     // by this object. Initializes to "false". This field is used by
 161     // Field, Method, and Constructor.
 162     //
 163     // NOTE: for security purposes, this field must not be visible
 164     // outside this package.
 165     boolean override;
 166 
 167     // Reflection factory used by subclasses for creating field,
 168     // method, and constructor accessors. Note that this is called
 169     // very early in the bootstrapping process.
 170     static final ReflectionFactory reflectionFactory =
 171         AccessController.doPrivileged(
 172             new sun.reflect.ReflectionFactory.GetReflectionFactoryAction());
 173 
 174     /**
 175      * @throws NullPointerException {@inheritDoc}
 176      * @since 1.5
 177      */
 178     public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
 179         throw new AssertionError("All subclasses should override this method");
 180     }
 181 
 182     /**
 183      * @throws NullPointerException {@inheritDoc}
 184      * @since 1.5
 185      */
 186     public boolean isAnnotationPresent(
 187         Class<? extends Annotation> annotationClass) {
 188         return getAnnotation(annotationClass) != null;
 189     }
 190 
 191     /**
 192      * @since 1.5
 193      */
 194     public Annotation[] getAnnotations() {
 195         return getDeclaredAnnotations();
 196     }
 197 
 198     /**
 199      * @since 1.5
 200      */
 201     public Annotation[] getDeclaredAnnotations()  {
 202         throw new AssertionError("All subclasses should override this method");
 203     }
 204 }