29 import com.sun.org.apache.bcel.internal.Const;
30 import com.sun.org.apache.bcel.internal.Repository;
31 import com.sun.org.apache.bcel.internal.classfile.ClassParser;
32 import com.sun.org.apache.bcel.internal.classfile.ConstantValue;
33 import com.sun.org.apache.bcel.internal.classfile.Field;
34 import com.sun.org.apache.bcel.internal.classfile.JavaClass;
35 import com.sun.org.apache.bcel.internal.classfile.Method;
36 import com.sun.org.apache.bcel.internal.classfile.Utility;
37 import com.sun.org.apache.bcel.internal.generic.ArrayType;
38 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
39 import com.sun.org.apache.bcel.internal.generic.MethodGen;
40 import com.sun.org.apache.bcel.internal.generic.Type;
41
42 /**
43 * This class takes a given JavaClass object and converts it to a
44 * Java program that creates that very class using BCEL. This
45 * gives new users of BCEL a useful example showing how things
46 * are done with BCEL. It does not cover all features of BCEL,
47 * but tries to mimic hand-written code as close as possible.
48 *
49 * @version $Id$
50 */
51 public class BCELifier extends com.sun.org.apache.bcel.internal.classfile.EmptyVisitor {
52
53 /**
54 * Enum corresponding to flag source.
55 */
56 public enum FLAGS {
57 UNKNOWN,
58 CLASS,
59 METHOD,
60 }
61
62 // The base package name for imports; assumes Const is at the top level
63 // N.B we use the class so renames will be detected by the compiler/IDE
64 private static final String BASE_PACKAGE = Const.class.getPackage().getName();
65 private static final String CONSTANT_PREFIX = Const.class.getSimpleName()+".";
66
67 private final JavaClass _clazz;
68 private final PrintWriter _out;
69 private final ConstantPoolGen _cp;
96 class_name = class_name.substring(package_name.length() + 1);
97 _out.println("package " + package_name + ";");
98 _out.println();
99 }
100 _out.println("import " + BASE_PACKAGE + ".generic.*;");
101 _out.println("import " + BASE_PACKAGE + ".classfile.*;");
102 _out.println("import " + BASE_PACKAGE + ".*;");
103 _out.println("import java.io.*;");
104 _out.println();
105 _out.println("public class " + class_name + "Creator {");
106 _out.println(" private InstructionFactory _factory;");
107 _out.println(" private ConstantPoolGen _cp;");
108 _out.println(" private ClassGen _cg;");
109 _out.println();
110 _out.println(" public " + class_name + "Creator() {");
111 _out.println(" _cg = new ClassGen(\""
112 + (("".equals(package_name)) ? class_name : package_name + "." + class_name)
113 + "\", \"" + super_name + "\", " + "\"" + clazz.getSourceFileName() + "\", "
114 + printFlags(clazz.getAccessFlags(), FLAGS.CLASS) + ", "
115 + "new String[] { " + inter + " });");
116 _out.println();
117 _out.println(" _cp = _cg.getConstantPool();");
118 _out.println(" _factory = new InstructionFactory(_cg, _cp);");
119 _out.println(" }");
120 _out.println();
121 printCreate();
122 final Field[] fields = clazz.getFields();
123 if (fields.length > 0) {
124 _out.println(" private void createFields() {");
125 _out.println(" FieldGen field;");
126 for (final Field field : fields) {
127 field.accept(this);
128 }
129 _out.println(" }");
130 _out.println();
131 }
132 final Method[] methods = clazz.getMethods();
133 for (int i = 0; i < methods.length; i++) {
134 _out.println(" private void createMethod_" + i + "() {");
135 methods[i].accept(this);
199 _out.println(" il.dispose();");
200 }
201
202
203 static String printFlags( final int flags ) {
204 return printFlags(flags, FLAGS.UNKNOWN);
205 }
206
207 /**
208 * Return a string with the flag settings
209 * @param flags the flags field to interpret
210 * @param location the item type
211 * @return the formatted string
212 * @since 6.0 made public
213 */
214 public static String printFlags( final int flags, final FLAGS location ) {
215 if (flags == 0) {
216 return "0";
217 }
218 final StringBuilder buf = new StringBuilder();
219 for (int i = 0, pow = 1; pow <= Const.MAX_ACC_FLAG; i++) {
220 if ((flags & pow) != 0) {
221 if ((pow == Const.ACC_SYNCHRONIZED) && (location == FLAGS.CLASS)) {
222 buf.append(CONSTANT_PREFIX+"ACC_SUPER | ");
223 } else if ((pow == Const.ACC_VOLATILE) && (location == FLAGS.METHOD)) {
224 buf.append(CONSTANT_PREFIX+"ACC_BRIDGE | ");
225 } else if ((pow == Const.ACC_TRANSIENT) && (location == FLAGS.METHOD)) {
226 buf.append(CONSTANT_PREFIX+"ACC_VARARGS | ");
227 } else {
228 if (i < Const.ACCESS_NAMES_LENGTH) {
229 buf.append(CONSTANT_PREFIX+"ACC_")
230 .append(Const.getAccessName(i).toUpperCase(Locale.ENGLISH))
231 .append( " | ");
232 } else {
233 buf.append(String.format (CONSTANT_PREFIX+"ACC_BIT %x | ", pow));
234 }
235 }
236 }
237 pow <<= 1;
238 }
239 final String str = buf.toString();
|
29 import com.sun.org.apache.bcel.internal.Const;
30 import com.sun.org.apache.bcel.internal.Repository;
31 import com.sun.org.apache.bcel.internal.classfile.ClassParser;
32 import com.sun.org.apache.bcel.internal.classfile.ConstantValue;
33 import com.sun.org.apache.bcel.internal.classfile.Field;
34 import com.sun.org.apache.bcel.internal.classfile.JavaClass;
35 import com.sun.org.apache.bcel.internal.classfile.Method;
36 import com.sun.org.apache.bcel.internal.classfile.Utility;
37 import com.sun.org.apache.bcel.internal.generic.ArrayType;
38 import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
39 import com.sun.org.apache.bcel.internal.generic.MethodGen;
40 import com.sun.org.apache.bcel.internal.generic.Type;
41
42 /**
43 * This class takes a given JavaClass object and converts it to a
44 * Java program that creates that very class using BCEL. This
45 * gives new users of BCEL a useful example showing how things
46 * are done with BCEL. It does not cover all features of BCEL,
47 * but tries to mimic hand-written code as close as possible.
48 *
49 */
50 public class BCELifier extends com.sun.org.apache.bcel.internal.classfile.EmptyVisitor {
51
52 /**
53 * Enum corresponding to flag source.
54 */
55 public enum FLAGS {
56 UNKNOWN,
57 CLASS,
58 METHOD,
59 }
60
61 // The base package name for imports; assumes Const is at the top level
62 // N.B we use the class so renames will be detected by the compiler/IDE
63 private static final String BASE_PACKAGE = Const.class.getPackage().getName();
64 private static final String CONSTANT_PREFIX = Const.class.getSimpleName()+".";
65
66 private final JavaClass _clazz;
67 private final PrintWriter _out;
68 private final ConstantPoolGen _cp;
95 class_name = class_name.substring(package_name.length() + 1);
96 _out.println("package " + package_name + ";");
97 _out.println();
98 }
99 _out.println("import " + BASE_PACKAGE + ".generic.*;");
100 _out.println("import " + BASE_PACKAGE + ".classfile.*;");
101 _out.println("import " + BASE_PACKAGE + ".*;");
102 _out.println("import java.io.*;");
103 _out.println();
104 _out.println("public class " + class_name + "Creator {");
105 _out.println(" private InstructionFactory _factory;");
106 _out.println(" private ConstantPoolGen _cp;");
107 _out.println(" private ClassGen _cg;");
108 _out.println();
109 _out.println(" public " + class_name + "Creator() {");
110 _out.println(" _cg = new ClassGen(\""
111 + (("".equals(package_name)) ? class_name : package_name + "." + class_name)
112 + "\", \"" + super_name + "\", " + "\"" + clazz.getSourceFileName() + "\", "
113 + printFlags(clazz.getAccessFlags(), FLAGS.CLASS) + ", "
114 + "new String[] { " + inter + " });");
115 _out.println(" _cg.setMajor(" + clazz.getMajor() +");");
116 _out.println(" _cg.setMinor(" + clazz.getMinor() +");");
117 _out.println();
118 _out.println(" _cp = _cg.getConstantPool();");
119 _out.println(" _factory = new InstructionFactory(_cg, _cp);");
120 _out.println(" }");
121 _out.println();
122 printCreate();
123 final Field[] fields = clazz.getFields();
124 if (fields.length > 0) {
125 _out.println(" private void createFields() {");
126 _out.println(" FieldGen field;");
127 for (final Field field : fields) {
128 field.accept(this);
129 }
130 _out.println(" }");
131 _out.println();
132 }
133 final Method[] methods = clazz.getMethods();
134 for (int i = 0; i < methods.length; i++) {
135 _out.println(" private void createMethod_" + i + "() {");
136 methods[i].accept(this);
200 _out.println(" il.dispose();");
201 }
202
203
204 static String printFlags( final int flags ) {
205 return printFlags(flags, FLAGS.UNKNOWN);
206 }
207
208 /**
209 * Return a string with the flag settings
210 * @param flags the flags field to interpret
211 * @param location the item type
212 * @return the formatted string
213 * @since 6.0 made public
214 */
215 public static String printFlags( final int flags, final FLAGS location ) {
216 if (flags == 0) {
217 return "0";
218 }
219 final StringBuilder buf = new StringBuilder();
220 for (int i = 0, pow = 1; pow <= Const.MAX_ACC_FLAG_I; i++) {
221 if ((flags & pow) != 0) {
222 if ((pow == Const.ACC_SYNCHRONIZED) && (location == FLAGS.CLASS)) {
223 buf.append(CONSTANT_PREFIX+"ACC_SUPER | ");
224 } else if ((pow == Const.ACC_VOLATILE) && (location == FLAGS.METHOD)) {
225 buf.append(CONSTANT_PREFIX+"ACC_BRIDGE | ");
226 } else if ((pow == Const.ACC_TRANSIENT) && (location == FLAGS.METHOD)) {
227 buf.append(CONSTANT_PREFIX+"ACC_VARARGS | ");
228 } else {
229 if (i < Const.ACCESS_NAMES_LENGTH) {
230 buf.append(CONSTANT_PREFIX+"ACC_")
231 .append(Const.getAccessName(i).toUpperCase(Locale.ENGLISH))
232 .append( " | ");
233 } else {
234 buf.append(String.format (CONSTANT_PREFIX+"ACC_BIT %x | ", pow));
235 }
236 }
237 }
238 pow <<= 1;
239 }
240 final String str = buf.toString();
|