View Javadoc

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 }