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