AccessibleObject.java 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /* java.lang.reflect.AccessibleObject
  2. Copyright (C) 2001, 2005, 2006 Free Software Foundation, Inc.
  3. This file is part of GNU Classpath.
  4. GNU Classpath is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2, or (at your option)
  7. any later version.
  8. GNU Classpath is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNU Classpath; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  15. 02110-1301 USA.
  16. Linking this library statically or dynamically with other modules is
  17. making a combined work based on this library. Thus, the terms and
  18. conditions of the GNU General Public License cover the whole
  19. combination.
  20. As a special exception, the copyright holders of this library give you
  21. permission to link this library with independent modules to produce an
  22. executable, regardless of the license terms of these independent
  23. modules, and to copy and distribute the resulting executable under
  24. terms of your choice, provided that you also meet, for each linked
  25. independent module, the terms and conditions of the license of that
  26. module. An independent module is a module which is not derived from
  27. or based on this library. If you modify this library, you may extend
  28. this exception to your version of the library, but you are not
  29. obligated to do so. If you do not wish to do so, delete this
  30. exception statement from your version. */
  31. package java.lang.reflect;
  32. import java.lang.annotation.Annotation;
  33. /**
  34. * This class is the superclass of various reflection classes, and
  35. * allows sufficiently trusted code to bypass normal restrictions to
  36. * do necessary things like invoke private methods outside of the
  37. * class during Serialization. If you don't have a good reason
  38. * to mess with this, don't try. Fortunately, there are adequate
  39. * security checks before you can set a reflection object as accessible.
  40. *
  41. * @author Tom Tromey (tromey@cygnus.com)
  42. * @author Eric Blake (ebb9@email.byu.edu)
  43. * @see Field
  44. * @see Constructor
  45. * @see Method
  46. * @see ReflectPermission
  47. * @since 1.2
  48. * @status updated to 1.5
  49. */
  50. public class AccessibleObject
  51. implements AnnotatedElement
  52. {
  53. /**
  54. * True if this object is marked accessible, which means the reflected
  55. * object bypasses normal security checks.
  56. */
  57. // default visibility for use by inherited classes
  58. boolean flag = false;
  59. /**
  60. * Only the three reflection classes that extend this can create an
  61. * accessible object. This is not serializable for security reasons.
  62. */
  63. protected AccessibleObject()
  64. {
  65. }
  66. /**
  67. * Return the accessibility status of this object.
  68. *
  69. * @return true if this object bypasses security checks
  70. */
  71. public boolean isAccessible()
  72. {
  73. return flag;
  74. }
  75. /**
  76. * Convenience method to set the flag on a number of objects with a single
  77. * security check. If a security manager exists, it is checked for
  78. * <code>ReflectPermission("suppressAccessChecks")</code>.<p>
  79. *
  80. * It is forbidden to set the accessibility flag to true on any constructor
  81. * for java.lang.Class. This will result in a SecurityException. If the
  82. * SecurityException is thrown for any of the passed AccessibleObjects,
  83. * the accessibility flag will be set on AccessibleObjects in the array prior
  84. * to the one which resulted in the exception.
  85. *
  86. * @param array the array of accessible objects
  87. * @param flag the desired state of accessibility, true to bypass security
  88. * @throws NullPointerException if array is null
  89. * @throws SecurityException if the request is denied
  90. * @see SecurityManager#checkPermission(java.security.Permission)
  91. * @see RuntimePermission
  92. */
  93. public static void setAccessible(AccessibleObject[] array, boolean flag)
  94. {
  95. checkPermission();
  96. for (int i = 0; i < array.length; i++)
  97. array[i].secureSetAccessible(flag);
  98. }
  99. /**
  100. * Sets the accessibility flag for this reflection object. If a security
  101. * manager exists, it is checked for
  102. * <code>ReflectPermission("suppressAccessChecks")</code>.<p>
  103. *
  104. * It is forbidden to set the accessibility flag to true on any constructor for
  105. * java.lang.Class. This will result in a SecurityException.
  106. *
  107. * @param flag the desired state of accessibility, true to bypass security
  108. * @throws NullPointerException if array is null
  109. * @throws SecurityException if the request is denied
  110. * @see SecurityManager#checkPermission(java.security.Permission)
  111. * @see RuntimePermission
  112. */
  113. public void setAccessible(boolean flag)
  114. {
  115. checkPermission();
  116. secureSetAccessible(flag);
  117. }
  118. /**
  119. * Performs the specified security check, for
  120. * <code>ReflectPermission("suppressAccessChecks")</code>.
  121. *
  122. * @throws SecurityException if permission is denied
  123. */
  124. private static void checkPermission()
  125. {
  126. SecurityManager sm = System.getSecurityManager();
  127. if (sm != null)
  128. sm.checkPermission(new ReflectPermission("suppressAccessChecks"));
  129. }
  130. /**
  131. * Performs the actual accessibility change, this must always be invoked
  132. * after calling checkPermission.
  133. *
  134. * @param flag the desired status
  135. * @throws SecurityException if flag is true and this is a constructor
  136. * for <code>java.lang.Class</code>.
  137. */
  138. private void secureSetAccessible(boolean flag)
  139. {
  140. if (flag &&
  141. (this instanceof Constructor
  142. && ((Constructor) this).getDeclaringClass() == Class.class))
  143. throw new SecurityException("Cannot make object accessible: " + this);
  144. this.flag = flag;
  145. }
  146. /**
  147. * <p>
  148. * Returns the element's annotation for the specified annotation type,
  149. * or <code>null</code> if no such annotation exists.
  150. * </p>
  151. * <p>
  152. * <strong>This method must be overridden by subclasses to provide
  153. * appropriate behaviour.</strong>
  154. * </p>
  155. *
  156. * @param annotationClass the type of annotation to look for.
  157. * @return this element's annotation for the specified type, or
  158. * <code>null</code> if no such annotation exists.
  159. * @throws NullPointerException if the annotation class is <code>null</code>.
  160. */
  161. public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
  162. {
  163. throw new AssertionError("Subclass must override this method");
  164. }
  165. /**
  166. * Returns all annotations associated with the element. If there are
  167. * no annotations associated with the element, then a zero-length array
  168. * will be returned. The returned array may be modified by the client
  169. * code, but this will have no effect on the annotation content of the
  170. * element, and hence no effect on the return value of this method for
  171. * future callers.
  172. *
  173. * @return this element's annotations.
  174. */
  175. public Annotation[] getAnnotations()
  176. {
  177. return getDeclaredAnnotations();
  178. }
  179. /**
  180. * <p>
  181. * Returns all annotations directly defined by the element. If there are
  182. * no annotations directly associated with the element, then a zero-length
  183. * array will be returned. The returned array may be modified by the client
  184. * code, but this will have no effect on the annotation content of this
  185. * class, and hence no effect on the return value of this method for
  186. * future callers.
  187. * </p>
  188. * <p>
  189. * <strong>This method must be overridden by subclasses to provide
  190. * appropriate behaviour.</strong>
  191. * </p>
  192. *
  193. * @return the annotations directly defined by the element.
  194. * @since 1.5
  195. */
  196. public Annotation[] getDeclaredAnnotations()
  197. {
  198. throw new AssertionError("Subclass must override this method");
  199. }
  200. /**
  201. * Returns true if an annotation for the specified type is associated
  202. * with the element. This is primarily a short-hand for using marker
  203. * annotations.
  204. *
  205. * @param annotationClass the type of annotation to look for.
  206. * @return true if an annotation exists for the specified type.
  207. * @since 1.5
  208. */
  209. public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass)
  210. {
  211. return getAnnotation(annotationClass) != null;
  212. }
  213. }