1 /*
2 * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package org.openjdk.asmtools.jdis;
24
25 import java.io.DataInputStream;
26 import java.io.IOException;
27 import java.io.PrintWriter;
28 import java.util.ArrayList;
29
30 import static java.lang.String.format;
31
32 /**
33 *
34 */
35 public class AnnotationData {
36 /*-------------------------------------------------------- */
37 /* AnnotData Fields */
38
39 protected String visAnnotToken = "@+";
40 protected String invAnnotToken = "@-";
41 protected String dataName = "AnnotationData";
42 private boolean invisible = false;
43 private int type_cpx = 0; //an index into the constant pool indicating the annotation type for this annotation.
44 private ArrayList<AnnotationElement> array = new ArrayList<>();
45 private ClassData cls;
46 /*-------------------------------------------------------- */
47
48 public AnnotationData(boolean invisible, ClassData cls) {
49 this.cls = cls;
50 this.invisible = invisible;
51 }
52
53 public void read(DataInputStream in) throws IOException {
54 type_cpx = in.readShort();
55 int elemValueLength = in.readShort();
56 TraceUtils.traceln(3, format(" %s: name[%d]=%s", dataName, type_cpx, cls.pool.getString(type_cpx)),
57 format(" %s: %s num_elems: %d", dataName, cls.pool.getString(type_cpx), elemValueLength));
58 for (int evc = 0; evc < elemValueLength; evc++) {
59 AnnotationElement elem = new AnnotationElement(cls);
60 TraceUtils.traceln(3, format(" %s: %s reading [%d]", dataName, cls.pool.getString(type_cpx), evc));
61 elem.read(in, invisible);
62 array.add(elem);
63 }
64 }
65
66 public void print(PrintWriter out, String tab) {
67 printHeader(out, tab);
68 printBody(out, "");
69 }
70
71 protected void printHeader(PrintWriter out, String tab) {
72 //Print annotation Header, which consists of the
73 // Annotation Token ('@'), visibility ('+', '-'),
74 // and the annotation name (type index, CPX).
75
76 // Mark whether it is invisible or not.
77 if (invisible) {
78 out.print(tab + invAnnotToken);
79 } else {
80 out.print(tab + visAnnotToken);
81 }
82 String annoName = cls.pool.getString(type_cpx);
83
84 // converts class type to java class name
85 if (annoName.startsWith("L") && annoName.endsWith(";")) {
86 annoName = annoName.substring(1, annoName.length() - 1);
87 }
88
89 out.print(annoName);
90 }
91
92 protected void printBody(PrintWriter out, String tab) {
93 // For a standard annotation, print out brackets,
94 // and list the name/value pairs.
95 out.print(" { ");
96 int i = 0;
97 for (AnnotationElement elem : array) {
98 elem.print(out, tab);
99 if (i++ < array.size() - 1) {
100 out.print(", ");
101 }
102 }
103 out.print(" }");
104 }
105
106 @Override
107 public String toString() {
108 StringBuilder sb = new StringBuilder();
109 String annoName = cls.pool.getString(type_cpx);
110
111 // converts class type to java class name
112 if (annoName.startsWith("L") && annoName.endsWith(";")) {
113 annoName = annoName.substring(1, annoName.length() - 1);
114 }
115
116 //Print annotation
117 // Mark whether it is invisible or not.
118 if (invisible) {
119 sb.append(invAnnotToken);
120 } else {
121 sb.append(visAnnotToken);
122 }
123
124 sb.append(annoName);
125 sb.append(" { ");
126
127 int i = 0;
128 for (AnnotationElement elem : array) {
129 sb.append(elem.toString());
130
131 if (i++ < array.size() - 1) {
132 sb.append(", ");
133 }
134 }
135
136 _toString(sb);
137
138 sb.append("}");
139 return sb.toString();
140 }
141
142 protected void _toString(StringBuilder sb) {
143 // sub-classes override this
144 }
145 }
146