?? proguard.java
字號:
ClassSpecificationVisitorFactory.createClassPoolVisitor(configuration.keepNames, nameMarker, nameMarker) }); // Mark the seeds. programClassPool.accept(classPoolvisitor); libraryClassPool.accept(classPoolvisitor); // Apply the mapping, if one has been specified. if (configuration.applyMapping != null) { if (configuration.verbose) { System.out.println("Applying mapping [" + configuration.applyMapping + "]"); } MappingReader reader = new MappingReader(configuration.applyMapping); MappingProcessor keeper = new MultiMappingProcessor(new MappingProcessor[] { new MappingKeeper(programClassPool), new MappingKeeper(libraryClassPool), }); reader.pump(keeper); } // Mark attributes that have to be kept. AttributeUsageMarker attributeUsageMarker = new AttributeUsageMarker(); if (configuration.keepAttributes != null) { if (configuration.keepAttributes.size() != 0) { attributeUsageMarker.setKeepAttributes(configuration.keepAttributes); } else { attributeUsageMarker.setKeepAllAttributes(); } } programClassPool.classFilesAccept(attributeUsageMarker); // Remove the attributes that can be discarded. programClassPool.classFilesAccept(new AttributeShrinker()); if (configuration.verbose) { System.out.println("Renaming program classes and class elements..."); } // Come up with new names for all class files. programClassPool.classFilesAccept(new ClassFileObfuscator(programClassPool, configuration.defaultPackage, configuration.useMixedCaseClassNames)); // Come up with new names for all class members. programClassPool.classFilesAccept(new BottomClassFileFilter( new MemberInfoObfuscator(configuration.overloadAggressively, configuration.obfuscationDictionary))); // Print out the mapping, if requested. if (configuration.printMapping != null) { if (configuration.verbose) { System.out.println("Printing mapping" + (configuration.printMapping.length() > 0 ? " to [" + configuration.printMapping + "]" : "...")); } PrintStream ps = configuration.printMapping.length() > 0 ? new PrintStream(new BufferedOutputStream(new FileOutputStream(configuration.printMapping))) : System.out; // Print out items that will be removed. programClassPool.classFilesAcceptAlphabetically(new MappingPrinter(ps)); if (ps != System.out) { ps.close(); } } // Actually apply these new names. programClassPool.classFilesAccept(new ClassFileRenamer(configuration.defaultPackage != null, configuration.newSourceFileAttribute)); // Mark NameAndType constant pool entries that have to be kept // and remove the other ones. programClassPool.classFilesAccept(new NameAndTypeUsageMarker()); programClassPool.classFilesAccept(new NameAndTypeShrinker(1024)); // Mark Utf8 constant pool entries that have to be kept // and remove the other ones. programClassPool.classFilesAccept(new Utf8UsageMarker()); programClassPool.classFilesAccept(new Utf8Shrinker(1024)); } /** * Sorts the constant pools of all program class files. */ private void sortConstantPools() { programClassPool.classFilesAccept(new ConstantPoolSorter(1024)); } /** * Writes the output jars. */ private void writeOutput() throws IOException { if (configuration.verbose) { System.out.println("Writing jars..."); } ClassPath programJars = configuration.programJars; // Perform a check on the first jar. ClassPathEntry firstEntry = programJars.get(0); if (firstEntry.isOutput()) { throw new IOException("The output jar [" + firstEntry.getName() + "] must be specified after an input jar, or it will be empty."); } // Perform some checks on the output jars. for (int index = 0; index < programJars.size() - 1; index++) { ClassPathEntry entry = programJars.get(index); if (entry.isOutput()) { // Check if all but the last output jars have filters. if (entry.getFilter() == null && entry.getJarFilter() == null && entry.getWarFilter() == null && entry.getEarFilter() == null && entry.getZipFilter() == null && programJars.get(index + 1).isOutput()) { throw new IOException("The output jar [" + entry.getName() + "] must have a filter, or all subsequent jars will be empty."); } // Check if the output jar name is different from the input jar names. for (int inIndex = 0; inIndex < programJars.size(); inIndex++) { ClassPathEntry otherEntry = programJars.get(inIndex); if (!otherEntry.isOutput() && entry.getName().equals(otherEntry.getName())) { throw new IOException("The output jar [" + entry.getName() + "] must be different from all input jars."); } } } } int firstInputIndex = 0; int lastInputIndex = 0; // Go over all program class path entries. for (int index = 0; index < programJars.size(); index++) { // Is it an input entry? ClassPathEntry entry = programJars.get(index); if (!entry.isOutput()) { // Remember the index of the last input entry. lastInputIndex = index; } else { // Check if this the last output entry in a series. int nextIndex = index + 1; if (nextIndex == programJars.size() || !programJars.get(nextIndex).isOutput()) { // Write the processed input entries to the output entries. writeOutput(programJars, firstInputIndex, lastInputIndex + 1, nextIndex); // Start with the next series of input entries. firstInputIndex = nextIndex; } } } } /** * Transfers the specified input jars to the specified output jars. */ private void writeOutput(ClassPath classPath, int fromInputIndex, int fromOutputIndex, int toOutputIndex) throws IOException { try { // Construct the writer that can write jars, wars, ears, zips, and // directories, cascading over the specified output entries. DataEntryWriter writer = DataEntryWriterFactory.createDataEntryWriter(classPath, fromOutputIndex, toOutputIndex); // Create the reader that can write class files and copy resource // files to the above writer. DataEntryReader reader = new ClassFileFilter(new ClassFileRewriter(programClassPool, writer), new DataEntryCopier(writer)); // Read and handle the specified input entries. readInput("Copying resources from program ", classPath, fromInputIndex, fromOutputIndex, reader); // Close all output entries. writer.close(); } catch (IOException ex) { throw new IOException("Can't write [" + classPath.get(fromOutputIndex).getName() + "] (" + ex.getMessage() + ")"); } } /** * Prints out the contents of the program class files. */ private void dump() throws IOException { if (configuration.verbose) { System.out.println("Printing classes" + (configuration.dump.length() > 0 ? " to [" + configuration.dump + "]" : "...")); } PrintStream ps = configuration.dump.length() > 0 ? new PrintStream(new BufferedOutputStream(new FileOutputStream(configuration.dump))) : System.out; programClassPool.classFilesAccept(new ClassFilePrinter(ps)); if (configuration.dump.length() > 0) { ps.close(); } } /** * The main method for ProGuard. */ public static void main(String[] args) { if (args.length == 0) { System.out.println("Usage: java proguard.ProGuard [options ...]"); System.exit(1); } // Create the default options. Configuration configuration = new Configuration(); try { // Parse the options specified in the command line arguments. ConfigurationParser parser = new ConfigurationParser(args); parser.parse(configuration); // Execute ProGuard with these options. ProGuard proGuard = new ProGuard(configuration); proGuard.execute(); } catch (Exception ex) { if (configuration.verbose) { // Print a verbose stack trace. ex.printStackTrace(); } else { // Print just the stack trace message. System.err.println("Error: "+ex.getMessage()); } System.exit(1); } System.exit(0); }}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -