1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.  Oracle designates this
9 * particular file as subject to the "Classpath" exception as provided
10 * by Oracle in the LICENSE file that accompanied this code.
11 *
12 * This code is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 * version 2 for more details (a copy is included in the LICENSE file that
16 * accompanied this code).
17 *
18 * You should have received a copy of the GNU General Public License version
19 * 2 along with this work; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23 * or visit www.oracle.com if you need additional information or have any
24 * questions.
25 */
26
27package java.lang.reflect;
28
29import java.security.AccessController;
30import sun.reflect.Reflection;
31import java.lang.annotation.Annotation;
32
33import libcore.reflect.AnnotatedElements;
34
35/**
36 * The AccessibleObject class is the base class for Field, Method and
37 * Constructor objects.  It provides the ability to flag a reflected
38 * object as suppressing default Java language access control checks
39 * when it is used.  The access checks--for public, default (package)
40 * access, protected, and private members--are performed when Fields,
41 * Methods or Constructors are used to set or get fields, to invoke
42 * methods, or to create and initialize new instances of classes,
43 * respectively.
44 *
45 * <p>Setting the {@code accessible} flag in a reflected object
46 * permits sophisticated applications with sufficient privilege, such
47 * as Java Object Serialization or other persistence mechanisms, to
48 * manipulate objects in a manner that would normally be prohibited.
49 *
50 * <p>By default, a reflected object is <em>not</em> accessible.
51 *
52 * @see Field
53 * @see Method
54 * @see Constructor
55 * @see ReflectPermission
56 *
57 * @since 1.2
58 */
59public class AccessibleObject implements AnnotatedElement {
60
61    /**
62     * Convenience method to set the {@code accessible} flag for an
63     * array of objects with a single security check (for efficiency).
64     *
65     * <p>First, if there is a security manager, its
66     * {@code checkPermission} method is called with a
67     * {@code ReflectPermission("suppressAccessChecks")} permission.
68     *
69     * <p>A {@code SecurityException} is raised if {@code flag} is
70     * {@code true} but accessibility of any of the elements of the input
71     * {@code array} may not be changed (for example, if the element
72     * object is a {@link Constructor} object for the class {@link
73     * java.lang.Class}).  In the event of such a SecurityException, the
74     * accessibility of objects is set to {@code flag} for array elements
75     * upto (and excluding) the element for which the exception occurred; the
76     * accessibility of elements beyond (and including) the element for which
77     * the exception occurred is unchanged.
78     *
79     * @param array the array of AccessibleObjects
80     * @param flag  the new value for the {@code accessible} flag
81     *              in each object
82     * @throws SecurityException if the request is denied.
83     * @see SecurityManager#checkPermission
84     * @see java.lang.RuntimePermission
85     */
86    public static void setAccessible(AccessibleObject[] array, boolean flag)
87        throws SecurityException {
88        for (int i = 0; i < array.length; i++) {
89            setAccessible0(array[i], flag);
90        }
91    }
92
93    /**
94     * Set the {@code accessible} flag for this object to
95     * the indicated boolean value.  A value of {@code true} indicates that
96     * the reflected object should suppress Java language access
97     * checking when it is used.  A value of {@code false} indicates
98     * that the reflected object should enforce Java language access checks.
99     *
100     * <p>First, if there is a security manager, its
101     * {@code checkPermission} method is called with a
102     * {@code ReflectPermission("suppressAccessChecks")} permission.
103     *
104     * <p>A {@code SecurityException} is raised if {@code flag} is
105     * {@code true} but accessibility of this object may not be changed
106     * (for example, if this element object is a {@link Constructor} object for
107     * the class {@link java.lang.Class}).
108     *
109     * <p>A {@code SecurityException} is raised if this object is a {@link
110     * java.lang.reflect.Constructor} object for the class
111     * {@code java.lang.Class}, and {@code flag} is true.
112     *
113     * @param flag the new value for the {@code accessible} flag
114     * @throws SecurityException if the request is denied.
115     * @see SecurityManager#checkPermission
116     * @see java.lang.RuntimePermission
117     */
118    public void setAccessible(boolean flag) throws SecurityException {
119        setAccessible0(this, flag);
120    }
121
122    /* Check that you aren't exposing java.lang.Class.<init>. */
123    private static void setAccessible0(AccessibleObject obj, boolean flag)
124        throws SecurityException
125    {
126        if (obj instanceof Constructor && flag == true) {
127            Constructor<?> c = (Constructor<?>)obj;
128            Class<?> clazz = c.getDeclaringClass();
129            if (clazz == Class.class) {
130                throw new SecurityException("Can not make a java.lang.Class" +
131                                            " constructor accessible");
132            } else if (clazz == Method.class) {
133                throw new SecurityException("Can not make a java.lang.reflect.Method" +
134                                            " constructor accessible");
135            } else if (clazz == Field.class) {
136                throw new SecurityException("Can not make a java.lang.reflect.Field" +
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    /**
169     * @throws NullPointerException {@inheritDoc}
170     * @since 1.5
171     */
172    public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
173        throw new AssertionError("All subclasses should override this method");
174    }
175
176    /**
177     * @since 1.5
178     */
179    public Annotation[] getAnnotations() {
180        return getDeclaredAnnotations();
181    }
182
183    /**
184     * @since 1.5
185     */
186    public Annotation[] getDeclaredAnnotations()  {
187        throw new AssertionError("All subclasses should override this method");
188    }
189}
190