1/* 2 * ProGuard -- shrinking, optimization, obfuscation, and preverification 3 * of Java bytecode. 4 * 5 * Copyright (c) 2002-2009 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 */ 21package proguard.gui; 22 23import proguard.retrace.ReTrace; 24 25import javax.swing.*; 26import java.awt.*; 27import 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 */ 37final 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 */ 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 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 */ 145 private String msg(String messageKey) 146 { 147 return GUIResources.getMessage(messageKey); 148 } 149} 150