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