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