1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.bcel.util;
20
21 import java.io.File;
22 import java.io.FileNotFoundException;
23 import java.io.IOException;
24 import java.io.PrintWriter;
25 import java.io.UnsupportedEncodingException;
26 import java.nio.charset.Charset;
27 import java.nio.charset.StandardCharsets;
28 import java.util.HashSet;
29 import java.util.Set;
30
31 import org.apache.bcel.Const;
32 import org.apache.bcel.Constants;
33 import org.apache.bcel.classfile.Attribute;
34 import org.apache.bcel.classfile.ClassParser;
35 import org.apache.bcel.classfile.ConstantPool;
36 import org.apache.bcel.classfile.JavaClass;
37 import org.apache.bcel.classfile.Method;
38 import org.apache.bcel.classfile.Utility;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 public class Class2HTML implements Constants {
57
58 private static String classPackage;
59 private static String className;
60 private static ConstantPool constantPool;
61 private static final Set<String> basicTypes = new HashSet<>();
62 static {
63 basicTypes.add("int");
64 basicTypes.add("short");
65 basicTypes.add("boolean");
66 basicTypes.add("void");
67 basicTypes.add("char");
68 basicTypes.add("byte");
69 basicTypes.add("long");
70 basicTypes.add("double");
71 basicTypes.add("float");
72 }
73
74
75
76
77
78
79
80 public static void main(final String[] argv) throws IOException {
81 final String[] fileName = new String[argv.length];
82 int files = 0;
83 ClassParser parser = null;
84 JavaClass javaClass = null;
85 String zipFile = null;
86 final char sep = File.separatorChar;
87 String dir = "." + sep;
88
89
90
91 for (int i = 0; i < argv.length; i++) {
92 if (argv[i].charAt(0) == '-') {
93 if (argv[i].equals("-d")) {
94 dir = argv[++i];
95 if (!dir.endsWith("" + sep)) {
96 dir += sep;
97 }
98 final File store = new File(dir);
99 if (!store.isDirectory()) {
100 final boolean created = store.mkdirs();
101 if (!created && !store.isDirectory()) {
102 System.out.println("Tried to create the directory " + dir + " but failed");
103 }
104 }
105 } else if (argv[i].equals("-zip")) {
106 zipFile = argv[++i];
107 } else {
108 System.out.println("Unknown option " + argv[i]);
109 }
110 } else {
111 fileName[files++] = argv[i];
112 }
113 }
114 if (files == 0) {
115 System.err.println("Class2HTML: No input files specified.");
116 } else {
117 for (int i = 0; i < files; i++) {
118 System.out.print("Processing " + fileName[i] + "...");
119 if (zipFile == null) {
120 parser = new ClassParser(fileName[i]);
121 } else {
122 parser = new ClassParser(zipFile, fileName[i]);
123 }
124 javaClass = parser.parse();
125 new Class2HTML(javaClass, dir);
126 System.out.println("Done.");
127 }
128 }
129 }
130
131
132
133
134 static String referenceClass(final int index) {
135 String str = constantPool.getConstantString(index, Const.CONSTANT_Class);
136 str = Utility.compactClassName(str);
137 str = Utility.compactClassName(str, classPackage + ".", true);
138 return "<A HREF=\"" + className + "_cp.html#cp" + index + "\" TARGET=ConstantPool>" + str + "</A>";
139 }
140
141 static String referenceType(final String type) {
142 String shortType = Utility.compactClassName(type);
143 shortType = Utility.compactClassName(shortType, classPackage + ".", true);
144 final int index = type.indexOf('[');
145 String baseType = type;
146 if (index > -1) {
147 baseType = type.substring(0, index);
148 }
149
150 if (basicTypes.contains(baseType)) {
151 return "<FONT COLOR=\"#00FF00\">" + type + "</FONT>";
152 }
153 return "<A HREF=\"" + baseType + ".html\" TARGET=_top>" + shortType + "</A>";
154 }
155
156 static String toHTML(final String str) {
157 final StringBuilder buf = new StringBuilder();
158 for (int i = 0; i < str.length(); i++) {
159 final char ch;
160 switch (ch = str.charAt(i)) {
161 case '<':
162 buf.append("<");
163 break;
164 case '>':
165 buf.append(">");
166 break;
167 case '\n':
168 buf.append("\\n");
169 break;
170 case '\r':
171 buf.append("\\r");
172 break;
173 default:
174 buf.append(ch);
175 }
176 }
177 return buf.toString();
178 }
179
180 private final JavaClass javaClass;
181
182 private final String dir;
183
184
185
186
187
188
189
190
191 public Class2HTML(final JavaClass javaClass, final String dir) throws IOException {
192 this(javaClass, dir, StandardCharsets.UTF_8);
193 }
194
195 private Class2HTML(final JavaClass javaClass, final String dir, final Charset charset) throws IOException {
196 final Method[] methods = javaClass.getMethods();
197 this.javaClass = javaClass;
198 this.dir = dir;
199 className = javaClass.getClassName();
200 constantPool = javaClass.getConstantPool();
201
202 final int index = className.lastIndexOf('.');
203 if (index > -1) {
204 classPackage = className.substring(0, index);
205 } else {
206 classPackage = "";
207 }
208 final ConstantHTML constantHtml = new ConstantHTML(dir, className, classPackage, methods, constantPool, charset);
209
210
211
212 try (AttributeHTML attributeHtml = new AttributeHTML(dir, className, constantPool, constantHtml, charset)) {
213 new MethodHTML(dir, className, methods, javaClass.getFields(), constantHtml, attributeHtml, charset);
214
215 writeMainHTML(attributeHtml, charset);
216 new CodeHTML(dir, className, methods, constantPool, constantHtml, charset);
217 }
218 }
219
220 private void writeMainHTML(final AttributeHTML attributeHtml, final Charset charset) throws FileNotFoundException, UnsupportedEncodingException {
221 try (PrintWriter file = new PrintWriter(dir + className + ".html", charset.name())) {
222
223 file.println("<HTML>\n"
224 + "<HEAD><TITLE>Documentation for " + className + "</TITLE></HEAD>\n"
225 + "<FRAMESET BORDER=1 cols=\"30%,*\">\n"
226 + "<FRAMESET BORDER=1 rows=\"80%,*\">\n"
227 + "<FRAME NAME=\"ConstantPool\" SRC=\"" + className + "_cp.html" + "\"\n"
228 + "MARGINWIDTH=\"0\" "
229 + "MARGINHEIGHT=\"0\" FRAMEBORDER=\"1\" SCROLLING=\"AUTO\">\n"
230 + "<FRAME NAME=\"Attributes\" SRC=\"" + className + "_attributes.html\"\n"
231 + " MARGINWIDTH=\"0\" MARGINHEIGHT=\"0\" FRAMEBORDER=\"1\" SCROLLING=\"AUTO\">\n"
232 + "</FRAMESET>\n"
233 + "<FRAMESET BORDER=1 rows=\"80%,*\">\n"
234 + "<FRAME NAME=\"Code\" SRC=\"" + className + "_code.html\"\n"
235 + " MARGINWIDTH=0 "
236 + "MARGINHEIGHT=0 FRAMEBORDER=1 SCROLLING=\"AUTO\">\n"
237 + "<FRAME NAME=\"Methods\" SRC=\"" + className + "_methods.html\"\n"
238 + " MARGINWIDTH=0 "
239 + "MARGINHEIGHT=0 FRAMEBORDER=1 SCROLLING=\"AUTO\">\n"
240 + "</FRAMESET></FRAMESET></HTML>");
241
242 }
243 final Attribute[] attributes = javaClass.getAttributes();
244 for (int i = 0; i < attributes.length; i++) {
245 attributeHtml.writeAttribute(attributes[i], "class" + i);
246 }
247 }
248 }