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 }