1b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/*
2b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * ProGuard -- shrinking, optimization, obfuscation, and preverification
3b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *             of Java bytecode.
4b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
52270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom * Copyright (c) 2002-2014 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;
22b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
23b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.ClassPool;
24b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.util.WarningPrinter;
25b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.visitor.*;
26b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.io.*;
27b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
28b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport java.io.IOException;
29b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
30b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/**
31b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * This class reads the input class files.
32b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
33b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @author Eric Lafortune
34b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */
35b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopublic class InputReader
36b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato{
37b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private final Configuration configuration;
38b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
39b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
40b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
41b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Creates a new InputReader to read input class files as specified by the
42b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * given configuration.
43b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
44b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public InputReader(Configuration configuration)
45b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
46b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        this.configuration = configuration;
47b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
48b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
49b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
50b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
51b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Fills the given program class pool and library class pool by reading
52b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * class files, based on the current configuration.
53b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
54b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void execute(ClassPool programClassPool,
55b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                        ClassPool libraryClassPool) throws IOException
56b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
57b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        WarningPrinter warningPrinter = new WarningPrinter(System.err, configuration.warn);
58b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        WarningPrinter notePrinter    = new WarningPrinter(System.out, configuration.note);
59b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
60b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        DuplicateClassPrinter duplicateClassPrinter = new DuplicateClassPrinter(notePrinter);
61b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
62b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Read the program class files.
63b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Prepare a data entry reader to filter all classes,
64b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // which are then decoded to classes by a class reader,
65b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // which are then put in the class pool by a class pool filler.
66b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        readInput("Reading program ",
67b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                  configuration.programJars,
68b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                  new ClassFilter(
69b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                  new ClassReader(false,
70b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                  configuration.skipNonPublicLibraryClasses,
71b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                  configuration.skipNonPublicLibraryClassMembers,
72b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                  warningPrinter,
73b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                  new ClassPresenceFilter(programClassPool, duplicateClassPrinter,
74b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                  new ClassPoolFiller(programClassPool)))));
75b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
76b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Check if we have at least some input classes.
77b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (programClassPool.size() == 0)
78b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
79b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            throw new IOException("The input doesn't contain any classes. Did you specify the proper '-injars' options?");
80b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
81b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
82b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Read the library class files, if any.
83b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (configuration.libraryJars != null)
84b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
85b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Prepare a data entry reader to filter all classes,
86b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // which are then decoded to classes by a class reader,
87b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // which are then put in the class pool by a class pool filler.
88b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            readInput("Reading library ",
89b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                      configuration.libraryJars,
90b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                      new ClassFilter(
91b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                      new ClassReader(true,
92b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                      configuration.skipNonPublicLibraryClasses,
93b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                      configuration.skipNonPublicLibraryClassMembers,
94b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                      warningPrinter,
95b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                      new ClassPresenceFilter(programClassPool, duplicateClassPrinter,
96b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                      new ClassPresenceFilter(libraryClassPool, duplicateClassPrinter,
97b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                      new ClassPoolFiller(libraryClassPool))))));
98b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
99b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
100b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Print out a summary of the notes, if necessary.
101b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        int noteCount = notePrinter.getWarningCount();
102b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (noteCount > 0)
103b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
104b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.err.println("Note: there were " + noteCount +
105b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                               " duplicate class definitions.");
1062270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom            System.err.println("      (http://proguard.sourceforge.net/manual/troubleshooting.html#duplicateclass)");
107b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
108b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
109b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Print out a summary of the warnings, if necessary.
110b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        int warningCount = warningPrinter.getWarningCount();
111b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (warningCount > 0)
112b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
113b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.err.println("Warning: there were " + warningCount +
114b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                               " classes in incorrectly named files.");
115b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.err.println("         You should make sure all file names correspond to their class names.");
116b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.err.println("         The directory hierarchies must correspond to the package hierarchies.");
117b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            System.err.println("         (http://proguard.sourceforge.net/manual/troubleshooting.html#unexpectedclass)");
118b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
119b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            if (!configuration.ignoreWarnings)
120b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
121b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                System.err.println("         If you don't mind the mentioned classes not being written out,");
122b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                System.err.println("         you could try your luck using the '-ignorewarnings' option.");
123b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                throw new IOException("Please correct the above warnings first.");
124b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
125b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
126b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
127b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
128b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
129b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
130b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Reads all input entries from the given class path.
131b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
132b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private void readInput(String          messagePrefix,
133b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                           ClassPath       classPath,
134b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                           DataEntryReader reader) throws IOException
135b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
136b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        readInput(messagePrefix,
137b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                  classPath,
138b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                  0,
139b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                  classPath.size(),
140b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                  reader);
141b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
142b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
143b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
144b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
145b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Reads all input entries from the given section of the given class path.
146b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
147b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void readInput(String          messagePrefix,
148b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                          ClassPath       classPath,
149b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                          int             fromIndex,
150b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                          int             toIndex,
151b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                          DataEntryReader reader) throws IOException
152b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
153b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        for (int index = fromIndex; index < toIndex; index++)
154b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
155b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            ClassPathEntry entry = classPath.get(index);
156b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            if (!entry.isOutput())
157b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
158b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                readInput(messagePrefix, entry, reader);
159b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
160b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
161b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
162b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
163b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
164b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
165b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Reads the given input class path entry.
166b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
167b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private void readInput(String          messagePrefix,
168b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                           ClassPathEntry  classPathEntry,
169b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                           DataEntryReader dataEntryReader) throws IOException
170b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
171b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        try
172b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
173b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Create a reader that can unwrap jars, wars, ears, and zips.
174b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            DataEntryReader reader =
175b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                DataEntryReaderFactory.createDataEntryReader(messagePrefix,
176b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                             classPathEntry,
177b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                                                             dataEntryReader);
178b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
179b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Create the data entry pump.
180b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            DirectoryPump directoryPump =
181b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                new DirectoryPump(classPathEntry.getFile());
182b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
183b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Pump the data entries into the reader.
184b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            directoryPump.pumpDataEntries(reader);
185b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
186b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        catch (IOException ex)
187b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
188b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            throw (IOException)new IOException("Can't read [" + classPathEntry + "] (" + ex.getMessage() + ")").initCause(ex);
189b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
190b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
191b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato}
192