1 34 35 package org.logicalcobwebs.asm.util; 36 37 import org.logicalcobwebs.asm.Constants; 38 import org.logicalcobwebs.asm.ClassReader; 39 import org.logicalcobwebs.asm.CodeVisitor; 40 import org.logicalcobwebs.asm.Attribute; 41 42 import java.io.PrintWriter ; 43 44 110 111 public class DumpClassVisitor extends PrintClassVisitor { 112 113 124 125 public static void main (final String [] args) throws Exception { 126 if (args.length == 0) { 127 System.err.println("Prints the ASM code to generate the given class."); 128 System.err.println("Usage: DumpClassVisitor <fully qualified class name>"); 129 System.exit(-1); 130 } 131 ClassReader cr = new ClassReader(args[0]); 132 cr.accept(new DumpClassVisitor(new PrintWriter (System.out)), true); 133 } 134 135 140 141 public DumpClassVisitor (final PrintWriter pw) { 142 super(pw); 143 } 144 145 public void visit ( 146 final int access, 147 final String name, 148 final String superName, 149 final String [] interfaces, 150 final String sourceFile) 151 { 152 text.add("import org.logicalcobwebs.asm.*;\n"); 153 text.add("import java.io.FileOutputStream;\n\n"); 154 text.add("public class Dump implements Constants {\n\n"); 155 text.add("public static void main (String[] args) throws Exception {\n\n"); 156 text.add("ClassWriter cw = new ClassWriter(false);\n"); 157 text.add("CodeVisitor cv;\n\n"); 158 159 buf.setLength(0); 160 buf.append("cw.visit("); 161 appendAccess(access | 262144); 162 buf.append(", "); 163 appendConstant(buf, name); 164 buf.append(", "); 165 appendConstant(buf, superName); 166 buf.append(", "); 167 if (interfaces != null && interfaces.length > 0) { 168 buf.append("new String[] {"); 169 for (int i = 0; i < interfaces.length; ++i) { 170 buf.append(i == 0 ? " " : ", "); 171 appendConstant(buf, interfaces[i]); 172 } 173 buf.append(" }"); 174 } else { 175 buf.append("null"); 176 } 177 buf.append(", "); 178 appendConstant(buf, sourceFile); 179 buf.append(");\n\n"); 180 text.add(buf.toString()); 181 } 182 183 public void visitInnerClass ( 184 final String name, 185 final String outerName, 186 final String innerName, 187 final int access) 188 { 189 buf.setLength(0); 190 buf.append("cw.visitInnerClass("); 191 appendConstant(buf, name); 192 buf.append(", "); 193 appendConstant(buf, outerName); 194 buf.append(", "); 195 appendConstant(buf, innerName); 196 buf.append(", "); 197 appendAccess(access); 198 buf.append(");\n\n"); 199 text.add(buf.toString()); 200 } 201 202 public void visitField ( 203 final int access, 204 final String name, 205 final String desc, 206 final Object value, 207 final Attribute attrs) 208 { 209 buf.setLength(0); 210 buf.append("cw.visitField("); 211 appendAccess(access); 212 buf.append(", "); 213 appendConstant(buf, name); 214 buf.append(", "); 215 appendConstant(buf, desc); 216 buf.append(", "); 217 appendConstant(buf, value); 218 buf.append(", null);\n\n"); 219 if (attrs != null) { 220 buf.append("// WARNING! skipped some non standard field attributes\n"); 221 } 222 text.add(buf.toString()); 223 } 224 225 public CodeVisitor visitMethod ( 226 final int access, 227 final String name, 228 final String desc, 229 final String [] exceptions, 230 final Attribute attrs) 231 { 232 buf.setLength(0); 233 buf.append("{\n").append("cv = cw.visitMethod("); 234 appendAccess(access); 235 buf.append(", "); 236 appendConstant(buf, name); 237 buf.append(", "); 238 appendConstant(buf, desc); 239 buf.append(", "); 240 if (exceptions != null && exceptions.length > 0) { 241 buf.append("new String[] {"); 242 for (int i = 0; i < exceptions.length; ++i) { 243 buf.append(i == 0 ? " " : ", "); 244 appendConstant(buf, exceptions[i]); 245 } 246 buf.append(" }"); 247 } else { 248 buf.append("null"); 249 } 250 buf.append(", null);\n"); 251 if (attrs != null) { 252 buf.append("// WARNING! skipped some non standard method attributes\n"); 253 } 254 text.add(buf.toString()); 255 PrintCodeVisitor pcv = new DumpCodeVisitor(); 256 text.add(pcv.getText()); 257 text.add("}\n"); 258 return pcv; 259 } 260 261 public void visitAttribute (final Attribute attr) { 262 buf.setLength(0); 263 buf.append("// WARNING! skipped a non standard class attribute of type \""); 264 buf.append(attr.type); 265 buf.append("\"\n"); 266 text.add(buf.toString()); 267 } 268 269 public void visitEnd () { 270 text.add("cw.visitEnd();\n\n"); 271 text.add("FileOutputStream os = new FileOutputStream(\"Dumped.class\");\n"); 272 text.add("os.write(cw.toByteArray());\n"); 273 text.add("os.close();\n"); 274 text.add("}\n"); 275 text.add("}\n"); 276 super.visitEnd(); 277 } 278 279 285 286 void appendAccess (final int access) { 287 boolean first = true; 288 if ((access & Constants.ACC_PUBLIC) != 0) { 289 buf.append("ACC_PUBLIC"); 290 first = false; 291 } 292 if ((access & Constants.ACC_PRIVATE) != 0) { 293 if (!first) { 294 buf.append(" + "); 295 } 296 buf.append("ACC_PRIVATE"); 297 first = false; 298 } 299 if ((access & Constants.ACC_PROTECTED) != 0) { 300 if (!first) { 301 buf.append(" + "); 302 } 303 buf.append("ACC_PROTECTED"); 304 first = false; 305 } 306 if ((access & Constants.ACC_FINAL) != 0) { 307 if (!first) { 308 buf.append(" + "); 309 } 310 buf.append("ACC_FINAL"); 311 first = false; 312 } 313 if ((access & Constants.ACC_STATIC) != 0) { 314 if (!first) { 315 buf.append(" + "); 316 } 317 buf.append("ACC_STATIC"); 318 first = false; 319 } 320 if ((access & Constants.ACC_SYNCHRONIZED) != 0) { 321 if (!first) { 322 buf.append(" + "); 323 } 324 if ((access & 262144) != 0) { 325 buf.append("ACC_SUPER"); 326 } else { 327 buf.append("ACC_SYNCHRONIZED"); 328 } 329 first = false; 330 } 331 if ((access & Constants.ACC_VOLATILE) != 0) { 332 if (!first) { 333 buf.append(" + "); 334 } 335 buf.append("ACC_VOLATILE"); 336 first = false; 337 } 338 if ((access & Constants.ACC_TRANSIENT) != 0) { 339 if (!first) { 340 buf.append(" + "); 341 } 342 buf.append("ACC_TRANSIENT"); 343 first = false; 344 } 345 if ((access & Constants.ACC_NATIVE) != 0) { 346 if (!first) { 347 buf.append(" + "); 348 } 349 buf.append("ACC_NATIVE"); 350 first = false; 351 } 352 if ((access & Constants.ACC_ABSTRACT) != 0) { 353 if (!first) { 354 buf.append(" + "); 355 } 356 buf.append("ACC_ABSTRACT"); 357 first = false; 358 } 359 if ((access & Constants.ACC_INTERFACE) != 0) { 360 if (!first) { 361 buf.append(" + "); 362 } 363 buf.append("ACC_INTERFACE"); 364 first = false; 365 } 366 if ((access & Constants.ACC_STRICT) != 0) { 367 if (!first) { 368 buf.append(" + "); 369 } 370 buf.append("ACC_STRICT"); 371 first = false; 372 } 373 if ((access & Constants.ACC_SYNTHETIC) != 0) { 374 if (!first) { 375 buf.append(" + "); 376 } 377 buf.append("ACC_SYNTHETIC"); 378 first = false; 379 } 380 if ((access & Constants.ACC_DEPRECATED) != 0) { 381 if (!first) { 382 buf.append(" + "); 383 } 384 buf.append("ACC_DEPRECATED"); 385 first = false; 386 } 387 if (first) { 388 buf.append("0"); 389 } 390 } 391 392 400 401 static void appendConstant (final StringBuffer buf, final Object cst) { 402 if (cst == null) { 403 buf.append("null"); 404 } else if (cst instanceof String ) { 405 String s = (String )cst; 406 buf.append("\""); 407 for (int i = 0; i < s.length(); ++i) { 408 char c = s.charAt(i); 409 if (c == '\n') { 410 buf.append("\\n"); 411 } else if (c == '\\') { 412 buf.append("\\\\"); 413 } else if (c == '"') { 414 buf.append("\\\""); 415 } else { 416 buf.append(c); 417 } 418 } 419 buf.append("\""); 420 } else if (cst instanceof Integer ) { 421 buf.append("new Integer(") 422 .append(cst) 423 .append(")"); 424 } else if (cst instanceof Float ) { 425 buf.append("new Float(") 426 .append(cst) 427 .append("F)"); 428 } else if (cst instanceof Long ) { 429 buf.append("new Long(") 430 .append(cst) 431 .append("L)"); 432 } else if (cst instanceof Double ) { 433 buf.append("new Double(") 434 .append(cst) 435 .append(")"); 436 } 437 } 438 } 439 | Popular Tags |