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
232270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstromimport proguard.classfile.*;
242270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstromimport proguard.classfile.attribute.visitor.AllAttributeVisitor;
252270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstromimport proguard.classfile.editor.*;
26b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.classfile.visitor.*;
27b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.obfuscate.Obfuscator;
282270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstromimport proguard.optimize.Optimizer;
29b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.preverify.*;
30b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport proguard.shrink.Shrinker;
31b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
32b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratoimport java.io.*;
33b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
34b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato/**
35b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * Tool for shrinking, optimizing, obfuscating, and preverifying Java classes.
36b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato *
37b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato * @author Eric Lafortune
38b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato */
39b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onoratopublic class ProGuard
40b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato{
412270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom    public static final String VERSION = "ProGuard, version 5.1";
42b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
43b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private final Configuration configuration;
44b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private       ClassPool     programClassPool = new ClassPool();
45b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private final ClassPool     libraryClassPool = new ClassPool();
46b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
47b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
48b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
49b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Creates a new ProGuard object to process jars as specified by the given
50b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * configuration.
51b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
52b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public ProGuard(Configuration configuration)
53b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
54b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        this.configuration = configuration;
55b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
56b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
57b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
58b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
59b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Performs all subsequent ProGuard operations.
60b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
61b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public void execute() throws IOException
62b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
63b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        System.out.println(VERSION);
64b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
65b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        GPL.check();
66b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
67b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (configuration.printConfiguration != null)
68b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
69b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            printConfiguration();
70b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
71b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
722270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom        new ConfigurationChecker(configuration).check();
732270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom
74b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (configuration.programJars != null     &&
75b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            configuration.programJars.hasOutput() &&
76b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            new UpToDateChecker(configuration).check())
77b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
78b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            return;
79b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
80b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
81b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        readInput();
82b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
832270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom        if (configuration.shrink    ||
842270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom            configuration.optimize  ||
852270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom            configuration.obfuscate ||
862270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom            configuration.preverify)
872270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom        {
882270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom            clearPreverification();
892270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom        }
902270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom
91b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        if (configuration.printSeeds != null ||
92b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            configuration.shrink    ||
93b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            configuration.optimize  ||
94b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            configuration.obfuscate ||
95b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            configuration.preverify)
96b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
97b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            initialize();
98b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
99b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
100b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (configuration.targetClassVersion != 0)
101b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
102b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            target();
103b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
104b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
105b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (configuration.printSeeds != null)
106b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
107b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            printSeeds();
108b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
109b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
110b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (configuration.shrink)
111b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
112b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            shrink();
113b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
114b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
115b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (configuration.preverify)
116b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
117b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            inlineSubroutines();
118b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
119b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
120b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (configuration.optimize)
121b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
122b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            for (int optimizationPass = 0;
123b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                 optimizationPass < configuration.optimizationPasses;
124b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                 optimizationPass++)
125b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
126b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                if (!optimize())
127b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                {
128b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    // Stop optimizing if the code doesn't improve any further.
129b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    break;
130b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                }
131b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
132b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                // Shrink again, if we may.
133b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                if (configuration.shrink)
134b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                {
135b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    // Don't print any usage this time around.
136b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    configuration.printUsage       = null;
137b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    configuration.whyAreYouKeeping = null;
138b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
139b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                    shrink();
140b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                }
141b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
142b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
143b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
144b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (configuration.obfuscate)
145b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
146b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            obfuscate();
147b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
148b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
149b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (configuration.preverify)
150b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
151b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            preverify();
152b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
153b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
154b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (configuration.shrink    ||
155b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            configuration.optimize  ||
156b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            configuration.obfuscate ||
157b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            configuration.preverify)
158b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
159b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            sortClassElements();
160b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
161b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
162b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (configuration.programJars.hasOutput())
163b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
164b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            writeOutput();
165b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
166b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
167b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (configuration.dump != null)
168b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
169b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            dump();
170b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
171b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
172b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
173b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
174b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
175b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Prints out the configuration that ProGuard is using.
176b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
177b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private void printConfiguration() throws IOException
178b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
179b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (configuration.verbose)
180b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
181b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.out.println("Printing configuration to [" + fileName(configuration.printConfiguration) + "]...");
182b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
183b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
184b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        PrintStream ps = createPrintStream(configuration.printConfiguration);
185b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        try
186b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
187b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            new ConfigurationWriter(ps).write(configuration);
188b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
189b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        finally
190b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
191b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            closePrintStream(ps);
192b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
193b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
194b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
195b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
196b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
197b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Reads the input class files.
198b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
199b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private void readInput() throws IOException
200b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
201b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (configuration.verbose)
202b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
203b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.out.println("Reading input...");
204b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
205b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
206b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Fill the program class pool and the library class pool.
207b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        new InputReader(configuration).execute(programClassPool, libraryClassPool);
208b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
209b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
210b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
211b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
212b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Initializes the cross-references between all classes, performs some
213b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * basic checks, and shrinks the library class pool.
214b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
215b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private void initialize() throws IOException
216b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
217b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (configuration.verbose)
218b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
219b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.out.println("Initializing...");
220b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
221b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
222b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        new Initializer(configuration).execute(programClassPool, libraryClassPool);
223b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
224b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
225b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
226b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
227b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Sets that target versions of the program classes.
228b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
229b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private void target() throws IOException
230b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
231b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (configuration.verbose)
232b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
233b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.out.println("Setting target versions...");
234b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
235b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
236b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        new Targeter(configuration).execute(programClassPool);
237b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
238b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
239b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
240b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
241b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Prints out classes and class members that are used as seeds in the
242b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * shrinking and obfuscation steps.
243b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
244b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private void printSeeds() throws IOException
245b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
246b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (configuration.verbose)
247b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
248b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.out.println("Printing kept classes, fields, and methods...");
249b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
250b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
251b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        PrintStream ps = createPrintStream(configuration.printSeeds);
252b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        try
253b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
254b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            new SeedPrinter(ps).write(configuration, programClassPool, libraryClassPool);
255b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
256b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        finally
257b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
258b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            closePrintStream(ps);
259b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
260b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
261b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
262b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
263b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
264b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Performs the shrinking step.
265b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
266b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private void shrink() throws IOException
267b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
268b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (configuration.verbose)
269b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
270b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.out.println("Shrinking...");
271b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
272b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // We'll print out some explanation, if requested.
273b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            if (configuration.whyAreYouKeeping != null)
274b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
275b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                System.out.println("Explaining why classes and class members are being kept...");
276b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
277b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
278b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // We'll print out the usage, if requested.
279b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            if (configuration.printUsage != null)
280b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
281b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                System.out.println("Printing usage to [" + fileName(configuration.printUsage) + "]...");
282b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
283b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
284b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
285b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Perform the actual shrinking.
286b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        programClassPool =
287b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            new Shrinker(configuration).execute(programClassPool, libraryClassPool);
288b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
289b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
290b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
291b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
292b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Performs the subroutine inlining step.
293b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
294b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private void inlineSubroutines()
295b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
296b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (configuration.verbose)
297b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
298b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.out.println("Inlining subroutines...");
299b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
300b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
301b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Perform the actual inlining.
302b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        new SubroutineInliner(configuration).execute(programClassPool);
303b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
304b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
305b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
306b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
307b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Performs the optimization step.
308b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
309b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private boolean optimize() throws IOException
310b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
311b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (configuration.verbose)
312b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
313b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.out.println("Optimizing...");
314b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
315b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
316b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Perform the actual optimization.
317b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        return new Optimizer(configuration).execute(programClassPool, libraryClassPool);
318b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
319b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
320b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
321b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
322b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Performs the obfuscation step.
323b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
324b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private void obfuscate() throws IOException
325b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
326b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (configuration.verbose)
327b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
328b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.out.println("Obfuscating...");
329b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
330b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // We'll apply a mapping, if requested.
331b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            if (configuration.applyMapping != null)
332b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
333b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                System.out.println("Applying mapping [" + fileName(configuration.applyMapping) + "]");
334b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
335b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
336b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // We'll print out the mapping, if requested.
337b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            if (configuration.printMapping != null)
338b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
339b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                System.out.println("Printing mapping to [" + fileName(configuration.printMapping) + "]...");
340b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
341b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
342b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
343b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Perform the actual obfuscation.
344b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        new Obfuscator(configuration).execute(programClassPool, libraryClassPool);
345b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
346b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
347b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
348b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
3492270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom     * Clears any JSE preverification information from the program classes.
3502270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom     */
3512270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom    private void clearPreverification()
3522270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom    {
3532270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom        programClassPool.classesAccept(
3542270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom            new ClassVersionFilter(ClassConstants.CLASS_VERSION_1_6,
3552270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom            new AllMethodVisitor(
3562270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom            new AllAttributeVisitor(
3572270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom            new NamedAttributeDeleter(ClassConstants.ATTR_StackMapTable)))));
3582270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom    }
3592270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom
3602270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom
3612270795fbe0b277bfd49f40950ecaa78583175ccBrian Carlstrom    /**
362b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Performs the preverification step.
363b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
364b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private void preverify()
365b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
366b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (configuration.verbose)
367b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
368b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.out.println("Preverifying...");
369b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
370b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
371b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Perform the actual preverification.
372b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        new Preverifier(configuration).execute(programClassPool);
373b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
374b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
375b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
376b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
377b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Sorts the elements of all program classes.
378b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
379b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private void sortClassElements()
380b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
381b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        programClassPool.classesAccept(new ClassElementSorter());
382b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
383b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
384b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
385b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
386b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Writes the output class files.
387b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
388b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private void writeOutput() throws IOException
389b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
390b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (configuration.verbose)
391b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
392b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.out.println("Writing output...");
393b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
394b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
395b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Write out the program class pool.
396b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        new OutputWriter(configuration).execute(programClassPool);
397b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
398b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
399b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
400b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
401b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Prints out the contents of the program classes.
402b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
403b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private void dump() throws IOException
404b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
405b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (configuration.verbose)
406b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
407b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.out.println("Printing classes to [" + fileName(configuration.dump) + "]...");
408b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
409b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
410b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        PrintStream ps = createPrintStream(configuration.dump);
411b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        try
412b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
413b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            programClassPool.classesAccept(new ClassPrinter(ps));
414b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
415b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        finally
416b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
417b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            closePrintStream(ps);
418b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
419b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
420b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
421b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
422b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
423b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Returns a print stream for the given file, or the standard output if
424b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * the file name is empty.
425b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
426b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private PrintStream createPrintStream(File file)
427b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    throws FileNotFoundException
428b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
429b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        return file == Configuration.STD_OUT ? System.out :
430b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            new PrintStream(
431b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            new BufferedOutputStream(
432b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            new FileOutputStream(file)));
433b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
434b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
435b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
436b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
437b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * Closes the given print stream, or closes it if is the standard output.
438b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * @param printStream
439b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
440b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private void closePrintStream(PrintStream printStream)
441b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
442b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (printStream == System.out)
443b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
444b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            printStream.flush();
445b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
446b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        else
447b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
448b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            printStream.close();
449b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
450b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
451b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
452b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
453b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
454b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang     * Returns the canonical file name for the given file, or "standard output"
455b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * if the file name is empty.
456b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
457b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    private String fileName(File file)
458b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
459b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        if (file == Configuration.STD_OUT)
460b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        {
461b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            return "standard output";
462b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        }
463b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        else
464b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        {
465b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            try
466b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            {
467b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                return file.getCanonicalPath();
468b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            }
469b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            catch (IOException ex)
470b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            {
471b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                return file.getPath();
472b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            }
473b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang        }
474b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
475b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
476b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
477b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    /**
478b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     * The main method for ProGuard.
479b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato     */
480b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    public static void main(String[] args)
481b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    {
482b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        if (args.length == 0)
483b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
484b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.out.println(VERSION);
485b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.out.println("Usage: java proguard.ProGuard [options ...]");
486b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.exit(1);
487b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
488b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
489b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        // Create the default options.
490b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        Configuration configuration = new Configuration();
491b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
492b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        try
493b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
494b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Parse the options specified in the command line arguments.
495b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang            ConfigurationParser parser = new ConfigurationParser(args,
496b9cc48a43ed984587c939d02fba5316bf5c0df6eYing Wang                                                                 System.getProperties());
497b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            try
498b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
499b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                parser.parse(configuration);
500b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
501b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            finally
502b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
503b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                parser.close();
504b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
505b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
506b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            // Execute ProGuard with these options.
507b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            new ProGuard(configuration).execute();
508b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
509b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        catch (Exception ex)
510b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        {
511b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            if (configuration.verbose)
512b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
513b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                // Print a verbose stack trace.
514b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                ex.printStackTrace();
515b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
516b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            else
517b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            {
518b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                // Print just the stack trace message.
519b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato                System.err.println("Error: "+ex.getMessage());
520b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            }
521b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
522b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato            System.exit(1);
523b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        }
524b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato
525b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato        System.exit(0);
526b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato    }
527b72c5c2e5482cf10117b2b25f642f7616b2326c3Joe Onorato}
528