KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > bcel > internal > util > BCELifier


1 package com.sun.org.apache.bcel.internal.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 com.sun.org.apache.bcel.internal.classfile.*;
57 import com.sun.org.apache.bcel.internal.generic.*;
58 import com.sun.org.apache.bcel.internal.Repository;
59 import com.sun.org.apache.bcel.internal.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.1.2.1 2005/07/31 23:47:01 jeffsuttor Exp $
70  * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
71  */

72 public class BCELifier extends com.sun.org.apache.bcel.internal.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 JavaDoc class_name = clazz.getClassName();
95     String JavaDoc super_name = clazz.getSuperclassName();
96     String JavaDoc package_name = clazz.getPackageName();
97     String JavaDoc inter = Utility.printArray(clazz.getInterfaceNames(),
98                          false, true);
99     if(!"".equals(package_name)) {
100       class_name = class_name.substring(package_name.length() + 1);
101       _out.println("package " + package_name + ";\n");
102      }
103
104     _out.println("import com.sun.org.apache.bcel.internal.generic.*;");
105     _out.println("import com.sun.org.apache.bcel.internal.classfile.*;");
106     _out.println("import com.sun.org.apache.bcel.internal.*;");
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 JavaDoc 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 JavaDoc 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 JavaDoc printFlags(int flags) {
226     return printFlags(flags, false);
227   }
228
229   static String JavaDoc printFlags(int flags, boolean for_class) {
230     if(flags == 0)
231       return "0";
232
233     StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
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 JavaDoc str = buf.toString();
246     return str.substring(0, str.length() - 3);
247   }
248
249   static String JavaDoc printArgumentTypes(Type[] arg_types) {
250     if(arg_types.length == 0)
251       return "Type.NO_ARGS";
252
253     StringBuffer JavaDoc args = new StringBuffer JavaDoc();
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 JavaDoc printType(Type type) {
266     return printType(type.getSignature());
267   }
268
269   static String JavaDoc printType(String JavaDoc 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 JavaDoc[] argv) throws Exception JavaDoc {
295     JavaClass java_class;
296     String JavaDoc 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 }
305
Popular Tags