Decompiler, JodeApplet and JodeWindow moved into decompile package makeDeclaration now transmits the done set over class borders git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@1201 379699f6-c40d-0410-875b-85095c16579ebranch_1_1
parent
47b22fdb21
commit
c5b840847b
@ -0,0 +1,41 @@ |
|||||||
|
/* Applet Copyright (C) 1999 Jochen Hoenicke. |
||||||
|
* |
||||||
|
* This program is free software; you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU General Public License as published by |
||||||
|
* the Free Software Foundation; either version 2, or (at your option) |
||||||
|
* any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU General Public License |
||||||
|
* along with this program; see the file COPYING. If not, write to |
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. |
||||||
|
* |
||||||
|
* $Id$ |
||||||
|
*/ |
||||||
|
|
||||||
|
package jode.decompiler; |
||||||
|
|
||||||
|
public class Applet extends java.applet.Applet { |
||||||
|
Window jodeWin = new Window(this); |
||||||
|
|
||||||
|
///#ifdef AWT10
|
||||||
|
/// public boolean action(Event e, Object arg) {
|
||||||
|
/// jodeWin.action(e, arg);
|
||||||
|
/// return true;
|
||||||
|
/// }
|
||||||
|
///#endif
|
||||||
|
|
||||||
|
public void init() { |
||||||
|
String cp = getParameter("classpath"); |
||||||
|
if (cp != null) |
||||||
|
jodeWin.setClasspath(cp); |
||||||
|
String cls = getParameter("class"); |
||||||
|
if (cls != null) |
||||||
|
jodeWin.setClass(cls); |
||||||
|
} |
||||||
|
} |
||||||
|
|
@ -0,0 +1,328 @@ |
|||||||
|
/* Main Copyright (C) 1998-1999 Jochen Hoenicke. |
||||||
|
* |
||||||
|
* This program is free software; you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU General Public License as published by |
||||||
|
* the Free Software Foundation; either version 2, or (at your option) |
||||||
|
* any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU General Public License |
||||||
|
* along with this program; see the file COPYING. If not, write to |
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. |
||||||
|
* |
||||||
|
* $Id$ |
||||||
|
*/ |
||||||
|
|
||||||
|
package jode.decompiler; |
||||||
|
import jode.bytecode.ClassInfo; |
||||||
|
import jode.bytecode.SearchPath; |
||||||
|
import jode.GlobalOptions; |
||||||
|
|
||||||
|
import java.io.BufferedOutputStream; |
||||||
|
import java.io.File; |
||||||
|
import java.io.FileOutputStream; |
||||||
|
import java.io.IOException; |
||||||
|
import java.io.PrintWriter; |
||||||
|
import java.util.zip.ZipOutputStream; |
||||||
|
import java.util.zip.ZipEntry; |
||||||
|
|
||||||
|
import gnu.getopt.LongOpt; |
||||||
|
import gnu.getopt.Getopt; |
||||||
|
|
||||||
|
|
||||||
|
public class Main extends Options { |
||||||
|
private static final int OPTION_START=0x10000; |
||||||
|
private static final int OPTION_END =0x20000; |
||||||
|
|
||||||
|
private static final LongOpt[] longOptions = new LongOpt[] { |
||||||
|
new LongOpt("cp", LongOpt.REQUIRED_ARGUMENT, null, 'c'), |
||||||
|
new LongOpt("classpath", LongOpt.REQUIRED_ARGUMENT, null, 'c'), |
||||||
|
new LongOpt("dest", LongOpt.REQUIRED_ARGUMENT, null, 'd'), |
||||||
|
new LongOpt("help", LongOpt.NO_ARGUMENT, null, 'h'), |
||||||
|
new LongOpt("version", LongOpt.NO_ARGUMENT, null, 'V'), |
||||||
|
new LongOpt("verbose", LongOpt.OPTIONAL_ARGUMENT, null, 'v'), |
||||||
|
new LongOpt("debug", LongOpt.OPTIONAL_ARGUMENT, null, 'D'), |
||||||
|
new LongOpt("import", LongOpt.REQUIRED_ARGUMENT, null, 'i'), |
||||||
|
new LongOpt("style", LongOpt.REQUIRED_ARGUMENT, null, 's'), |
||||||
|
new LongOpt("lvt", LongOpt.OPTIONAL_ARGUMENT, null, |
||||||
|
OPTION_START+0), |
||||||
|
new LongOpt("inner", LongOpt.OPTIONAL_ARGUMENT, null, |
||||||
|
OPTION_START+1), |
||||||
|
new LongOpt("anonymous", LongOpt.OPTIONAL_ARGUMENT, null, |
||||||
|
OPTION_START+2), |
||||||
|
new LongOpt("push", LongOpt.OPTIONAL_ARGUMENT, null, |
||||||
|
OPTION_START+3), |
||||||
|
new LongOpt("pretty", LongOpt.OPTIONAL_ARGUMENT, null, |
||||||
|
OPTION_START+4), |
||||||
|
new LongOpt("decrypt", LongOpt.OPTIONAL_ARGUMENT, null, |
||||||
|
OPTION_START+5), |
||||||
|
new LongOpt("onetime", LongOpt.OPTIONAL_ARGUMENT, null, |
||||||
|
OPTION_START+6), |
||||||
|
new LongOpt("immediate", LongOpt.OPTIONAL_ARGUMENT, null, |
||||||
|
OPTION_START+7), |
||||||
|
new LongOpt("verify", LongOpt.OPTIONAL_ARGUMENT, null, |
||||||
|
OPTION_START+8), |
||||||
|
new LongOpt("contrafo", LongOpt.OPTIONAL_ARGUMENT, null, |
||||||
|
OPTION_START+9) |
||||||
|
}; |
||||||
|
|
||||||
|
public static void usage() { |
||||||
|
PrintWriter err = GlobalOptions.err; |
||||||
|
err.println("Version: " + GlobalOptions.version); |
||||||
|
err.println("Usage: java jode.decompiler.Main [OPTIONS]... [CLASSES]..."); |
||||||
|
err.println(" -h, --help "+ |
||||||
|
"show this information."); |
||||||
|
err.println(" -V, --version "+ |
||||||
|
"output version information and exit."); |
||||||
|
err.println(" -v, --verbose "+ |
||||||
|
"be verbose (multiple times means more verbose)."); |
||||||
|
err.println(" -c, --classpath <path> "+ |
||||||
|
"search for classes in specified classpath."); |
||||||
|
err.println(" "+ |
||||||
|
"The directories should be separated by ','."); |
||||||
|
err.println(" -d, --dest <dir> "+ |
||||||
|
"write decompiled files to disk into directory destdir."); |
||||||
|
err.println(" -s, --style {sun|gnu} "+ |
||||||
|
"specify indentation style"); |
||||||
|
err.println(" -i, --import <pkglimit>,<clslimit>"); |
||||||
|
err.println(" "+ |
||||||
|
"import classes used more than clslimit times"); |
||||||
|
err.println(" "+ |
||||||
|
"and packages with more then pkglimit used classes."); |
||||||
|
err.println(" "+ |
||||||
|
"Limit 0 means, never import, default is 0,1."); |
||||||
|
|
||||||
|
err.println("The following options can be turned on or off with `yes' or `no' argument."); |
||||||
|
err.println(" --inner "+ |
||||||
|
"decompile inner classes (default)."); |
||||||
|
err.println(" --anonymous "+ |
||||||
|
"decompile anonymous classes (default)."); |
||||||
|
err.println(" --contrafo "+ |
||||||
|
"transform constructors of inner classes (default)."); |
||||||
|
err.println(" --lvt "+ |
||||||
|
"use the local variable table (default)."); |
||||||
|
err.println(" --pretty "+ |
||||||
|
"use `pretty' names for local variables."); |
||||||
|
err.println(" --push "+ |
||||||
|
"allow PUSH instructions in output."); |
||||||
|
err.println(" --decrypt "+ |
||||||
|
"decrypt encrypted strings (default)."); |
||||||
|
err.println(" --onetime "+ |
||||||
|
"remove locals, that are used only one time."); |
||||||
|
err.println(" --immediate "+ |
||||||
|
"output source immediately (may produce buggy code)."); |
||||||
|
err.println(" --verify "+ |
||||||
|
"verify code before decompiling it."); |
||||||
|
err.println("Debugging options, mainly used to debug this decompiler:"); |
||||||
|
err.println(" -D, --debug=... "+ |
||||||
|
"use --debug=help for more information."); |
||||||
|
} |
||||||
|
|
||||||
|
public static boolean handleOption(int option, int longind, String arg) { |
||||||
|
if (arg == null) |
||||||
|
options ^= 1 << option; |
||||||
|
else if ("yes".startsWith(arg) || arg.equals("on")) |
||||||
|
options |= 1 << option; |
||||||
|
else if ("no".startsWith(arg) || arg.equals("off")) |
||||||
|
options &= ~(1 << option); |
||||||
|
else { |
||||||
|
GlobalOptions.err.println |
||||||
|
("jode.decompiler.Main: option --"+longOptions[longind].getName() |
||||||
|
+" takes one of `yes', `no', `on', `off' as parameter"); |
||||||
|
return false; |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
public static void main(String[] params) { |
||||||
|
if (params.length == 0) { |
||||||
|
usage(); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
String classPath = System.getProperty("java.class.path") |
||||||
|
.replace(File.pathSeparatorChar, SearchPath.altPathSeparatorChar); |
||||||
|
String destDir = null; |
||||||
|
|
||||||
|
int importPackageLimit = ImportHandler.DEFAULT_PACKAGE_LIMIT; |
||||||
|
int importClassLimit = ImportHandler.DEFAULT_CLASS_LIMIT;; |
||||||
|
|
||||||
|
GlobalOptions.err.println(GlobalOptions.copyright); |
||||||
|
|
||||||
|
boolean errorInParams = false; |
||||||
|
Getopt g = new Getopt("jode.decompiler.Main", params, "hVvc:d:D:i:s:", |
||||||
|
longOptions, true); |
||||||
|
for (int opt = g.getopt(); opt != -1; opt = g.getopt()) { |
||||||
|
switch(opt) { |
||||||
|
case 0: |
||||||
|
break; |
||||||
|
case 'h': |
||||||
|
usage(); |
||||||
|
errorInParams = true; |
||||||
|
break; |
||||||
|
case 'V': |
||||||
|
GlobalOptions.err.println(GlobalOptions.version); |
||||||
|
break; |
||||||
|
case 'c': |
||||||
|
classPath = g.getOptarg(); |
||||||
|
break; |
||||||
|
case 'd': |
||||||
|
destDir = g.getOptarg(); |
||||||
|
break; |
||||||
|
case 'v': { |
||||||
|
String arg = g.getOptarg(); |
||||||
|
if (arg == null) |
||||||
|
GlobalOptions.verboseLevel++; |
||||||
|
else { |
||||||
|
try { |
||||||
|
GlobalOptions.verboseLevel = Integer.parseInt(arg); |
||||||
|
} catch (NumberFormatException ex) { |
||||||
|
GlobalOptions.err.println |
||||||
|
("jode.decompiler.Main: Argument `" |
||||||
|
+arg+"' to --verbose must be numeric:"); |
||||||
|
errorInParams = true; |
||||||
|
} |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
case 'D': { |
||||||
|
String arg = g.getOptarg(); |
||||||
|
if (arg == null) |
||||||
|
arg = "help"; |
||||||
|
errorInParams |= !GlobalOptions.setDebugging(arg); |
||||||
|
break; |
||||||
|
} |
||||||
|
case 's': { |
||||||
|
String arg = g.getOptarg(); |
||||||
|
if ("sun".startsWith(arg)) |
||||||
|
outputStyle = SUN_STYLE; |
||||||
|
else if ("gnu".startsWith(arg)) |
||||||
|
outputStyle = GNU_STYLE; |
||||||
|
else { |
||||||
|
GlobalOptions.err.println |
||||||
|
("jode.decompiler.Main: Unknown style `"+arg+"'."); |
||||||
|
errorInParams = true; |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
case 'i': { |
||||||
|
String arg = g.getOptarg(); |
||||||
|
int comma = arg.indexOf(','); |
||||||
|
try { |
||||||
|
int packLimit = Integer.parseInt(arg.substring(0, comma)); |
||||||
|
if (packLimit == 0) |
||||||
|
packLimit = Integer.MAX_VALUE; |
||||||
|
if (packLimit < 0) |
||||||
|
throw new IllegalArgumentException(); |
||||||
|
int clazzLimit = Integer.parseInt(arg.substring(comma+1)); |
||||||
|
if (clazzLimit == 0) |
||||||
|
clazzLimit = Integer.MAX_VALUE; |
||||||
|
if (clazzLimit < 0) |
||||||
|
throw new IllegalArgumentException(); |
||||||
|
|
||||||
|
importPackageLimit = packLimit; |
||||||
|
importClassLimit = clazzLimit; |
||||||
|
|
||||||
|
} catch (RuntimeException ex) { |
||||||
|
GlobalOptions.err.println |
||||||
|
("jode.decompiler.Main: Invalid argument for -i option."); |
||||||
|
errorInParams = true; |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
default: |
||||||
|
if (opt >= OPTION_START && opt <= OPTION_END) { |
||||||
|
errorInParams |= !handleOption(opt-OPTION_START, |
||||||
|
g.getLongind(), |
||||||
|
g.getOptarg()); |
||||||
|
} else |
||||||
|
errorInParams = true; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
if (errorInParams) |
||||||
|
return; |
||||||
|
ClassInfo.setClassPath(classPath.toString()); |
||||||
|
ImportHandler imports = new ImportHandler(importPackageLimit, |
||||||
|
importClassLimit); |
||||||
|
|
||||||
|
ZipOutputStream destZip = null; |
||||||
|
TabbedPrintWriter writer = null; |
||||||
|
if (destDir == null) |
||||||
|
writer = new TabbedPrintWriter(System.out, imports); |
||||||
|
else if (destDir.toLowerCase().endsWith(".zip") |
||||||
|
|| destDir.toLowerCase().endsWith(".jar")) { |
||||||
|
try { |
||||||
|
destZip = new ZipOutputStream(new FileOutputStream(destDir)); |
||||||
|
} catch (IOException ex) { |
||||||
|
GlobalOptions.err.println("Can't open zip file "+destDir); |
||||||
|
ex.printStackTrace(GlobalOptions.err); |
||||||
|
return; |
||||||
|
} |
||||||
|
writer = new TabbedPrintWriter(new BufferedOutputStream(destZip), |
||||||
|
imports, false); |
||||||
|
} |
||||||
|
for (int i= g.getOptind(); i< params.length; i++) { |
||||||
|
try { |
||||||
|
ClassInfo clazz; |
||||||
|
try { |
||||||
|
clazz = ClassInfo.forName(params[i]); |
||||||
|
} catch (IllegalArgumentException ex) { |
||||||
|
GlobalOptions.err.println |
||||||
|
("`"+params[i]+"' is not a class name"); |
||||||
|
continue; |
||||||
|
} |
||||||
|
if (skipClass(clazz)) |
||||||
|
continue; |
||||||
|
|
||||||
|
String filename = |
||||||
|
params[i].replace('.', File.separatorChar)+".java"; |
||||||
|
if (destZip != null) { |
||||||
|
writer.flush(); |
||||||
|
destZip.putNextEntry(new ZipEntry(filename)); |
||||||
|
} else if (destDir != null) { |
||||||
|
File file = new File (destDir, filename); |
||||||
|
File directory = new File(file.getParent()); |
||||||
|
if (!directory.exists() && !directory.mkdirs()) { |
||||||
|
GlobalOptions.err.println |
||||||
|
("Could not create directory " |
||||||
|
+ directory.getPath() + ", check permissions."); |
||||||
|
} |
||||||
|
writer = new TabbedPrintWriter |
||||||
|
(new BufferedOutputStream(new FileOutputStream(file)), |
||||||
|
imports, false); |
||||||
|
} |
||||||
|
|
||||||
|
GlobalOptions.err.println(params[i]); |
||||||
|
|
||||||
|
ClassAnalyzer clazzAna = new ClassAnalyzer(clazz, imports); |
||||||
|
clazzAna.dumpJavaFile(writer); |
||||||
|
|
||||||
|
if (destZip != null) { |
||||||
|
writer.flush(); |
||||||
|
destZip.closeEntry(); |
||||||
|
} else if (destDir != null) |
||||||
|
writer.close(); |
||||||
|
/* Now is a good time to clean up */ |
||||||
|
System.gc(); |
||||||
|
} catch (IOException ex) { |
||||||
|
GlobalOptions.err.println |
||||||
|
("Can't write source of "+params[i]+"."); |
||||||
|
GlobalOptions.err.println("Check the permissions."); |
||||||
|
ex.printStackTrace(GlobalOptions.err); |
||||||
|
} |
||||||
|
} |
||||||
|
if (destZip != null) { |
||||||
|
try { |
||||||
|
destZip.close(); |
||||||
|
} catch (IOException ex) { |
||||||
|
GlobalOptions.err.println("Can't close Zipfile"); |
||||||
|
ex.printStackTrace(GlobalOptions.err); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,66 @@ |
|||||||
|
/* Options Copyright (C) 1998-1999 Jochen Hoenicke. |
||||||
|
* |
||||||
|
* This program is free software; you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU General Public License as published by |
||||||
|
* the Free Software Foundation; either version 2, or (at your option) |
||||||
|
* any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU General Public License |
||||||
|
* along with this program; see the file COPYING. If not, write to |
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. |
||||||
|
* |
||||||
|
* $Id$ |
||||||
|
*/ |
||||||
|
|
||||||
|
package jode.decompiler; |
||||||
|
import jode.bytecode.ClassInfo; |
||||||
|
import jode.bytecode.InnerClassInfo; |
||||||
|
|
||||||
|
public class Options { |
||||||
|
public static final int TAB_SIZE_MASK = 0x0f; |
||||||
|
public static final int BRACE_AT_EOL = 0x10; |
||||||
|
public static final int SUN_STYLE = 0x14; |
||||||
|
public static final int GNU_STYLE = 0x02; |
||||||
|
|
||||||
|
public static final int OPTION_LVT = 0x0001; |
||||||
|
public static final int OPTION_INNER = 0x0002; |
||||||
|
public static final int OPTION_ANON = 0x0004; |
||||||
|
public static final int OPTION_PUSH = 0x0008; |
||||||
|
public static final int OPTION_PRETTY = 0x0010; |
||||||
|
public static final int OPTION_DECRYPT = 0x0020; |
||||||
|
public static final int OPTION_ONETIME = 0x0040; |
||||||
|
public static final int OPTION_IMMEDIATE = 0x0080; |
||||||
|
public static final int OPTION_VERIFY = 0x0100; |
||||||
|
public static final int OPTION_CONTRAFO = 0x0200; |
||||||
|
|
||||||
|
public static int options = |
||||||
|
OPTION_LVT | OPTION_INNER | OPTION_ANON | |
||||||
|
OPTION_DECRYPT | OPTION_VERIFY | OPTION_CONTRAFO; |
||||||
|
|
||||||
|
public static int outputStyle = SUN_STYLE; |
||||||
|
|
||||||
|
public final static boolean doAnonymous() { |
||||||
|
return (options & OPTION_ANON) != 0; |
||||||
|
} |
||||||
|
|
||||||
|
public final static boolean doInner() { |
||||||
|
return (options & OPTION_INNER) != 0; |
||||||
|
} |
||||||
|
|
||||||
|
public static boolean skipClass(ClassInfo clazz) { |
||||||
|
InnerClassInfo[] outers = clazz.getOuterClasses(); |
||||||
|
if (outers != null) { |
||||||
|
if (outers[0].outer == null) { |
||||||
|
return doAnonymous(); |
||||||
|
} else { |
||||||
|
return doInner(); |
||||||
|
} |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,310 @@ |
|||||||
|
/* Window Copyright (C) 1999 Jochen Hoenicke. |
||||||
|
* |
||||||
|
* This program is free software; you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU General Public License as published by |
||||||
|
* the Free Software Foundation; either version 2, or (at your option) |
||||||
|
* any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU General Public License |
||||||
|
* along with this program; see the file COPYING. If not, write to |
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. |
||||||
|
* |
||||||
|
* $Id$ |
||||||
|
*/ |
||||||
|
|
||||||
|
package jode.decompiler; |
||||||
|
import java.applet.*; |
||||||
|
import java.awt.*; |
||||||
|
///#ifndef AWT10
|
||||||
|
import java.awt.event.*; |
||||||
|
///#endif
|
||||||
|
import java.io.*; |
||||||
|
import jode.bytecode.ClassInfo; |
||||||
|
import jode.bytecode.SearchPath; |
||||||
|
import jode.GlobalOptions; |
||||||
|
|
||||||
|
public class Window |
||||||
|
implements Runnable |
||||||
|
///#ifndef AWT10
|
||||||
|
, ActionListener |
||||||
|
///#endif
|
||||||
|
|
||||||
|
{ |
||||||
|
TextField classpathField, classField; |
||||||
|
TextArea sourcecodeArea, errorArea; |
||||||
|
Checkbox verboseCheck, prettyCheck; |
||||||
|
Button startButton, saveButton; |
||||||
|
String lastClassName; |
||||||
|
Frame frame; |
||||||
|
|
||||||
|
Thread decompileThread; |
||||||
|
|
||||||
|
public Window(Container window) { |
||||||
|
buildComponents(window); |
||||||
|
} |
||||||
|
|
||||||
|
private void buildComponents(Container window) { |
||||||
|
if (window instanceof Frame) |
||||||
|
frame = (Frame) window; |
||||||
|
|
||||||
|
window.setFont(new Font("dialog", Font.PLAIN, 10)); |
||||||
|
|
||||||
|
classpathField = new TextField(50); |
||||||
|
classField = new TextField(50); |
||||||
|
sourcecodeArea = new TextArea(20, 80); |
||||||
|
errorArea = new TextArea(3, 80); |
||||||
|
verboseCheck = new Checkbox("verbose", false); |
||||||
|
prettyCheck = new Checkbox("pretty", false); |
||||||
|
startButton = new Button("start"); |
||||||
|
saveButton = new Button("save"); |
||||||
|
///#ifdef AWT10
|
||||||
|
/// saveButton.disable();
|
||||||
|
///#else
|
||||||
|
saveButton.setEnabled(false); |
||||||
|
///#endif
|
||||||
|
|
||||||
|
sourcecodeArea.setEditable(false); |
||||||
|
errorArea.setEditable(false); |
||||||
|
Font monospaced = new Font("monospaced", Font.PLAIN, 10); |
||||||
|
sourcecodeArea.setFont(monospaced); |
||||||
|
errorArea.setFont(monospaced); |
||||||
|
|
||||||
|
GridBagLayout gbl = new GridBagLayout(); |
||||||
|
window.setLayout(gbl); |
||||||
|
GridBagConstraints labelConstr = new GridBagConstraints(); |
||||||
|
GridBagConstraints textConstr = new GridBagConstraints(); |
||||||
|
GridBagConstraints areaConstr = new GridBagConstraints(); |
||||||
|
GridBagConstraints checkConstr = new GridBagConstraints(); |
||||||
|
GridBagConstraints buttonConstr = new GridBagConstraints(); |
||||||
|
labelConstr.fill = GridBagConstraints.NONE; |
||||||
|
textConstr.fill = GridBagConstraints.HORIZONTAL; |
||||||
|
areaConstr.fill = GridBagConstraints.BOTH; |
||||||
|
checkConstr.fill = GridBagConstraints.NONE; |
||||||
|
buttonConstr.fill = GridBagConstraints.NONE; |
||||||
|
labelConstr.anchor = GridBagConstraints.EAST; |
||||||
|
textConstr.anchor = GridBagConstraints.CENTER; |
||||||
|
checkConstr.anchor = GridBagConstraints.WEST; |
||||||
|
buttonConstr.anchor = GridBagConstraints.CENTER; |
||||||
|
labelConstr.anchor = GridBagConstraints.EAST; |
||||||
|
textConstr.gridwidth = GridBagConstraints.REMAINDER; |
||||||
|
textConstr.weightx = 1.0; |
||||||
|
areaConstr.gridwidth = GridBagConstraints.REMAINDER; |
||||||
|
areaConstr.weightx = 1.0; |
||||||
|
areaConstr.weighty = 1.0; |
||||||
|
|
||||||
|
///#ifdef AWT10
|
||||||
|
/// Label label = new Label("class path: ");
|
||||||
|
/// gbl.setConstraints(label, labelConstr);
|
||||||
|
/// window.add(label);
|
||||||
|
/// gbl.setConstraints(classpathField, textConstr);
|
||||||
|
/// window.add(classpathField);
|
||||||
|
/// label = new Label("class name: ");
|
||||||
|
/// gbl.setConstraints(label, labelConstr);
|
||||||
|
/// window.add(label);
|
||||||
|
/// gbl.setConstraints(classField, textConstr);
|
||||||
|
/// window.add(classField);
|
||||||
|
/// gbl.setConstraints(verboseCheck, checkConstr);
|
||||||
|
/// window.add(verboseCheck);
|
||||||
|
/// gbl.setConstraints(prettyCheck, checkConstr);
|
||||||
|
/// window.add(prettyCheck);
|
||||||
|
/// labelConstr.weightx = 1.0;
|
||||||
|
/// label = new Label();
|
||||||
|
/// gbl.setConstraints(label, labelConstr);
|
||||||
|
/// window.add(label);
|
||||||
|
/// gbl.setConstraints(startButton, buttonConstr);
|
||||||
|
/// window.add(startButton);
|
||||||
|
/// buttonConstr.gridwidth = GridBagConstraints.REMAINDER;
|
||||||
|
/// gbl.setConstraints(saveButton, buttonConstr);
|
||||||
|
/// window.add(saveButton);
|
||||||
|
/// gbl.setConstraints(sourcecodeArea, areaConstr);
|
||||||
|
/// window.add(sourcecodeArea);
|
||||||
|
/// areaConstr.gridheight = GridBagConstraints.REMAINDER;
|
||||||
|
/// areaConstr.weighty = 0.0;
|
||||||
|
/// gbl.setConstraints(errorArea, areaConstr);
|
||||||
|
/// window.add(errorArea);
|
||||||
|
///#else
|
||||||
|
window.add(new Label("class path: "), labelConstr); |
||||||
|
window.add(classpathField, textConstr); |
||||||
|
window.add(new Label("class name: "), labelConstr); |
||||||
|
window.add(classField, textConstr); |
||||||
|
window.add(verboseCheck, checkConstr); |
||||||
|
window.add(prettyCheck, checkConstr); |
||||||
|
labelConstr.weightx = 1.0; |
||||||
|
window.add(new Label(), labelConstr); |
||||||
|
window.add(startButton, buttonConstr); |
||||||
|
buttonConstr.gridwidth = GridBagConstraints.REMAINDER; |
||||||
|
window.add(saveButton, buttonConstr); |
||||||
|
window.add(sourcecodeArea, areaConstr); |
||||||
|
areaConstr.gridheight = GridBagConstraints.REMAINDER; |
||||||
|
areaConstr.weighty = 0.0; |
||||||
|
window.add(errorArea, areaConstr); |
||||||
|
|
||||||
|
startButton.addActionListener(this); |
||||||
|
saveButton.addActionListener(this); |
||||||
|
///#endif
|
||||||
|
GlobalOptions.err = new PrintWriter(new AreaWriter(errorArea)); |
||||||
|
} |
||||||
|
|
||||||
|
public void setClasspath(String cp) { |
||||||
|
classpathField.setText(cp); |
||||||
|
} |
||||||
|
public void setClass(String cls) { |
||||||
|
classField.setText(cls); |
||||||
|
} |
||||||
|
|
||||||
|
///#ifdef AWT10
|
||||||
|
/// public synchronized void action(Event e, Object target) {
|
||||||
|
///#else
|
||||||
|
public synchronized void actionPerformed(ActionEvent e) { |
||||||
|
Object target = e.getSource(); |
||||||
|
///#endif
|
||||||
|
if (target == startButton) { |
||||||
|
|
||||||
|
///#ifdef AWT10
|
||||||
|
/// startButton.disable();
|
||||||
|
///#else
|
||||||
|
startButton.setEnabled(false); |
||||||
|
///#endif
|
||||||
|
decompileThread = new Thread(this); |
||||||
|
sourcecodeArea.setText("Please wait, while decompiling...\n"); |
||||||
|
decompileThread.start(); |
||||||
|
} else if (target == saveButton) { |
||||||
|
if (frame == null) |
||||||
|
frame = new Frame(); //XXX
|
||||||
|
FileDialog fd = new FileDialog(frame, |
||||||
|
"Save decompiled code", |
||||||
|
FileDialog.SAVE); |
||||||
|
fd.setFile(lastClassName.substring |
||||||
|
(lastClassName.lastIndexOf('.')+1).concat(".java")); |
||||||
|
fd.show(); |
||||||
|
String fileName = fd.getFile(); |
||||||
|
if (fileName == null) |
||||||
|
return; |
||||||
|
try { |
||||||
|
File f = new File(new File(fd.getDirectory()), fileName); |
||||||
|
FileWriter out = new FileWriter(f); |
||||||
|
out.write(sourcecodeArea.getText()); |
||||||
|
out.close(); |
||||||
|
} catch (IOException ex) { |
||||||
|
errorArea.setText(""); |
||||||
|
GlobalOptions.err.println("Couldn't write to file " |
||||||
|
+ fileName + ": "); |
||||||
|
ex.printStackTrace(GlobalOptions.err); |
||||||
|
} catch (SecurityException ex) { |
||||||
|
errorArea.setText(""); |
||||||
|
GlobalOptions.err.println("Couldn't write to file " |
||||||
|
+ fileName + ": "); |
||||||
|
ex.printStackTrace(GlobalOptions.err); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public class AreaWriter extends Writer { |
||||||
|
boolean initialized = false; |
||||||
|
private TextArea area; |
||||||
|
|
||||||
|
public AreaWriter(TextArea a) { |
||||||
|
area = a; |
||||||
|
} |
||||||
|
|
||||||
|
public void write(char[] b, int off, int len) throws IOException { |
||||||
|
if (!initialized) { |
||||||
|
area.setText(""); |
||||||
|
initialized = true; |
||||||
|
} |
||||||
|
///#ifdef AWT10
|
||||||
|
/// area.appendText(new String(b, off, len));
|
||||||
|
///#else
|
||||||
|
area.append(new String(b, off, len)); |
||||||
|
///#endif
|
||||||
|
} |
||||||
|
|
||||||
|
public void flush() { |
||||||
|
} |
||||||
|
|
||||||
|
public void close() { |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void run() { |
||||||
|
GlobalOptions.verboseLevel = verboseCheck.getState() ? 1 : 0; |
||||||
|
if (prettyCheck.getState()) |
||||||
|
Options.options |= Options.OPTION_PRETTY; |
||||||
|
else |
||||||
|
Options.options &= ~Options.OPTION_PRETTY; |
||||||
|
errorArea.setText(""); |
||||||
|
///#ifdef AWT10
|
||||||
|
/// saveButton.disable();
|
||||||
|
///#else
|
||||||
|
saveButton.setEnabled(false); |
||||||
|
///#endif
|
||||||
|
|
||||||
|
lastClassName = classField.getText(); |
||||||
|
ClassInfo.setClassPath(classpathField.getText()); |
||||||
|
ImportHandler imports = new ImportHandler(); |
||||||
|
try { |
||||||
|
ClassInfo clazz; |
||||||
|
try { |
||||||
|
clazz = ClassInfo.forName(lastClassName); |
||||||
|
} catch (IllegalArgumentException ex) { |
||||||
|
sourcecodeArea.setText |
||||||
|
("`"+lastClassName+"' is not a class name\n" |
||||||
|
+"You have to give a full qualified classname " |
||||||
|
+"with '.' as package delimiter \n" |
||||||
|
+"and without .class ending"); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
TabbedPrintWriter writer = |
||||||
|
new TabbedPrintWriter(new AreaWriter(sourcecodeArea), imports); |
||||||
|
ClassAnalyzer clazzAna = new ClassAnalyzer(null, clazz, imports); |
||||||
|
clazzAna.dumpJavaFile(writer); |
||||||
|
|
||||||
|
///#ifdef AWT10
|
||||||
|
/// saveButton.enable();
|
||||||
|
///#else
|
||||||
|
saveButton.setEnabled(true); |
||||||
|
///#endif
|
||||||
|
} catch (Throwable t) { |
||||||
|
sourcecodeArea.setText("Didn't succeed.\n" |
||||||
|
+"Check the below area for more info."); |
||||||
|
t.printStackTrace(); |
||||||
|
} finally { |
||||||
|
synchronized(this) { |
||||||
|
decompileThread = null; |
||||||
|
///#ifdef AWT10
|
||||||
|
/// startButton.enable();
|
||||||
|
///#else
|
||||||
|
startButton.setEnabled(true); |
||||||
|
///#endif
|
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void main(String argv[]) { |
||||||
|
Frame frame = new Frame(GlobalOptions.copyright); |
||||||
|
Window win = new Window(frame); |
||||||
|
|
||||||
|
String cp = System.getProperty("java.class.path"); |
||||||
|
if (cp != null) |
||||||
|
win.setClasspath(cp.replace(File.pathSeparatorChar, |
||||||
|
SearchPath.altPathSeparatorChar)); |
||||||
|
String cls = win.getClass().getName(); |
||||||
|
win.setClass(cls); |
||||||
|
|
||||||
|
///#ifndef AWT10
|
||||||
|
frame.addWindowListener(new WindowAdapter() { |
||||||
|
public void windowClosing(WindowEvent e) { |
||||||
|
System.exit(0); |
||||||
|
} |
||||||
|
}); |
||||||
|
///#endif
|
||||||
|
frame.pack(); |
||||||
|
frame.show(); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue