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.*; 24 import proguard.*; 25 26 import java.io.IOException; 27 import java.util.*; 28 29 /** 30 * This Task allows to define a ProGuard configuration from Ant. 31 * 32 * @author Eric Lafortune 33 */ 34 public class ConfigurationTask extends Task 35 { 36 protected final Configuration configuration = new Configuration(); 37 38 39 /** 40 * Adds the contents of this configuration task to the given configuration. 41 * @param configuration the configuration to be extended. 42 */ appendTo(Configuration configuration)43 public void appendTo(Configuration configuration) 44 { 45 // Append all of these configuration entries to the given configuration. 46 configuration.programJars = extendClassPath(configuration.programJars, 47 this.configuration.programJars); 48 49 configuration.libraryJars = extendClassPath(configuration.libraryJars, 50 this.configuration.libraryJars); 51 52 configuration.keep = extendClassSpecifications(configuration.keep, 53 this.configuration.keep); 54 55 configuration.keepDirectories = extendList(configuration.keepDirectories, 56 this.configuration.keepDirectories); 57 58 configuration.whyAreYouKeeping = extendClassSpecifications(configuration.whyAreYouKeeping, 59 this.configuration.whyAreYouKeeping); 60 61 configuration.optimizations = extendClassSpecifications(configuration.optimizations, 62 this.configuration.optimizations); 63 64 configuration.assumeNoSideEffects = extendClassSpecifications(configuration.assumeNoSideEffects, 65 this.configuration.assumeNoSideEffects); 66 67 configuration.keepPackageNames = extendList(configuration.keepPackageNames, 68 this.configuration.keepPackageNames); 69 70 configuration.keepAttributes = extendList(configuration.keepAttributes, 71 this.configuration.keepAttributes); 72 73 configuration.adaptClassStrings = extendList(configuration.adaptClassStrings, 74 this.configuration.adaptClassStrings); 75 76 configuration.adaptResourceFileNames = extendList(configuration.adaptResourceFileNames, 77 this.configuration.adaptResourceFileNames); 78 79 configuration.adaptResourceFileContents = extendList(configuration.adaptResourceFileContents, 80 this.configuration.adaptResourceFileContents); 81 82 configuration.note = extendList(configuration.note, 83 this.configuration.note); 84 85 configuration.warn = extendList(configuration.warn, 86 this.configuration.warn); 87 } 88 89 90 // Ant task nested elements. 91 addConfiguredInjar(ClassPathElement classPathElement)92 public void addConfiguredInjar(ClassPathElement classPathElement) 93 { 94 configuration.programJars = extendClassPath(configuration.programJars, 95 classPathElement, 96 false); 97 } 98 99 addConfiguredOutjar(ClassPathElement classPathElement)100 public void addConfiguredOutjar(ClassPathElement classPathElement) 101 { 102 configuration.programJars = extendClassPath(configuration.programJars, 103 classPathElement, 104 true); 105 } 106 107 addConfiguredLibraryjar(ClassPathElement classPathElement)108 public void addConfiguredLibraryjar(ClassPathElement classPathElement) 109 { 110 configuration.libraryJars = extendClassPath(configuration.libraryJars, 111 classPathElement, 112 false); 113 } 114 115 addConfiguredKeepdirectory(FilterElement filterElement)116 public void addConfiguredKeepdirectory(FilterElement filterElement) 117 { 118 configuration.keepDirectories = extendFilter(configuration.keepDirectories, 119 filterElement); 120 } 121 122 addConfiguredKeepdirectories(FilterElement filterElement)123 public void addConfiguredKeepdirectories(FilterElement filterElement) 124 { 125 configuration.keepDirectories = extendFilter(configuration.keepDirectories, 126 filterElement); 127 } 128 129 addConfiguredKeep(KeepSpecificationElement keepSpecificationElement)130 public void addConfiguredKeep(KeepSpecificationElement keepSpecificationElement) 131 { 132 configuration.keep = extendKeepSpecifications(configuration.keep, 133 keepSpecificationElement, 134 true, 135 false); 136 } 137 138 addConfiguredKeepclassmembers(KeepSpecificationElement keepSpecificationElement)139 public void addConfiguredKeepclassmembers(KeepSpecificationElement keepSpecificationElement) 140 { 141 configuration.keep = extendKeepSpecifications(configuration.keep, 142 keepSpecificationElement, 143 false, 144 false); 145 } 146 147 addConfiguredKeepclasseswithmembers(KeepSpecificationElement keepSpecificationElement)148 public void addConfiguredKeepclasseswithmembers(KeepSpecificationElement keepSpecificationElement) 149 { 150 configuration.keep = extendKeepSpecifications(configuration.keep, 151 keepSpecificationElement, 152 true, 153 true); 154 } 155 156 addConfiguredKeepnames(KeepSpecificationElement keepSpecificationElement)157 public void addConfiguredKeepnames(KeepSpecificationElement keepSpecificationElement) 158 { 159 // Set the shrinking flag, based on the name (backward compatibility). 160 keepSpecificationElement.setAllowshrinking(true); 161 162 configuration.keep = extendKeepSpecifications(configuration.keep, 163 keepSpecificationElement, 164 true, 165 false); 166 } 167 168 addConfiguredKeepclassmembernames(KeepSpecificationElement keepSpecificationElement)169 public void addConfiguredKeepclassmembernames(KeepSpecificationElement keepSpecificationElement) 170 { 171 // Set the shrinking flag, based on the name (backward compatibility). 172 keepSpecificationElement.setAllowshrinking(true); 173 174 configuration.keep = extendKeepSpecifications(configuration.keep, 175 keepSpecificationElement, 176 false, 177 false); 178 } 179 180 addConfiguredKeepclasseswithmembernames(KeepSpecificationElement keepSpecificationElement)181 public void addConfiguredKeepclasseswithmembernames(KeepSpecificationElement keepSpecificationElement) 182 { 183 // Set the shrinking flag, based on the name (backward compatibility). 184 keepSpecificationElement.setAllowshrinking(true); 185 186 configuration.keep = extendKeepSpecifications(configuration.keep, 187 keepSpecificationElement, 188 true, 189 true); 190 } 191 192 addConfiguredWhyareyoukeeping(ClassSpecificationElement classSpecificationElement)193 public void addConfiguredWhyareyoukeeping(ClassSpecificationElement classSpecificationElement) 194 { 195 configuration.whyAreYouKeeping = extendClassSpecifications(configuration.whyAreYouKeeping, 196 classSpecificationElement); 197 } 198 199 addConfiguredAssumenosideeffects(ClassSpecificationElement classSpecificationElement)200 public void addConfiguredAssumenosideeffects(ClassSpecificationElement classSpecificationElement) 201 { 202 configuration.assumeNoSideEffects = extendClassSpecifications(configuration.assumeNoSideEffects, 203 classSpecificationElement); 204 } 205 206 addConfiguredOptimizations(FilterElement filterElement)207 public void addConfiguredOptimizations(FilterElement filterElement) 208 { 209 addConfiguredOptimization(filterElement); 210 } 211 212 addConfiguredOptimization(FilterElement filterElement)213 public void addConfiguredOptimization(FilterElement filterElement) 214 { 215 configuration.optimizations = extendFilter(configuration.optimizations, 216 filterElement); 217 } 218 219 addConfiguredKeeppackagename(FilterElement filterElement)220 public void addConfiguredKeeppackagename(FilterElement filterElement) 221 { 222 configuration.keepPackageNames = extendFilter(configuration.keepPackageNames, 223 filterElement, 224 true); 225 } 226 227 addConfiguredKeeppackagenames(FilterElement filterElement)228 public void addConfiguredKeeppackagenames(FilterElement filterElement) 229 { 230 configuration.keepPackageNames = extendFilter(configuration.keepPackageNames, 231 filterElement, 232 true); 233 } 234 235 addConfiguredKeepattributes(FilterElement filterElement)236 public void addConfiguredKeepattributes(FilterElement filterElement) 237 { 238 addConfiguredKeepattribute(filterElement); 239 } 240 241 addConfiguredKeepattribute(FilterElement filterElement)242 public void addConfiguredKeepattribute(FilterElement filterElement) 243 { 244 configuration.keepAttributes = extendFilter(configuration.keepAttributes, 245 filterElement); 246 } 247 248 addConfiguredAdaptclassstrings(FilterElement filterElement)249 public void addConfiguredAdaptclassstrings(FilterElement filterElement) 250 { 251 configuration.adaptClassStrings = extendFilter(configuration.adaptClassStrings, 252 filterElement, true); 253 } 254 255 addConfiguredAdaptresourcefilenames(FilterElement filterElement)256 public void addConfiguredAdaptresourcefilenames(FilterElement filterElement) 257 { 258 configuration.adaptResourceFileNames = extendFilter(configuration.adaptResourceFileNames, 259 filterElement); 260 } 261 262 addConfiguredAdaptresourcefilecontents(FilterElement filterElement)263 public void addConfiguredAdaptresourcefilecontents(FilterElement filterElement) 264 { 265 configuration.adaptResourceFileContents = extendFilter(configuration.adaptResourceFileContents, 266 filterElement); 267 } 268 269 addConfiguredDontnote(FilterElement filterElement)270 public void addConfiguredDontnote(FilterElement filterElement) 271 { 272 configuration.note = extendFilter(configuration.note, filterElement, true); 273 } 274 275 addConfiguredDontwarn(FilterElement filterElement)276 public void addConfiguredDontwarn(FilterElement filterElement) 277 { 278 configuration.warn = extendFilter(configuration.warn, filterElement, true); 279 } 280 281 addConfiguredConfiguration(ConfigurationElement configurationElement)282 public void addConfiguredConfiguration(ConfigurationElement configurationElement) 283 { 284 configurationElement.appendTo(configuration); 285 } 286 287 288 // Implementations for Task. 289 addText(String text)290 public void addText(String text) throws BuildException 291 { 292 try 293 { 294 String arg = getProject().replaceProperties(text); 295 296 ConfigurationParser parser = new ConfigurationParser(new String[] { arg }, 297 getProject().getBaseDir()); 298 299 try 300 { 301 parser.parse(configuration); 302 } 303 catch (ParseException ex) 304 { 305 throw new BuildException(ex.getMessage()); 306 } 307 finally 308 { 309 parser.close(); 310 } 311 } 312 catch (IOException ex) 313 { 314 throw new BuildException(ex.getMessage()); 315 } 316 } 317 318 319 // Small utility methods. 320 extendClassPath(ClassPath classPath, ClassPathElement classPathElement, boolean output)321 private ClassPath extendClassPath(ClassPath classPath, 322 ClassPathElement classPathElement, 323 boolean output) 324 { 325 if (classPath == null) 326 { 327 classPath = new ClassPath(); 328 } 329 330 classPathElement.appendClassPathEntriesTo(classPath, 331 output); 332 333 return classPath; 334 } 335 336 extendClassPath(ClassPath classPath, ClassPath additionalClassPath)337 private ClassPath extendClassPath(ClassPath classPath, 338 ClassPath additionalClassPath) 339 { 340 if (additionalClassPath != null) 341 { 342 if (classPath == null) 343 { 344 classPath = new ClassPath(); 345 } 346 347 classPath.addAll(additionalClassPath); 348 } 349 350 return classPath; 351 } 352 353 extendKeepSpecifications(List keepSpecifications, KeepSpecificationElement keepSpecificationElement, boolean markClasses, boolean markClassesConditionally)354 private List extendKeepSpecifications(List keepSpecifications, 355 KeepSpecificationElement keepSpecificationElement, 356 boolean markClasses, 357 boolean markClassesConditionally) 358 { 359 if (keepSpecifications == null) 360 { 361 keepSpecifications = new ArrayList(); 362 } 363 364 keepSpecificationElement.appendTo(keepSpecifications, 365 markClasses, 366 markClassesConditionally); 367 368 return keepSpecifications; 369 } 370 371 extendClassSpecifications(List classSpecifications, ClassSpecificationElement classSpecificationElement)372 private List extendClassSpecifications(List classSpecifications, 373 ClassSpecificationElement classSpecificationElement) 374 { 375 if (classSpecifications == null) 376 { 377 classSpecifications = new ArrayList(); 378 } 379 380 classSpecificationElement.appendTo(classSpecifications); 381 382 return classSpecifications; 383 } 384 385 extendClassSpecifications(List classSpecifications, List additionalClassSpecifications)386 private List extendClassSpecifications(List classSpecifications, 387 List additionalClassSpecifications) 388 { 389 if (additionalClassSpecifications != null) 390 { 391 if (classSpecifications == null) 392 { 393 classSpecifications = new ArrayList(); 394 } 395 396 classSpecifications.addAll(additionalClassSpecifications); 397 } 398 399 return classSpecifications; 400 } 401 402 extendFilter(List filter, FilterElement filterElement)403 private List extendFilter(List filter, 404 FilterElement filterElement) 405 { 406 return extendFilter(filter, filterElement, false); 407 } 408 409 extendFilter(List filter, FilterElement filterElement, boolean internal)410 private List extendFilter(List filter, 411 FilterElement filterElement, 412 boolean internal) 413 { 414 if (filter == null) 415 { 416 filter = new ArrayList(); 417 } 418 419 filterElement.appendTo(filter, internal); 420 421 return filter; 422 } 423 424 extendList(List list, List additionalList)425 private List extendList(List list, 426 List additionalList) 427 { 428 if (additionalList != null) 429 { 430 if (list == null) 431 { 432 list = new ArrayList(); 433 } 434 435 list.addAll(additionalList); 436 } 437 438 return list; 439 } 440 } 441