001 package serp.bytecode; 002 003 /** 004 * An annotated entity. 005 * 006 * @author Abe White 007 */ 008 public abstract class Annotated extends Attributes { 009 /** 010 * Return runtime <b>invisible</b> annotation information for the entity. 011 * Acts internally through the {@link Attributes} interface. 012 * 013 * @param add if true, a new annotations attribute will be added if not 014 * already present 015 * @return the annotation information, or null if none and the 016 * <code>add</code> param is set to false 017 */ 018 public Annotations getDeclaredAnnotations(boolean add) { 019 Annotations ann = (Annotations) getAttribute 020 (Constants.ATTR_ANNOTATIONS); 021 if (!add || ann != null) 022 return ann; 023 ensureBytecodeVersion(); 024 return (Annotations) addAttribute(Constants.ATTR_ANNOTATIONS); 025 } 026 027 /** 028 * Remove the runtime <b>invisible</b> annotations attribute for the entity. 029 * Acts internally through the {@link Attributes} interface. 030 * 031 * @return true if there was an attribute to remove 032 */ 033 public boolean removeDeclaredAnnotations() { 034 return removeAttribute(Constants.ATTR_ANNOTATIONS); 035 } 036 037 /** 038 * Return runtime visible annotation information for the entity. 039 * Acts internally through the {@link Attributes} interface. 040 * 041 * @param add if true, a new runtime annotations attribute will be 042 * added if not already present 043 * @return the annotation information, or null if none and the 044 * <code>add</code> param is set to false 045 */ 046 public Annotations getDeclaredRuntimeAnnotations(boolean add) { 047 Annotations ann = (Annotations) getAttribute 048 (Constants.ATTR_RUNTIME_ANNOTATIONS); 049 if (!add || ann != null) 050 return ann; 051 ensureBytecodeVersion(); 052 return (Annotations) addAttribute(Constants.ATTR_RUNTIME_ANNOTATIONS); 053 } 054 055 /** 056 * Remove the runtime visible annotations attribute for the entity. 057 * Acts internally through the {@link Attributes} interface. 058 * 059 * @return true if there was an attribute to remove 060 */ 061 public boolean removeDeclaredRuntimeAnnotations() { 062 return removeAttribute(Constants.ATTR_RUNTIME_ANNOTATIONS); 063 } 064 065 /** 066 * When adding annotations, make sure the bytecode spec supports them. 067 */ 068 private void ensureBytecodeVersion() { 069 BCClass bc = getBCClass(); 070 if (bc.getMajorVersion() < Constants.MAJOR_VERSION_JAVA5) { 071 bc.setMajorVersion(Constants.MAJOR_VERSION_JAVA5); 072 bc.setMinorVersion(Constants.MINOR_VERSION_JAVA5); 073 } 074 } 075 076 /** 077 * Internal access to the owning class. 078 */ 079 abstract BCClass getBCClass(); 080 }