1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 package com.sun.org.apache.bcel.internal.util;
   6 
   7 /* ====================================================================
   8  * The Apache Software License, Version 1.1
   9  *
  10  * Copyright (c) 2001 The Apache Software Foundation.  All rights
  11  * reserved.
  12  *
  13  * Redistribution and use in source and binary forms, with or without
  14  * modification, are permitted provided that the following conditions
  15  * are met:
  16  *
  17  * 1. Redistributions of source code must retain the above copyright
  18  *    notice, this list of conditions and the following disclaimer.
  19  *
  20  * 2. Redistributions in binary form must reproduce the above copyright
  21  *    notice, this list of conditions and the following disclaimer in
  22  *    the documentation and/or other materials provided with the
  23  *    distribution.
  24  *
  25  * 3. The end-user documentation included with the redistribution,
  26  *    if any, must include the following acknowledgment:
  27  *       "This product includes software developed by the
  28  *        Apache Software Foundation (http://www.apache.org/)."
  29  *    Alternately, this acknowledgment may appear in the software itself,
  30  *    if and wherever such third-party acknowledgments normally appear.
  31  *
  32  * 4. The names "Apache" and "Apache Software Foundation" and
  33  *    "Apache BCEL" must not be used to endorse or promote products
  34  *    derived from this software without prior written permission. For
  35  *    written permission, please contact apache@apache.org.
  36  *
  37  * 5. Products derived from this software may not be called "Apache",
  38  *    "Apache BCEL", nor may "Apache" appear in their name, without
  39  *    prior written permission of the Apache Software Foundation.
  40  *
  41  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  42  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  43  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  44  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  45  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  46  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  47  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  48  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  49  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  50  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  51  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  52  * SUCH DAMAGE.
  53  * ====================================================================
  54  *
  55  * This software consists of voluntary contributions made by many
  56  * individuals on behalf of the Apache Software Foundation.  For more
  57  * information on the Apache Software Foundation, please see
  58  * <http://www.apache.org/>.
  59  */
  60 
  61 import java.io.*;
  62 import java.util.BitSet;
  63 import com.sun.org.apache.bcel.internal.classfile.*;
  64 import com.sun.org.apache.bcel.internal.Constants;
  65 
  66 /**
  67  * Read class file(s) and convert them into HTML files.
  68  *
  69  * Given a JavaClass object "class" that is in package "package" five files
  70  * will be created in the specified directory.
  71  *
  72  * <OL>
  73  * <LI> "package"."class".html as the main file which defines the frames for
  74  * the following subfiles.
  75  * <LI>  "package"."class"_attributes.html contains all (known) attributes found in the file
  76  * <LI>  "package"."class"_cp.html contains the constant pool
  77  * <LI>  "package"."class"_code.html contains the byte code
  78  * <LI>  "package"."class"_methods.html contains references to all methods and fields of the class
  79  * </OL>
  80  *
  81  * All subfiles reference each other appropiately, e.g. clicking on a
  82  * method in the Method's frame will jump to the appropiate method in
  83  * the Code frame.
  84  *
  85  * @version $Id: Class2HTML.java,v 1.3 2007-07-19 04:34:52 ofung Exp $
  86  * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
  87 */
  88 public class Class2HTML implements Constants
  89 {
  90   private JavaClass java_class;     // current class object
  91   private String    dir;
  92 
  93   private static String       class_package;  // name of package, unclean to make it static, but ...
  94   private static String       class_name;     // name of current class, dito
  95   private static ConstantPool constant_pool;
  96 
  97   /**
  98    * Write contents of the given JavaClass into HTML files.
  99    *
 100    * @param java_class The class to write
 101    * @param dir The directory to put the files in
 102    */
 103   public Class2HTML(JavaClass java_class, String dir) throws IOException {
 104     Method[]     methods       = java_class.getMethods();
 105 
 106     this.java_class = java_class;
 107     this.dir        = dir;
 108     class_name      = java_class.getClassName();     // Remember full name
 109     constant_pool   = java_class.getConstantPool();
 110 
 111     // Get package name by tacking off everything after the last `.'
 112     int index = class_name.lastIndexOf('.');
 113     if(index > -1)
 114       class_package = class_name.substring(0, index);
 115     else
 116       class_package = ""; // default package
 117 
 118     ConstantHTML constant_html = new ConstantHTML(dir, class_name, class_package, methods,
 119                                                   constant_pool);
 120 
 121     /* Attributes can't be written in one step, so we just open a file
 122      * which will be written consequently.
 123      */
 124     AttributeHTML attribute_html = new AttributeHTML(dir, class_name, constant_pool, constant_html);
 125 
 126     MethodHTML method_html = new MethodHTML(dir, class_name, methods, java_class.getFields(),
 127                                             constant_html, attribute_html);
 128     // Write main file (with frames, yuk)
 129     writeMainHTML(attribute_html);
 130     new CodeHTML(dir, class_name, methods, constant_pool, constant_html);
 131     attribute_html.close();
 132   }
 133 
 134   public static void _main(String argv[])
 135   {
 136     String[]    file_name = new String[argv.length];
 137     int         files=0;
 138     ClassParser parser=null;
 139     JavaClass   java_class=null;
 140     String      zip_file = null;
 141     char        sep = SecuritySupport.getSystemProperty("file.separator").toCharArray()[0];
 142     String      dir = "." + sep; // Where to store HTML files
 143 
 144     try {
 145       /* Parse command line arguments.
 146        */
 147       for(int i=0; i < argv.length; i++) {
 148         if(argv[i].charAt(0) == '-') {  // command line switch
 149           if(argv[i].equals("-d")) {   // Specify target directory, default '.'
 150             dir = argv[++i];
 151 
 152             if(!dir.endsWith("" + sep))
 153               dir = dir + sep;
 154 
 155             new File(dir).mkdirs(); // Create target directory if necessary
 156           }
 157           else if(argv[i].equals("-zip"))
 158             zip_file = argv[++i];
 159           else
 160             System.out.println("Unknown option " + argv[i]);
 161         }
 162         else // add file name to list */
 163           file_name[files++] = argv[i];
 164       }
 165 
 166       if(files == 0)
 167         System.err.println("Class2HTML: No input files specified.");
 168       else { // Loop through files ...
 169         for(int i=0; i < files; i++) {
 170           System.out.print("Processing " + file_name[i] + "...");
 171           if(zip_file == null)
 172             parser = new ClassParser(file_name[i]); // Create parser object from file
 173           else
 174             parser = new ClassParser(zip_file, file_name[i]); // Create parser object from zip file
 175 
 176           java_class = parser.parse();
 177           new Class2HTML(java_class, dir);
 178           System.out.println("Done.");
 179         }
 180       }
 181     } catch(Exception e) {
 182       System.out.println(e);
 183       e.printStackTrace(System.out);
 184     }
 185   }
 186 
 187   /**
 188    * Utility method that converts a class reference in the constant pool,
 189    * i.e., an index to a string.
 190    */
 191   static String referenceClass(int index) {
 192     String str = constant_pool.getConstantString(index, CONSTANT_Class);
 193     str = Utility.compactClassName(str);
 194     str = Utility.compactClassName(str, class_package + ".", true);
 195 
 196     return "<A HREF=\"" + class_name + "_cp.html#cp" + index +
 197       "\" TARGET=ConstantPool>" + str + "</A>";
 198   }
 199 
 200   static final String referenceType(String type) {
 201     String short_type = Utility.compactClassName(type);
 202     short_type = Utility.compactClassName(short_type, class_package + ".", true);
 203 
 204     int index = type.indexOf('['); // Type is an array?
 205     if(index > -1)
 206       type = type.substring(0, index); // Tack of the `['
 207 
 208     // test for basic type
 209     if(type.equals("int")  || type.equals("short") || type.equals("boolean") || type.equals("void")   ||
 210        type.equals("char") || type.equals("byte")  || type.equals("long")    || type.equals("double") ||
 211        type.equals("float"))
 212       return "<FONT COLOR=\"#00FF00\">" + type + "</FONT>";
 213     else
 214       return "<A HREF=\"" + type + ".html\" TARGET=_top>" + short_type + "</A>";
 215   }
 216 
 217   static String toHTML(String str) {
 218     StringBuffer buf = new StringBuffer();
 219 
 220     try { // Filter any characters HTML doesn't like such as < and > in particular
 221       for(int i=0; i < str.length(); i++) {
 222         char ch;
 223 
 224         switch(ch=str.charAt(i)) {
 225         case '<': buf.append("&lt;"); break;
 226         case '>': buf.append("&gt;"); break;
 227         case '\n': buf.append("\\n"); break;
 228         case '\r': buf.append("\\r"); break;
 229         default:  buf.append(ch);
 230         }
 231       }
 232     } catch(StringIndexOutOfBoundsException e) {} // Never occurs
 233 
 234     return buf.toString();
 235   }
 236 
 237   private void writeMainHTML(AttributeHTML attribute_html) throws IOException {
 238     PrintWriter file       = new PrintWriter(new FileOutputStream(dir + class_name + ".html"));
 239     Attribute[] attributes = java_class.getAttributes();
 240 
 241     file.println("<HTML>\n" + "<HEAD><TITLE>Documentation for " + class_name + "</TITLE>" +
 242                  "</HEAD>\n" +
 243                  "<FRAMESET BORDER=1 cols=\"30%,*\">\n" +
 244                  "<FRAMESET BORDER=1 rows=\"80%,*\">\n" +
 245 
 246                  "<FRAME NAME=\"ConstantPool\" SRC=\"" + class_name + "_cp.html" + "\"\n MARGINWIDTH=\"0\" " +
 247                  "MARGINHEIGHT=\"0\" FRAMEBORDER=\"1\" SCROLLING=\"AUTO\">\n" +
 248                  "<FRAME NAME=\"Attributes\" SRC=\"" + class_name + "_attributes.html" +
 249                  "\"\n MARGINWIDTH=\"0\" " +
 250                  "MARGINHEIGHT=\"0\" FRAMEBORDER=\"1\" SCROLLING=\"AUTO\">\n" +
 251                  "</FRAMESET>\n" +
 252 
 253                  "<FRAMESET BORDER=1 rows=\"80%,*\">\n" +
 254                  "<FRAME NAME=\"Code\" SRC=\"" + class_name + "_code.html\"\n MARGINWIDTH=0 " +
 255                  "MARGINHEIGHT=0 FRAMEBORDER=1 SCROLLING=\"AUTO\">\n" +
 256                  "<FRAME NAME=\"Methods\" SRC=\"" + class_name + "_methods.html\"\n MARGINWIDTH=0 " +
 257                  "MARGINHEIGHT=0 FRAMEBORDER=1 SCROLLING=\"AUTO\">\n" +
 258                  "</FRAMESET></FRAMESET></HTML>"
 259                  );
 260 
 261     file.close();
 262 
 263     for(int i=0; i < attributes.length; i++)
 264       attribute_html.writeAttribute(attributes[i], "class" + i);
 265   }
 266 }