1 package org.apache.bcel.util;
2
3 /* ====================================================================
4 * The Apache Software License, Version 1.1
5 *
6 * Copyright (c) 2002 The Apache Software Foundation. All rights
7 * reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
19 * distribution.
20 *
21 * 3. The end-user documentation included with the redistribution,
22 * if any, must include the following acknowledgment:
23 * "This product includes software developed by the
24 * Apache Software Foundation (http://www.apache.org/)."
25 * Alternately, this acknowledgment may appear in the software itself,
26 * if and wherever such third-party acknowledgments normally appear.
27 *
28 * 4. The names "Apache" and "Apache Software Foundation" and
29 * "Apache BCEL" must not be used to endorse or promote products
30 * derived from this software without prior written permission. For
31 * written permission, please contact apache@apache.org.
32 *
33 * 5. Products derived from this software may not be called "Apache",
34 * "Apache BCEL", nor may "Apache" appear in their name, without
35 * prior written permission of the Apache Software Foundation.
36 *
37 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
44 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
45 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
46 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
47 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48 * SUCH DAMAGE.
49 * ====================================================================
50 *
51 * This software consists of voluntary contributions made by many
52 * individuals on behalf of the Apache Software Foundation. For more
53 * information on the Apache Software Foundation, please see
54 * <http://www.apache.org/>.
55 */
56 import org.apache.bcel.classfile.*;
57 import org.apache.bcel.generic.*;
58 import org.apache.bcel.Repository;
59 import org.apache.bcel.Constants;
60 import java.io.*;
61
62 /***
63 * This class takes a given JavaClass object and converts it to a
64 * Java program that creates that very class using BCEL. This
65 * gives new users of BCEL a useful example showing how things
66 * are done with BCEL. It does not cover all features of BCEL,
67 * but tries to mimic hand-written code as close as possible.
68 *
69 * @version $Id: BCELifier.java,v 1.4 2002/11/30 11:12:21 mdahm Exp $
70 * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
71 */
72 public class BCELifier extends org.apache.bcel.classfile.EmptyVisitor {
73 private JavaClass _clazz;
74 private PrintWriter _out;
75 private ConstantPoolGen _cp;
76
77 /*** @param clazz Java class to "decompile"
78 * @param out where to output Java program
79 */
80 public BCELifier(JavaClass clazz, OutputStream out) {
81 _clazz = clazz;
82 _out = new PrintWriter(out);
83 _cp = new ConstantPoolGen(_clazz.getConstantPool());
84 }
85
86 /*** Start Java code generation
87 */
88 public void start() {
89 visitJavaClass(_clazz);
90 _out.flush();
91 }
92
93 public void visitJavaClass(JavaClass clazz) {
94 String class_name = clazz.getClassName();
95 String super_name = clazz.getSuperclassName();
96 String package_name = clazz.getPackageName();
97 String inter = Utility.printArray(clazz.getInterfaceNames(),
98 false, true);
99 if(!"".equals(package_name)) {
100 class_name = class_name/substring(package_name/length() + 1)/package-summary.html">>_name = class_name.substring(package_name.length() + 1);
101 _out.println("package " + package_name + ";\n");
102 }
103
104 _out.println("import org.apache.bcel.generic.*;");
105 _out.println("import org.apache.bcel.classfile.*;");
106 _out.println("import org.apache.bcel.*;");
107 _out.println("import java.io.*;\n");
108
109 _out.println("public class " + class_name + "Creator implements Constants {");
110 _out.println(" private InstructionFactory _factory;");
111 _out.println(" private ConstantPoolGen _cp;");
112 _out.println(" private ClassGen _cg;\n");
113
114 _out.println(" public " + class_name + "Creator() {");
115 _out.println(" _cg = new ClassGen(\"" +
116 (("".equals(package_name))? class_name :
117 package_name + "." + class_name) +
118 "\", \"" + super_name + "\", " +
119 "\"" + clazz.getSourceFileName() + "\", " +
120 printFlags(clazz.getAccessFlags(), true) + ", " +
121 "new String[] { " + inter + " });\n");
122
123 _out.println(" _cp = _cg.getConstantPool();");
124 _out.println(" _factory = new InstructionFactory(_cg, _cp);");
125 _out.println(" }\n");
126
127 printCreate();
128
129 Field[] fields = clazz.getFields();
130
131 if(fields.length > 0) {
132 _out.println(" private void createFields() {");
133 _out.println(" FieldGen field;");
134
135 for(int i=0; i < fields.length; i++) {
136 fields[i].accept(this);
137 }
138
139 _out.println(" }\n");
140 }
141
142 Method[] methods = clazz.getMethods();
143
144 for(int i=0; i < methods.length; i++) {
145 _out.println(" private void createMethod_" + i + "() {");
146
147 methods[i].accept(this);
148 _out.println(" }\n");
149 }
150
151 printMain();
152 _out.println("}");
153 }
154
155 private void printCreate() {
156 _out.println(" public void create(OutputStream out) throws IOException {");
157
158 Field[] fields = _clazz.getFields();
159 if(fields.length > 0) {
160 _out.println(" createFields();");
161 }
162
163 Method[] methods = _clazz.getMethods();
164 for(int i=0; i < methods.length; i++) {
165 _out.println(" createMethod_" + i + "();");
166 }
167
168 _out.println(" _cg.getJavaClass().dump(out);");
169
170 _out.println(" }\n");
171 }
172
173 private void printMain() {
174 String class_name = _clazz.getClassName();
175
176 _out.println(" public static void main(String[] args) throws Exception {");
177 _out.println(" " + class_name + "Creator creator = new " +
178 class_name + "Creator();");
179 _out.println(" creator.create(new FileOutputStream(\"" + class_name +
180 ".class\"));");
181 _out.println(" }");
182 }
183
184 public void visitField(Field field) {
185 _out.println("\n field = new FieldGen(" +
186 printFlags(field.getAccessFlags()) +
187 ", " + printType(field.getSignature()) + ", \"" +
188 field.getName() + "\", _cp);");
189
190 ConstantValue cv = field.getConstantValue();
191
192 if(cv != null) {
193 String value = cv.toString();
194 _out.println(" field.setInitValue(" + value + ")");
195 }
196
197 _out.println(" _cg.addField(field.getField());");
198 }
199
200 public void visitMethod(Method method) {
201 MethodGen mg = new MethodGen(method, _clazz.getClassName(), _cp);
202
203 Type result_type = mg.getReturnType();
204 Type[] arg_types = mg.getArgumentTypes();
205
206 _out.println(" InstructionList il = new InstructionList();");
207 _out.println(" MethodGen method = new MethodGen(" +
208 printFlags(method.getAccessFlags()) +
209 ", " + printType(result_type) +
210 ", " + printArgumentTypes(arg_types) + ", " +
211 "new String[] { " +
212 Utility.printArray(mg.getArgumentNames(), false, true) +
213 " }, \"" + method.getName() + "\", \"" +
214 _clazz.getClassName() + "\", il, _cp);\n");
215
216 BCELFactory factory = new BCELFactory(mg, _out);
217 factory.start();
218
219 _out.println(" method.setMaxStack();");
220 _out.println(" method.setMaxLocals();");
221 _out.println(" _cg.addMethod(method.getMethod());");
222 _out.println(" il.dispose();");
223 }
224
225 static String printFlags(int flags) {
226 return printFlags(flags, false);
227 }
228
229 static String printFlags(int flags, boolean for_class) {
230 if(flags == 0)
231 return "0";
232
233 StringBuffer buf = new StringBuffer();
234 for(int i=0, pow=1; i <= Constants.MAX_ACC_FLAG; i++) {
235 if((flags & pow) != 0) {
236 if((pow == Constants.ACC_SYNCHRONIZED) && for_class)
237 buf.append("ACC_SUPER | ");
238 else
239 buf.append("ACC_" + Constants.ACCESS_NAMES[i].toUpperCase() + " | ");
240 }
241
242 pow <<= 1;
243 }
244
245 String str = buf.toString();
246 return str.substring(0, str.length() - 3);
247 }
248
249 static String printArgumentTypes(Type[] arg_types) {
250 if(arg_types.length == 0)
251 return "Type.NO_ARGS";
252
253 StringBuffer args = new StringBuffer();
254
255 for(int i=0; i < arg_types.length; i++) {
256 args.append(printType(arg_types[i]));
257
258 if(i < arg_types.length - 1)
259 args.append(", ");
260 }
261
262 return "new Type[] { " + args.toString() + " }";
263 }
264
265 static String printType(Type type) {
266 return printType(type.getSignature());
267 }
268
269 static String printType(String signature) {
270 Type type = Type.getType(signature);
271 byte t = type.getType();
272
273 if(t <= Constants.T_VOID) {
274 return "Type." + Constants.TYPE_NAMES[t].toUpperCase();
275 } else if(type.toString().equals("java.lang.String")) {
276 return "Type.STRING";
277 } else if(type.toString().equals("java.lang.Object")) {
278 return "Type.OBJECT";
279 } else if(type.toString().equals("java.lang.StringBuffer")) {
280 return "Type.STRINGBUFFER";
281 } else if(type instanceof ArrayType) {
282 ArrayType at = (ArrayType)type;
283
284 return "new ArrayType(" + printType(at.getBasicType()) +
285 ", " + at.getDimensions() + ")";
286 } else {
287 return "new ObjectType(\"" + Utility.signatureToString(signature, false) +
288 "\")";
289 }
290 }
291
292 /*** Default main method
293 */
294 public static void main(String[] argv) throws Exception {
295 JavaClass java_class;
296 String name = argv[0];
297
298 if((java_class = Repository.lookupClass(name)) == null)
299 java_class = new ClassParser(name).parse(); // May throw IOException
300
301 BCELifier bcelifier = new BCELifier(java_class, System.out);
302 bcelifier.start();
303 }
304 }
This page was automatically generated by Maven