< prev index next >

src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/BCELifier.java

Print this page

        

@@ -19,253 +19,289 @@
  * limitations under the License.
  */
 
 package com.sun.org.apache.bcel.internal.util;
 
-import com.sun.org.apache.bcel.internal.classfile.*;
-import com.sun.org.apache.bcel.internal.generic.*;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.Locale;
+
+import com.sun.org.apache.bcel.internal.Const;
 import com.sun.org.apache.bcel.internal.Repository;
-import com.sun.org.apache.bcel.internal.Constants;
-import java.io.*;
+import com.sun.org.apache.bcel.internal.classfile.ClassParser;
+import com.sun.org.apache.bcel.internal.classfile.ConstantValue;
+import com.sun.org.apache.bcel.internal.classfile.Field;
+import com.sun.org.apache.bcel.internal.classfile.JavaClass;
+import com.sun.org.apache.bcel.internal.classfile.Method;
+import com.sun.org.apache.bcel.internal.classfile.Utility;
+import com.sun.org.apache.bcel.internal.generic.ArrayType;
+import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
+import com.sun.org.apache.bcel.internal.generic.MethodGen;
+import com.sun.org.apache.bcel.internal.generic.Type;
 
 /**
  * This class takes a given JavaClass object and converts it to a
  * Java program that creates that very class using BCEL. This
  * gives new users of BCEL a useful example showing how things
  * are done with BCEL. It does not cover all features of BCEL,
  * but tries to mimic hand-written code as close as possible.
  *
- * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @version $Id: BCELifier.java 1750228 2016-06-25 21:47:44Z ggregory $
  */
 public class BCELifier extends com.sun.org.apache.bcel.internal.classfile.EmptyVisitor {
-  private JavaClass         _clazz;
-  private PrintWriter       _out;
-  private ConstantPoolGen   _cp;
+
+    /**
+     * Enum corresponding to flag source.
+     */
+    public enum FLAGS {
+        UNKNOWN,
+        CLASS,
+        METHOD,
+    }
+
+    // The base package name for imports; assumes Const is at the top level
+    // N.B we use the class so renames will be detected by the compiler/IDE
+    private static final String BASE_PACKAGE = Const.class.getPackage().getName();
+    private static final String CONSTANT_PREFIX = Const.class.getSimpleName()+".";
+
+    private final JavaClass _clazz;
+    private final PrintWriter _out;
+    private final ConstantPoolGen _cp;
 
   /** @param clazz Java class to "decompile"
    * @param out where to output Java program
    */
-  public BCELifier(JavaClass clazz, OutputStream out) {
+    public BCELifier(final JavaClass clazz, final OutputStream out) {
     _clazz = clazz;
     _out = new PrintWriter(out);
     _cp = new ConstantPoolGen(_clazz.getConstantPool());
   }
 
+
   /** Start Java code generation
    */
   public void start() {
     visitJavaClass(_clazz);
     _out.flush();
   }
 
-  public void visitJavaClass(JavaClass clazz) {
+
+    @Override
+    public void visitJavaClass( final JavaClass clazz ) {
     String class_name   = clazz.getClassName();
-    String super_name   = clazz.getSuperclassName();
-    String package_name = clazz.getPackageName();
-    String inter        = Utility.printArray(clazz.getInterfaceNames(),
-                                             false, true);
-    if(!"".equals(package_name)) {
+        final String super_name = clazz.getSuperclassName();
+        final String package_name = clazz.getPackageName();
+        final String inter = Utility.printArray(clazz.getInterfaceNames(), false, true);
+        if (!"".equals(package_name)) {
       class_name = class_name.substring(package_name.length() + 1);
-      _out.println("package " + package_name + ";\n");
+            _out.println("package " + package_name + ";");
+            _out.println();
      }
-
-    _out.println("import com.sun.org.apache.bcel.internal.generic.*;");
-    _out.println("import com.sun.org.apache.bcel.internal.classfile.*;");
-    _out.println("import com.sun.org.apache.bcel.internal.*;");
-    _out.println("import java.io.*;\n");
-
-    _out.println("public class " + class_name + "Creator implements Constants {");
+        _out.println("import " + BASE_PACKAGE + ".generic.*;");
+        _out.println("import " + BASE_PACKAGE + ".classfile.*;");
+        _out.println("import " + BASE_PACKAGE + ".*;");
+        _out.println("import java.io.*;");
+        _out.println();
+        _out.println("public class " + class_name + "Creator {");
     _out.println("  private InstructionFactory _factory;");
     _out.println("  private ConstantPoolGen    _cp;");
-    _out.println("  private ClassGen           _cg;\n");
-
+        _out.println("  private ClassGen           _cg;");
+        _out.println();
     _out.println("  public " + class_name  + "Creator() {");
-    _out.println("    _cg = new ClassGen(\"" +
-                 (("".equals(package_name))? class_name :
-                  package_name + "." + class_name) +
-                 "\", \"" + super_name + "\", " +
-                 "\"" + clazz.getSourceFileName() + "\", " +
-                 printFlags(clazz.getAccessFlags(), true) + ", " +
-                 "new String[] { " + inter + " });\n");
-
+        _out.println("    _cg = new ClassGen(\""
+                + (("".equals(package_name)) ? class_name : package_name + "." + class_name)
+                + "\", \"" + super_name + "\", " + "\"" + clazz.getSourceFileName() + "\", "
+                + printFlags(clazz.getAccessFlags(), FLAGS.CLASS) + ", "
+                + "new String[] { " + inter + " });");
+        _out.println();
     _out.println("    _cp = _cg.getConstantPool();");
     _out.println("    _factory = new InstructionFactory(_cg, _cp);");
-    _out.println("  }\n");
-
+        _out.println("  }");
+        _out.println();
     printCreate();
-
-    Field[] fields = clazz.getFields();
-
-    if(fields.length > 0) {
+        final Field[] fields = clazz.getFields();
+        if (fields.length > 0) {
       _out.println("  private void createFields() {");
       _out.println("    FieldGen field;");
-
-      for(int i=0; i < fields.length; i++) {
-        fields[i].accept(this);
+            for (final Field field : fields) {
+                field.accept(this);
       }
-
-      _out.println("  }\n");
+            _out.println("  }");
+            _out.println();
     }
-
-    Method[] methods = clazz.getMethods();
-
-    for(int i=0; i < methods.length; i++) {
+        final Method[] methods = clazz.getMethods();
+        for (int i = 0; i < methods.length; i++) {
       _out.println("  private void createMethod_" + i + "() {");
-
       methods[i].accept(this);
-      _out.println("  }\n");
+            _out.println("  }");
+            _out.println();
     }
-
     printMain();
     _out.println("}");
   }
 
+
   private void printCreate() {
     _out.println("  public void create(OutputStream out) throws IOException {");
-
-    Field[] fields = _clazz.getFields();
-    if(fields.length > 0) {
+        final Field[] fields = _clazz.getFields();
+        if (fields.length > 0) {
       _out.println("    createFields();");
     }
-
-    Method[] methods = _clazz.getMethods();
-    for(int i=0; i < methods.length; i++) {
+        final Method[] methods = _clazz.getMethods();
+        for (int i = 0; i < methods.length; i++) {
       _out.println("    createMethod_" + i + "();");
     }
-
     _out.println("    _cg.getJavaClass().dump(out);");
-
-    _out.println("  }\n");
+        _out.println("  }");
+        _out.println();
   }
 
-  private void printMain() {
-    String   class_name   = _clazz.getClassName();
 
-    _out.println("  public static void _main(String[] args) throws Exception {");
-    _out.println("    " + class_name + "Creator creator = new " +
-                 class_name + "Creator();");
-    _out.println("    creator.create(new FileOutputStream(\"" + class_name +
-                 ".class\"));");
+    private void printMain() {
+        final String class_name = _clazz.getClassName();
+        _out.println("  public static void main(String[] args) throws Exception {");
+        _out.println("    " + class_name + "Creator creator = new " + class_name + "Creator();");
+        _out.println("    creator.create(new FileOutputStream(\"" + class_name + ".class\"));");
     _out.println("  }");
   }
 
-  public void visitField(Field field) {
-    _out.println("\n    field = new FieldGen(" +
-                 printFlags(field.getAccessFlags()) +
-                 ", " + printType(field.getSignature()) + ", \"" +
-                 field.getName() + "\", _cp);");
 
-    ConstantValue cv = field.getConstantValue();
-
-    if(cv != null) {
-      String value = cv.toString();
+    @Override
+    public void visitField( final Field field ) {
+        _out.println();
+        _out.println("    field = new FieldGen(" + printFlags(field.getAccessFlags()) + ", "
+                + printType(field.getSignature()) + ", \"" + field.getName() + "\", _cp);");
+        final ConstantValue cv = field.getConstantValue();
+        if (cv != null) {
+            final String value = cv.toString();
       _out.println("    field.setInitValue(" + value + ")");
     }
-
     _out.println("    _cg.addField(field.getField());");
   }
 
-  public void visitMethod(Method method) {
-    MethodGen mg = new MethodGen(method, _clazz.getClassName(), _cp);
-
-    Type   result_type = mg.getReturnType();
-    Type[] arg_types   = mg.getArgumentTypes();
 
+    @Override
+    public void visitMethod( final Method method ) {
+        final MethodGen mg = new MethodGen(method, _clazz.getClassName(), _cp);
     _out.println("    InstructionList il = new InstructionList();");
-    _out.println("    MethodGen method = new MethodGen(" +
-                 printFlags(method.getAccessFlags()) +
-                 ", " + printType(result_type) +
-                 ", " + printArgumentTypes(arg_types) + ", " +
-                 "new String[] { " +
-                 Utility.printArray(mg.getArgumentNames(), false, true) +
-                 " }, \"" + method.getName() + "\", \"" +
-                 _clazz.getClassName() + "\", il, _cp);\n");
-
-    BCELFactory factory = new BCELFactory(mg, _out);
+        _out.println("    MethodGen method = new MethodGen("
+                + printFlags(method.getAccessFlags(), FLAGS.METHOD) + ", "
+                + printType(mg.getReturnType()) + ", "
+                + printArgumentTypes(mg.getArgumentTypes()) + ", "
+                + "new String[] { " + Utility.printArray(mg.getArgumentNames(), false, true)
+                + " }, \"" + method.getName() + "\", \"" + _clazz.getClassName() + "\", il, _cp);");
+        _out.println();
+        final BCELFactory factory = new BCELFactory(mg, _out);
     factory.start();
-
     _out.println("    method.setMaxStack();");
     _out.println("    method.setMaxLocals();");
     _out.println("    _cg.addMethod(method.getMethod());");
     _out.println("    il.dispose();");
   }
 
-  static String printFlags(int flags) {
-    return printFlags(flags, false);
+
+    static String printFlags( final int flags ) {
+        return printFlags(flags, FLAGS.UNKNOWN);
   }
 
-  static String printFlags(int flags, boolean for_class) {
-    if(flags == 0)
+    /**
+     * Return a string with the flag settings
+     * @param flags the flags field to interpret
+     * @param location the item type
+     * @return the formatted string
+     * @since 6.0 made public
+     */
+    public static String printFlags( final int flags, final FLAGS location ) {
+        if (flags == 0) {
       return "0";
-
-    StringBuffer buf = new StringBuffer();
-    for(int i=0, pow=1; i <= Constants.MAX_ACC_FLAG; i++) {
-      if((flags & pow) != 0) {
-        if((pow == Constants.ACC_SYNCHRONIZED) && for_class)
-          buf.append("ACC_SUPER | ");
-        else
-          buf.append("ACC_" + Constants.ACCESS_NAMES[i].toUpperCase() + " | ");
       }
-
+        final StringBuilder buf = new StringBuilder();
+        for (int i = 0, pow = 1; pow <= Const.MAX_ACC_FLAG; i++) {
+            if ((flags & pow) != 0) {
+                if ((pow == Const.ACC_SYNCHRONIZED) && (location == FLAGS.CLASS)) {
+                    buf.append(CONSTANT_PREFIX+"ACC_SUPER | ");
+                } else if ((pow == Const.ACC_VOLATILE) && (location == FLAGS.METHOD)) {
+                    buf.append(CONSTANT_PREFIX+"ACC_BRIDGE | ");
+                } else if ((pow == Const.ACC_TRANSIENT) && (location == FLAGS.METHOD)) {
+                    buf.append(CONSTANT_PREFIX+"ACC_VARARGS | ");
+                } else {
+                    if (i < Const.ACCESS_NAMES_LENGTH) {
+                        buf.append(CONSTANT_PREFIX+"ACC_")
+                                .append(Const.getAccessName(i).toUpperCase(Locale.ENGLISH))
+                                .append( " | ");
+                    } else {
+                        buf.append(String.format (CONSTANT_PREFIX+"ACC_BIT %x | ", pow));
+                    }
+                }
+            }
       pow <<= 1;
     }
-
-    String str = buf.toString();
+        final String str = buf.toString();
     return str.substring(0, str.length() - 3);
   }
 
-  static String printArgumentTypes(Type[] arg_types) {
-    if(arg_types.length == 0)
-      return "Type.NO_ARGS";
-
-    StringBuffer args = new StringBuffer();
 
-    for(int i=0; i < arg_types.length; i++) {
+    static String printArgumentTypes( final Type[] arg_types ) {
+        if (arg_types.length == 0) {
+            return "Type.NO_ARGS";
+        }
+        final StringBuilder args = new StringBuilder();
+        for (int i = 0; i < arg_types.length; i++) {
       args.append(printType(arg_types[i]));
-
-      if(i < arg_types.length - 1)
+            if (i < arg_types.length - 1) {
         args.append(", ");
     }
-
+        }
     return "new Type[] { " + args.toString() + " }";
   }
 
-  static String printType(Type type) {
+
+    static String printType( final Type type ) {
     return printType(type.getSignature());
   }
 
-  static String printType(String signature) {
-    Type type = Type.getType(signature);
-    byte t    = type.getType();
-
-    if(t <= Constants.T_VOID) {
-      return "Type." + Constants.TYPE_NAMES[t].toUpperCase();
-    } else if(type.toString().equals("java.lang.String")) {
+
+    static String printType( final String signature ) {
+        final Type type = Type.getType(signature);
+        final byte t = type.getType();
+        if (t <= Const.T_VOID) {
+            return "Type." + Const.getTypeName(t).toUpperCase(Locale.ENGLISH);
+        } else if (type.toString().equals("java.lang.String")) {
       return "Type.STRING";
-    } else if(type.toString().equals("java.lang.Object")) {
+        } else if (type.toString().equals("java.lang.Object")) {
       return "Type.OBJECT";
-    } else if(type.toString().equals("java.lang.StringBuffer")) {
+        } else if (type.toString().equals("java.lang.StringBuffer")) {
       return "Type.STRINGBUFFER";
-    } else if(type instanceof ArrayType) {
-      ArrayType at = (ArrayType)type;
-
-      return "new ArrayType(" + printType(at.getBasicType()) +
-        ", " + at.getDimensions() + ")";
+        } else if (type instanceof ArrayType) {
+            final ArrayType at = (ArrayType) type;
+            return "new ArrayType(" + printType(at.getBasicType()) + ", " + at.getDimensions()
+                    + ")";
     } else {
-      return "new ObjectType(\"" + Utility.signatureToString(signature, false) +
-        "\")";
+            return "new ObjectType(\"" + Utility.signatureToString(signature, false) + "\")";
     }
   }
 
-  /** Default _main method
+
+    /** Default main method
    */
-  public static void _main(String[] argv) throws Exception {
-    JavaClass java_class;
-    String    name = argv[0];
+    public static void _main( final String[] argv ) throws Exception {
+        if (argv.length != 1) {
+            System.out.println("Usage: BCELifier classname");
+            System.out.println("\tThe class must exist on the classpath");
+            return;
+        }
+        final JavaClass java_class = getJavaClass(argv[0]);
+        final BCELifier bcelifier = new BCELifier(java_class, System.out);
+        bcelifier.start();
+    }
 
-    if((java_class = Repository.lookupClass(name)) == null)
-      java_class = new ClassParser(name).parse(); // May throw IOException
 
-    BCELifier bcelifier = new BCELifier(java_class, System.out);
-    bcelifier.start();
+    // Needs to be accessible from unit test code
+    static JavaClass getJavaClass(final String name) throws ClassNotFoundException, IOException {
+        JavaClass java_class;
+        if ((java_class = Repository.lookupClass(name)) == null) {
+            java_class = new ClassParser(name).parse(); // May throw IOException
+        }
+        return java_class;
   }
 }
< prev index next >