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 }