View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   */
17  package org.apache.bcel.classfile;
18  
19  import java.io.DataInput;
20  import java.io.DataOutputStream;
21  import java.io.IOException;
22  import java.util.Iterator;
23  import java.util.stream.Stream;
24  
25  import org.apache.bcel.Const;
26  
27  /**
28   * base class for annotations
29   *
30   * @since 6.0
31   */
32  public abstract class Annotations extends Attribute implements Iterable<AnnotationEntry> {
33  
34      private AnnotationEntry[] annotationTable;
35      private final boolean isRuntimeVisible;
36  
37      /**
38       * Constructs an instance.
39       *
40       * @param annotationType   the subclass type of the annotation
41       * @param nameIndex        Index pointing to the name <em>Code</em>
42       * @param length           Content length in bytes
43       * @param annotationTable  the actual annotations
44       * @param constantPool     Array of constants
45       * @param isRuntimeVisible whether this Annotation visible at runtime
46       */
47      public Annotations(final byte annotationType, final int nameIndex, final int length, final AnnotationEntry[] annotationTable,
48              final ConstantPool constantPool, final boolean isRuntimeVisible) {
49          super(annotationType, nameIndex, length, constantPool);
50          setAnnotationTable(annotationTable);
51          this.isRuntimeVisible = isRuntimeVisible;
52      }
53  
54      /**
55       * Constructs an instance.
56       *
57       * @param annotationType   the subclass type of the annotation
58       * @param nameIndex        Index pointing to the name <em>Code</em>
59       * @param length           Content length in bytes
60       * @param input            Input stream
61       * @param constantPool     Array of constants
62       * @param isRuntimeVisible whether this Annotation visible at runtime
63       * @throws IOException if an I/O error occurs.
64       */
65      Annotations(final byte annotationType, final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool,
66              final boolean isRuntimeVisible) throws IOException {
67          this(annotationType, nameIndex, length, (AnnotationEntry[]) null, constantPool, isRuntimeVisible);
68          final int annotationTableLength = input.readUnsignedShort();
69          annotationTable = new AnnotationEntry[annotationTableLength];
70          for (int i = 0; i < annotationTableLength; i++) {
71              annotationTable[i] = AnnotationEntry.read(input, constantPool, isRuntimeVisible);
72          }
73      }
74  
75      /**
76       * Called by objects that are traversing the nodes of the tree implicitly
77       * defined by the contents of a Java class. I.e., the hierarchy of methods,
78       * fields, attributes, etc. spawns a tree of objects.
79       *
80       * @param v Visitor object
81       */
82      @Override
83      public void accept(final Visitor v) {
84          v.visitAnnotation(this);
85      }
86  
87      @Override
88      public Attribute copy(final ConstantPool constantPool) {
89          // TODO Auto-generated method stub
90          return null;
91      }
92  
93      /**
94       * Gets the array of annotation entries in this annotation
95       */
96      public AnnotationEntry[] getAnnotationEntries() {
97          return annotationTable;
98      }
99  
100     /**
101      * Gets the number of annotation entries in this annotation.
102      *
103      * @return the number of annotation entries in this annotation
104      */
105     public final int getNumAnnotations() {
106         return annotationTable.length;
107     }
108 
109     public boolean isRuntimeVisible() {
110         return isRuntimeVisible;
111     }
112 
113     @Override
114     public Iterator<AnnotationEntry> iterator() {
115         return Stream.of(annotationTable).iterator();
116     }
117 
118     /**
119      * Sets the entries to set in this annotation.
120      *
121      * @param annotationTable the entries to set in this annotation
122      */
123     public final void setAnnotationTable(final AnnotationEntry[] annotationTable) {
124         this.annotationTable = annotationTable != null ? annotationTable : AnnotationEntry.EMPTY_ARRAY;
125     }
126 
127     /**
128      * Converts to a String representation.
129      *
130      * @return String representation
131      */
132     @Override
133     public final String toString() {
134         final StringBuilder buf = new StringBuilder(Const.getAttributeName(getTag()));
135         buf.append(":\n");
136         for (int i = 0; i < annotationTable.length; i++) {
137             buf.append("  ").append(annotationTable[i]);
138             if (i < annotationTable.length - 1) {
139                 buf.append('\n');
140             }
141         }
142         return buf.toString();
143     }
144 
145     protected void writeAnnotations(final DataOutputStream dos) throws IOException {
146         dos.writeShort(annotationTable.length);
147         for (final AnnotationEntry element : annotationTable) {
148             element.dump(dos);
149         }
150     }
151 
152 }