Home | History | Annotate | Download | only in gui
      1 /*
      2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
      3  *             of Java bytecode.
      4  *
      5  * Copyright (c) 2002-2009 Eric Lafortune (eric (at) 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      */
     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