1b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/* 2b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ProGuard -- shrinking, optimization, obfuscation, and preverification 3b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * of Java bytecode. 4b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 5b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu) 6b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 7b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This program is free software; you can redistribute it and/or modify it 8b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * under the terms of the GNU General Public License as published by the Free 9b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Software Foundation; either version 2 of the License, or (at your option) 10b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * any later version. 11b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 12b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This program is distributed in the hope that it will be useful, but WITHOUT 13b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * more details. 16b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 17b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * You should have received a copy of the GNU General Public License along 18b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * with this program; if not, write to the Free Software Foundation, Inc., 19b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 21b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopackage proguard.io; 22b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 23b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.*; 24b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.io.*; 25b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.util.*; 26b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.visitor.ClassVisitor; 27b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 28b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport java.io.*; 29b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 30b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/** 31b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This DataEntryReader applies a given ClassVisitor to the class 32b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * definitions that it reads. 33b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * <p> 34b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Class files are read as ProgramClass objects or LibraryClass objects, 35b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * depending on the <code>isLibrary</code> flag. 36b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * <p> 37b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * In case of libraries, only public classes are considered, if the 38b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * <code>skipNonPublicLibraryClasses</code> flag is set. 39b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * 40b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @author Eric Lafortune 41b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 42b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopublic class ClassReader implements DataEntryReader 43b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato{ 44b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private final boolean isLibrary; 45b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private final boolean skipNonPublicLibraryClasses; 46b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private final boolean skipNonPublicLibraryClassMembers; 47b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private final WarningPrinter warningPrinter; 48b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato private final ClassVisitor classVisitor; 49b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 50b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 51b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato /** 52b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Creates a new DataEntryClassFilter for reading the specified 53b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Clazz objects. 54b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */ 55b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public ClassReader(boolean isLibrary, 56b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato boolean skipNonPublicLibraryClasses, 57b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato boolean skipNonPublicLibraryClassMembers, 58b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato WarningPrinter warningPrinter, 59b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato ClassVisitor classVisitor) 60b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 61b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.isLibrary = isLibrary; 62b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.skipNonPublicLibraryClasses = skipNonPublicLibraryClasses; 63b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.skipNonPublicLibraryClassMembers = skipNonPublicLibraryClassMembers; 64b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.warningPrinter = warningPrinter; 65b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato this.classVisitor = classVisitor; 66b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 67b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 68b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 69b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Implementations for DataEntryReader. 70b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 71b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato public void read(DataEntry dataEntry) throws IOException 72b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 73b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato try 74b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 75b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Get the input stream. 76b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato InputStream inputStream = dataEntry.getInputStream(); 77b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 78b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Wrap it into a data input stream. 79b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato DataInputStream dataInputStream = new DataInputStream(inputStream); 80b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 81b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Create a Clazz representation. 82b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato Clazz clazz; 83b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (isLibrary) 84b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 85b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato clazz = new LibraryClass(); 86b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato clazz.accept(new LibraryClassReader(dataInputStream, skipNonPublicLibraryClasses, skipNonPublicLibraryClassMembers)); 87b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 88b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato else 89b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 90b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato clazz = new ProgramClass(); 91b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato clazz.accept(new ProgramClassReader(dataInputStream)); 92b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 93b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 94b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato // Apply the visitor, if we have a real class. 95b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato String className = clazz.getName(); 96b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (className != null) 97b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 98b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato if (!dataEntry.getName().replace(File.pathSeparatorChar, ClassConstants.INTERNAL_PACKAGE_SEPARATOR).equals(className+ClassConstants.CLASS_FILE_EXTENSION) && 99b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato warningPrinter != null) 100b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 101b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato warningPrinter.print(className, 102b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato "Warning: class [" + dataEntry.getName() + "] unexpectedly contains class [" + ClassUtil.externalClassName(className) + "]"); 103b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 104b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 105b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato clazz.accept(classVisitor); 106b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 107b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato 108b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato dataEntry.closeInputStream(); 109b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 110b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato catch (Exception ex) 111b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato { 112b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang throw (IOException)new IOException("Can't process class ["+dataEntry.getName()+"] ("+ex.getMessage()+")").initCause(ex); 113b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 114b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato } 115b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato} 116