Home | History | Annotate | Download | only in proguard
      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;
     22 
     23 import proguard.util.ListUtil;
     24 
     25 import java.io.*;
     26 import java.util.List;
     27 
     28 
     29 /**
     30  * This class represents an entry from a class path: an apk, a jar, an aar, a
     31  * war, a zip, an ear, or a directory, with a name and a flag to indicates
     32  * whether the entry is an input entry or an output entry. Optional filters can
     33  * be specified for the names of the contained resource/classes, apks, jars,
     34  * aars, wars, ears, and zips.
     35  *
     36  * @author Eric Lafortune
     37  */
     38 public class ClassPathEntry
     39 {
     40     private File    file;
     41     private boolean output;
     42     private List    filter;
     43     private List    apkFilter;
     44     private List    jarFilter;
     45     private List    aarFilter;
     46     private List    warFilter;
     47     private List    earFilter;
     48     private List    zipFilter;
     49 
     50     private String cachedName;
     51 
     52 
     53     /**
     54      * Creates a new ClassPathEntry with the given file and output flag.
     55      */
     56     public ClassPathEntry(File file, boolean isOutput)
     57     {
     58         this.file   = file;
     59         this.output = isOutput;
     60     }
     61 
     62 
     63     /**
     64      * Returns the path name of the entry.
     65      */
     66     public String getName()
     67     {
     68         if (cachedName == null)
     69         {
     70             cachedName = getUncachedName();
     71         }
     72 
     73         return cachedName;
     74     }
     75 
     76 
     77     /**
     78      * Returns the uncached path name of the entry.
     79      */
     80     private String getUncachedName()
     81     {
     82         try
     83         {
     84             return file.getCanonicalPath();
     85         }
     86         catch (IOException ex)
     87         {
     88             return file.getPath();
     89         }
     90     }
     91 
     92 
     93     /**
     94      * Returns the file.
     95      */
     96     public File getFile()
     97     {
     98         return file;
     99     }
    100 
    101 
    102     /**
    103      * Sets the file.
    104      */
    105     public void setFile(File file)
    106     {
    107         this.file       = file;
    108         this.cachedName = null;
    109     }
    110 
    111 
    112     /**
    113      * Returns whether this data entry is an output entry.
    114      */
    115     public boolean isOutput()
    116     {
    117         return output;
    118     }
    119 
    120 
    121     /**
    122      * Specifies whether this data entry is an output entry.
    123      */
    124     public void setOutput(boolean output)
    125     {
    126         this.output = output;
    127     }
    128 
    129 
    130     /**
    131      * Returns whether this data entry is a dex file.
    132      */
    133     public boolean isDex()
    134     {
    135         return hasExtension(".dex");
    136     }
    137 
    138 
    139     /**
    140      * Returns whether this data entry is an apk file.
    141      */
    142     public boolean isApk()
    143     {
    144         return hasExtension(".apk") ||
    145                hasExtension(".ap_");
    146     }
    147 
    148 
    149     /**
    150      * Returns whether this data entry is a jar file.
    151      */
    152     public boolean isJar()
    153     {
    154         return hasExtension(".jar");
    155     }
    156 
    157 
    158     /**
    159      * Returns whether this data entry is an aar file.
    160      */
    161     public boolean isAar()
    162     {
    163         return hasExtension(".aar");
    164     }
    165 
    166 
    167     /**
    168      * Returns whether this data entry is a war file.
    169      */
    170     public boolean isWar()
    171     {
    172         return hasExtension(".war");
    173     }
    174 
    175 
    176     /**
    177      * Returns whether this data entry is a ear file.
    178      */
    179     public boolean isEar()
    180     {
    181         return hasExtension(".ear");
    182     }
    183 
    184 
    185     /**
    186      * Returns whether this data entry is a zip file.
    187      */
    188     public boolean isZip()
    189     {
    190         return hasExtension(".zip");
    191     }
    192 
    193 
    194     /**
    195      * Returns whether this data entry has the given extension.
    196      */
    197     private boolean hasExtension(String extension)
    198     {
    199         return endsWithIgnoreCase(file.getPath(), extension);
    200     }
    201 
    202 
    203     /**
    204      * Returns whether the given string ends with the given suffix, ignoring
    205      * its case.
    206      */
    207     private static boolean endsWithIgnoreCase(String string, String suffix)
    208     {
    209         int stringLength = string.length();
    210         int suffixLength = suffix.length();
    211 
    212         return string.regionMatches(true, stringLength -
    213                                           suffixLength, suffix, 0, suffixLength);
    214     }
    215 
    216 
    217     /**
    218      * Returns whether this data entry has any kind of filter.
    219      */
    220     public boolean isFiltered()
    221     {
    222         return filter    != null ||
    223                apkFilter != null ||
    224                jarFilter != null ||
    225                aarFilter != null ||
    226                warFilter != null ||
    227                earFilter != null ||
    228                zipFilter != null;
    229     }
    230 
    231 
    232     /**
    233      * Returns the name filter that is applied to bottom-level files in this entry.
    234      */
    235     public List getFilter()
    236     {
    237         return filter;
    238     }
    239 
    240     /**
    241      * Sets the name filter that is applied to bottom-level files in this entry.
    242      */
    243     public void setFilter(List filter)
    244     {
    245         this.filter = filter == null || filter.size() == 0 ? null : filter;
    246     }
    247 
    248 
    249     /**
    250      * Returns the name filter that is applied to apk files in this entry, if any.
    251      */
    252     public List getApkFilter()
    253     {
    254         return apkFilter;
    255     }
    256 
    257     /**
    258      * Sets the name filter that is applied to apk files in this entry, if any.
    259      */
    260     public void setApkFilter(List filter)
    261     {
    262         this.apkFilter = filter == null || filter.size() == 0 ? null : filter;
    263     }
    264 
    265 
    266     /**
    267      * Returns the name filter that is applied to jar files in this entry, if any.
    268      */
    269     public List getJarFilter()
    270     {
    271         return jarFilter;
    272     }
    273 
    274     /**
    275      * Sets the name filter that is applied to jar files in this entry, if any.
    276      */
    277     public void setJarFilter(List filter)
    278     {
    279         this.jarFilter = filter == null || filter.size() == 0 ? null : filter;
    280     }
    281 
    282 
    283     /**
    284      * Returns the name filter that is applied to aar files in this entry, if any.
    285      */
    286     public List getAarFilter()
    287     {
    288         return aarFilter;
    289     }
    290 
    291     /**
    292      * Sets the name filter that is applied to aar files in this entry, if any.
    293      */
    294     public void setAarFilter(List filter)
    295     {
    296         this.aarFilter = filter == null || filter.size() == 0 ? null : filter;
    297     }
    298 
    299 
    300     /**
    301      * Returns the name filter that is applied to war files in this entry, if any.
    302      */
    303     public List getWarFilter()
    304     {
    305         return warFilter;
    306     }
    307 
    308     /**
    309      * Sets the name filter that is applied to war files in this entry, if any.
    310      */
    311     public void setWarFilter(List filter)
    312     {
    313         this.warFilter = filter == null || filter.size() == 0 ? null : filter;
    314     }
    315 
    316 
    317     /**
    318      * Returns the name filter that is applied to ear files in this entry, if any.
    319      */
    320     public List getEarFilter()
    321     {
    322         return earFilter;
    323     }
    324 
    325     /**
    326      * Sets the name filter that is applied to ear files in this entry, if any.
    327      */
    328     public void setEarFilter(List filter)
    329     {
    330         this.earFilter = filter == null || filter.size() == 0 ? null : filter;
    331     }
    332 
    333 
    334     /**
    335      * Returns the name filter that is applied to zip files in this entry, if any.
    336      */
    337     public List getZipFilter()
    338     {
    339         return zipFilter;
    340     }
    341 
    342     /**
    343      * Sets the name filter that is applied to zip files in this entry, if any.
    344      */
    345     public void setZipFilter(List filter)
    346     {
    347         this.zipFilter = filter == null || filter.size() == 0 ? null : filter;
    348     }
    349 
    350 
    351     // Implementations for Object.
    352 
    353     public String toString()
    354     {
    355         String string = getName();
    356 
    357         if (filter    != null ||
    358             jarFilter != null ||
    359             aarFilter != null ||
    360             warFilter != null ||
    361             earFilter != null ||
    362             zipFilter != null)
    363         {
    364             string +=
    365                 ConfigurationConstants.OPEN_ARGUMENTS_KEYWORD +
    366                 (aarFilter != null ? ListUtil.commaSeparatedString(aarFilter, true) : "")  +
    367                 ConfigurationConstants.SEPARATOR_KEYWORD +
    368                 (apkFilter != null ? ListUtil.commaSeparatedString(apkFilter, true) : "")  +
    369                 ConfigurationConstants.SEPARATOR_KEYWORD +
    370                 (zipFilter != null ? ListUtil.commaSeparatedString(zipFilter, true) : "")  +
    371                 ConfigurationConstants.SEPARATOR_KEYWORD +
    372                 (earFilter != null ? ListUtil.commaSeparatedString(earFilter, true) : "")  +
    373                 ConfigurationConstants.SEPARATOR_KEYWORD +
    374                 (warFilter != null ? ListUtil.commaSeparatedString(warFilter, true) : "")  +
    375                 ConfigurationConstants.SEPARATOR_KEYWORD +
    376                 (jarFilter != null ? ListUtil.commaSeparatedString(jarFilter, true) : "")  +
    377                 ConfigurationConstants.SEPARATOR_KEYWORD +
    378                 (filter    != null ? ListUtil.commaSeparatedString(filter, true)    : "")  +
    379                 ConfigurationConstants.CLOSE_ARGUMENTS_KEYWORD;
    380         }
    381 
    382         return string;
    383     }
    384 }
    385