001: /*
002: * @(#)AccessibleObject.java 1.22 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027:
028: package java.lang.reflect;
029:
030: /**
031: * The AccessibleObject class is the base class for Field, Method and
032: * Constructor objects. It provides the ability to flag a reflected
033: * object as suppressing default Java language access control checks
034: * when it is used. The access checks--for public, default (package)
035: * access, protected, and private members--are performed when Fields,
036: * Methods or Constructors are used to set or get fields, to invoke
037: * methods, or to create and initialize new instances of classes,
038: * respectively.
039: *
040: * <p>Setting the <tt>accessible</tt> flag in a reflected object
041: * permits sophisticated applications with sufficient privilege, such
042: * as Java Object Serialization or other persistence mechanisms, to
043: * manipulate objects in a manner that would normally be prohibited.
044: *
045: * @see Field
046: * @see Method
047: * @see Constructor
048: * @see ReflectPermission
049: *
050: * @since 1.2
051: */
052: public class AccessibleObject {
053:
054: /**
055: * The Permission object that is used to check whether a client
056: * has sufficient privilege to defeat Java language access
057: * control checks.
058: */
059: static final private java.security.Permission ACCESS_PERMISSION = new ReflectPermission(
060: "suppressAccessChecks");
061:
062: /**
063: * Convenience method to set the <tt>accessible</tt> flag for an
064: * array of objects with a single security check (for efficiency).
065: *
066: * <p>First, if there is a security manager, its
067: * <code>checkPermission</code> method is called with a
068: * <code>ReflectPermission("suppressAccessChecks")</code> permission.
069: *
070: * <p>A <code>SecurityException</code> is raised if <code>flag</code> is
071: * <code>true</code> but accessibility of any of the elements of the input
072: * <code>array</code> may not be changed (for example, if the element
073: * object is a {@link Constructor} object for the class {@link
074: * java.lang.Class}). In the event of such a SecurityException, the
075: * accessiblity of objects is set to <code>flag</code> for array elements
076: * upto (and excluding) the element for which the exception occurred; the
077: * accessiblity of elements beyond (and including) the element for which
078: * the exception occurred is unchanged.
079: *
080: * @param array the array of AccessibleObjects
081: * @param flag the new value for the <tt>accessible</tt> flag
082: * in each object
083: * @throws SecurityException if the request is denied.
084: * @see SecurityManager#checkPermission
085: * @see java.lang.RuntimePermission
086: */
087: public static void setAccessible(AccessibleObject[] array,
088: boolean flag) throws SecurityException {
089: SecurityManager sm = System.getSecurityManager();
090: if (sm != null)
091: sm.checkPermission(ACCESS_PERMISSION);
092: for (int i = 0; i < array.length; i++) {
093: setAccessible0(array[i], flag);
094: }
095: }
096:
097: /**
098: * Set the <tt>accessible</tt> flag for this object to
099: * the indicated boolean value. A value of <tt>true</tt> indicates that
100: * the reflected object should suppress Java language access
101: * checking when it is used. A value of <tt>false</tt> indicates
102: * that the reflected object should enforce Java language access checks.
103: *
104: * <p>First, if there is a security manager, its
105: * <code>checkPermission</code> method is called with a
106: * <code>ReflectPermission("suppressAccessChecks")</code> permission.
107: *
108: * <p>A <code>SecurityException</code> is raised if <code>flag</code> is
109: * <code>true</code> but accessibility of this object may not be changed
110: * (for example, if this element object is a {@link Constructor} object for
111: * the class {@link java.lang.Class}).
112: *
113: * <p>A <code>SecurityException</code> is raised if this object is a {@link
114: * java.lang.reflect.Constructor} object for the class
115: * <code>java.lang.Class</code>, and <code>flag</code> is true.
116: *
117: * @param flag the new value for the <tt>accessible</tt> flag
118: * @throws SecurityException if the request is denied.
119: * @see SecurityManager#checkPermission
120: * @see java.lang.RuntimePermission
121: */
122: public void setAccessible(boolean flag) throws SecurityException {
123: SecurityManager sm = System.getSecurityManager();
124: if (sm != null)
125: 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,
131: boolean flag) throws SecurityException {
132: if (obj instanceof Constructor && flag == true) {
133: Constructor c = (Constructor) obj;
134: if (c.getDeclaringClass() == Class.class) {
135: throw new SecurityException(
136: "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 <tt>accessible</tt> flag for this object.
145: *
146: * @return the value of the object's <tt>accessible</tt> 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:
158: // N.B. jvm depends on this field name, and initializes to <tt>false</tt>.
159: private boolean override;
160:
161: }
|