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