001: /*
002: * ProGuard -- shrinking, optimization, obfuscation, and preverification
003: * of Java bytecode.
004: *
005: * Copyright (c) 2002-2007 Eric Lafortune (eric@graphics.cornell.edu)
006: *
007: * This program is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU General Public License as published by the Free
009: * Software Foundation; either version 2 of the License, or (at your option)
010: * any later version.
011: *
012: * This program is distributed in the hope that it will be useful, but WITHOUT
013: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
015: * more details.
016: *
017: * You should have received a copy of the GNU General Public License along
018: * with this program; if not, write to the Free Software Foundation, Inc.,
019: * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: */
021: package proguard.gui;
022:
023: import proguard.retrace.ReTrace;
024:
025: import javax.swing.*;
026: import java.awt.*;
027: import java.io.*;
028:
029: /**
030: * This <code>Runnable</code> runs ReTrace, sending console output to a text
031: * area and any exceptions to message dialogs.
032: *
033: * @see ReTrace
034: * @author Eric Lafortune
035: */
036: final class ReTraceRunnable implements Runnable {
037: private final JTextArea consoleTextArea;
038: private final boolean verbose;
039: private final File mappingFile;
040: private final String stackTrace;
041:
042: /**
043: * Creates a new ProGuardRunnable object.
044: * @param consoleTextArea the text area to send the console output to.
045: * @param verbose specifies whether the de-obfuscated stack trace
046: * should be verbose.
047: * @param mappingFile the mapping file that was written out by ProGuard.
048: */
049: public ReTraceRunnable(JTextArea consoleTextArea, boolean verbose,
050: File mappingFile, String stackTrace) {
051: this .consoleTextArea = consoleTextArea;
052: this .verbose = verbose;
053: this .mappingFile = mappingFile;
054: this .stackTrace = stackTrace;
055: }
056:
057: // Implementation for Runnable.
058:
059: public void run() {
060: consoleTextArea.setCursor(Cursor
061: .getPredefinedCursor(Cursor.WAIT_CURSOR));
062: consoleTextArea.setText("");
063:
064: // Redirect the stack trace string to the System's in stream, and the
065: // out and err streams to the console text area.
066: InputStream oldIn = System.in;
067: PrintStream oldOut = System.out;
068: PrintStream oldErr = System.err;
069:
070: ByteArrayInputStream inputStream = new ByteArrayInputStream(
071: stackTrace.getBytes());
072:
073: PrintStream printStream = new PrintStream(
074: new TextAreaOutputStream(consoleTextArea), true);
075:
076: System.setIn(inputStream);
077: System.setOut(printStream);
078: System.setErr(printStream);
079:
080: try {
081: // Create a new ProGuard object with the GUI's configuration.
082: ReTrace reTrace = new ReTrace(verbose, mappingFile);
083:
084: // Run it.
085: reTrace.execute();
086: } catch (Exception ex) {
087: // Print out the exception message.
088: System.out.println(ex.getMessage());
089:
090: // Show a dialog as well.
091: MessageDialogRunnable.showMessageDialog(consoleTextArea, ex
092: .getMessage(), msg("errorReTracing"),
093: JOptionPane.ERROR_MESSAGE);
094: } catch (OutOfMemoryError er) {
095: // Forget about the ProGuard object as quickly as possible.
096: System.gc();
097:
098: // Print out a message suggesting what to do next.
099: System.out.println(msg("outOfMemory"));
100:
101: // Show a dialog as well.
102: MessageDialogRunnable.showMessageDialog(consoleTextArea,
103: msg("outOfMemory"), msg("errorReTracing"),
104: JOptionPane.ERROR_MESSAGE);
105: }
106:
107: // Make sure all output has been sent to the console text area.
108: printStream.flush();
109:
110: // Restore the old System's in, out, and err streams.
111: System.setIn(oldIn);
112: System.setOut(oldOut);
113: System.setErr(oldErr);
114:
115: consoleTextArea.setCursor(Cursor
116: .getPredefinedCursor(Cursor.DEFAULT_CURSOR));
117: consoleTextArea.setCaretPosition(0);
118:
119: // Reset the global static redirection lock.
120: ProGuardGUI.systemOutRedirected = false;
121: }
122:
123: // Small utility methods.
124:
125: /**
126: * Returns the message from the GUI resources that corresponds to the given
127: * key.
128: */
129: private String msg(String messageKey) {
130: return GUIResources.getMessage(messageKey);
131: }
132: }
|