• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
3  *             of Java bytecode.
4  *
5  * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the Free
9  * Software Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */
21 package proguard.gui;
22 
23 import proguard.retrace.ReTrace;
24 
25 import javax.swing.*;
26 import java.awt.*;
27 import java.io.*;
28 
29 
30 /**
31  * This <code>Runnable</code> runs ReTrace, sending console output to a text
32  * area and any exceptions to message dialogs.
33  *
34  * @see ReTrace
35  * @author Eric Lafortune
36  */
37 final class ReTraceRunnable implements Runnable
38 {
39     private final JTextArea consoleTextArea;
40     private final boolean   verbose;
41     private final File      mappingFile;
42     private final String    stackTrace;
43 
44 
45     /**
46      * Creates a new ProGuardRunnable object.
47      * @param consoleTextArea the text area to send the console output to.
48      * @param verbose         specifies whether the de-obfuscated stack trace
49      *                        should be verbose.
50      * @param mappingFile     the mapping file that was written out by ProGuard.
51      */
ReTraceRunnable(JTextArea consoleTextArea, boolean verbose, File mappingFile, String stackTrace)52     public ReTraceRunnable(JTextArea consoleTextArea,
53                            boolean   verbose,
54                            File      mappingFile,
55                            String    stackTrace)
56     {
57         this.consoleTextArea = consoleTextArea;
58         this.verbose         = verbose;
59         this.mappingFile     = mappingFile;
60         this.stackTrace      = stackTrace;
61     }
62 
63 
64     // Implementation for Runnable.
65 
run()66     public void run()
67     {
68         consoleTextArea.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
69         consoleTextArea.setText("");
70 
71         // Redirect the stack trace string to the System's in stream, and the
72         // out and err streams to the console text area.
73         InputStream oldIn  = System.in;
74         PrintStream oldOut = System.out;
75         PrintStream oldErr = System.err;
76 
77         ByteArrayInputStream inputStream =
78            new ByteArrayInputStream(stackTrace.getBytes());
79 
80         PrintStream printStream =
81             new PrintStream(new TextAreaOutputStream(consoleTextArea), true);
82 
83         System.setIn(inputStream);
84         System.setOut(printStream);
85         System.setErr(printStream);
86 
87         try
88         {
89             // Create a new ProGuard object with the GUI's configuration.
90             ReTrace reTrace = new ReTrace(ReTrace.STACK_TRACE_EXPRESSION,
91                                           verbose,
92                                           mappingFile);
93 
94             // Run it.
95             reTrace.execute();
96         }
97         catch (Exception ex)
98         {
99             // Print out the exception message.
100             System.out.println(ex.getMessage());
101 
102             // Show a dialog as well.
103             MessageDialogRunnable.showMessageDialog(consoleTextArea,
104                                                     ex.getMessage(),
105                                                     msg("errorReTracing"),
106                                                     JOptionPane.ERROR_MESSAGE);
107         }
108         catch (OutOfMemoryError er)
109         {
110             // Forget about the ProGuard object as quickly as possible.
111             System.gc();
112 
113             // Print out a message suggesting what to do next.
114             System.out.println(msg("outOfMemory"));
115 
116             // Show a dialog as well.
117             MessageDialogRunnable.showMessageDialog(consoleTextArea,
118                                                     msg("outOfMemory"),
119                                                     msg("errorReTracing"),
120                                                     JOptionPane.ERROR_MESSAGE);
121         }
122 
123         // Make sure all output has been sent to the console text area.
124         printStream.flush();
125 
126         // Restore the old System's in, out, and err streams.
127         System.setIn(oldIn);
128         System.setOut(oldOut);
129         System.setErr(oldErr);
130 
131         consoleTextArea.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
132         consoleTextArea.setCaretPosition(0);
133 
134         // Reset the global static redirection lock.
135         ProGuardGUI.systemOutRedirected = false;
136     }
137 
138 
139     // Small utility methods.
140 
141     /**
142      * Returns the message from the GUI resources that corresponds to the given
143      * key.
144      */
msg(String messageKey)145     private String msg(String messageKey)
146     {
147          return GUIResources.getMessage(messageKey);
148     }
149 }
150