View Javadoc
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); 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