DataEntryReaderFactory.java revision b72c5c2e5482cf10117b2b25f642f7616b2326c3
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 */ 21package proguard; 22 23import proguard.io.*; 24import proguard.util.*; 25 26import java.util.List; 27 28 29/** 30 * This class can create DataEntryReader instances based on class path entries. 31 * The readers will unwrap the input data entries from any jars, wars, ears, 32 * and zips, before passing them to a given reader. 33 * 34 * @author Eric Lafortune 35 */ 36public class DataEntryReaderFactory 37{ 38 /** 39 * Creates a DataEntryReader that can read the given class path entry. 40 * 41 * @param messagePrefix a prefix for messages that are printed out. 42 * @param classPathEntry the input class path entry. 43 * @param reader a data entry reader to which the reading of actual 44 * classes and resource files can be delegated. 45 * @return a DataEntryReader for reading the given class path entry. 46 */ 47 public static DataEntryReader createDataEntryReader(String messagePrefix, 48 ClassPathEntry classPathEntry, 49 DataEntryReader reader) 50 { 51 String entryName = classPathEntry.getName(); 52 boolean isJar = endsWithIgnoreCase(entryName, ".jar"); 53 boolean isWar = endsWithIgnoreCase(entryName, ".war"); 54 boolean isEar = endsWithIgnoreCase(entryName, ".ear"); 55 boolean isZip = endsWithIgnoreCase(entryName, ".zip"); 56 57 List filter = classPathEntry.getFilter(); 58 List jarFilter = classPathEntry.getJarFilter(); 59 List warFilter = classPathEntry.getWarFilter(); 60 List earFilter = classPathEntry.getEarFilter(); 61 List zipFilter = classPathEntry.getZipFilter(); 62 63 System.out.println(messagePrefix + 64 (isJar ? "jar" : 65 isWar ? "war" : 66 isEar ? "ear" : 67 isZip ? "zip" : 68 "directory") + 69 " [" + classPathEntry.getName() + "]" + 70 (filter != null || 71 jarFilter != null || 72 warFilter != null || 73 earFilter != null || 74 zipFilter != null ? " (filtered)" : "")); 75 76 // Add a filter, if specified. 77 if (filter != null) 78 { 79 reader = new FilteredDataEntryReader( 80 new DataEntryNameFilter( 81 new ListParser(new FileNameParser()).parse(filter)), 82 reader); 83 } 84 85 // Unzip any jars, if necessary. 86 reader = wrapInJarReader(reader, isJar, jarFilter, ".jar"); 87 if (!isJar) 88 { 89 // Unzip any wars, if necessary. 90 reader = wrapInJarReader(reader, isWar, warFilter, ".war"); 91 if (!isWar) 92 { 93 // Unzip any ears, if necessary. 94 reader = wrapInJarReader(reader, isEar, earFilter, ".ear"); 95 if (!isEar) 96 { 97 // Unzip any zips, if necessary. 98 reader = wrapInJarReader(reader, isZip, zipFilter, ".zip"); 99 } 100 } 101 } 102 103 return reader; 104 } 105 106 107 /** 108 * Wraps the given DataEntryReader in a JarReader, filtering it if necessary. 109 */ 110 private static DataEntryReader wrapInJarReader(DataEntryReader reader, 111 boolean isJar, 112 List jarFilter, 113 String jarExtension) 114 { 115 // Unzip any jars, if necessary. 116 DataEntryReader jarReader = new JarReader(reader); 117 118 if (isJar) 119 { 120 // Always unzip. 121 return jarReader; 122 } 123 else 124 { 125 // Add a filter, if specified. 126 if (jarFilter != null) 127 { 128 jarReader = new FilteredDataEntryReader( 129 new DataEntryNameFilter( 130 new ListParser(new FileNameParser()).parse(jarFilter)), 131 jarReader); 132 } 133 134 // Only unzip the right type of jars. 135 return new FilteredDataEntryReader( 136 new DataEntryNameFilter( 137 new ExtensionMatcher(jarExtension)), 138 jarReader, 139 reader); 140 } 141 } 142 143 144 /** 145 * Returns whether the given string ends with the given suffix, ignoring its 146 * case. 147 */ 148 private static boolean endsWithIgnoreCase(String string, String suffix) 149 { 150 int stringLength = string.length(); 151 int suffixLength = suffix.length(); 152 153 return string.regionMatches(true, stringLength - suffixLength, suffix, 0, suffixLength); 154 } 155} 156