2727import com .strobel .decompiler .languages .java .JavaFormattingOptions ;
2828import org .objectweb .asm .tree .ClassNode ;
2929import the .bytecode .club .bytecodeviewer .BytecodeViewer ;
30+ import the .bytecode .club .bytecodeviewer .Constants ;
3031import the .bytecode .club .bytecodeviewer .api .ExceptionUI ;
3132import the .bytecode .club .bytecodeviewer .decompilers .AbstractDecompiler ;
3233import the .bytecode .club .bytecodeviewer .translation .TranslatedStrings ;
4243import java .util .zip .ZipOutputStream ;
4344
4445import static the .bytecode .club .bytecodeviewer .Constants .*;
45- import static the .bytecode .club .bytecodeviewer .translation .TranslatedStrings .ERROR ;
46- import static the .bytecode .club .bytecodeviewer .translation .TranslatedStrings .PROCYON ;
46+ import static the .bytecode .club .bytecodeviewer .translation .TranslatedStrings .*;
4747
4848/**
4949 * Procyon Java Decompiler Wrapper
5050 *
5151 * @author Konloch
5252 * @author DeathMarine
5353 */
54+
5455public class ProcyonDecompiler extends AbstractDecompiler
5556{
5657
5758 public ProcyonDecompiler ()
5859 {
59- super ("Procyon Decompiler" , "proycon " );
60+ super ("Procyon Decompiler" , "procyon " );
6061 }
6162
6263 @ Override
@@ -69,34 +70,43 @@ public String decompileClassNode(ClassNode cn, byte[] bytes)
6970 {
7071 //create the temporary files
7172 tempFile = TempFile .createTemporaryFile (false , ".class" );
72- File tempClassFile = tempFile .getFile ();
73+ File tempInputClassFile = tempFile .getFile ();
7374
7475 //write the ClassNode bytes to the temp file
75- try (FileOutputStream fos = new FileOutputStream (tempClassFile ))
76+ try (FileOutputStream fos = new FileOutputStream (tempInputClassFile ))
7677 {
7778 fos .write (bytes );
7879 }
7980
80- //setup proycon decompiler settings
81+ //initialize procyon
8182 DecompilerSettings settings = getDecompilerSettings ();
82-
8383 LuytenTypeLoader typeLoader = new LuytenTypeLoader ();
8484 MetadataSystem metadataSystem = new MetadataSystem (typeLoader );
85- TypeReference type = metadataSystem .lookupType (tempClassFile .getCanonicalPath ());
86-
8785 DecompilationOptions decompilationOptions = new DecompilationOptions ();
86+ StringWriter writer = new StringWriter ();
87+
88+ //lookup the class-file
89+ TypeReference type = metadataSystem .lookupType (tempInputClassFile .getCanonicalPath ());
90+
91+ //configure procyon
8892 decompilationOptions .setSettings (settings );
8993 decompilationOptions .setFullDecompilation (true );
9094
95+ //parse class-file
9196 TypeDefinition resolvedType ;
9297
9398 if (type == null || ((resolvedType = type .resolve ()) == null ))
94- throw new Exception ("Unable to resolve type." );
99+ throw new Exception ("Unable to resolve class-filetype." );
100+
101+ //decompile the class-file
102+ settings .getLanguage ().decompileType (resolvedType , new PlainTextOutput (writer ), decompilationOptions );
95103
96- StringWriter stringwriter = new StringWriter ();
97- settings .getLanguage ().decompileType (resolvedType , new PlainTextOutput (stringwriter ), decompilationOptions );
104+ //handle simulated errors
105+ if (Constants .DEV_FLAG_DECOMPILERS_SIMULATED_ERRORS )
106+ throw new RuntimeException (DEV_MODE_SIMULATED_ERROR .toString ());
98107
99- return EncodeUtils .unicodeToString (stringwriter .toString ());
108+ //return the writer contents
109+ return EncodeUtils .unicodeToString (writer .toString ());
100110 }
101111 catch (Throwable e )
102112 {
@@ -106,7 +116,7 @@ public String decompileClassNode(ClassNode cn, byte[] bytes)
106116 {
107117 //delete all temporary files
108118 if (tempFile != null )
109- tempFile .delete ();
119+ tempFile .cleanup ();
110120 }
111121
112122 return PROCYON + " " + ERROR + "! " + ExceptionUI .SEND_STACKTRACE_TO + NL + NL
@@ -118,108 +128,105 @@ public void decompileToZip(String sourceJar, String zipName)
118128 {
119129 try
120130 {
121- doSaveJarDecompiled (new File (sourceJar ), new File (zipName ));
122- }
123- catch (StackOverflowError | Exception e )
124- {
125- BytecodeViewer .handleException (e );
126- }
127- }
131+ try (JarFile jarFile = new JarFile (sourceJar );
132+ FileOutputStream destination = new FileOutputStream (zipName );
133+ BufferedOutputStream buffer = new BufferedOutputStream (destination );
134+ ZipOutputStream zip = new ZipOutputStream (buffer ))
135+ {
136+ byte [] data = new byte [1024 ];
128137
129- /**
130- * @author DeathMarine
131- */
132- private void doSaveJarDecompiled (File inFile , File outFile ) throws Exception
133- {
134- try (JarFile jfile = new JarFile (inFile );
135- FileOutputStream dest = new FileOutputStream (outFile );
136- BufferedOutputStream buffDest = new BufferedOutputStream (dest );
137- ZipOutputStream out = new ZipOutputStream (buffDest ))
138- {
139- byte [] data = new byte [1024 ];
140- DecompilerSettings settings = getDecompilerSettings ();
141- LuytenTypeLoader typeLoader = new LuytenTypeLoader ();
142- MetadataSystem metadataSystem = new MetadataSystem (typeLoader );
143- ITypeLoader jarLoader = new JarTypeLoader (jfile );
144- typeLoader .getTypeLoaders ().add (jarLoader );
138+ //initialize procyon
139+ DecompilerSettings settings = getDecompilerSettings ();
140+ LuytenTypeLoader typeLoader = new LuytenTypeLoader ();
141+ MetadataSystem metadataSystem = new MetadataSystem (typeLoader );
142+ ITypeLoader jarLoader = new JarTypeLoader (jarFile );
145143
146- DecompilationOptions decompilationOptions = new DecompilationOptions ();
147- decompilationOptions .setSettings (settings );
148- decompilationOptions .setFullDecompilation (true );
144+ //lookup the jar-file
145+ typeLoader .getTypeLoaders ().add (jarLoader );
149146
150- Enumeration <JarEntry > ent = jfile .entries ();
151- Set <JarEntry > history = new HashSet <>();
147+ //configure procyon
148+ DecompilationOptions decompilationOptions = new DecompilationOptions ();
149+ decompilationOptions .setSettings (settings );
150+ decompilationOptions .setFullDecompilation (true );
152151
153- while ( ent . hasMoreElements ())
154- {
155- JarEntry entry = ent . nextElement ();
152+ //setup jar output
153+ Enumeration < JarEntry > ent = jarFile . entries ();
154+ Set < JarEntry > history = new HashSet <> ();
156155
157- if ( entry . getName (). endsWith ( ".class" ))
156+ while ( ent . hasMoreElements ( ))
158157 {
159- JarEntry etn = new JarEntry ( entry . getName (). replace ( ".class" , ".java" ) );
158+ JarEntry entry = ent . nextElement ( );
160159
161- if (history . add ( etn ))
160+ if (entry . getName (). endsWith ( ".class" ))
162161 {
163- out . putNextEntry ( etn );
162+ JarEntry etn = new JarEntry ( entry . getName (). replace ( ".class" , ".java" ) );
164163
165- try
164+ if ( history . add ( etn ))
166165 {
167- String internalName = StringUtilities .removeRight (entry .getName (), ".class" );
168- TypeReference type = metadataSystem .lookupType (internalName );
169- TypeDefinition resolvedType ;
166+ zip .putNextEntry (etn );
170167
171- if (( type == null ) || (( resolvedType = type . resolve ()) == null ))
168+ try
172169 {
173- throw new Exception ("Unable to resolve type." );
174- }
170+ String internalName = StringUtilities .removeRight (entry .getName (), ".class" );
171+ TypeReference type = metadataSystem .lookupType (internalName );
172+ TypeDefinition resolvedType ;
175173
176- Writer writer = new OutputStreamWriter (out );
177- settings .getLanguage ().decompileType (resolvedType , new PlainTextOutput (writer ), decompilationOptions );
178- writer .flush ();
179- }
180- finally
181- {
182- out .closeEntry ();
174+ if ((type == null ) || ((resolvedType = type .resolve ()) == null ))
175+ throw new Exception ("Unable to resolve type." );
176+
177+ Writer writer = new OutputStreamWriter (zip );
178+ settings .getLanguage ().decompileType (resolvedType , new PlainTextOutput (writer ), decompilationOptions );
179+ writer .flush ();
180+ }
181+ finally
182+ {
183+ zip .closeEntry ();
184+ }
183185 }
184186 }
185- }
186- else
187- {
188- try
187+ else
189188 {
190- JarEntry etn = new JarEntry (entry .getName ());
189+ try
190+ {
191+ JarEntry etn = new JarEntry (entry .getName ());
191192
192- if (history .add (etn ))
193- continue ;
193+ if (history .add (etn ))
194+ continue ;
194195
195- history .add (etn );
196- out .putNextEntry (etn );
196+ history .add (etn );
197+ zip .putNextEntry (etn );
197198
198- try (InputStream in = jfile .getInputStream (entry ))
199- {
200- if (in != null )
199+ try (InputStream in = jarFile .getInputStream (entry ))
201200 {
202- int count ;
203- while ((count = in .read (data , 0 , 1024 )) != -1 )
201+ if (in != null )
204202 {
205- out .write (data , 0 , count );
203+ int count ;
204+
205+ while ((count = in .read (data , 0 , 1024 )) != -1 )
206+ {
207+ zip .write (data , 0 , count );
208+ }
206209 }
207210 }
211+ finally
212+ {
213+ zip .closeEntry ();
214+ }
208215 }
209- finally
216+ catch ( ZipException ze )
210217 {
211- out .closeEntry ();
218+ // some jars contain duplicate pom.xml entries: ignore it
219+ if (!ze .getMessage ().contains ("duplicate" ))
220+ throw ze ;
212221 }
213222 }
214- catch (ZipException ze )
215- {
216- // some jars contain duplicate pom.xml entries: ignore it
217- if (!ze .getMessage ().contains ("duplicate" ))
218- throw ze ;
219- }
220223 }
221224 }
222225 }
226+ catch (StackOverflowError | Exception e )
227+ {
228+ BytecodeViewer .handleException (e );
229+ }
223230 }
224231
225232 public DecompilerSettings getDecompilerSettings ()
0 commit comments