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   */
18  package org.apache.bcel.classfile;
19  
20  import java.io.DataInput;
21  import java.io.DataOutputStream;
22  import java.io.IOException;
23  import java.util.ArrayList;
24  import java.util.Collections;
25  import java.util.List;
26  
27  import org.apache.bcel.Const;
28  
29  /**
30   * represents one annotation in the annotation table
31   *
32   * @since 6.0
33   */
34  public class AnnotationEntry implements Node {
35  
36      private final int typeIndex;
37      private final ConstantPool constantPool;
38      private final boolean isRuntimeVisible;
39  
40      private List<ElementValuePair> elementValuePairs;
41  
42      /*
43       * Factory method to create an AnnotionEntry from a DataInput
44       *
45       * @param input
46       * @param constantPool
47       * @param isRuntimeVisible
48       * @return the entry
49       * @throws IOException
50       */
51      public static AnnotationEntry read(final DataInput input, final ConstantPool constant_pool, final boolean isRuntimeVisible) throws IOException {
52  
53          final AnnotationEntry#AnnotationEntry">AnnotationEntry annotationEntry = new AnnotationEntry(input.readUnsignedShort(), constant_pool, isRuntimeVisible);
54          final int num_element_value_pairs = input.readUnsignedShort();
55          annotationEntry.elementValuePairs = new ArrayList<>();
56          for (int i = 0; i < num_element_value_pairs; i++) {
57              annotationEntry.elementValuePairs.add(
58                      new ElementValuePair(input.readUnsignedShort(), ElementValue.readElementValue(input, constant_pool),
59                      constant_pool));
60          }
61          return annotationEntry;
62      }
63  
64      public AnnotationEntry(final int type_index, final ConstantPool constant_pool, final boolean isRuntimeVisible) {
65          this.typeIndex = type_index;
66          this.constantPool = constant_pool;
67          this.isRuntimeVisible = isRuntimeVisible;
68      }
69  
70      public int getTypeIndex() {
71          return typeIndex;
72      }
73  
74      public ConstantPool getConstantPool() {
75          return constantPool;
76      }
77  
78      public boolean isRuntimeVisible() {
79          return isRuntimeVisible;
80      }
81  
82      /**
83       * Called by objects that are traversing the nodes of the tree implicitely defined by the contents of a Java class.
84       * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects.
85       *
86       * @param v Visitor object
87       */
88      @Override
89      public void accept(final Visitor v) {
90          v.visitAnnotationEntry(this);
91      }
92  
93      /**
94       * @return the annotation type name
95       */
96      public String getAnnotationType() {
97          final ConstantUtf8./../../../org/apache/bcel/classfile/ConstantUtf8.html#ConstantUtf8">ConstantUtf8 c = (ConstantUtf8) constantPool.getConstant(typeIndex, Const.CONSTANT_Utf8);
98          return c.getBytes();
99      }
100 
101     /**
102      * @return the annotation type index
103      */
104     public int getAnnotationTypeIndex() {
105         return typeIndex;
106     }
107 
108     /**
109      * @return the number of element value pairs in this annotation entry
110      */
111     public final int getNumElementValuePairs() {
112         return elementValuePairs.size();
113     }
114 
115     /**
116      * @return the element value pairs in this annotation entry
117      */
118     public ElementValuePair[] getElementValuePairs() {
119         // TODO return List
120         return elementValuePairs.toArray(new ElementValuePair[elementValuePairs.size()]);
121     }
122 
123     public void dump(final DataOutputStream dos) throws IOException {
124         dos.writeShort(typeIndex); // u2 index of type name in cpool
125         dos.writeShort(elementValuePairs.size()); // u2 element_value pair
126         // count
127         for (final ElementValuePair envp : elementValuePairs) {
128             envp.dump(dos);
129         }
130     }
131 
132     public void addElementNameValuePair(final ElementValuePair elementNameValuePair) {
133         elementValuePairs.add(elementNameValuePair);
134     }
135 
136     public String toShortString() {
137         final StringBuilder result = new StringBuilder();
138         result.append("@");
139         result.append(getAnnotationType());
140         final ElementValuePair[] evPairs = getElementValuePairs();
141         if (evPairs.length > 0) {
142             result.append("(");
143             for (final ElementValuePair element : evPairs) {
144                 result.append(element.toShortString());
145             }
146             result.append(")");
147         }
148         return result.toString();
149     }
150 
151     @Override
152     public String toString() {
153         return toShortString();
154     }
155 
156     public static AnnotationEntry[] createAnnotationEntries(final Attribute[] attrs) {
157         // Find attributes that contain annotation data
158         final List<AnnotationEntry> accumulatedAnnotations = new ArrayList<>(attrs.length);
159         for (final Attribute attribute : attrs) {
160             if (attribute instanceof Annotations) {
161                 final Annotationspache/bcel/classfile/Annotations.html#Annotations">Annotations runtimeAnnotations = (Annotations) attribute;
162                 Collections.addAll(accumulatedAnnotations, runtimeAnnotations.getAnnotationEntries());
163             }
164         }
165         return accumulatedAnnotations.toArray(new AnnotationEntry[accumulatedAnnotations.size()]);
166     }
167 }