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