1b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/* 2b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ProGuard -- shrinking, optimization, obfuscation, and preverification 3b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * of Java bytecode. 4b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 5b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) 6b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 7b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This program is free software; you can redistribute it and/or modify it 8b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * under the terms of the GNU General Public License as published by the Free 9b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Software Foundation; either version 2 of the License, or (at your option) 10b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * any later version. 11b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 12b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This program is distributed in the hope that it will be useful, but WITHOUT 13b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * more details. 16b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 17b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * You should have received a copy of the GNU General Public License along 18b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * with this program; if not, write to the Free Software Foundation, Inc., 19b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 21b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopackage proguard; 22b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 23b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.ClassConstants; 24b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.util.ClassUtil; 25b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.util.ListUtil; 26b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 27b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport java.io.*; 28b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport java.util.List; 29b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 30b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 31b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/** 32b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This class writes ProGuard configurations to a file. 33b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 34b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @author Eric Lafortune 35b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 36b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopublic class ConfigurationWriter 37b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato{ 38b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private static final String[] KEEP_OPTIONS = new String[] 39b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 40b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ConfigurationConstants.KEEP_OPTION, 41b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ConfigurationConstants.KEEP_CLASS_MEMBERS_OPTION, 42b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ConfigurationConstants.KEEP_CLASSES_WITH_MEMBERS_OPTION 43b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato }; 44b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 45b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 46b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private final PrintWriter writer; 47b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private File baseDir; 48b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 49b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 50b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 51b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Creates a new ConfigurationWriter for the given file name. 52b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 53b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public ConfigurationWriter(File configurationFile) throws IOException 54b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 55b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this(new PrintWriter(new FileWriter(configurationFile))); 56b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 57b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato baseDir = configurationFile.getParentFile(); 58b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 59b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 60b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 61b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 62b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Creates a new ConfigurationWriter for the given OutputStream. 63b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 64b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public ConfigurationWriter(OutputStream outputStream) throws IOException 65b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 66b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this(new PrintWriter(outputStream)); 67b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 68b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 69b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 70b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 71b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Creates a new ConfigurationWriter for the given PrintWriter. 72b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 73b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public ConfigurationWriter(PrintWriter writer) throws IOException 74b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 75b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.writer = writer; 76b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 77b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 78b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 79b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 80b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Closes this ConfigurationWriter. 81b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 82b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void close() throws IOException 83b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 84b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.close(); 85b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 86b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 87b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 88b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 89b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Writes the given configuration. 90b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @param configuration the configuration that is to be written out. 91b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @throws IOException if an IO error occurs while writing the configuration. 92b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 93b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void write(Configuration configuration) throws IOException 94b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 95b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Write the program class path (input and output entries). 96b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeJarOptions(ConfigurationConstants.INJARS_OPTION, 97b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ConfigurationConstants.OUTJARS_OPTION, 98b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato configuration.programJars); 99b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.println(); 100b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 101b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Write the library class path (output entries only). 102b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeJarOptions(ConfigurationConstants.LIBRARYJARS_OPTION, 103b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ConfigurationConstants.LIBRARYJARS_OPTION, 104b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato configuration.libraryJars); 105b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.println(); 106b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 107b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Write the other options. 108b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.DONT_SKIP_NON_PUBLIC_LIBRARY_CLASSES_OPTION, !configuration.skipNonPublicLibraryClasses); 109b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.DONT_SKIP_NON_PUBLIC_LIBRARY_CLASS_MEMBERS_OPTION, !configuration.skipNonPublicLibraryClassMembers); 110b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.KEEP_DIRECTORIES_OPTION, configuration.keepDirectories); 111b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.TARGET_OPTION, ClassUtil.externalClassVersion(configuration.targetClassVersion)); 112b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.FORCE_PROCESSING_OPTION, configuration.lastModified == Long.MAX_VALUE); 113b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 114b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.DONT_SHRINK_OPTION, !configuration.shrink); 115b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.PRINT_USAGE_OPTION, configuration.printUsage); 116b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 117b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.DONT_OPTIMIZE_OPTION, !configuration.optimize); 118b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.OPTIMIZATIONS, configuration.optimize ? ListUtil.commaSeparatedString(configuration.optimizations) : null); 119b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.OPTIMIZATION_PASSES, configuration.optimizationPasses); 120b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.ALLOW_ACCESS_MODIFICATION_OPTION, configuration.allowAccessModification); 121b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.MERGE_INTERFACES_AGGRESSIVELY_OPTION, configuration.mergeInterfacesAggressively); 122b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 123b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.DONT_OBFUSCATE_OPTION, !configuration.obfuscate); 124b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.PRINT_MAPPING_OPTION, configuration.printMapping); 125b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.APPLY_MAPPING_OPTION, configuration.applyMapping); 126b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.OBFUSCATION_DICTIONARY_OPTION, configuration.obfuscationDictionary); 127b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.CLASS_OBFUSCATION_DICTIONARY_OPTION, configuration.classObfuscationDictionary); 128b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.PACKAGE_OBFUSCATION_DICTIONARY_OPTION, configuration.packageObfuscationDictionary); 129b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.OVERLOAD_AGGRESSIVELY_OPTION, configuration.overloadAggressively); 130b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.USE_UNIQUE_CLASS_MEMBER_NAMES_OPTION, configuration.useUniqueClassMemberNames); 131b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.DONT_USE_MIXED_CASE_CLASS_NAMES_OPTION, !configuration.useMixedCaseClassNames); 132b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.KEEP_PACKAGE_NAMES_OPTION, configuration.keepPackageNames, true); 133b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.FLATTEN_PACKAGE_HIERARCHY_OPTION, configuration.flattenPackageHierarchy, true); 134b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.REPACKAGE_CLASSES_OPTION, configuration.repackageClasses, true); 135b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.KEEP_ATTRIBUTES_OPTION, configuration.keepAttributes); 136b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.RENAME_SOURCE_FILE_ATTRIBUTE_OPTION, configuration.newSourceFileAttribute); 137b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.ADAPT_CLASS_STRINGS_OPTION, configuration.adaptClassStrings, true); 138b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.ADAPT_RESOURCE_FILE_NAMES_OPTION, configuration.adaptResourceFileNames); 139b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.ADAPT_RESOURCE_FILE_CONTENTS_OPTION, configuration.adaptResourceFileContents); 140b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 141b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.DONT_PREVERIFY_OPTION, !configuration.preverify); 142b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.MICRO_EDITION_OPTION, configuration.microEdition); 143b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 144b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.VERBOSE_OPTION, configuration.verbose); 145b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.DONT_NOTE_OPTION, configuration.note, true); 146b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.DONT_WARN_OPTION, configuration.warn, true); 147b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.IGNORE_WARNINGS_OPTION, configuration.ignoreWarnings); 148b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.PRINT_CONFIGURATION_OPTION, configuration.printConfiguration); 149b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.DUMP_OPTION, configuration.dump); 150b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 151b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(ConfigurationConstants.PRINT_SEEDS_OPTION, configuration.printSeeds); 152b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.println(); 153b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 154b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Write the "why are you keeping" options. 155b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOptions(ConfigurationConstants.WHY_ARE_YOU_KEEPING_OPTION, configuration.whyAreYouKeeping); 156b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 157b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Write the keep options. 158b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOptions(KEEP_OPTIONS, configuration.keep); 159b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 160b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Write the "no side effect methods" options. 161b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOptions(ConfigurationConstants.ASSUME_NO_SIDE_EFFECTS_OPTION, configuration.assumeNoSideEffects); 162b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 163b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (writer.checkError()) 164b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 165b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato throw new IOException("Can't write configuration"); 166b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 167b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 168b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 169b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 170b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private void writeJarOptions(String inputEntryOptionName, 171b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String outputEntryOptionName, 172b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ClassPath classPath) 173b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 174b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (classPath != null) 175b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 176b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato for (int index = 0; index < classPath.size(); index++) 177b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 178b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ClassPathEntry entry = classPath.get(index); 179b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String optionName = entry.isOutput() ? 180b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato outputEntryOptionName : 181b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato inputEntryOptionName; 182b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 183b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(optionName); 184b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(' '); 185b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(relativeFileName(entry.getFile())); 186b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 187b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Append the filters, if any. 188b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato boolean filtered = false; 189b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 190b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato filtered = writeFilter(filtered, entry.getZipFilter()); 191b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato filtered = writeFilter(filtered, entry.getEarFilter()); 192b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato filtered = writeFilter(filtered, entry.getWarFilter()); 193b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato filtered = writeFilter(filtered, entry.getJarFilter()); 194b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato filtered = writeFilter(filtered, entry.getFilter()); 195b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 196b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (filtered) 197b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 198b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(ConfigurationConstants.CLOSE_ARGUMENTS_KEYWORD); 199b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 200b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 201b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.println(); 202b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 203b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 204b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 205b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 206b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 207b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private boolean writeFilter(boolean filtered, List filter) 208b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 209b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (filtered) 210b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 211b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(ConfigurationConstants.SEPARATOR_KEYWORD); 212b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 213b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 214b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (filter != null) 215b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 216b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (!filtered) 217b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 218b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(ConfigurationConstants.OPEN_ARGUMENTS_KEYWORD); 219b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 220b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 221b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato for (int index = 0; index < filter.size(); index++) 222b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 223b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (index > 0) 224b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 225b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(ConfigurationConstants.ARGUMENT_SEPARATOR_KEYWORD); 226b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 227b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 228b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(quotedString((String)filter.get(index))); 229b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 230b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 231b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato filtered = true; 232b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 233b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 234b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return filtered; 235b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 236b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 237b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 238b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private void writeOption(String optionName, boolean flag) 239b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 240b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (flag) 241b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 242b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.println(optionName); 243b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 244b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 245b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 246b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 247b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private void writeOption(String optionName, int argument) 248b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 249b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (argument != 1) 250b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 251b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(optionName); 252b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(' '); 253b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.println(argument); 254b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 255b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 256b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 257b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 258b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private void writeOption(String optionName, List arguments) 259b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 260b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(optionName, arguments, false); 261b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 262b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 263b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 264b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private void writeOption(String optionName, 265b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato List arguments, 266b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato boolean replaceInternalClassNames) 267b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 268b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (arguments != null) 269b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 270b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (arguments.isEmpty()) 271b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 272b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.println(optionName); 273b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 274b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato else 275b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 276b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String argumentString = ListUtil.commaSeparatedString(arguments); 277b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 278b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (replaceInternalClassNames) 279b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 280b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato argumentString = ClassUtil.externalClassName(argumentString); 281b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 282b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 283b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(optionName); 284b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(' '); 285b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.println(quotedString(argumentString)); 286b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 287b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 288b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 289b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 290b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 291b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private void writeOption(String optionName, String arguments) 292b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 293b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(optionName, arguments, false); 294b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 295b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 296b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 297b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private void writeOption(String optionName, 298b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String arguments, 299b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato boolean replaceInternalClassNames) 300b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 301b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (arguments != null) 302b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 303b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (replaceInternalClassNames) 304b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 305b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato arguments = ClassUtil.externalClassName(arguments); 306b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 307b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 308b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(optionName); 309b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(' '); 310b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.println(quotedString(arguments)); 311b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 312b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 313b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 314b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 315b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private void writeOption(String optionName, File file) 316b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 317b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (file != null) 318b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 319b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (file.getPath().length() > 0) 320b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 321b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(optionName); 322b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(' '); 323b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.println(relativeFileName(file)); 324b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 325b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato else 326b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 327b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.println(optionName); 328b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 329b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 330b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 331b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 332b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 333b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private void writeOptions(String[] optionNames, 334b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato List keepClassSpecifications) 335b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 336b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (keepClassSpecifications != null) 337b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 338b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato for (int index = 0; index < keepClassSpecifications.size(); index++) 339b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 340b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(optionNames, (KeepClassSpecification)keepClassSpecifications.get(index)); 341b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 342b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 343b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 344b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 345b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 346b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private void writeOption(String[] optionNames, 347b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato KeepClassSpecification keepClassSpecification) 348b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 349b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Compose the option name. 350b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String optionName = optionNames[keepClassSpecification.markConditionally ? 2 : 351b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato keepClassSpecification.markClasses ? 0 : 352b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 1]; 353b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 354b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (keepClassSpecification.allowShrinking) 355b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 356b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato optionName += ConfigurationConstants.ARGUMENT_SEPARATOR_KEYWORD + 357b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ConfigurationConstants.ALLOW_SHRINKING_SUBOPTION; 358b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 359b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 360b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (keepClassSpecification.allowOptimization) 361b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 362b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato optionName += ConfigurationConstants.ARGUMENT_SEPARATOR_KEYWORD + 363b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ConfigurationConstants.ALLOW_OPTIMIZATION_SUBOPTION; 364b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 365b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 366b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (keepClassSpecification.allowObfuscation) 367b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 368b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato optionName += ConfigurationConstants.ARGUMENT_SEPARATOR_KEYWORD + 369b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ConfigurationConstants.ALLOW_OBFUSCATION_SUBOPTION; 370b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 371b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 372b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Write out the option with the proper class specification. 373b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(optionName, keepClassSpecification); 374b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 375b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 376b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 377b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private void writeOptions(String optionName, 378b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato List classSpecifications) 379b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 380b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (classSpecifications != null) 381b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 382b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato for (int index = 0; index < classSpecifications.size(); index++) 383b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 384b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeOption(optionName, (ClassSpecification)classSpecifications.get(index)); 385b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 386b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 387b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 388b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 389b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 390b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private void writeOption(String optionName, 391b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ClassSpecification classSpecification) 392b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 393b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.println(); 394b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 395b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Write out the comments for this option. 396b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeComments(classSpecification.comments); 397b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 398b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(optionName); 399b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(' '); 400b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 401b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Write out the required annotation, if any. 402b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (classSpecification.annotationType != null) 403b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 404b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(ConfigurationConstants.ANNOTATION_KEYWORD); 405b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(ClassUtil.externalType(classSpecification.annotationType)); 406b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(' '); 407b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 408b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 409b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Write out the class access flags. 410b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(ClassUtil.externalClassAccessFlags(classSpecification.requiredUnsetAccessFlags, 411b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ConfigurationConstants.NEGATOR_KEYWORD)); 412b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 413b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(ClassUtil.externalClassAccessFlags(classSpecification.requiredSetAccessFlags)); 414b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 415b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Write out the class keyword, if we didn't write the interface 416b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // keyword earlier. 417b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (((classSpecification.requiredSetAccessFlags | 418b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato classSpecification.requiredUnsetAccessFlags) & 419b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato (ClassConstants.INTERNAL_ACC_INTERFACE | 420b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ClassConstants.INTERNAL_ACC_ENUM)) == 0) 421b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 422b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(ConfigurationConstants.CLASS_KEYWORD); 423b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 424b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 425b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(' '); 426b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 427b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Write out the class name. 428b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(classSpecification.className != null ? 429b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ClassUtil.externalClassName(classSpecification.className) : 430b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ConfigurationConstants.ANY_CLASS_KEYWORD); 431b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 432b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Write out the extends template, if any. 433b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (classSpecification.extendsAnnotationType != null || 434b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato classSpecification.extendsClassName != null) 435b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 436b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(' '); 437b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(ConfigurationConstants.EXTENDS_KEYWORD); 438b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(' '); 439b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 440b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Write out the required extends annotation, if any. 441b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (classSpecification.extendsAnnotationType != null) 442b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 443b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(ConfigurationConstants.ANNOTATION_KEYWORD); 444b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(ClassUtil.externalType(classSpecification.extendsAnnotationType)); 445b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(' '); 446b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 447b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 448b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Write out the extended class name. 449b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(classSpecification.extendsClassName != null ? 450b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ClassUtil.externalClassName(classSpecification.extendsClassName) : 451b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ConfigurationConstants.ANY_CLASS_KEYWORD); 452b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 453b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 454b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Write out the keep field and keep method options, if any. 455b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (classSpecification.fieldSpecifications != null || 456b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato classSpecification.methodSpecifications != null) 457b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 458b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(' '); 459b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.println(ConfigurationConstants.OPEN_KEYWORD); 460b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 461b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeFieldSpecification( classSpecification.fieldSpecifications); 462b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writeMethodSpecification(classSpecification.methodSpecifications); 463b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 464b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.println(ConfigurationConstants.CLOSE_KEYWORD); 465b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 466b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato else 467b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 468b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.println(); 469b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 470b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 471b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 472b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 473b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 474b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private void writeComments(String comments) 475b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 476b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (comments != null) 477b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 478b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato int index = 0; 479b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato while (index < comments.length()) 480b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 481b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato int breakIndex = comments.indexOf('\n', index); 482b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (breakIndex < 0) 483b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 484b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato breakIndex = comments.length(); 485b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 486b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 487b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print('#'); 488b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 489b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (comments.charAt(index) != ' ') 490b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 491b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(' '); 492b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 493b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 494b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.println(comments.substring(index, breakIndex)); 495b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 496b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato index = breakIndex + 1; 497b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 498b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 499b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 500b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 501b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 502b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private void writeFieldSpecification(List memberSpecifications) 503b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 504b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (memberSpecifications != null) 505b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 506b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato for (int index = 0; index < memberSpecifications.size(); index++) 507b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 508b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato MemberSpecification memberSpecification = 509b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato (MemberSpecification)memberSpecifications.get(index); 510b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 511b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(" "); 512b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 513b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Write out the required annotation, if any. 514b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (memberSpecification.annotationType != null) 515b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 516b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(ConfigurationConstants.ANNOTATION_KEYWORD); 517b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.println(ClassUtil.externalType(memberSpecification.annotationType)); 518b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(" "); 519b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 520b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 521b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Write out the field access flags. 522b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(ClassUtil.externalFieldAccessFlags(memberSpecification.requiredUnsetAccessFlags, 523b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ConfigurationConstants.NEGATOR_KEYWORD)); 524b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 525b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(ClassUtil.externalFieldAccessFlags(memberSpecification.requiredSetAccessFlags)); 526b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 527b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Write out the field name and descriptor. 528b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String name = memberSpecification.name; 529b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String descriptor = memberSpecification.descriptor; 530b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 531b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(descriptor == null ? name == null ? 532b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ConfigurationConstants.ANY_FIELD_KEYWORD : 533b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ConfigurationConstants.ANY_TYPE_KEYWORD + ' ' + name : 534b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ClassUtil.externalFullFieldDescription(0, 535b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato name == null ? ConfigurationConstants.ANY_CLASS_MEMBER_KEYWORD : name, 536b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato descriptor)); 537b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 538b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.println(ConfigurationConstants.SEPARATOR_KEYWORD); 539b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 540b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 541b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 542b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 543b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 544b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private void writeMethodSpecification(List memberSpecifications) 545b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 546b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (memberSpecifications != null) 547b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 548b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato for (int index = 0; index < memberSpecifications.size(); index++) 549b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 550b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato MemberSpecification memberSpecification = 551b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato (MemberSpecification)memberSpecifications.get(index); 552b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 553b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(" "); 554b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 555b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Write out the required annotation, if any. 556b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (memberSpecification.annotationType != null) 557b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 558b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(ConfigurationConstants.ANNOTATION_KEYWORD); 559b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.println(ClassUtil.externalType(memberSpecification.annotationType)); 560b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(" "); 561b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 562b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 563b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Write out the method access flags. 564b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(ClassUtil.externalMethodAccessFlags(memberSpecification.requiredUnsetAccessFlags, 565b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ConfigurationConstants.NEGATOR_KEYWORD)); 566b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 567b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(ClassUtil.externalMethodAccessFlags(memberSpecification.requiredSetAccessFlags)); 568b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 569b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Write out the method name and descriptor. 570b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String name = memberSpecification.name; 571b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String descriptor = memberSpecification.descriptor; 572b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 573b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.print(descriptor == null ? name == null ? 574b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ConfigurationConstants.ANY_METHOD_KEYWORD : 575b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ConfigurationConstants.ANY_TYPE_KEYWORD + ' ' + name + ConfigurationConstants.OPEN_ARGUMENTS_KEYWORD + ConfigurationConstants.ANY_ARGUMENTS_KEYWORD + ConfigurationConstants.CLOSE_ARGUMENTS_KEYWORD : 576b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ClassUtil.externalFullMethodDescription(ClassConstants.INTERNAL_METHOD_NAME_INIT, 577b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 0, 578b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato name == null ? ConfigurationConstants.ANY_CLASS_MEMBER_KEYWORD : name, 579b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato descriptor)); 580b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 581b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.println(ConfigurationConstants.SEPARATOR_KEYWORD); 582b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 583b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 584b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 585b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 586b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 587b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 588b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Returns a relative file name of the given file, if possible. 589b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * The file name is also quoted, if necessary. 590b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 591b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private String relativeFileName(File file) 592b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 593b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String fileName = file.getAbsolutePath(); 594b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 595b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // See if we can convert the file name into a relative file name. 596b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (baseDir != null) 597b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 598b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String baseDirName = baseDir.getAbsolutePath() + File.separator; 599b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (fileName.startsWith(baseDirName)) 600b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 601b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato fileName = fileName.substring(baseDirName.length()); 602b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 603b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 604b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 605b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return quotedString(fileName); 606b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 607b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 608b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 609b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 610b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Returns a quoted version of the given string, if necessary. 611b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 612b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private String quotedString(String string) 613b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 614b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato return string.length() == 0 || 615b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato string.indexOf(' ') >= 0 || 616b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato string.indexOf('@') >= 0 || 617b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato string.indexOf('{') >= 0 || 618b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato string.indexOf('}') >= 0 || 619b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato string.indexOf('(') >= 0 || 620b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato string.indexOf(')') >= 0 || 621b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato string.indexOf(':') >= 0 || 622b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato string.indexOf(';') >= 0 || 623b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato string.indexOf(',') >= 0 ? ("'" + string + "'") : 624b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ( string ); 625b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 626b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 627b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 628b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 629b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * A main method for testing configuration writing. 630b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 631b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public static void main(String[] args) { 632b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato try 633b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 634b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ConfigurationWriter writer = new ConfigurationWriter(new File(args[0])); 635b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 636b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato writer.write(new Configuration()); 637b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 638b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato catch (Exception ex) 639b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 640b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ex.printStackTrace(); 641b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 642b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 643b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato} 644