Merge branch 'master' of https://github.com/java-decompiler/jd-gui
roswalt
4 years ago
1 | 1 | |
2 | 2 | JD-GUI, a standalone graphical utility that displays Java sources from CLASS files. |
3 | 3 | |
4 | ![](http://java-decompiler.github.io/img/screenshot17.png) | |
4 | ![](https://raw.githubusercontent.com/java-decompiler/jd-gui/master/src/website/img/jd-gui.png) | |
5 | 5 | |
6 | 6 | - Java Decompiler projects home page: [http://java-decompiler.github.io](http://java-decompiler.github.io) |
7 | 7 | - JD-GUI source code: [https://github.com/java-decompiler/jd-gui](https://github.com/java-decompiler/jd-gui) |
290 | 290 | if (matchedEntries == null) { |
291 | 291 | Map<String, Collection> index = indexes.getIndex(indexName); |
292 | 292 | |
293 | if (patternLength == 1) { | |
294 | matchedEntries = matchWithCharFunction.apply(pattern.charAt(0), index); | |
295 | } else { | |
296 | String lastKey = key.substring(0, key.length() - 1); | |
297 | Map<String, Collection> lastMatchedTypes = cache.get(lastKey); | |
298 | if (lastMatchedTypes != null) { | |
299 | matchedEntries = matchWithStringFunction.apply(pattern, lastMatchedTypes); | |
293 | if (index != null) { | |
294 | if (patternLength == 1) { | |
295 | matchedEntries = matchWithCharFunction.apply(pattern.charAt(0), index); | |
300 | 296 | } else { |
301 | matchedEntries = matchWithStringFunction.apply(pattern, index); | |
297 | String lastKey = key.substring(0, key.length() - 1); | |
298 | Map<String, Collection> lastMatchedTypes = cache.get(lastKey); | |
299 | if (lastMatchedTypes != null) { | |
300 | matchedEntries = matchWithStringFunction.apply(pattern, lastMatchedTypes); | |
301 | } else { | |
302 | matchedEntries = matchWithStringFunction.apply(pattern, index); | |
303 | } | |
302 | 304 | } |
303 | 305 | } |
304 | 306 |
+28
-6
14 | 14 | import javax.swing.*; |
15 | 15 | import javax.xml.stream.*; |
16 | 16 | import java.awt.*; |
17 | import java.io.File; | |
18 | import java.io.FileInputStream; | |
19 | import java.io.FileOutputStream; | |
20 | import java.util.ArrayList; | |
17 | import java.io.*; | |
18 | import java.net.URL; | |
19 | import java.util.*; | |
21 | 20 | import java.util.List; |
22 | import java.util.Map; | |
23 | import java.util.Stack; | |
21 | import java.util.jar.Manifest; | |
24 | 22 | |
25 | 23 | public class ConfigurationXmlPersisterProvider implements ConfigurationPersister { |
26 | 24 | protected static final String ERROR_BACKGROUND_COLOR = "JdGuiPreferences.errorBackgroundColor"; |
25 | protected static final String JD_CORE_VERSION = "JdGuiPreferences.jdCoreVersion"; | |
27 | 26 | |
28 | 27 | protected static final File FILE = getConfigFile(); |
29 | 28 | |
56 | 55 | return new File(Constants.CONFIG_FILENAME); |
57 | 56 | } |
58 | 57 | |
58 | @Override | |
59 | 59 | public Configuration load() { |
60 | 60 | // Default values |
61 | 61 | Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); |
169 | 169 | config.getPreferences().put(ERROR_BACKGROUND_COLOR, "0xFF6666"); |
170 | 170 | } |
171 | 171 | |
172 | config.getPreferences().put(JD_CORE_VERSION, getJdCoreVersion()); | |
173 | ||
172 | 174 | return config; |
173 | 175 | } |
174 | 176 | |
177 | protected String getJdCoreVersion() { | |
178 | try { | |
179 | Enumeration<URL> enumeration = ConfigurationXmlPersisterProvider.class.getClassLoader().getResources("META-INF/MANIFEST.MF"); | |
180 | ||
181 | while (enumeration.hasMoreElements()) { | |
182 | try (InputStream is = enumeration.nextElement().openStream()) { | |
183 | String attribute = new Manifest(is).getMainAttributes().getValue("JD-Core-Version"); | |
184 | if (attribute != null) { | |
185 | return attribute; | |
186 | } | |
187 | } | |
188 | } | |
189 | } catch (IOException e) { | |
190 | assert ExceptionUtil.printStackTrace(e); | |
191 | } | |
192 | ||
193 | return "SNAPSHOT"; | |
194 | } | |
195 | ||
196 | @Override | |
175 | 197 | public void save(Configuration configuration) { |
176 | 198 | Point l = configuration.getMainWindowLocation(); |
177 | 199 | Dimension s = configuration.getMainWindowSize(); |
96 | 96 | hbox.add(Box.createHorizontalGlue()); |
97 | 97 | |
98 | 98 | hbox = Box.createHorizontalBox(); |
99 | hbox.add(new JLabel("Copyright © 2008-2019 Emmanuel Dupuy")); | |
99 | hbox.add(new JLabel("Copyright © 2008, 2019 Emmanuel Dupuy")); | |
100 | 100 | hbox.add(Box.createHorizontalGlue()); |
101 | 101 | subvbox.add(hbox); |
102 | 102 |
249 | 249 | if (selectedTreeNode != null) { |
250 | 250 | selectedTypeCallback.accept(selectedTreeNode.getUri(), searchInConstantPoolsEnterTextField.getText(), getFlags()); |
251 | 251 | } |
252 | searchInConstantPoolsDialog.setVisible(false); | |
253 | 252 | } |
254 | 253 | }; |
255 | 254 | searchInConstantPoolsOpenButton.addActionListener(searchInConstantPoolsOpenActionListener); |
14 | 14 | apply plugin: 'nebula.ospackage' |
15 | 15 | |
16 | 16 | // Common configuration // |
17 | rootProject.version='1.5.2' | |
18 | rootProject.ext.set('jdCoreVersion', '1.0.3') | |
17 | rootProject.version='1.6.3' | |
18 | rootProject.ext.set('jdCoreVersion', '1.0.7') | |
19 | 19 | targetCompatibility = '1.8' |
20 | 20 | |
21 | 21 | allprojects { |
30 | 30 | } |
31 | 31 | |
32 | 32 | repositories { |
33 | mavenCentral() | |
34 | maven { | |
35 | url 'https://raw.github.com/java-decompiler/mvn-repo/master' | |
36 | } | |
33 | jcenter() | |
37 | 34 | } |
38 | 35 | |
39 | 36 | configurations { |
+1
-0
31 | 31 | } |
32 | 32 | } |
33 | 33 | |
34 | @SuppressWarnings("unchecked") | |
34 | 35 | protected static void index(API api, Container.Entry entry, Indexes indexes, Map<String, Collection> packageDeclarationIndex) { |
35 | 36 | for (Container.Entry e : entry.getChildren()) { |
36 | 37 | if (e.isDirectory()) { |
+5
-25
15 | 15 | import org.jd.gui.util.io.NewlineOutputStream; |
16 | 16 | |
17 | 17 | import java.io.*; |
18 | import java.net.URL; | |
19 | 18 | import java.nio.charset.Charset; |
20 | 19 | import java.nio.file.Files; |
21 | 20 | import java.nio.file.Path; |
22 | import java.util.Enumeration; | |
23 | 21 | import java.util.HashMap; |
24 | 22 | import java.util.Map; |
25 | import java.util.jar.Manifest; | |
26 | 23 | |
27 | 24 | public class ClassFileSourceSaverProvider extends AbstractSourceSaverProvider { |
28 | 25 | protected static final String ESCAPE_UNICODE_CHARACTERS = "ClassFileDecompilerPreferences.escapeUnicodeCharacters"; |
29 | protected static final String REALIGN_LINE_NUMBERS = "ClassFileDecompilerPreferences.realignLineNumbers"; | |
30 | protected static final String WRITE_LINE_NUMBERS = "ClassFileSaverPreferences.writeLineNumbers"; | |
31 | protected static final String WRITE_METADATA = "ClassFileSaverPreferences.writeMetadata"; | |
26 | protected static final String REALIGN_LINE_NUMBERS = "ClassFileDecompilerPreferences.realignLineNumbers"; | |
27 | protected static final String WRITE_LINE_NUMBERS = "ClassFileSaverPreferences.writeLineNumbers"; | |
28 | protected static final String WRITE_METADATA = "ClassFileSaverPreferences.writeMetadata"; | |
29 | protected static final String JD_CORE_VERSION = "JdGuiPreferences.jdCoreVersion"; | |
32 | 30 | |
33 | 31 | protected static final ClassFileToJavaSourceDecompiler DECOMPILER = new ClassFileToJavaSourceDecompiler(); |
34 | 32 | |
35 | 33 | protected ContainerLoader loader = new ContainerLoader(); |
36 | 34 | protected LineNumberStringBuilderPrinter printer = new LineNumberStringBuilderPrinter(); |
37 | protected String jdCoreVersion = "SNAPSHOT"; | |
38 | ||
39 | public ClassFileSourceSaverProvider() { | |
40 | try { | |
41 | Enumeration<URL> enumeration = ClassFileSourceSaverProvider.class.getClassLoader().getResources("META-INF/MANIFEST.MF"); | |
42 | ||
43 | while (enumeration.hasMoreElements()) { | |
44 | try (InputStream is = enumeration.nextElement().openStream()) { | |
45 | String attribute = new Manifest(is).getMainAttributes().getValue("JD-Core-Version"); | |
46 | if (attribute != null) { | |
47 | jdCoreVersion = attribute; | |
48 | } | |
49 | } | |
50 | } | |
51 | } catch (IOException e) { | |
52 | assert ExceptionUtil.printStackTrace(e); | |
53 | } | |
54 | } | |
55 | 35 | |
56 | 36 | @Override public String[] getSelectors() { return appendSelectors("*:file:*.class"); } |
57 | 37 | |
143 | 123 | } |
144 | 124 | // Add JD-Core version |
145 | 125 | stringBuffer.append("\n * JD-Core Version: "); |
146 | stringBuffer.append(jdCoreVersion); | |
126 | stringBuffer.append(preferences.get(JD_CORE_VERSION)); | |
147 | 127 | stringBuffer.append("\n */"); |
148 | 128 | } |
149 | 129 |
+79
-79
7 | 7 | package org.jd.gui.util.decompiler; |
8 | 8 | |
9 | 9 | public class LineNumberStringBuilderPrinter extends StringBuilderPrinter { |
10 | protected boolean showLineNumbers = false; | |
10 | protected boolean showLineNumbers = false; | |
11 | 11 | |
12 | protected int maxLineNumber = 0; | |
13 | protected int digitCount = 0; | |
12 | protected int maxLineNumber = 0; | |
13 | protected int digitCount = 0; | |
14 | 14 | |
15 | protected String lineNumberBeginPrefix; | |
16 | protected String lineNumberEndPrefix; | |
17 | protected String unknownLineNumberPrefix; | |
15 | protected String lineNumberBeginPrefix; | |
16 | protected String lineNumberEndPrefix; | |
17 | protected String unknownLineNumberPrefix; | |
18 | 18 | |
19 | public void setShowLineNumbers(boolean showLineNumbers) { this.showLineNumbers = showLineNumbers; } | |
19 | public void setShowLineNumbers(boolean showLineNumbers) { this.showLineNumbers = showLineNumbers; } | |
20 | 20 | |
21 | protected int printDigit(int dcv, int lineNumber, int divisor, int left) { | |
22 | if (digitCount >= dcv) { | |
23 | if (lineNumber < divisor) { | |
24 | append(' '); | |
25 | } else { | |
26 | int e = (lineNumber-left) / divisor; | |
27 | append((char)('0' + e)); | |
28 | left += e*divisor; | |
29 | } | |
30 | } | |
21 | protected int printDigit(int dcv, int lineNumber, int divisor, int left) { | |
22 | if (digitCount >= dcv) { | |
23 | if (lineNumber < divisor) { | |
24 | stringBuffer.append(' '); | |
25 | } else { | |
26 | int e = (lineNumber-left) / divisor; | |
27 | stringBuffer.append((char)('0' + e)); | |
28 | left += e*divisor; | |
29 | } | |
30 | } | |
31 | 31 | |
32 | return left; | |
33 | } | |
32 | return left; | |
33 | } | |
34 | 34 | |
35 | // --- Printer --- // | |
36 | @Override | |
37 | public void start(int maxLineNumber, int majorVersion, int minorVersion) { | |
38 | super.start(maxLineNumber, majorVersion, minorVersion); | |
35 | // --- Printer --- // | |
36 | @Override | |
37 | public void start(int maxLineNumber, int majorVersion, int minorVersion) { | |
38 | super.start(maxLineNumber, majorVersion, minorVersion); | |
39 | 39 | |
40 | if (showLineNumbers) { | |
41 | this.maxLineNumber = maxLineNumber; | |
40 | if (showLineNumbers) { | |
41 | this.maxLineNumber = maxLineNumber; | |
42 | 42 | |
43 | if (maxLineNumber > 0) { | |
44 | digitCount = 1; | |
45 | unknownLineNumberPrefix = " "; | |
46 | int maximum = 9; | |
43 | if (maxLineNumber > 0) { | |
44 | digitCount = 1; | |
45 | unknownLineNumberPrefix = " "; | |
46 | int maximum = 9; | |
47 | 47 | |
48 | while (maximum < maxLineNumber) { | |
49 | digitCount++; | |
50 | unknownLineNumberPrefix += ' '; | |
51 | maximum = maximum*10 + 9; | |
52 | } | |
48 | while (maximum < maxLineNumber) { | |
49 | digitCount++; | |
50 | unknownLineNumberPrefix += ' '; | |
51 | maximum = maximum*10 + 9; | |
52 | } | |
53 | 53 | |
54 | lineNumberBeginPrefix = "/* "; | |
55 | lineNumberEndPrefix = " */ "; | |
56 | } else { | |
57 | unknownLineNumberPrefix = ""; | |
58 | lineNumberBeginPrefix = ""; | |
59 | lineNumberEndPrefix = ""; | |
60 | } | |
61 | } else { | |
62 | this.maxLineNumber = 0; | |
63 | unknownLineNumberPrefix = ""; | |
64 | lineNumberBeginPrefix = ""; | |
65 | lineNumberEndPrefix = ""; | |
66 | } | |
67 | } | |
54 | lineNumberBeginPrefix = "/* "; | |
55 | lineNumberEndPrefix = " */ "; | |
56 | } else { | |
57 | unknownLineNumberPrefix = ""; | |
58 | lineNumberBeginPrefix = ""; | |
59 | lineNumberEndPrefix = ""; | |
60 | } | |
61 | } else { | |
62 | this.maxLineNumber = 0; | |
63 | unknownLineNumberPrefix = ""; | |
64 | lineNumberBeginPrefix = ""; | |
65 | lineNumberEndPrefix = ""; | |
66 | } | |
67 | } | |
68 | 68 | |
69 | @Override public void startLine(int lineNumber) { | |
70 | if (maxLineNumber > 0) { | |
71 | append(lineNumberBeginPrefix); | |
69 | @Override public void startLine(int lineNumber) { | |
70 | if (maxLineNumber > 0) { | |
71 | stringBuffer.append(lineNumberBeginPrefix); | |
72 | 72 | |
73 | if (lineNumber == UNKNOWN_LINE_NUMBER) { | |
74 | append(unknownLineNumberPrefix); | |
75 | } else { | |
76 | int left = 0; | |
73 | if (lineNumber == UNKNOWN_LINE_NUMBER) { | |
74 | stringBuffer.append(unknownLineNumberPrefix); | |
75 | } else { | |
76 | int left = 0; | |
77 | 77 | |
78 | left = printDigit(5, lineNumber, 10000, left); | |
79 | left = printDigit(4, lineNumber, 1000, left); | |
80 | left = printDigit(3, lineNumber, 100, left); | |
81 | left = printDigit(2, lineNumber, 10, left); | |
82 | append((char)('0' + (lineNumber-left))); | |
83 | } | |
78 | left = printDigit(5, lineNumber, 10000, left); | |
79 | left = printDigit(4, lineNumber, 1000, left); | |
80 | left = printDigit(3, lineNumber, 100, left); | |
81 | left = printDigit(2, lineNumber, 10, left); | |
82 | stringBuffer.append((char)('0' + (lineNumber-left))); | |
83 | } | |
84 | 84 | |
85 | append(lineNumberEndPrefix); | |
86 | } | |
85 | stringBuffer.append(lineNumberEndPrefix); | |
86 | } | |
87 | 87 | |
88 | for (int i=0; i<indentationCount; i++) { | |
89 | append(TAB); | |
90 | } | |
91 | } | |
92 | @Override public void extraLine(int count) { | |
93 | if (realignmentLineNumber) { | |
94 | while (count-- > 0) { | |
95 | if (maxLineNumber > 0) { | |
96 | append(lineNumberBeginPrefix); | |
97 | append(unknownLineNumberPrefix); | |
98 | append(lineNumberEndPrefix); | |
99 | } | |
88 | for (int i=0; i<indentationCount; i++) { | |
89 | stringBuffer.append(TAB); | |
90 | } | |
91 | } | |
92 | @Override public void extraLine(int count) { | |
93 | if (realignmentLineNumber) { | |
94 | while (count-- > 0) { | |
95 | if (maxLineNumber > 0) { | |
96 | stringBuffer.append(lineNumberBeginPrefix); | |
97 | stringBuffer.append(unknownLineNumberPrefix); | |
98 | stringBuffer.append(lineNumberEndPrefix); | |
99 | } | |
100 | 100 | |
101 | append(NEWLINE); | |
102 | } | |
103 | } | |
104 | } | |
101 | stringBuffer.append(NEWLINE); | |
102 | } | |
103 | } | |
104 | } | |
105 | 105 | } |
28 | 28 | public int getMinorVersion() { return minorVersion; } |
29 | 29 | public StringBuilder getStringBuffer() { return stringBuffer; } |
30 | 30 | |
31 | public void append(char c) { stringBuffer.append(c); } | |
32 | public void append(String s) { stringBuffer.append(s); } | |
33 | ||
34 | protected void printEscape(String s) { | |
31 | protected void escape(String s) { | |
35 | 32 | if (unicodeEscape && (s != null)) { |
36 | 33 | int length = s.length(); |
37 | 34 | |
39 | 36 | char c = s.charAt(i); |
40 | 37 | |
41 | 38 | if (c == '\t') { |
42 | append(c); | |
39 | stringBuffer.append(c); | |
43 | 40 | } else if (c < 32) { |
44 | 41 | // Write octal format |
45 | append("\\0"); | |
46 | append((char) ('0' + (c >> 3))); | |
47 | append((char) ('0' + (c & 0x7))); | |
42 | stringBuffer.append("\\0"); | |
43 | stringBuffer.append((char) ('0' + (c >> 3))); | |
44 | stringBuffer.append((char) ('0' + (c & 0x7))); | |
48 | 45 | } else if (c > 127) { |
49 | 46 | // Write octal format |
50 | append("\\u"); | |
47 | stringBuffer.append("\\u"); | |
51 | 48 | |
52 | 49 | int z = (c >> 12); |
53 | append((char) ((z <= 9) ? ('0' + z) : (('A' - 10) + z))); | |
50 | stringBuffer.append((char) ((z <= 9) ? ('0' + z) : (('A' - 10) + z))); | |
54 | 51 | z = ((c >> 8) & 0xF); |
55 | append((char) ((z <= 9) ? ('0' + z) : (('A' - 10) + z))); | |
52 | stringBuffer.append((char) ((z <= 9) ? ('0' + z) : (('A' - 10) + z))); | |
56 | 53 | z = ((c >> 4) & 0xF); |
57 | append((char) ((z <= 9) ? ('0' + z) : (('A' - 10) + z))); | |
54 | stringBuffer.append((char) ((z <= 9) ? ('0' + z) : (('A' - 10) + z))); | |
58 | 55 | z = (c & 0xF); |
59 | append((char) ((z <= 9) ? ('0' + z) : (('A' - 10) + z))); | |
56 | stringBuffer.append((char) ((z <= 9) ? ('0' + z) : (('A' - 10) + z))); | |
60 | 57 | } else { |
61 | append(c); | |
58 | stringBuffer.append(c); | |
62 | 59 | } |
63 | 60 | } |
64 | 61 | } else { |
65 | append(s); | |
62 | stringBuffer.append(s); | |
66 | 63 | } |
67 | 64 | } |
68 | 65 | |
77 | 74 | |
78 | 75 | @Override public void end() {} |
79 | 76 | |
80 | @Override public void printText(String text) { printEscape(text); } | |
81 | @Override public void printNumericConstant(String constant) { append(constant); } | |
82 | @Override public void printStringConstant(String constant, String ownerInternalName) { append(constant); } | |
83 | @Override public void printKeyword(String keyword) { append(keyword); } | |
77 | @Override public void printText(String text) { escape(text); } | |
78 | @Override public void printNumericConstant(String constant) { escape(constant); } | |
79 | @Override public void printStringConstant(String constant, String ownerInternalName) { escape(constant); } | |
80 | @Override public void printKeyword(String keyword) { stringBuffer.append(keyword); } | |
84 | 81 | |
85 | @Override public void printDeclaration(int type, String internalTypeName, String name, String descriptor) { append(name); } | |
86 | @Override public void printReference(int type, String internalTypeName, String name, String descriptor, String ownerInternalName) { append(name); } | |
82 | @Override public void printDeclaration(int type, String internalTypeName, String name, String descriptor) { escape(name); } | |
83 | @Override public void printReference(int type, String internalTypeName, String name, String descriptor, String ownerInternalName) { escape(name); } | |
87 | 84 | |
88 | 85 | @Override public void indent() { indentationCount++; } |
89 | 86 | @Override public void unindent() { if (indentationCount > 0) indentationCount--; } |
90 | 87 | |
91 | @Override public void startLine(int lineNumber) { for (int i=0; i<indentationCount; i++) append(TAB); } | |
92 | @Override public void endLine() { append(NEWLINE); } | |
93 | @Override public void extraLine(int count) { if (realignmentLineNumber) while (count-- > 0) append(NEWLINE); } | |
88 | @Override public void startLine(int lineNumber) { for (int i=0; i<indentationCount; i++) stringBuffer.append(TAB); } | |
89 | @Override public void endLine() { stringBuffer.append(NEWLINE); } | |
90 | @Override public void extraLine(int count) { if (realignmentLineNumber) while (count-- > 0) stringBuffer.append(NEWLINE); } | |
94 | 91 | |
95 | 92 | @Override public void startMarker(int type) {} |
96 | 93 | @Override public void endMarker(int type) {} |
11 | 11 | import org.jd.core.v1.ClassFileToJavaSourceDecompiler; |
12 | 12 | import org.jd.gui.api.API; |
13 | 13 | import org.jd.gui.api.model.Container; |
14 | import org.jd.gui.util.decompiler.ClassPathLoader; | |
15 | import org.jd.gui.util.decompiler.ContainerLoader; | |
16 | import org.jd.gui.util.decompiler.NopPrinter; | |
17 | import org.jd.gui.util.decompiler.StringBuilderPrinter; | |
14 | import org.jd.gui.util.decompiler.*; | |
18 | 15 | import org.jd.gui.util.exception.ExceptionUtil; |
16 | import org.jd.gui.util.io.NewlineOutputStream; | |
19 | 17 | |
20 | 18 | import javax.swing.text.BadLocationException; |
21 | 19 | import javax.swing.text.DefaultCaret; |
22 | 20 | import java.awt.*; |
21 | import java.io.*; | |
22 | import java.nio.charset.Charset; | |
23 | 23 | import java.util.HashMap; |
24 | 24 | import java.util.Map; |
25 | 25 | |
26 | 26 | public class ClassFilePage extends TypePage { |
27 | 27 | protected static final String ESCAPE_UNICODE_CHARACTERS = "ClassFileDecompilerPreferences.escapeUnicodeCharacters"; |
28 | 28 | protected static final String REALIGN_LINE_NUMBERS = "ClassFileDecompilerPreferences.realignLineNumbers"; |
29 | protected static final String WRITE_LINE_NUMBERS = "ClassFileSaverPreferences.writeLineNumbers"; | |
30 | protected static final String WRITE_METADATA = "ClassFileSaverPreferences.writeMetadata"; | |
31 | protected static final String JD_CORE_VERSION = "JdGuiPreferences.jdCoreVersion"; | |
29 | 32 | |
30 | 33 | protected static final ClassFileToJavaSourceDecompiler DECOMPILER = new ClassFileToJavaSourceDecompiler(); |
31 | 34 | |
96 | 99 | return (v == null) ? defaultValue : Boolean.valueOf(v); |
97 | 100 | } |
98 | 101 | |
102 | @Override | |
99 | 103 | public String getSyntaxStyle() { return SyntaxConstants.SYNTAX_STYLE_JAVA; } |
100 | 104 | |
101 | 105 | // --- ContentSavable --- // |
106 | @Override | |
102 | 107 | public String getFileName() { |
103 | 108 | String path = entry.getPath(); |
104 | 109 | int index = path.lastIndexOf('.'); |
105 | 110 | return path.substring(0, index) + ".java"; |
106 | 111 | } |
107 | 112 | |
113 | @Override | |
114 | public void save(API api, OutputStream os) { | |
115 | try { | |
116 | // Init preferences | |
117 | Map<String, String> preferences = api.getPreferences(); | |
118 | boolean realignmentLineNumbers = getPreferenceValue(preferences, REALIGN_LINE_NUMBERS, true); | |
119 | boolean unicodeEscape = getPreferenceValue(preferences, ESCAPE_UNICODE_CHARACTERS, false); | |
120 | boolean showLineNumbers = getPreferenceValue(preferences, WRITE_LINE_NUMBERS, true); | |
121 | ||
122 | Map<String, Object> configuration = new HashMap<>(); | |
123 | configuration.put("realignLineNumbers", realignmentLineNumbers); | |
124 | ||
125 | // Init loader | |
126 | ContainerLoader loader = new ContainerLoader(entry); | |
127 | ||
128 | // Init printer | |
129 | LineNumberStringBuilderPrinter printer = new LineNumberStringBuilderPrinter(); | |
130 | printer.setRealignmentLineNumber(realignmentLineNumbers); | |
131 | printer.setUnicodeEscape(unicodeEscape); | |
132 | printer.setShowLineNumbers(showLineNumbers); | |
133 | ||
134 | // Format internal name | |
135 | String entryPath = entry.getPath(); | |
136 | assert entryPath.endsWith(".class"); | |
137 | String entryInternalName = entryPath.substring(0, entryPath.length() - 6); // 6 = ".class".length() | |
138 | ||
139 | // Decompile class file | |
140 | DECOMPILER.decompile(loader, printer, entryInternalName, configuration); | |
141 | ||
142 | StringBuilder stringBuffer = printer.getStringBuffer(); | |
143 | ||
144 | // Metadata | |
145 | if (getPreferenceValue(preferences, WRITE_METADATA, true)) { | |
146 | // Add location | |
147 | String location = | |
148 | new File(entry.getUri()).getPath() | |
149 | // Escape "\ u" sequence to prevent "Invalid unicode" errors | |
150 | .replaceAll("(^|[^\\\\])\\\\u", "\\\\\\\\u"); | |
151 | stringBuffer.append("\n\n/* Location: "); | |
152 | stringBuffer.append(location); | |
153 | // Add Java compiler version | |
154 | int majorVersion = printer.getMajorVersion(); | |
155 | ||
156 | if (majorVersion >= 45) { | |
157 | stringBuffer.append("\n * Java compiler version: "); | |
158 | ||
159 | if (majorVersion >= 49) { | |
160 | stringBuffer.append(majorVersion - (49 - 5)); | |
161 | } else { | |
162 | stringBuffer.append(majorVersion - (45 - 1)); | |
163 | } | |
164 | ||
165 | stringBuffer.append(" ("); | |
166 | stringBuffer.append(majorVersion); | |
167 | stringBuffer.append('.'); | |
168 | stringBuffer.append(printer.getMinorVersion()); | |
169 | stringBuffer.append(')'); | |
170 | } | |
171 | // Add JD-Core version | |
172 | stringBuffer.append("\n * JD-Core Version: "); | |
173 | stringBuffer.append(preferences.get(JD_CORE_VERSION)); | |
174 | stringBuffer.append("\n */"); | |
175 | } | |
176 | ||
177 | try (PrintStream ps = new PrintStream(new NewlineOutputStream(os), true, "UTF-8")) { | |
178 | ps.print(stringBuffer.toString()); | |
179 | } catch (IOException e) { | |
180 | assert ExceptionUtil.printStackTrace(e); | |
181 | } | |
182 | } catch (Throwable t) { | |
183 | assert ExceptionUtil.printStackTrace(t); | |
184 | ||
185 | try (OutputStreamWriter writer = new OutputStreamWriter(os, Charset.defaultCharset())) { | |
186 | writer.write("// INTERNAL ERROR //"); | |
187 | } catch (IOException ee) { | |
188 | assert ExceptionUtil.printStackTrace(ee); | |
189 | } | |
190 | } | |
191 | } | |
192 | ||
108 | 193 | // --- LineNumberNavigable --- // |
194 | @Override | |
109 | 195 | public int getMaximumLineNumber() { return maximumLineNumber; } |
110 | 196 | |
197 | @Override | |
111 | 198 | public void goToLineNumber(int lineNumber) { |
112 | 199 | int textAreaLineNumber = getTextAreaLineNumber(lineNumber); |
113 | 200 | if (textAreaLineNumber > 0) { |
121 | 208 | } |
122 | 209 | } |
123 | 210 | |
211 | @Override | |
124 | 212 | public boolean checkLineNumber(int lineNumber) { return lineNumber <= maximumLineNumber; } |
125 | 213 | |
126 | 214 | // --- PreferencesChangeListener --- // |
215 | @Override | |
127 | 216 | public void preferencesChanged(Map<String, String> preferences) { |
128 | 217 | DefaultCaret caret = (DefaultCaret)textArea.getCaret(); |
129 | 218 | int updatePolicy = caret.getUpdatePolicy(); |
219 | 308 | super.endLine(); |
220 | 309 | textAreaLineNumber++; |
221 | 310 | } |
311 | @Override | |
222 | 312 | public void extraLine(int count) { |
223 | 313 | super.extraLine(count); |
224 | 314 | if (realignmentLineNumber) { |
21 | 21 | public class TextPage extends AbstractTextPage implements ContentCopyable, ContentSelectable, ContentSavable { |
22 | 22 | |
23 | 23 | // --- ContentCopyable --- // |
24 | @Override | |
24 | 25 | public void copy() { |
25 | 26 | if (textArea.getSelectionStart() == textArea.getSelectionEnd()) { |
26 | 27 | getToolkit().getSystemClipboard().setContents(new StringSelection(""), null); |
30 | 31 | } |
31 | 32 | |
32 | 33 | // --- ContentSelectable --- // |
34 | @Override | |
33 | 35 | public void selectAll() { |
34 | 36 | textArea.selectAll(); |
35 | 37 | } |
36 | 38 | |
37 | 39 | // --- ContentSavable --- // |
40 | @Override | |
38 | 41 | public String getFileName() { return "file.txt"; } |
39 | 42 | |
43 | @Override | |
40 | 44 | public void save(API api, OutputStream os) { |
41 | 45 | try (OutputStreamWriter writer = new OutputStreamWriter(new NewlineOutputStream(os), "UTF-8")) { |
42 | 46 | writer.write(textArea.getText()); |
4 | 4 | <key>CFBundleDevelopmentRegion</key> <string>English</string> |
5 | 5 | <key>CFBundleExecutable</key> <string>universalJavaApplicationStub.sh</string> |
6 | 6 | <key>CFBundleName</key> <string>JD-GUI</string> |
7 | <key>CFBundleGetInfoString</key> <string>JD-GUI version ${VERSION}, Copyright 2008-2019 Emmanuel Dupuy</string> | |
7 | <key>CFBundleGetInfoString</key> <string>JD-GUI version ${VERSION}, Copyright 2008, 2019 Emmanuel Dupuy</string> | |
8 | 8 | <key>CFBundleIconFile</key> <string>jd-gui.icns</string> |
9 | 9 | <key>CFBundleIdentifier</key> <string>jd.jd-gui</string> |
10 | 10 | <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> |
11 | 11 | <key>CFBundlePackageType</key> <string>APPL</string> |
12 | <key>CFBundleLongVersionString</key> <string>${VERSION}, Copyright 2008-2019 Emmanuel Dupuy</string> | |
12 | <key>CFBundleLongVersionString</key> <string>${VERSION}, Copyright 2008, 2019 Emmanuel Dupuy</string> | |
13 | 13 | <key>CFBundleShortVersionString</key> <string>${VERSION}</string> |
14 | 14 | <key>CSResourcesFileMapped</key> <true/> |
15 | 15 | <key>LSRequiresCarbon</key> <true/> |
16 | <key>NSHumanReadableCopyright</key> <string>Copyright 2008-2019 Emmanuel Dupuy</string> | |
16 | <key>NSHumanReadableCopyright</key> <string>Copyright 2008, 2019 Emmanuel Dupuy</string> | |
17 | 17 | <key>NSPrincipalClass</key> <string>NSApplication</string> |
18 | 18 | <key>NSHighResolutionCapable</key> <true/> |
19 | 19 | <key>CFBundleDocumentTypes</key> |
22 | 22 | <key>CFBundleTypeExtensions</key> |
23 | 23 | <array> |
24 | 24 | <string>class</string> |
25 | </array> | |
26 | <key>CFBundleTypeMIMETypes</key> | |
27 | <array> | |
28 | <string>application/java</string> | |
25 | 29 | </array> |
26 | 30 | <key>CFBundleTypeRole</key> <string>Viewer</string> |
27 | 31 | <key>CFBundleTypeName</key> <string>Class File</string> |
33 | 37 | <array> |
34 | 38 | <string>java</string> |
35 | 39 | </array> |
40 | <key>CFBundleTypeMIMETypes</key> | |
41 | <array> | |
42 | <string>text/plain</string> | |
43 | </array> | |
36 | 44 | <key>CFBundleTypeRole</key> <string>Viewer</string> |
37 | 45 | <key>CFBundleTypeName</key> <string>Java File</string> |
38 | 46 | <key>LSIsAppleDefaultForType</key> <false/> |
42 | 50 | <key>CFBundleTypeExtensions</key> |
43 | 51 | <array> |
44 | 52 | <string>jar</string> |
53 | </array> | |
54 | <key>CFBundleTypeMIMETypes</key> | |
55 | <array> | |
56 | <string>application/java-archive</string> | |
45 | 57 | </array> |
46 | 58 | <key>CFBundleTypeName</key> <string>Jar File</string> |
47 | 59 | <key>CFBundleTypeRole</key> <string>Viewer</string> |
53 | 65 | <array> |
54 | 66 | <string>war</string> |
55 | 67 | </array> |
68 | <key>CFBundleTypeMIMETypes</key> | |
69 | <array> | |
70 | <string>application/java-archive</string> | |
71 | </array> | |
56 | 72 | <key>CFBundleTypeName</key> <string>War File</string> |
57 | 73 | <key>CFBundleTypeRole</key> <string>Viewer</string> |
58 | 74 | <key>LSIsAppleDefaultForType</key> <false/> |
63 | 79 | <array> |
64 | 80 | <string>ear</string> |
65 | 81 | </array> |
82 | <key>CFBundleTypeMIMETypes</key> | |
83 | <array> | |
84 | <string>application/java-archive</string> | |
85 | </array> | |
66 | 86 | <key>CFBundleTypeName</key> <string>Ear File</string> |
67 | 87 | <key>CFBundleTypeRole</key> <string>Viewer</string> |
68 | 88 | <key>LSIsAppleDefaultForType</key> <false/> |
71 | 91 | <dict> |
72 | 92 | <key>CFBundleTypeExtensions</key> |
73 | 93 | <array> |
94 | <string>aar</string> | |
95 | </array> | |
96 | <key>CFBundleTypeName</key> <string>Android archive File</string> | |
97 | <key>CFBundleTypeRole</key> <string>Viewer</string> | |
98 | <key>LSIsAppleDefaultForType</key> <false/> | |
99 | <key>LSTypeIsPackage</key> <false/> | |
100 | </dict> | |
101 | <dict> | |
102 | <key>CFBundleTypeExtensions</key> | |
103 | <array> | |
104 | <string>jmod</string> | |
105 | </array> | |
106 | <key>CFBundleTypeMIMETypes</key> | |
107 | <array> | |
108 | <string>application/java-archive</string> | |
109 | </array> | |
110 | <key>CFBundleTypeName</key> <string>Java module File</string> | |
111 | <key>CFBundleTypeRole</key> <string>Viewer</string> | |
112 | <key>LSIsAppleDefaultForType</key> <false/> | |
113 | <key>LSTypeIsPackage</key> <false/> | |
114 | </dict> | |
115 | <dict> | |
116 | <key>CFBundleTypeExtensions</key> | |
117 | <array> | |
74 | 118 | <string>zip</string> |
119 | </array> | |
120 | <key>CFBundleTypeMIMETypes</key> | |
121 | <array> | |
122 | <string>application/zip</string> | |
75 | 123 | </array> |
76 | 124 | <key>CFBundleTypeName</key> <string>Zip File</string> |
77 | 125 | <key>CFBundleTypeRole</key> <string>Viewer</string> |
83 | 131 | <array> |
84 | 132 | <string>log</string> |
85 | 133 | <string>txt</string> |
134 | </array> | |
135 | <key>CFBundleTypeMIMETypes</key> | |
136 | <array> | |
137 | <string>text/plain</string> | |
86 | 138 | </array> |
87 | 139 | <key>CFBundleTypeName</key> <string>Log File</string> |
88 | 140 | <key>CFBundleTypeRole</key> <string>Viewer</string> |
Binary diff not shown