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
22package com.sun.org.apache.bcel.internal.util;
23
24import java.io.FileOutputStream;
25import java.io.IOException;
26import java.io.PrintWriter;
27
28import com.sun.org.apache.bcel.internal.Const;
29import com.sun.org.apache.bcel.internal.classfile.Attribute;
30import com.sun.org.apache.bcel.internal.classfile.Code;
31import com.sun.org.apache.bcel.internal.classfile.ConstantValue;
32import com.sun.org.apache.bcel.internal.classfile.ExceptionTable;
33import com.sun.org.apache.bcel.internal.classfile.Field;
34import com.sun.org.apache.bcel.internal.classfile.Method;
35import com.sun.org.apache.bcel.internal.classfile.Utility;
36
37/**
38 * Convert methods and fields into HTML file.
39 *
40 * @version $Id: MethodHTML.java 1749603 2016-06-21 20:50:19Z ggregory $
41 *
42 */
43final class MethodHTML {
44
45    private final String class_name; // name of current class
46    private final PrintWriter file; // file to write to
47    private final ConstantHTML constant_html;
48    private final AttributeHTML attribute_html;
49
50
51    MethodHTML(final String dir, final String class_name, final Method[] methods, final Field[] fields,
52            final ConstantHTML constant_html, final AttributeHTML attribute_html) throws IOException {
53        this.class_name = class_name;
54        this.attribute_html = attribute_html;
55        this.constant_html = constant_html;
56        file = new PrintWriter(new FileOutputStream(dir + class_name + "_methods.html"));
57        file.println("<HTML><BODY BGCOLOR=\"#C0C0C0\"><TABLE BORDER=0>");
58        file.println("<TR><TH ALIGN=LEFT>Access&nbsp;flags</TH><TH ALIGN=LEFT>Type</TH>"
59                + "<TH ALIGN=LEFT>Field&nbsp;name</TH></TR>");
60        for (final Field field : fields) {
61            writeField(field);
62        }
63        file.println("</TABLE>");
64        file.println("<TABLE BORDER=0><TR><TH ALIGN=LEFT>Access&nbsp;flags</TH>"
65                + "<TH ALIGN=LEFT>Return&nbsp;type</TH><TH ALIGN=LEFT>Method&nbsp;name</TH>"
66                + "<TH ALIGN=LEFT>Arguments</TH></TR>");
67        for (int i = 0; i < methods.length; i++) {
68            writeMethod(methods[i], i);
69        }
70        file.println("</TABLE></BODY></HTML>");
71        file.close();
72    }
73
74
75    /**
76     * Print field of class.
77     *
78     * @param field field to print
79     * @throws java.io.IOException
80     */
81    private void writeField( final Field field ) throws IOException {
82        final String type = Utility.signatureToString(field.getSignature());
83        final String name = field.getName();
84        String access = Utility.accessToString(field.getAccessFlags());
85        Attribute[] attributes;
86        access = Utility.replace(access, " ", "&nbsp;");
87        file.print("<TR><TD><FONT COLOR=\"#FF0000\">" + access + "</FONT></TD>\n<TD>"
88                + Class2HTML.referenceType(type) + "</TD><TD><A NAME=\"field" + name + "\">" + name
89                + "</A></TD>");
90        attributes = field.getAttributes();
91        // Write them to the Attributes.html file with anchor "<name>[<i>]"
92        for (int i = 0; i < attributes.length; i++) {
93            attribute_html.writeAttribute(attributes[i], name + "@" + i);
94        }
95        for (int i = 0; i < attributes.length; i++) {
96            if (attributes[i].getTag() == Const.ATTR_CONSTANT_VALUE) { // Default value
97                final String str = ((ConstantValue) attributes[i]).toString();
98                // Reference attribute in _attributes.html
99                file.print("<TD>= <A HREF=\"" + class_name + "_attributes.html#" + name + "@" + i
100                        + "\" TARGET=\"Attributes\">" + str + "</TD>\n");
101                break;
102            }
103        }
104        file.println("</TR>");
105    }
106
107
108    private void writeMethod( final Method method, final int method_number ) {
109        // Get raw signature
110        final String signature = method.getSignature();
111        // Get array of strings containing the argument types
112        final String[] args = Utility.methodSignatureArgumentTypes(signature, false);
113        // Get return type string
114        final String type = Utility.methodSignatureReturnType(signature, false);
115        // Get method name
116        final String name = method.getName();
117        String html_name;
118        // Get method's access flags
119        String access = Utility.accessToString(method.getAccessFlags());
120        // Get the method's attributes, the Code Attribute in particular
121        final Attribute[] attributes = method.getAttributes();
122        /* HTML doesn't like names like <clinit> and spaces are places to break
123         * lines. Both we don't want...
124         */
125        access = Utility.replace(access, " ", "&nbsp;");
126        html_name = Class2HTML.toHTML(name);
127        file.print("<TR VALIGN=TOP><TD><FONT COLOR=\"#FF0000\"><A NAME=method" + method_number
128                + ">" + access + "</A></FONT></TD>");
129        file.print("<TD>" + Class2HTML.referenceType(type) + "</TD><TD>" + "<A HREF=" + class_name
130                + "_code.html#method" + method_number + " TARGET=Code>" + html_name
131                + "</A></TD>\n<TD>(");
132        for (int i = 0; i < args.length; i++) {
133            file.print(Class2HTML.referenceType(args[i]));
134            if (i < args.length - 1) {
135                file.print(", ");
136            }
137        }
138        file.print(")</TD></TR>");
139        // Check for thrown exceptions
140        for (int i = 0; i < attributes.length; i++) {
141            attribute_html.writeAttribute(attributes[i], "method" + method_number + "@" + i,
142                    method_number);
143            final byte tag = attributes[i].getTag();
144            if (tag == Const.ATTR_EXCEPTIONS) {
145                file.print("<TR VALIGN=TOP><TD COLSPAN=2></TD><TH ALIGN=LEFT>throws</TH><TD>");
146                final int[] exceptions = ((ExceptionTable) attributes[i]).getExceptionIndexTable();
147                for (int j = 0; j < exceptions.length; j++) {
148                    file.print(constant_html.referenceConstant(exceptions[j]));
149                    if (j < exceptions.length - 1) {
150                        file.print(", ");
151                    }
152                }
153                file.println("</TD></TR>");
154            } else if (tag == Const.ATTR_CODE) {
155                final Attribute[] c_a = ((Code) attributes[i]).getAttributes();
156                for (int j = 0; j < c_a.length; j++) {
157                    attribute_html.writeAttribute(c_a[j], "method" + method_number + "@" + i + "@"
158                            + j, method_number);
159                }
160            }
161        }
162    }
163}
164