1 package serp.bytecode; 2 3 import java.io.*; 4 import java.util.*; 5 6 import serp.bytecode.visitor.*; 7 8 /*** 9 * Java annotation data. 10 * 11 * @author Abe White 12 */ 13 public class Annotations extends Attribute { 14 private final List _annotations = new ArrayList(); 15 16 Annotations(int nameIndex, Attributes owner) { 17 super(nameIndex, owner); 18 } 19 20 /*** 21 * Whether these annotations are runtime-visible. 22 */ 23 public boolean isRuntime() { 24 return getName().equals(Constants.ATTR_RUNTIME_ANNOTATIONS); 25 } 26 27 /*** 28 * All declared annotations. 29 */ 30 public Annotation[] getAnnotations() { 31 return (Annotation[]) _annotations.toArray 32 (new Annotation[_annotations.size()]); 33 } 34 35 /*** 36 * Set the annotations. This method is useful when 37 * importing annotations from another instance. 38 */ 39 public void setAnnotations(Annotation[] annos) { 40 clear(); 41 if (annos != null) 42 for (int i = 0; i < annos.length; i++) 43 addAnnotation(annos[i]); 44 } 45 46 /*** 47 * Return the annotation of the given type, or null if none. 48 */ 49 public Annotation getAnnotation(Class type) { 50 return (type == null) ? null : getAnnotation(type.getName()); 51 } 52 53 /*** 54 * Return the annotation of the given type, or null if none. 55 */ 56 public Annotation getAnnotation(BCClass type) { 57 return (type == null) ? null : getAnnotation(type.getName()); 58 } 59 60 /*** 61 * Return the annotation of the given type, or null if none. 62 */ 63 public Annotation getAnnotation(String type) { 64 Annotation anno; 65 for (int i = 0; i < _annotations.size(); i++) { 66 anno = (Annotation) _annotations.get(i); 67 if (anno.getTypeName().equals(type)) 68 return anno; 69 } 70 return null; 71 } 72 73 /*** 74 * Import an annotation from another instance. 75 * 76 * @return the newly added annotation 77 */ 78 public Annotation addAnnotation(Annotation an) { 79 Annotation anno = addAnnotation(an.getTypeName()); 80 anno.setProperties(an.getProperties()); 81 return anno; 82 } 83 84 /*** 85 * Add a new annotation. 86 */ 87 public Annotation addAnnotation(Class type) { 88 return addAnnotation(type.getName()); 89 } 90 91 /*** 92 * Add a new annotation. 93 */ 94 public Annotation addAnnotation(BCClass type) { 95 return addAnnotation(type.getName()); 96 } 97 98 /*** 99 * Add a new annotation. 100 */ 101 public Annotation addAnnotation(String type) { 102 Annotation anno = new Annotation(this); 103 anno.setType(type); 104 _annotations.add(anno); 105 return anno; 106 } 107 108 /*** 109 * Remove all annotations. 110 */ 111 public void clear() { 112 for (int i = 0; i < _annotations.size(); i++) 113 ((Annotation) _annotations.get(i)).invalidate(); 114 _annotations.clear(); 115 } 116 117 /*** 118 * Remove the given annotation. 119 * 120 * @return true if an annotation was removed, false otherwise 121 */ 122 public boolean removeAnnotation(Annotation anno) { 123 return anno != null && removeAnnotation(anno.getTypeName()); 124 } 125 126 /*** 127 * Remove the annotation of the given type. 128 * 129 * @return true if an annotation was removed, false otherwise 130 */ 131 public boolean removeAnnotation(Class type) { 132 return type != null && removeAnnotation(type.getName()); 133 } 134 135 /*** 136 * Remove the annotation of the given type. 137 * 138 * @return true if an annotation was removed, false otherwise 139 */ 140 public boolean removeAnnotation(BCClass type) { 141 return type != null && removeAnnotation(type.getName()); 142 } 143 144 /*** 145 * Remove the annotation of the given type. 146 * 147 * @return true if an annotation was removed, false otherwise 148 */ 149 public boolean removeAnnotation(String type) { 150 if (type == null) 151 return false; 152 Annotation anno; 153 for (int i = 0; i < _annotations.size(); i++) { 154 anno = (Annotation) _annotations.get(i); 155 if (anno.getTypeName().equals(type)) { 156 anno.invalidate(); 157 _annotations.remove(i); 158 return true; 159 } 160 } 161 return false; 162 } 163 164 int getLength() { 165 int len = 2; 166 for (int i = 0; i < _annotations.size(); i++) 167 len += ((Annotation) _annotations.get(i)).getLength(); 168 return len; 169 } 170 171 void read(Attribute other) { 172 setAnnotations(((Annotations) other).getAnnotations()); 173 } 174 175 void read(DataInput in, int length) throws IOException { 176 _annotations.clear(); 177 int annos = in.readUnsignedShort(); 178 Annotation anno; 179 for (int i = 0; i < annos; i++) { 180 anno = new Annotation(this); 181 anno.read(in); 182 _annotations.add(anno); 183 } 184 } 185 186 void write(DataOutput out, int length) throws IOException { 187 out.writeShort(_annotations.size()); 188 for (int i = 0; i < _annotations.size(); i++) 189 ((Annotation) _annotations.get(i)).write(out); 190 } 191 192 public void acceptVisit(BCVisitor visit) { 193 visit.enterAnnotations(this); 194 for (int i = 0; i < _annotations.size(); i++) 195 ((Annotation) _annotations.get(i)).acceptVisit(visit); 196 visit.exitAnnotations(this); 197 } 198 }