Home | History | Annotate | Download | only in ant
      1 /*
      2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
      3  *             of Java bytecode.
      4  *
      5  * Copyright (c) 2002-2014 Eric Lafortune (eric (at) 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      */
     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 
     92     public void addConfiguredInjar(ClassPathElement classPathElement)
     93     {
     94         configuration.programJars = extendClassPath(configuration.programJars,
     95                                                     classPathElement,
     96                                                     false);
     97     }
     98 
     99 
    100     public void addConfiguredOutjar(ClassPathElement classPathElement)
    101     {
    102         configuration.programJars = extendClassPath(configuration.programJars,
    103                                                     classPathElement,
    104                                                     true);
    105     }
    106 
    107 
    108     public void addConfiguredLibraryjar(ClassPathElement classPathElement)
    109     {
    110         configuration.libraryJars = extendClassPath(configuration.libraryJars,
    111                                                     classPathElement,
    112                                                     false);
    113     }
    114 
    115 
    116     public void addConfiguredKeepdirectory(FilterElement filterElement)
    117     {
    118         configuration.keepDirectories = extendFilter(configuration.keepDirectories,
    119                                                      filterElement);
    120     }
    121 
    122 
    123     public void addConfiguredKeepdirectories(FilterElement filterElement)
    124     {
    125         configuration.keepDirectories = extendFilter(configuration.keepDirectories,
    126                                                      filterElement);
    127     }
    128 
    129 
    130     public void addConfiguredKeep(KeepSpecificationElement keepSpecificationElement)
    131     {
    132         configuration.keep = extendKeepSpecifications(configuration.keep,
    133                                                       keepSpecificationElement,
    134                                                       true,
    135                                                       false);
    136     }
    137 
    138 
    139     public void addConfiguredKeepclassmembers(KeepSpecificationElement keepSpecificationElement)
    140     {
    141         configuration.keep = extendKeepSpecifications(configuration.keep,
    142                                                       keepSpecificationElement,
    143                                                       false,
    144                                                       false);
    145     }
    146 
    147 
    148     public void addConfiguredKeepclasseswithmembers(KeepSpecificationElement keepSpecificationElement)
    149     {
    150         configuration.keep = extendKeepSpecifications(configuration.keep,
    151                                                       keepSpecificationElement,
    152                                                       true,
    153                                                       true);
    154     }
    155 
    156 
    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 
    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 
    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 
    193     public void addConfiguredWhyareyoukeeping(ClassSpecificationElement classSpecificationElement)
    194     {
    195         configuration.whyAreYouKeeping = extendClassSpecifications(configuration.whyAreYouKeeping,
    196                                                                    classSpecificationElement);
    197     }
    198 
    199 
    200     public void addConfiguredAssumenosideeffects(ClassSpecificationElement classSpecificationElement)
    201     {
    202         configuration.assumeNoSideEffects = extendClassSpecifications(configuration.assumeNoSideEffects,
    203                                                                       classSpecificationElement);
    204     }
    205 
    206 
    207     public void addConfiguredOptimizations(FilterElement filterElement)
    208     {
    209         addConfiguredOptimization(filterElement);
    210     }
    211 
    212 
    213     public void addConfiguredOptimization(FilterElement filterElement)
    214     {
    215         configuration.optimizations = extendFilter(configuration.optimizations,
    216                                                    filterElement);
    217     }
    218 
    219 
    220     public void addConfiguredKeeppackagename(FilterElement filterElement)
    221     {
    222         configuration.keepPackageNames = extendFilter(configuration.keepPackageNames,
    223                                                       filterElement,
    224                                                       true);
    225     }
    226 
    227 
    228     public void addConfiguredKeeppackagenames(FilterElement filterElement)
    229     {
    230         configuration.keepPackageNames = extendFilter(configuration.keepPackageNames,
    231                                                       filterElement,
    232                                                       true);
    233     }
    234 
    235 
    236     public void addConfiguredKeepattributes(FilterElement filterElement)
    237     {
    238         addConfiguredKeepattribute(filterElement);
    239     }
    240 
    241 
    242     public void addConfiguredKeepattribute(FilterElement filterElement)
    243     {
    244         configuration.keepAttributes = extendFilter(configuration.keepAttributes,
    245                                                     filterElement);
    246     }
    247 
    248 
    249     public void addConfiguredAdaptclassstrings(FilterElement filterElement)
    250     {
    251         configuration.adaptClassStrings = extendFilter(configuration.adaptClassStrings,
    252                                                        filterElement, true);
    253     }
    254 
    255 
    256     public void addConfiguredAdaptresourcefilenames(FilterElement filterElement)
    257     {
    258         configuration.adaptResourceFileNames = extendFilter(configuration.adaptResourceFileNames,
    259                                                             filterElement);
    260     }
    261 
    262 
    263     public void addConfiguredAdaptresourcefilecontents(FilterElement filterElement)
    264     {
    265         configuration.adaptResourceFileContents = extendFilter(configuration.adaptResourceFileContents,
    266                                                                filterElement);
    267     }
    268 
    269 
    270     public void addConfiguredDontnote(FilterElement filterElement)
    271     {
    272         configuration.note = extendFilter(configuration.note, filterElement, true);
    273     }
    274 
    275 
    276     public void addConfiguredDontwarn(FilterElement filterElement)
    277     {
    278         configuration.warn = extendFilter(configuration.warn, filterElement, true);
    279     }
    280 
    281 
    282     public void addConfiguredConfiguration(ConfigurationElement configurationElement)
    283     {
    284         configurationElement.appendTo(configuration);
    285     }
    286 
    287 
    288     // Implementations for Task.
    289 
    290     public void addText(String text) throws BuildException
    291     {
    292         try
    293         {
    294             Project project = getProject();
    295 
    296             // Replace Ant-style properties ('${...}').
    297             String arg = project.replaceProperties(text);
    298 
    299             // Get the combined system properties and Ant properties, for
    300             // replacing ProGuard-style properties ('<...>').
    301             Properties properties = new Properties();
    302             properties.putAll(project.getProperties());
    303 
    304             ConfigurationParser parser = new ConfigurationParser(arg,
    305                                                                  "embedded configuration",
    306                                                                  project.getBaseDir(),
    307                                                                  properties);
    308 
    309             try
    310             {
    311                 parser.parse(configuration);
    312             }
    313             catch (ParseException ex)
    314             {
    315                 throw new BuildException(ex.getMessage());
    316             }
    317             finally
    318             {
    319                 parser.close();
    320             }
    321         }
    322         catch (IOException ex)
    323         {
    324             throw new BuildException(ex.getMessage());
    325         }
    326     }
    327 
    328 
    329     // Small utility methods.
    330 
    331     private ClassPath extendClassPath(ClassPath        classPath,
    332                                       ClassPathElement classPathElement,
    333                                       boolean          output)
    334     {
    335         if (classPath == null)
    336         {
    337             classPath = new ClassPath();
    338         }
    339 
    340         classPathElement.appendClassPathEntriesTo(classPath,
    341                                                   output);
    342 
    343         return classPath;
    344     }
    345 
    346 
    347     private ClassPath extendClassPath(ClassPath classPath,
    348                                       ClassPath additionalClassPath)
    349     {
    350         if (additionalClassPath != null)
    351         {
    352             if (classPath == null)
    353             {
    354                 classPath = new ClassPath();
    355             }
    356 
    357             classPath.addAll(additionalClassPath);
    358         }
    359 
    360         return classPath;
    361     }
    362 
    363 
    364     private List extendKeepSpecifications(List                     keepSpecifications,
    365                                           KeepSpecificationElement keepSpecificationElement,
    366                                           boolean                  markClasses,
    367                                           boolean                  markClassesConditionally)
    368     {
    369         if (keepSpecifications == null)
    370         {
    371             keepSpecifications = new ArrayList();
    372         }
    373 
    374         keepSpecificationElement.appendTo(keepSpecifications,
    375                                           markClasses,
    376                                           markClassesConditionally);
    377 
    378         return keepSpecifications;
    379     }
    380 
    381 
    382     private List extendClassSpecifications(List                      classSpecifications,
    383                                            ClassSpecificationElement classSpecificationElement)
    384     {
    385         if (classSpecifications == null)
    386         {
    387             classSpecifications = new ArrayList();
    388         }
    389 
    390         classSpecificationElement.appendTo(classSpecifications);
    391 
    392         return classSpecifications;
    393     }
    394 
    395 
    396     private List extendClassSpecifications(List classSpecifications,
    397                                            List additionalClassSpecifications)
    398     {
    399         if (additionalClassSpecifications != null)
    400         {
    401             if (classSpecifications == null)
    402             {
    403                 classSpecifications = new ArrayList();
    404             }
    405 
    406             classSpecifications.addAll(additionalClassSpecifications);
    407         }
    408 
    409         return classSpecifications;
    410     }
    411 
    412 
    413     private List extendFilter(List          filter,
    414                               FilterElement filterElement)
    415     {
    416         return extendFilter(filter, filterElement, false);
    417     }
    418 
    419 
    420     private List extendFilter(List          filter,
    421                               FilterElement filterElement,
    422                               boolean       internal)
    423     {
    424         if (filter == null)
    425         {
    426             filter = new ArrayList();
    427         }
    428 
    429         filterElement.appendTo(filter, internal);
    430 
    431         return filter;
    432     }
    433 
    434 
    435     private List extendList(List list,
    436                             List additionalList)
    437     {
    438         if (additionalList != null)
    439         {
    440             if (list == null)
    441             {
    442                 list = new ArrayList();
    443             }
    444 
    445             list.addAll(additionalList);
    446         }
    447 
    448         return list;
    449     }
    450 }
    451