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 java.io.*;
  26 import java.util.BitSet;
  27 import com.sun.org.apache.bcel.internal.classfile.*;
  28 import com.sun.org.apache.bcel.internal.Constants;
  29 
  30 /**
  31  * Read class file(s) and convert them into HTML files.
  32  *
  33  * Given a JavaClass object "class" that is in package "package" five files
  34  * will be created in the specified directory.
  35  *
  36  * <OL>
  37  * <LI> "package"."class".html as the main file which defines the frames for
  38  * the following subfiles.
  39  * <LI>  "package"."class"_attributes.html contains all (known) attributes found in the file
  40  * <LI>  "package"."class"_cp.html contains the constant pool
  41  * <LI>  "package"."class"_code.html contains the byte code
  42  * <LI>  "package"."class"_methods.html contains references to all methods and fields of the class
  43  * </OL>
  44  *
  45  * All subfiles reference each other appropiately, e.g. clicking on a
  46  * method in the Method's frame will jump to the appropiate method in
  47  * the Code frame.
  48  *
  49  * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
  50 */
  51 public class Class2HTML implements Constants
  52 {
  53   private JavaClass java_class;     // current class object
  54   private String    dir;
  55 
  56   private static String       class_package;  // name of package, unclean to make it static, but ...
  57   private static String       class_name;     // name of current class, dito
  58   private static ConstantPool constant_pool;
  59 
  60   /**
  61    * Write contents of the given JavaClass into HTML files.
  62    *
  63    * @param java_class The class to write
  64    * @param dir The directory to put the files in
  65    */
  66   public Class2HTML(JavaClass java_class, String dir) throws IOException {
  67     Method[]     methods       = java_class.getMethods();
  68 
  69     this.java_class = java_class;
  70     this.dir        = dir;
  71     class_name      = java_class.getClassName();     // Remember full name
  72     constant_pool   = java_class.getConstantPool();
  73 
  74     // Get package name by tacking off everything after the last `.'
  75     int index = class_name.lastIndexOf('.');
  76     if(index > -1)
  77       class_package = class_name.substring(0, index);
  78     else
  79       class_package = ""; // default package
  80 
  81     ConstantHTML constant_html = new ConstantHTML(dir, class_name, class_package, methods,
  82                                                   constant_pool);
  83 
  84     /* Attributes can't be written in one step, so we just open a file
  85      * which will be written consequently.
  86      */
  87     AttributeHTML attribute_html = new AttributeHTML(dir, class_name, constant_pool, constant_html);
  88 
  89     MethodHTML method_html = new MethodHTML(dir, class_name, methods, java_class.getFields(),
  90                                             constant_html, attribute_html);
  91     // Write main file (with frames, yuk)
  92     writeMainHTML(attribute_html);
  93     new CodeHTML(dir, class_name, methods, constant_pool, constant_html);
  94     attribute_html.close();
  95   }
  96 
  97   public static void _main(String argv[])
  98   {
  99     String[]    file_name = new String[argv.length];
 100     int         files=0;
 101     ClassParser parser=null;
 102     JavaClass   java_class=null;
 103     String      zip_file = null;
 104     char        sep = SecuritySupport.getSystemProperty("file.separator").toCharArray()[0];
 105     String      dir = "." + sep; // Where to store HTML files
 106 
 107     try {
 108       /* Parse command line arguments.
 109        */
 110       for(int i=0; i < argv.length; i++) {
 111         if(argv[i].charAt(0) == '-') {  // command line switch
 112           if(argv[i].equals("-d")) {   // Specify target directory, default '.'
 113             dir = argv[++i];
 114 
 115             if(!dir.endsWith("" + sep))
 116               dir = dir + sep;
 117 
 118             new File(dir).mkdirs(); // Create target directory if necessary
 119           }
 120           else if(argv[i].equals("-zip"))
 121             zip_file = argv[++i];
 122           else
 123             System.out.println("Unknown option " + argv[i]);
 124         }
 125         else // add file name to list */
 126           file_name[files++] = argv[i];
 127       }
 128 
 129       if(files == 0)
 130         System.err.println("Class2HTML: No input files specified.");
 131       else { // Loop through files ...
 132         for(int i=0; i < files; i++) {
 133           System.out.print("Processing " + file_name[i] + "...");
 134           if(zip_file == null)
 135             parser = new ClassParser(file_name[i]); // Create parser object from file
 136           else
 137             parser = new ClassParser(zip_file, file_name[i]); // Create parser object from zip file
 138 
 139           java_class = parser.parse();
 140           new Class2HTML(java_class, dir);
 141           System.out.println("Done.");
 142         }
 143       }
 144     } catch(Exception e) {
 145       System.out.println(e);
 146       e.printStackTrace(System.out);
 147     }
 148   }
 149 
 150   /**
 151    * Utility method that converts a class reference in the constant pool,
 152    * i.e., an index to a string.
 153    */
 154   static String referenceClass(int index) {
 155     String str = constant_pool.getConstantString(index, CONSTANT_Class);
 156     str = Utility.compactClassName(str);
 157     str = Utility.compactClassName(str, class_package + ".", true);
 158 
 159     return "<A HREF=\"" + class_name + "_cp.html#cp" + index +
 160       "\" TARGET=ConstantPool>" + str + "</A>";
 161   }
 162 
 163   static final String referenceType(String type) {
 164     String short_type = Utility.compactClassName(type);
 165     short_type = Utility.compactClassName(short_type, class_package + ".", true);
 166 
 167     int index = type.indexOf('['); // Type is an array?
 168     if(index > -1)
 169       type = type.substring(0, index); // Tack of the `['
 170 
 171     // test for basic type
 172     if(type.equals("int")  || type.equals("short") || type.equals("boolean") || type.equals("void")   ||
 173        type.equals("char") || type.equals("byte")  || type.equals("long")    || type.equals("double") ||
 174        type.equals("float"))
 175       return "<FONT COLOR=\"#00FF00\">" + type + "</FONT>";
 176     else
 177       return "<A HREF=\"" + type + ".html\" TARGET=_top>" + short_type + "</A>";
 178   }
 179 
 180   static String toHTML(String str) {
 181     StringBuffer buf = new StringBuffer();
 182 
 183     try { // Filter any characters HTML doesn't like such as < and > in particular
 184       for(int i=0; i < str.length(); i++) {
 185         char ch;
 186 
 187         switch(ch=str.charAt(i)) {
 188         case '<': buf.append("&lt;"); break;
 189         case '>': buf.append("&gt;"); break;
 190         case '\n': buf.append("\\n"); break;
 191         case '\r': buf.append("\\r"); break;
 192         default:  buf.append(ch);
 193         }
 194       }
 195     } catch(StringIndexOutOfBoundsException e) {} // Never occurs
 196 
 197     return buf.toString();
 198   }
 199 
 200   private void writeMainHTML(AttributeHTML attribute_html) throws IOException {
 201     PrintWriter file       = new PrintWriter(new FileOutputStream(dir + class_name + ".html"));
 202     Attribute[] attributes = java_class.getAttributes();
 203 
 204     file.println("<HTML>\n" + "<HEAD><TITLE>Documentation for " + class_name + "</TITLE>" +
 205                  "</HEAD>\n" +
 206                  "<FRAMESET BORDER=1 cols=\"30%,*\">\n" +
 207                  "<FRAMESET BORDER=1 rows=\"80%,*\">\n" +
 208 
 209                  "<FRAME NAME=\"ConstantPool\" SRC=\"" + class_name + "_cp.html" + "\"\n MARGINWIDTH=\"0\" " +
 210                  "MARGINHEIGHT=\"0\" FRAMEBORDER=\"1\" SCROLLING=\"AUTO\">\n" +
 211                  "<FRAME NAME=\"Attributes\" SRC=\"" + class_name + "_attributes.html" +
 212                  "\"\n MARGINWIDTH=\"0\" " +
 213                  "MARGINHEIGHT=\"0\" FRAMEBORDER=\"1\" SCROLLING=\"AUTO\">\n" +
 214                  "</FRAMESET>\n" +
 215 
 216                  "<FRAMESET BORDER=1 rows=\"80%,*\">\n" +
 217                  "<FRAME NAME=\"Code\" SRC=\"" + class_name + "_code.html\"\n MARGINWIDTH=0 " +
 218                  "MARGINHEIGHT=0 FRAMEBORDER=1 SCROLLING=\"AUTO\">\n" +
 219                  "<FRAME NAME=\"Methods\" SRC=\"" + class_name + "_methods.html\"\n MARGINWIDTH=0 " +
 220                  "MARGINHEIGHT=0 FRAMEBORDER=1 SCROLLING=\"AUTO\">\n" +
 221                  "</FRAMESET></FRAMESET></HTML>"
 222                  );
 223 
 224     file.close();
 225 
 226     for(int i=0; i < attributes.length; i++)
 227       attribute_html.writeAttribute(attributes[i], "class" + i);
 228   }
 229 }