ConstantHTML.java

  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. package org.apache.bcel.util;

  18. import java.io.FileNotFoundException;
  19. import java.io.PrintWriter;
  20. import java.io.UnsupportedEncodingException;
  21. import java.nio.charset.Charset;

  22. import org.apache.bcel.Const;
  23. import org.apache.bcel.classfile.Constant;
  24. import org.apache.bcel.classfile.ConstantClass;
  25. import org.apache.bcel.classfile.ConstantFieldref;
  26. import org.apache.bcel.classfile.ConstantInterfaceMethodref;
  27. import org.apache.bcel.classfile.ConstantMethodref;
  28. import org.apache.bcel.classfile.ConstantNameAndType;
  29. import org.apache.bcel.classfile.ConstantPool;
  30. import org.apache.bcel.classfile.ConstantString;
  31. import org.apache.bcel.classfile.Method;
  32. import org.apache.bcel.classfile.Utility;

  33. /**
  34.  * Convert constant pool into HTML file.
  35.  */
  36. final class ConstantHTML {

  37.     private final String className; // name of current class
  38.     private final String classPackage; // name of package
  39.     private final ConstantPool constantPool; // reference to constant pool
  40.     private final PrintWriter printWriter; // file to write to
  41.     private final String[] constantRef; // String to return for cp[i]
  42.     private final Constant[] constants; // The constants in the cp
  43.     private final Method[] methods;

  44.     ConstantHTML(final String dir, final String className, final String classPackage, final Method[] methods, final ConstantPool constantPool,
  45.         final Charset charset) throws FileNotFoundException, UnsupportedEncodingException {
  46.         this.className = className;
  47.         this.classPackage = classPackage;
  48.         this.constantPool = constantPool;
  49.         this.methods = methods;
  50.         this.constants = constantPool.getConstantPool();
  51.         try (PrintWriter newPrintWriter = new PrintWriter(dir + className + "_cp.html", charset.name())) {
  52.             printWriter = newPrintWriter;
  53.             constantRef = new String[constants.length];
  54.             constantRef[0] = "<unknown>";
  55.             printWriter.print("<HTML><head><meta charset=\"");
  56.             printWriter.print(charset.name());
  57.             printWriter.println("\"></head>");
  58.             printWriter.println("<BODY BGCOLOR=\"#C0C0C0\"><TABLE BORDER=0>");
  59.             // Loop through constants, constants[0] is reserved
  60.             for (int i = 1; i < constants.length; i++) {
  61.                 if (i % 2 == 0) {
  62.                     printWriter.print("<TR BGCOLOR=\"#C0C0C0\"><TD>");
  63.                 } else {
  64.                     printWriter.print("<TR BGCOLOR=\"#A0A0A0\"><TD>");
  65.                 }
  66.                 if (constants[i] != null) {
  67.                     writeConstant(i);
  68.                 }
  69.                 printWriter.print("</TD></TR>\n");
  70.             }
  71.             printWriter.println("</TABLE></BODY></HTML>");
  72.         }
  73.     }

  74.     private int getMethodNumber(final String str) {
  75.         for (int i = 0; i < methods.length; i++) {
  76.             final String cmp = methods[i].getName() + methods[i].getSignature();
  77.             if (cmp.equals(str)) {
  78.                 return i;
  79.             }
  80.         }
  81.         return -1;
  82.     }

  83.     String referenceConstant(final int index) {
  84.         return constantRef[index];
  85.     }

  86.     private void writeConstant(final int index) {
  87.         final byte tag = constants[index].getTag();
  88.         int classIndex;
  89.         int nameIndex;
  90.         String ref;
  91.         // The header is always the same
  92.         printWriter.println("<H4> <A NAME=cp" + index + ">" + index + "</A> " + Const.getConstantName(tag) + "</H4>");
  93.         /*
  94.          * For every constant type get the needed parameters and print them appropriately
  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 = constantPool.getConstant(index, Const.CONSTANT_Methodref, ConstantMethodref.class);
  102.                 classIndex = c.getClassIndex();
  103.                 nameIndex = c.getNameAndTypeIndex();
  104.             } else {
  105.                 final ConstantInterfaceMethodref c1 = constantPool.getConstant(index, Const.CONSTANT_InterfaceMethodref, ConstantInterfaceMethodref.class);
  106.                 classIndex = c1.getClassIndex();
  107.                 nameIndex = c1.getNameAndTypeIndex();
  108.             }
  109.             // Get method name and its class
  110.             final String methodName = constantPool.constantToString(nameIndex, Const.CONSTANT_NameAndType);
  111.             final String htmlMethodName = Class2HTML.toHTML(methodName);
  112.             // Partially compacted class name, i.e., / -> .
  113.             final String methodClass = constantPool.constantToString(classIndex, Const.CONSTANT_Class);
  114.             String shortMethodClass = Utility.compactClassName(methodClass); // I.e., remove java.lang.
  115.             shortMethodClass = Utility.compactClassName(shortMethodClass, classPackage + ".", true); // Remove class package prefix
  116.             // Get method signature
  117.             final ConstantNameAndType c2 = constantPool.getConstant(nameIndex, Const.CONSTANT_NameAndType, ConstantNameAndType.class);
  118.             final String signature = constantPool.constantToString(c2.getSignatureIndex(), Const.CONSTANT_Utf8);
  119.             // Get array of strings containing the argument types
  120.             final String[] args = Utility.methodSignatureArgumentTypes(signature, false);
  121.             // Get return type string
  122.             final String type = Utility.methodSignatureReturnType(signature, false);
  123.             final String retType = Class2HTML.referenceType(type);
  124.             final StringBuilder buf = new StringBuilder("(");
  125.             for (int i = 0; i < args.length; i++) {
  126.                 buf.append(Class2HTML.referenceType(args[i]));
  127.                 if (i < args.length - 1) {
  128.                     buf.append(",&nbsp;");
  129.                 }
  130.             }
  131.             buf.append(")");
  132.             final String argTypes = buf.toString();
  133.             if (methodClass.equals(className)) {
  134.                 ref = "<A HREF=\"" + className + "_code.html#method" + getMethodNumber(methodName + signature) + "\" TARGET=Code>" + htmlMethodName + "</A>";
  135.             } else {
  136.                 ref = "<A HREF=\"" + methodClass + ".html" + "\" TARGET=_top>" + shortMethodClass + "</A>." + htmlMethodName;
  137.             }
  138.             constantRef[index] = retType + "&nbsp;<A HREF=\"" + className + "_cp.html#cp" + classIndex + "\" TARGET=Constants>" + shortMethodClass
  139.                 + "</A>.<A HREF=\"" + className + "_cp.html#cp" + index + "\" TARGET=ConstantPool>" + htmlMethodName + "</A>&nbsp;" + argTypes;
  140.             printWriter.println("<P><TT>" + retType + "&nbsp;" + ref + argTypes + "&nbsp;</TT>\n<UL>" + "<LI><A HREF=\"#cp" + classIndex + "\">Class index("
  141.                 + classIndex + ")</A>\n" + "<LI><A HREF=\"#cp" + nameIndex + "\">NameAndType index(" + nameIndex + ")</A></UL>");
  142.             break;
  143.         case Const.CONSTANT_Fieldref:
  144.             // Get class_index and name_and_type_index
  145.             final ConstantFieldref c3 = constantPool.getConstant(index, Const.CONSTANT_Fieldref, ConstantFieldref.class);
  146.             classIndex = c3.getClassIndex();
  147.             nameIndex = c3.getNameAndTypeIndex();
  148.             // Get method name and its class (compacted)
  149.             final String fieldClass = constantPool.constantToString(classIndex, Const.CONSTANT_Class);
  150.             String shortFieldClass = Utility.compactClassName(fieldClass); // I.e., remove java.lang.
  151.             shortFieldClass = Utility.compactClassName(shortFieldClass, classPackage + ".", true); // Remove class package prefix
  152.             final String fieldName = constantPool.constantToString(nameIndex, Const.CONSTANT_NameAndType);
  153.             if (fieldClass.equals(className)) {
  154.                 ref = "<A HREF=\"" + fieldClass + "_methods.html#field" + fieldName + "\" TARGET=Methods>" + fieldName + "</A>";
  155.             } else {
  156.                 ref = "<A HREF=\"" + fieldClass + ".html\" TARGET=_top>" + shortFieldClass + "</A>." + fieldName + "\n";
  157.             }
  158.             constantRef[index] = "<A HREF=\"" + className + "_cp.html#cp" + classIndex + "\" TARGET=Constants>" + shortFieldClass + "</A>.<A HREF=\""
  159.                 + className + "_cp.html#cp" + index + "\" TARGET=ConstantPool>" + fieldName + "</A>";
  160.             printWriter.println("<P><TT>" + ref + "</TT><BR>\n" + "<UL>" + "<LI><A HREF=\"#cp" + classIndex + "\">Class(" + classIndex + ")</A><BR>\n"
  161.                 + "<LI><A HREF=\"#cp" + nameIndex + "\">NameAndType(" + nameIndex + ")</A></UL>");
  162.             break;
  163.         case Const.CONSTANT_Class:
  164.             final ConstantClass c4 = constantPool.getConstant(index, Const.CONSTANT_Class, ConstantClass.class);
  165.             nameIndex = c4.getNameIndex();
  166.             final String className2 = constantPool.constantToString(index, tag); // / -> .
  167.             String shortClassName = Utility.compactClassName(className2); // I.e., remove java.lang.
  168.             shortClassName = Utility.compactClassName(shortClassName, classPackage + ".", true); // Remove class package prefix
  169.             ref = "<A HREF=\"" + className2 + ".html\" TARGET=_top>" + shortClassName + "</A>";
  170.             constantRef[index] = "<A HREF=\"" + className + "_cp.html#cp" + index + "\" TARGET=ConstantPool>" + shortClassName + "</A>";
  171.             printWriter.println("<P><TT>" + ref + "</TT><UL>" + "<LI><A HREF=\"#cp" + nameIndex + "\">Name index(" + nameIndex + ")</A></UL>\n");
  172.             break;
  173.         case Const.CONSTANT_String:
  174.             final ConstantString c5 = constantPool.getConstant(index, Const.CONSTANT_String, ConstantString.class);
  175.             nameIndex = c5.getStringIndex();
  176.             final String str = Class2HTML.toHTML(constantPool.constantToString(index, tag));
  177.             printWriter.println("<P><TT>" + str + "</TT><UL>" + "<LI><A HREF=\"#cp" + nameIndex + "\">Name index(" + nameIndex + ")</A></UL>\n");
  178.             break;
  179.         case Const.CONSTANT_NameAndType:
  180.             final ConstantNameAndType c6 = constantPool.getConstant(index, Const.CONSTANT_NameAndType, ConstantNameAndType.class);
  181.             nameIndex = c6.getNameIndex();
  182.             final int signatureIndex = c6.getSignatureIndex();
  183.             printWriter.println("<P><TT>" + Class2HTML.toHTML(constantPool.constantToString(index, tag)) + "</TT><UL>" + "<LI><A HREF=\"#cp" + nameIndex
  184.                 + "\">Name index(" + nameIndex + ")</A>\n" + "<LI><A HREF=\"#cp" + signatureIndex + "\">Signature index(" + signatureIndex + ")</A></UL>\n");
  185.             break;
  186.         default:
  187.             printWriter.println("<P><TT>" + Class2HTML.toHTML(constantPool.constantToString(index, tag)) + "</TT>\n");
  188.         } // switch
  189.     }
  190. }