1 21 package proguard; 22 23 import proguard.classfile.ClassPool; 24 import proguard.classfile.editor.*; 25 import proguard.classfile.visitor.*; 26 import proguard.obfuscate.Obfuscator; 27 import proguard.optimize.Optimizer; 28 import proguard.preverify.*; 29 import proguard.shrink.Shrinker; 30 31 import java.io.*; 32 33 38 public class ProGuard 39 { 40 public static final String VERSION = "ProGuard, version 4.0 beta5"; 41 42 private Configuration configuration; 43 private ClassPool programClassPool = new ClassPool(); 44 private ClassPool libraryClassPool = new ClassPool(); 45 46 47 51 public ProGuard(Configuration configuration) 52 { 53 this.configuration = configuration; 54 } 55 56 57 60 public void execute() throws IOException 61 { 62 System.out.println(VERSION); 63 64 GPL.check(); 65 66 if (configuration.printConfiguration != null) 67 { 68 printConfiguration(); 69 } 70 71 if (configuration.programJars != null && 72 configuration.programJars.hasOutput() && 73 new UpToDateChecker(configuration).check()) 74 { 75 return; 76 } 77 78 readInput(); 79 80 if (configuration.shrink || 81 configuration.optimize || 82 configuration.obfuscate || 83 configuration.preverify) 84 { 85 initialize(); 86 } 87 88 if (configuration.targetClassVersion != 0) 89 { 90 target(); 91 } 92 93 if (configuration.printSeeds != null) 94 { 95 printSeeds(); 96 } 97 98 if (configuration.shrink) 99 { 100 shrink(); 101 } 102 103 if (configuration.preverify) 104 { 105 inlineSubroutines(); 106 } 107 108 if (configuration.optimize) 109 { 110 for (int optimizationPass = 0; 111 optimizationPass < configuration.optimizationPasses; 112 optimizationPass++) 113 { 114 if (!optimize()) 115 { 116 break; 118 } 119 120 if (configuration.shrink) 122 { 123 configuration.printUsage = null; 125 configuration.whyAreYouKeeping = null; 126 127 shrink(); 128 } 129 } 130 } 131 132 if (configuration.obfuscate) 133 { 134 obfuscate(); 135 } 136 137 if (configuration.preverify) 138 { 139 preverify(); 140 } 141 142 if (configuration.shrink || 143 configuration.optimize || 144 configuration.obfuscate || 145 configuration.preverify) 146 { 147 sortClassElements(); 148 } 149 150 if (configuration.programJars.hasOutput()) 151 { 152 writeOutput(); 153 } 154 155 if (configuration.dump != null) 156 { 157 dump(); 158 } 159 } 160 161 162 165 private void printConfiguration() throws IOException 166 { 167 if (configuration.verbose) 168 { 169 System.out.println("Printing configuration to [" + fileName(configuration.printConfiguration) + "]..."); 170 } 171 172 PrintStream ps = createPrintStream(configuration.printConfiguration); 173 try 174 { 175 new ConfigurationWriter(ps).write(configuration); 176 } 177 finally 178 { 179 closePrintStream(ps); 180 } 181 } 182 183 184 187 private void readInput() throws IOException 188 { 189 if (configuration.verbose) 190 { 191 System.out.println("Reading input..."); 192 } 193 194 new InputReader(configuration).execute(programClassPool, libraryClassPool); 196 } 197 198 199 203 private void initialize() throws IOException 204 { 205 if (configuration.verbose) 206 { 207 System.out.println("Initializing..."); 208 } 209 210 new Initializer(configuration).execute(programClassPool, libraryClassPool); 211 } 212 213 214 217 private void target() throws IOException 218 { 219 if (configuration.verbose) 220 { 221 System.out.println("Setting target versions..."); 222 } 223 224 new Targeter(configuration).execute(programClassPool); 225 } 226 227 228 232 private void printSeeds() throws IOException 233 { 234 if (configuration.verbose) 235 { 236 System.out.println("Printing kept classes, fields, and methods..."); 237 } 238 239 if (configuration.keep == null) 241 { 242 throw new IOException("You have to specify '-keep' options for the shrinking step."); 243 } 244 245 PrintStream ps = createPrintStream(configuration.printSeeds); 246 try 247 { 248 SimpleClassPrinter printer = new SimpleClassPrinter(false, ps); 252 ClassPoolVisitor classPoolvisitor = 253 ClassSpecificationVisitorFactory.createClassPoolVisitor(configuration.keep, 254 new ProgramClassFilter(printer), 255 new ProgramMemberFilter(printer), 256 true, 257 true, 258 true); 259 260 programClassPool.accept(classPoolvisitor); 262 libraryClassPool.accept(classPoolvisitor); 263 } 264 finally 265 { 266 closePrintStream(ps); 267 } 268 } 269 270 271 274 private void shrink() throws IOException 275 { 276 if (configuration.verbose) 277 { 278 System.out.println("Shrinking..."); 279 280 if (configuration.whyAreYouKeeping != null) 282 { 283 System.out.println("Explaining why classes and class members are being kept..."); 284 } 285 286 if (configuration.printUsage != null) 288 { 289 System.out.println("Printing usage to [" + fileName(configuration.printUsage) + "]..."); 290 } 291 } 292 293 programClassPool = 295 new Shrinker(configuration).execute(programClassPool, libraryClassPool); 296 } 297 298 299 302 private void inlineSubroutines() 303 { 304 if (configuration.verbose) 305 { 306 System.out.println("Inlining subroutines..."); 307 } 308 309 new SubroutineInliner(configuration).execute(programClassPool); 311 } 312 313 314 317 private boolean optimize() throws IOException 318 { 319 if (configuration.verbose) 320 { 321 System.out.println("Optimizing..."); 322 } 323 324 return new Optimizer(configuration).execute(programClassPool, libraryClassPool); 326 } 327 328 329 332 private void obfuscate() throws IOException 333 { 334 if (configuration.verbose) 335 { 336 System.out.println("Obfuscating..."); 337 338 if (configuration.applyMapping != null) 340 { 341 System.out.println("Applying mapping [" + fileName(configuration.applyMapping) + "]"); 342 } 343 344 if (configuration.printMapping != null) 346 { 347 System.out.println("Printing mapping to [" + fileName(configuration.printMapping) + "]..."); 348 } 349 } 350 351 new Obfuscator(configuration).execute(programClassPool, libraryClassPool); 353 } 354 355 356 359 private void preverify() 360 { 361 if (configuration.verbose) 362 { 363 System.out.println("Preverifying..."); 364 } 365 366 new Preverifier(configuration).execute(programClassPool); 368 } 369 370 371 374 private void sortClassElements() 375 { 376 programClassPool.classesAccept(new ClassElementSorter()); 377 } 378 379 380 383 private void writeOutput() throws IOException 384 { 385 if (configuration.verbose) 386 { 387 System.out.println("Writing output..."); 388 } 389 390 new OutputWriter(configuration).execute(programClassPool); 392 } 393 394 395 398 private void dump() throws IOException 399 { 400 if (configuration.verbose) 401 { 402 System.out.println("Printing classes to [" + fileName(configuration.dump) + "]..."); 403 } 404 405 PrintStream ps = createPrintStream(configuration.dump); 406 try 407 { 408 programClassPool.classesAccept(new ClassPrinter(ps)); 409 } 410 finally 411 { 412 closePrintStream(ps); 413 } 414 } 415 416 417 421 private PrintStream createPrintStream(File file) 422 throws FileNotFoundException 423 { 424 return isFile(file) ? 425 new PrintStream(new BufferedOutputStream(new FileOutputStream(file))) : 426 System.out; 427 } 428 429 430 434 private void closePrintStream(PrintStream printStream) 435 { 436 if (printStream == System.out) 437 { 438 printStream.flush(); 439 } 440 else 441 { 442 printStream.close(); 443 } 444 } 445 446 447 451 private String fileName(File file) 452 { 453 return isFile(file) ? 454 file.getAbsolutePath() : 455 "standard output"; 456 } 457 458 459 463 private boolean isFile(File file) 464 { 465 return file.getPath().length() > 0; 466 } 467 468 469 472 public static void main(String [] args) 473 { 474 if (args.length == 0) 475 { 476 System.out.println(VERSION); 477 System.out.println("Usage: java proguard.ProGuard [options ...]"); 478 System.exit(1); 479 } 480 481 Configuration configuration = new Configuration(); 483 484 try 485 { 486 ConfigurationParser parser = new ConfigurationParser(args); 488 489 try 490 { 491 parser.parse(configuration); 492 493 new ProGuard(configuration).execute(); 495 } 496 finally 497 { 498 parser.close(); 499 } 500 } 501 catch (Exception ex) 502 { 503 if (configuration.verbose) 504 { 505 ex.printStackTrace(); 507 } 508 else 509 { 510 System.err.println("Error: "+ex.getMessage()); 512 } 513 514 System.exit(1); 515 } 516 517 System.exit(0); 518 } 519 } 520 | Popular Tags |