1 /* 2 * ProGuard -- shrinking, optimization, obfuscation, and preverification 3 * of Java bytecode. 4 * 5 * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the Free 9 * Software Foundation; either version 2 of the License, or (at your option) 10 * any later version. 11 * 12 * This program is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15 * more details. 16 * 17 * You should have received a copy of the GNU General Public License along 18 * with this program; if not, write to the Free Software Foundation, Inc., 19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 */ 21 package proguard.ant; 22 23 import org.apache.tools.ant.BuildException; 24 import proguard.*; 25 import proguard.classfile.util.ClassUtil; 26 27 import java.io.*; 28 import java.util.ArrayList; 29 30 /** 31 * This Task allows to configure and run ProGuard from Ant. 32 * 33 * @author Eric Lafortune 34 */ 35 public class ProGuardTask extends ConfigurationTask 36 { 37 // Ant task attributes. 38 setConfiguration(File configurationFile)39 public void setConfiguration(File configurationFile) throws BuildException 40 { 41 try 42 { 43 ConfigurationParser parser = new ConfigurationParser(configurationFile); 44 45 try 46 { 47 parser.parse(configuration); 48 } 49 catch (ParseException ex) 50 { 51 throw new BuildException(ex.getMessage()); 52 } 53 finally 54 { 55 parser.close(); 56 } 57 } 58 catch (IOException ex) 59 { 60 throw new BuildException(ex.getMessage()); 61 } 62 } 63 64 65 /** 66 * @deprecated Use the nested outjar element instead. 67 */ setOutjar(String parameters)68 public void setOutjar(String parameters) 69 { 70 throw new BuildException("Use the <outjar> nested element instead of the 'outjar' attribute"); 71 } 72 73 setSkipnonpubliclibraryclasses(boolean skipNonPublicLibraryClasses)74 public void setSkipnonpubliclibraryclasses(boolean skipNonPublicLibraryClasses) 75 { 76 configuration.skipNonPublicLibraryClasses = skipNonPublicLibraryClasses; 77 } 78 79 setSkipnonpubliclibraryclassmembers(boolean skipNonPublicLibraryClassMembers)80 public void setSkipnonpubliclibraryclassmembers(boolean skipNonPublicLibraryClassMembers) 81 { 82 configuration.skipNonPublicLibraryClassMembers = skipNonPublicLibraryClassMembers; 83 } 84 85 setTarget(String target)86 public void setTarget(String target) 87 { 88 configuration.targetClassVersion = ClassUtil.internalClassVersion(target); 89 if (configuration.targetClassVersion == 0) 90 { 91 throw new BuildException("Unsupported target '"+target+"'"); 92 } 93 } 94 95 setForceprocessing(boolean forceProcessing)96 public void setForceprocessing(boolean forceProcessing) 97 { 98 configuration.lastModified = forceProcessing ? Long.MAX_VALUE : 0; 99 } 100 101 setPrintseeds(File printSeeds)102 public void setPrintseeds(File printSeeds) 103 { 104 configuration.printSeeds = optionalFile(printSeeds); 105 } 106 107 setShrink(boolean shrink)108 public void setShrink(boolean shrink) 109 { 110 configuration.shrink = shrink; 111 } 112 113 setPrintusage(File printUsage)114 public void setPrintusage(File printUsage) 115 { 116 configuration.printUsage = optionalFile(printUsage); 117 } 118 119 setOptimize(boolean optimize)120 public void setOptimize(boolean optimize) 121 { 122 configuration.optimize = optimize; 123 } 124 125 setOptimizationpasses(int optimizationPasses)126 public void setOptimizationpasses(int optimizationPasses) 127 { 128 configuration.optimizationPasses = optimizationPasses; 129 } 130 131 setAllowaccessmodification(boolean allowAccessModification)132 public void setAllowaccessmodification(boolean allowAccessModification) 133 { 134 configuration.allowAccessModification = allowAccessModification; 135 } 136 137 setMergeinterfacesaggressively(boolean mergeinterfacesaggressively)138 public void setMergeinterfacesaggressively(boolean mergeinterfacesaggressively) 139 { 140 configuration.mergeInterfacesAggressively = mergeinterfacesaggressively; 141 } 142 143 setObfuscate(boolean obfuscate)144 public void setObfuscate(boolean obfuscate) 145 { 146 configuration.obfuscate = obfuscate; 147 } 148 149 setPrintmapping(File printMapping)150 public void setPrintmapping(File printMapping) 151 { 152 configuration.printMapping = optionalFile(printMapping); 153 } 154 155 setApplymapping(File applyMapping)156 public void setApplymapping(File applyMapping) 157 { 158 configuration.applyMapping = resolvedFile(applyMapping); 159 } 160 161 setObfuscationdictionary(File obfuscationDictionary)162 public void setObfuscationdictionary(File obfuscationDictionary) 163 { 164 configuration.obfuscationDictionary = resolvedFile(obfuscationDictionary); 165 } 166 167 setClassobfuscationdictionary(File classObfuscationDictionary)168 public void setClassobfuscationdictionary(File classObfuscationDictionary) 169 { 170 configuration.classObfuscationDictionary = resolvedFile(classObfuscationDictionary); 171 } 172 173 setPackageobfuscationdictionary(File packageObfuscationDictionary)174 public void setPackageobfuscationdictionary(File packageObfuscationDictionary) 175 { 176 configuration.packageObfuscationDictionary = resolvedFile(packageObfuscationDictionary); 177 } 178 179 setOverloadaggressively(boolean overloadAggressively)180 public void setOverloadaggressively(boolean overloadAggressively) 181 { 182 configuration.overloadAggressively = overloadAggressively; 183 } 184 185 setUseuniqueclassmembernames(boolean useUniqueClassMemberNames)186 public void setUseuniqueclassmembernames(boolean useUniqueClassMemberNames) 187 { 188 configuration.useUniqueClassMemberNames = useUniqueClassMemberNames; 189 } 190 191 setUsemixedcaseclassnames(boolean useMixedCaseClassNames)192 public void setUsemixedcaseclassnames(boolean useMixedCaseClassNames) 193 { 194 configuration.useMixedCaseClassNames = useMixedCaseClassNames; 195 } 196 197 setFlattenpackagehierarchy(String flattenPackageHierarchy)198 public void setFlattenpackagehierarchy(String flattenPackageHierarchy) 199 { 200 configuration.flattenPackageHierarchy = ClassUtil.internalClassName(flattenPackageHierarchy); 201 } 202 203 setRepackageclasses(String repackageClasses)204 public void setRepackageclasses(String repackageClasses) 205 { 206 configuration.repackageClasses = ClassUtil.internalClassName(repackageClasses); 207 } 208 209 /** 210 * @deprecated Use the repackageclasses attribute instead. 211 */ setDefaultpackage(String defaultPackage)212 public void setDefaultpackage(String defaultPackage) 213 { 214 configuration.repackageClasses = ClassUtil.internalClassName(defaultPackage); 215 } 216 217 setRenamesourcefileattribute(String newSourceFileAttribute)218 public void setRenamesourcefileattribute(String newSourceFileAttribute) 219 { 220 configuration.newSourceFileAttribute = newSourceFileAttribute; 221 } 222 223 setPreverify(boolean preverify)224 public void setPreverify(boolean preverify) 225 { 226 configuration.preverify = preverify; 227 } 228 229 setMicroedition(boolean microEdition)230 public void setMicroedition(boolean microEdition) 231 { 232 configuration.microEdition = microEdition; 233 } 234 235 setVerbose(boolean verbose)236 public void setVerbose(boolean verbose) 237 { 238 configuration.verbose = verbose; 239 } 240 241 setNote(boolean note)242 public void setNote(boolean note) 243 { 244 configuration.note = note ? null : new ArrayList(); 245 } 246 247 setWarn(boolean warn)248 public void setWarn(boolean warn) 249 { 250 configuration.warn = warn ? null : new ArrayList(); 251 } 252 253 setIgnorewarnings(boolean ignoreWarnings)254 public void setIgnorewarnings(boolean ignoreWarnings) 255 { 256 configuration.ignoreWarnings = ignoreWarnings; 257 } 258 259 setPrintconfiguration(File printConfiguration)260 public void setPrintconfiguration(File printConfiguration) 261 { 262 configuration.printConfiguration = optionalFile(printConfiguration); 263 } 264 265 setDump(File dump)266 public void setDump(File dump) 267 { 268 configuration.dump = optionalFile(dump); 269 } 270 271 272 // Implementations for Task. 273 execute()274 public void execute() throws BuildException 275 { 276 try 277 { 278 ProGuard proGuard = new ProGuard(configuration); 279 proGuard.execute(); 280 } 281 catch (IOException ex) 282 { 283 throw new BuildException(ex.getMessage()); 284 } 285 } 286 287 288 // Small utility methods. 289 290 /** 291 * Returns a file that is properly resolved with respect to the project 292 * directory, or <code>null</code> or empty if its name is actually a 293 * boolean flag. 294 */ optionalFile(File file)295 private File optionalFile(File file) 296 { 297 String fileName = file.getName(); 298 299 return 300 fileName.equalsIgnoreCase("false") || 301 fileName.equalsIgnoreCase("no") || 302 fileName.equalsIgnoreCase("off") ? null : 303 fileName.equalsIgnoreCase("true") || 304 fileName.equalsIgnoreCase("yes") || 305 fileName.equalsIgnoreCase("on") ? new File("") : 306 resolvedFile(file); 307 } 308 309 310 /** 311 * Returns a file that is properly resolved with respect to the project 312 * directory. 313 */ resolvedFile(File file)314 private File resolvedFile(File file) 315 { 316 return file.isAbsolute() ? file : 317 new File(getProject().getBaseDir(), 318 file.getName()); 319 } 320 } 321