/* -*- Mode: JDE; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * This file is part of the debugger and core tools for the AspectJ(tm) * programming language; see http://aspectj.org * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/. * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is AspectJ. * * The Initial Developer of the Original Code is Xerox Corporation. Portions * created by Xerox Corporation are Copyright (C) 1999-2002 Xerox Corporation. * All Rights Reserved. */ package org.aspectj.tools.ajdoc; import org.aspectj.compiler.base.ast.Modifiers; import org.aspectj.compiler.base.ast.FieldDec; import org.aspectj.compiler.base.ast.TypeDec; import org.aspectj.compiler.base.ast.NameType; import org.aspectj.compiler.base.ast.CodeDec; import org.aspectj.compiler.crosscuts.ast.PointcutDec; /** * This utility tells whether a declaration is accessible * based on its access modifiers (and that of its declaring * class, if it is a member (i.e., including inner classes). *

Instantiation and subclassing: * The constants should suffice for most uses, but subclassing * is permitted if you need to implement new functionality or * make new instances. */ public abstract class AccessChecker { // constants open doCanAccess to public to permit direct use /** return true only for public elements */ public static final AccessChecker PUBLIC = new AccessChecker("public") { public boolean doCanAccess(Modifiers mods, Object object) { return mods.isPublic(); } }; /** return true for public and protected elements */ public static final AccessChecker PROTECTED = new AccessChecker("protected") { public boolean doCanAccess(Modifiers mods, Object object) { return mods.isPublic() || mods.isProtected(); } }; /** return true unless private elements */ public static final AccessChecker PACKAGE = new AccessChecker("package") { public boolean doCanAccess(Modifiers mods, Object object) { return !mods.isPrivate(); } }; /** return true for all elements */ public static final AccessChecker PRIVATE = new AccessChecker("private") { public boolean doCanAccess(Modifiers mods, Object object) { return true; } }; /** lowercase option without - */ protected final String optionName; /** * Encourage use of static constants by prohibiting construction * but permit new subclasses. * Subclasses should ensure optionName is lowercase and * doCanAccess is public if need be. */ protected AccessChecker(String optionName){ this.optionName = optionName; } /** @return true if modifiers permitted for self and declaring type */ public boolean canAccess(FieldDec dec) { if (null == dec) return false; if (!canAccess(dec.getModifiers(), dec)) { return false; } else { return canAccess(dec.getBytecodeTypeDec()); } } /** @return true if modifiers permitted for self and declaring type */ public boolean canAccess(CodeDec dec) { if (null == dec) return false; if (!canAccess(dec.getModifiers(), dec)) { return false; } else { return canAccess(dec.getBytecodeTypeDec()); } } /** @return true if modifiers permitted for self and declaring type */ public boolean canAccess(PointcutDec dec) { if (null == dec) return false; if (!canAccess(dec.getModifiers(), dec)) { return false; } else { return canAccess(dec.getBytecodeTypeDec()); } } /** decode dec modifiers and return whether access is permitted * Access is permitted if it is permitted to the dec. * The caller must prohibit access when displaying in the aspect * (i.e., canAccess(dec.getLexicalType()) or in * the target class * (i.e., canAccess(dec.getDeclaringType())) * and to the enclosing lexical type (i.e,. the enclosing aspect). */ /* public boolean canAccess(IntroducedDec dec) { // todo: users if (null == dec) return false; if (!canAccess(dec.getModifiers(), dec)) { return false; } else { return canAccess(dec.getLexicalType()); } } */ /** @return true if modifiers permitted for self and any enclosing type */ public boolean canAccess(TypeDec dec) { if (null == dec) return false; boolean result = canAccess(dec.getModifiers(), dec); if (result) { // avoiding NPE in getEnclosingInstanceTypeDec NameType outerType = dec.getEnclosingInstanceType(); TypeDec outer = (null == outerType? null : outerType.getTypeDec()); // todo: typeDec? result = ((null == outer) || canAccess(outer)); } return result; } /** * This is called from canAccess to log any results * of doCanAccess * and should return the result or a principled variant thereof. */ protected boolean canAccessLog(Modifiers mods, Object object, boolean result) { return result; } /** * Check whether client has access to the object * based on the modifiers. * @param object the Object with the modifier flags - may be null * @param modifiers the Modifiers to check * @return false if modifiers are null or true if access is permitted */ // todo: object unused but useful for logging public final boolean canAccess(Modifiers mods, Object object) { boolean result = (null == mods? false : doCanAccess(mods, object)); return canAccessLog(mods, object, result); } /** @return lowercase variant of option name (e.g., "private" for -private) */ public final String getOption() { return optionName; } /** @return UPPERCASE variant of option name (e.g., "PRIVATE" for -private) */ public final String toString() { return optionName.toUpperCase(); } /** subclasses implement semantics here. */ abstract protected boolean doCanAccess(Modifiers mods, Object object); }