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.util; 19 20 import java.io.FileOutputStream; 21 import java.io.IOException; 22 import java.io.PrintWriter; 23 24 import org.apache.bcel.Const; 25 import org.apache.bcel.classfile.Constant; 26 import org.apache.bcel.classfile.ConstantClass; 27 import org.apache.bcel.classfile.ConstantFieldref; 28 import org.apache.bcel.classfile.ConstantInterfaceMethodref; 29 import org.apache.bcel.classfile.ConstantMethodref; 30 import org.apache.bcel.classfile.ConstantNameAndType; 31 import org.apache.bcel.classfile.ConstantPool; 32 import org.apache.bcel.classfile.ConstantString; 33 import org.apache.bcel.classfile.Method; 34 import org.apache.bcel.classfile.Utility; 35 36 /** 37 * Convert constant pool into HTML file. 38 * 39 * @version $Id$ 40 * 41 */ 42 final class ConstantHTML { 43 44 private final String class_name; // name of current class 45 private final String class_package; // name of package 46 private final ConstantPool constant_pool; // reference to constant pool 47 private final PrintWriter file; // file to write to 48 private final String[] constant_ref; // String to return for cp[i] 49 private final Constant[] constants; // The constants in the cp 50 private final Method[] methods; 51 52 ConstantHTML(final String dir, final String class_name, final String class_package, final Method[] methods, final ConstantPool constant_pool)53 ConstantHTML(final String dir, final String class_name, final String class_package, final Method[] methods, 54 final ConstantPool constant_pool) throws IOException { 55 this.class_name = class_name; 56 this.class_package = class_package; 57 this.constant_pool = constant_pool; 58 this.methods = methods; 59 constants = constant_pool.getConstantPool(); 60 file = new PrintWriter(new FileOutputStream(dir + class_name + "_cp.html")); 61 constant_ref = new String[constants.length]; 62 constant_ref[0] = "<unknown>"; 63 file.println("<HTML><BODY BGCOLOR=\"#C0C0C0\"><TABLE BORDER=0>"); 64 // Loop through constants, constants[0] is reserved 65 for (int i = 1; i < constants.length; i++) { 66 if (i % 2 == 0) { 67 file.print("<TR BGCOLOR=\"#C0C0C0\"><TD>"); 68 } else { 69 file.print("<TR BGCOLOR=\"#A0A0A0\"><TD>"); 70 } 71 if (constants[i] != null) { 72 writeConstant(i); 73 } 74 file.print("</TD></TR>\n"); 75 } 76 file.println("</TABLE></BODY></HTML>"); 77 file.close(); 78 } 79 80 referenceConstant( final int index )81 String referenceConstant( final int index ) { 82 return constant_ref[index]; 83 } 84 85 writeConstant( final int index )86 private void writeConstant( final int index ) { 87 final byte tag = constants[index].getTag(); 88 int class_index; 89 int name_index; 90 String ref; 91 // The header is always the same 92 file.println("<H4> <A NAME=cp" + index + ">" + index + "</A> " + Const.getConstantName(tag) 93 + "</H4>"); 94 /* For every constant type get the needed parameters and print them appropiately 95 */ 96 switch (tag) { 97 case Const.CONSTANT_InterfaceMethodref: 98 case Const.CONSTANT_Methodref: 99 // Get class_index and name_and_type_index, depending on type 100 if (tag == Const.CONSTANT_Methodref) { 101 final ConstantMethodref c = (ConstantMethodref) constant_pool.getConstant(index, 102 Const.CONSTANT_Methodref); 103 class_index = c.getClassIndex(); 104 name_index = c.getNameAndTypeIndex(); 105 } else { 106 final ConstantInterfaceMethodref c1 = (ConstantInterfaceMethodref) constant_pool 107 .getConstant(index, Const.CONSTANT_InterfaceMethodref); 108 class_index = c1.getClassIndex(); 109 name_index = c1.getNameAndTypeIndex(); 110 } 111 // Get method name and its class 112 final String method_name = constant_pool.constantToString(name_index, 113 Const.CONSTANT_NameAndType); 114 final String html_method_name = Class2HTML.toHTML(method_name); 115 // Partially compacted class name, i.e., / -> . 116 final String method_class = constant_pool.constantToString(class_index, Const.CONSTANT_Class); 117 String short_method_class = Utility.compactClassName(method_class); // I.e., remove java.lang. 118 short_method_class = Utility.compactClassName(short_method_class, class_package 119 + ".", true); // Remove class package prefix 120 // Get method signature 121 final ConstantNameAndType c2 = (ConstantNameAndType) constant_pool.getConstant( 122 name_index, Const.CONSTANT_NameAndType); 123 final String signature = constant_pool.constantToString(c2.getSignatureIndex(), 124 Const.CONSTANT_Utf8); 125 // Get array of strings containing the argument types 126 final String[] args = Utility.methodSignatureArgumentTypes(signature, false); 127 // Get return type string 128 final String type = Utility.methodSignatureReturnType(signature, false); 129 final String ret_type = Class2HTML.referenceType(type); 130 final StringBuilder buf = new StringBuilder("("); 131 for (int i = 0; i < args.length; i++) { 132 buf.append(Class2HTML.referenceType(args[i])); 133 if (i < args.length - 1) { 134 buf.append(", "); 135 } 136 } 137 buf.append(")"); 138 final String arg_types = buf.toString(); 139 if (method_class.equals(class_name)) { 140 ref = "<A HREF=\"" + class_name + "_code.html#method" 141 + getMethodNumber(method_name + signature) + "\" TARGET=Code>" 142 + html_method_name + "</A>"; 143 } else { 144 ref = "<A HREF=\"" + method_class + ".html" + "\" TARGET=_top>" 145 + short_method_class + "</A>." + html_method_name; 146 } 147 constant_ref[index] = ret_type + " <A HREF=\"" + class_name + "_cp.html#cp" 148 + class_index + "\" TARGET=Constants>" + short_method_class 149 + "</A>.<A HREF=\"" + class_name + "_cp.html#cp" + index 150 + "\" TARGET=ConstantPool>" + html_method_name + "</A> " + arg_types; 151 file.println("<P><TT>" + ret_type + " " + ref + arg_types 152 + " </TT>\n<UL>" + "<LI><A HREF=\"#cp" + class_index 153 + "\">Class index(" + class_index + ")</A>\n" + "<LI><A HREF=\"#cp" 154 + name_index + "\">NameAndType index(" + name_index + ")</A></UL>"); 155 break; 156 case Const.CONSTANT_Fieldref: 157 // Get class_index and name_and_type_index 158 final ConstantFieldref c3 = (ConstantFieldref) constant_pool.getConstant(index, 159 Const.CONSTANT_Fieldref); 160 class_index = c3.getClassIndex(); 161 name_index = c3.getNameAndTypeIndex(); 162 // Get method name and its class (compacted) 163 final String field_class = constant_pool.constantToString(class_index, Const.CONSTANT_Class); 164 String short_field_class = Utility.compactClassName(field_class); // I.e., remove java.lang. 165 short_field_class = Utility.compactClassName(short_field_class, 166 class_package + ".", true); // Remove class package prefix 167 final String field_name = constant_pool 168 .constantToString(name_index, Const.CONSTANT_NameAndType); 169 if (field_class.equals(class_name)) { 170 ref = "<A HREF=\"" + field_class + "_methods.html#field" + field_name 171 + "\" TARGET=Methods>" + field_name + "</A>"; 172 } else { 173 ref = "<A HREF=\"" + field_class + ".html\" TARGET=_top>" + short_field_class 174 + "</A>." + field_name + "\n"; 175 } 176 constant_ref[index] = "<A HREF=\"" + class_name + "_cp.html#cp" + class_index 177 + "\" TARGET=Constants>" + short_field_class + "</A>.<A HREF=\"" 178 + class_name + "_cp.html#cp" + index + "\" TARGET=ConstantPool>" 179 + field_name + "</A>"; 180 file.println("<P><TT>" + ref + "</TT><BR>\n" + "<UL>" + "<LI><A HREF=\"#cp" 181 + class_index + "\">Class(" + class_index + ")</A><BR>\n" 182 + "<LI><A HREF=\"#cp" + name_index + "\">NameAndType(" + name_index 183 + ")</A></UL>"); 184 break; 185 case Const.CONSTANT_Class: 186 final ConstantClass c4 = (ConstantClass) constant_pool.getConstant(index, Const.CONSTANT_Class); 187 name_index = c4.getNameIndex(); 188 final String class_name2 = constant_pool.constantToString(index, tag); // / -> . 189 String short_class_name = Utility.compactClassName(class_name2); // I.e., remove java.lang. 190 short_class_name = Utility.compactClassName(short_class_name, class_package + ".", 191 true); // Remove class package prefix 192 ref = "<A HREF=\"" + class_name2 + ".html\" TARGET=_top>" + short_class_name 193 + "</A>"; 194 constant_ref[index] = "<A HREF=\"" + class_name + "_cp.html#cp" + index 195 + "\" TARGET=ConstantPool>" + short_class_name + "</A>"; 196 file.println("<P><TT>" + ref + "</TT><UL>" + "<LI><A HREF=\"#cp" + name_index 197 + "\">Name index(" + name_index + ")</A></UL>\n"); 198 break; 199 case Const.CONSTANT_String: 200 final ConstantString c5 = (ConstantString) constant_pool.getConstant(index, 201 Const.CONSTANT_String); 202 name_index = c5.getStringIndex(); 203 final String str = Class2HTML.toHTML(constant_pool.constantToString(index, tag)); 204 file.println("<P><TT>" + str + "</TT><UL>" + "<LI><A HREF=\"#cp" + name_index 205 + "\">Name index(" + name_index + ")</A></UL>\n"); 206 break; 207 case Const.CONSTANT_NameAndType: 208 final ConstantNameAndType c6 = (ConstantNameAndType) constant_pool.getConstant(index, 209 Const.CONSTANT_NameAndType); 210 name_index = c6.getNameIndex(); 211 final int signature_index = c6.getSignatureIndex(); 212 file.println("<P><TT>" 213 + Class2HTML.toHTML(constant_pool.constantToString(index, tag)) 214 + "</TT><UL>" + "<LI><A HREF=\"#cp" + name_index + "\">Name index(" 215 + name_index + ")</A>\n" + "<LI><A HREF=\"#cp" + signature_index 216 + "\">Signature index(" + signature_index + ")</A></UL>\n"); 217 break; 218 default: 219 file.println("<P><TT>" + Class2HTML.toHTML(constant_pool.constantToString(index, tag)) + "</TT>\n"); 220 } // switch 221 } 222 223 getMethodNumber( final String str )224 private int getMethodNumber( final String str ) { 225 for (int i = 0; i < methods.length; i++) { 226 final String cmp = methods[i].getName() + methods[i].getSignature(); 227 if (cmp.equals(str)) { 228 return i; 229 } 230 } 231 return -1; 232 } 233 } 234