1 /* 2 * ProGuard -- shrinking, optimization, obfuscation, and preverification 3 * of Java bytecode. 4 * 5 * Copyright (c) 2002-2014 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; 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 */ ClassPathEntry(File file, boolean isOutput)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 */ getName()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 */ getUncachedName()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 */ getFile()96 public File getFile() 97 { 98 return file; 99 } 100 101 102 /** 103 * Sets the file. 104 */ setFile(File file)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 */ isOutput()115 public boolean isOutput() 116 { 117 return output; 118 } 119 120 121 /** 122 * Specifies whether this data entry is an output entry. 123 */ setOutput(boolean output)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 */ isDex()133 public boolean isDex() 134 { 135 return hasExtension(".dex"); 136 } 137 138 139 /** 140 * Returns whether this data entry is an apk file. 141 */ isApk()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 */ isJar()152 public boolean isJar() 153 { 154 return hasExtension(".jar"); 155 } 156 157 158 /** 159 * Returns whether this data entry is an aar file. 160 */ isAar()161 public boolean isAar() 162 { 163 return hasExtension(".aar"); 164 } 165 166 167 /** 168 * Returns whether this data entry is a war file. 169 */ isWar()170 public boolean isWar() 171 { 172 return hasExtension(".war"); 173 } 174 175 176 /** 177 * Returns whether this data entry is a ear file. 178 */ isEar()179 public boolean isEar() 180 { 181 return hasExtension(".ear"); 182 } 183 184 185 /** 186 * Returns whether this data entry is a zip file. 187 */ isZip()188 public boolean isZip() 189 { 190 return hasExtension(".zip"); 191 } 192 193 194 /** 195 * Returns whether this data entry has the given extension. 196 */ hasExtension(String extension)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 */ endsWithIgnoreCase(String string, String suffix)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 */ isFiltered()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 */ getFilter()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 */ setFilter(List filter)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 */ getApkFilter()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 */ setApkFilter(List filter)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 */ getJarFilter()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 */ setJarFilter(List filter)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 */ getAarFilter()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 */ setAarFilter(List filter)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 */ getWarFilter()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 */ setWarFilter(List filter)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 */ getEarFilter()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 */ setEarFilter(List filter)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 */ getZipFilter()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 */ setZipFilter(List filter)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 toString()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