You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AccessChecker.java 6.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  2. *
  3. * This file is part of the debugger and core tools for the AspectJ(tm)
  4. * programming language; see http://aspectj.org
  5. *
  6. * The contents of this file are subject to the Mozilla Public License
  7. * Version 1.1 (the "License"); you may not use this file except in
  8. * compliance with the License. You may obtain a copy of the License at
  9. * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/.
  10. *
  11. * Software distributed under the License is distributed on an "AS IS" basis,
  12. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  13. * for the specific language governing rights and limitations under the
  14. * License.
  15. *
  16. * The Original Code is AspectJ.
  17. *
  18. * The Initial Developer of the Original Code is Xerox Corporation. Portions
  19. * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation.
  20. * All Rights Reserved.
  21. */
  22. package org.aspectj.tools.ajdoc;
  23. import org.aspectj.compiler.base.ast.Modifiers;
  24. import org.aspectj.compiler.base.ast.FieldDec;
  25. import org.aspectj.compiler.base.ast.TypeDec;
  26. import org.aspectj.compiler.base.ast.NameType;
  27. import org.aspectj.compiler.base.ast.CodeDec;
  28. import org.aspectj.compiler.crosscuts.ast.PointcutDec;
  29. /**
  30. * This utility tells whether a declaration is accessible
  31. * based on its access modifiers (and that of its declaring
  32. * class, if it is a member (i.e., including inner classes).
  33. * <p><u>Instantiation and subclassing</u>:
  34. * The constants should suffice for most uses, but subclassing
  35. * is permitted if you need to implement new functionality or
  36. * make new instances.
  37. */
  38. public abstract class AccessChecker {
  39. // constants open doCanAccess to public to permit direct use
  40. /** return true only for public elements */
  41. public static final AccessChecker PUBLIC = new AccessChecker("public") {
  42. public boolean doCanAccess(Modifiers mods, Object object) {
  43. return mods.isPublic();
  44. }
  45. };
  46. /** return true for public and protected elements */
  47. public static final AccessChecker PROTECTED = new AccessChecker("protected") {
  48. public boolean doCanAccess(Modifiers mods, Object object) {
  49. return mods.isPublic() || mods.isProtected();
  50. }
  51. };
  52. /** return true unless private elements */
  53. public static final AccessChecker PACKAGE = new AccessChecker("package") {
  54. public boolean doCanAccess(Modifiers mods, Object object) {
  55. return !mods.isPrivate();
  56. }
  57. };
  58. /** return true for all elements */
  59. public static final AccessChecker PRIVATE = new AccessChecker("private") {
  60. public boolean doCanAccess(Modifiers mods, Object object) {
  61. return true;
  62. }
  63. };
  64. /** lowercase option without - */
  65. protected final String optionName;
  66. /**
  67. * Encourage use of static constants by prohibiting construction
  68. * but permit new subclasses.
  69. * Subclasses should ensure optionName is lowercase and
  70. * doCanAccess is public if need be.
  71. */
  72. protected AccessChecker(String optionName){
  73. this.optionName = optionName;
  74. }
  75. /** @return true if modifiers permitted for self and declaring type */
  76. public boolean canAccess(FieldDec dec) {
  77. if (null == dec) return false;
  78. if (!canAccess(dec.getModifiers(), dec)) {
  79. return false;
  80. } else {
  81. return canAccess(dec.getBytecodeTypeDec());
  82. }
  83. }
  84. /** @return true if modifiers permitted for self and declaring type */
  85. public boolean canAccess(CodeDec dec) {
  86. if (null == dec) return false;
  87. if (!canAccess(dec.getModifiers(), dec)) {
  88. return false;
  89. } else {
  90. return canAccess(dec.getBytecodeTypeDec());
  91. }
  92. }
  93. /** @return true if modifiers permitted for self and declaring type */
  94. public boolean canAccess(PointcutDec dec) {
  95. if (null == dec) return false;
  96. if (!canAccess(dec.getModifiers(), dec)) {
  97. return false;
  98. } else {
  99. return canAccess(dec.getBytecodeTypeDec());
  100. }
  101. }
  102. /** decode dec modifiers and return whether access is permitted
  103. * Access is permitted if it is permitted to the dec.
  104. * The caller must prohibit access when displaying in the aspect
  105. * (i.e., <code>canAccess(dec.getLexicalType())</code> or in
  106. * the target class
  107. * (i.e., <code>canAccess(dec.getDeclaringType())</code>)
  108. * and to the enclosing lexical type (i.e,. the enclosing aspect).
  109. */
  110. /*
  111. public boolean canAccess(IntroducedDec dec) { // todo: users
  112. if (null == dec) return false;
  113. if (!canAccess(dec.getModifiers(), dec)) {
  114. return false;
  115. } else {
  116. return canAccess(dec.getLexicalType());
  117. }
  118. }
  119. */
  120. /** @return true if modifiers permitted for self and any enclosing type */
  121. public boolean canAccess(TypeDec dec) {
  122. if (null == dec) return false;
  123. boolean result = canAccess(dec.getModifiers(), dec);
  124. if (result) {
  125. // avoiding NPE in getEnclosingInstanceTypeDec
  126. NameType outerType = dec.getEnclosingInstanceType();
  127. TypeDec outer = (null == outerType? null
  128. : outerType.getTypeDec()); // todo: typeDec?
  129. result = ((null == outer) || canAccess(outer));
  130. }
  131. return result;
  132. }
  133. /**
  134. * This is called from <code>canAccess</code> to log any results
  135. * of <code>doCanAccess</code>
  136. * and should return the result or a principled variant thereof.
  137. */
  138. protected boolean canAccessLog(Modifiers mods, Object object,
  139. boolean result) {
  140. return result;
  141. }
  142. /**
  143. * Check whether client has access to the object
  144. * based on the modifiers.
  145. * @param object the Object with the modifier flags - may be null
  146. * @param modifiers the Modifiers to check
  147. * @return false if modifiers are null or true if access is permitted
  148. */
  149. // todo: object unused but useful for logging
  150. public final boolean canAccess(Modifiers mods, Object object) {
  151. boolean result = (null == mods? false : doCanAccess(mods, object));
  152. return canAccessLog(mods, object, result);
  153. }
  154. /** @return lowercase variant of option name (e.g., "private" for -private) */
  155. public final String getOption() { return optionName; }
  156. /** @return UPPERCASE variant of option name (e.g., "PRIVATE" for -private) */
  157. public final String toString() { return optionName.toUpperCase(); }
  158. /** subclasses implement semantics here. */
  159. abstract protected boolean doCanAccess(Modifiers mods, Object object);
  160. }