diff --git a/.gitignore b/.gitignore
index 0bacf76..a19a1bc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,9 @@
*.class
*.jar
+# JD
+debug*
+
# Eclipse
.settings/
bin/
diff --git a/.project b/.project
new file mode 100644
index 0000000..044654e
--- /dev/null
+++ b/.project
@@ -0,0 +1,9 @@
+
+
+ jd-eclipse
+
+
+
+
+
+
diff --git a/LICENSE b/LICENSE
index 21dbbc6..230579e 100644
--- a/LICENSE
+++ b/LICENSE
@@ -2,7 +2,7 @@
Version 3, 29 June 2007
- Copyright (C) 2007 Free Software Foundation, Inc.
+ Copyright (c) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
@@ -635,7 +635,7 @@ the "copyright" line and a pointer to where the full notice is found.
JD-Eclipse is a plug-in for the Eclipse platform. It allows you to
display all the Java sources during your debugging process, even if
you do not have them all.
- Copyright (C) 2008-2015 Emmanuel Dupuy
+ Copyright (c) 2008, 2019 Emmanuel Dupuy
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
@@ -655,7 +655,7 @@ Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
- JD-Eclipse Copyright (C) 2008-2015 Emmanuel Dupuy
+ JD-Eclipse Copyright (c) 2008, 2019 Emmanuel Dupuy
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
diff --git a/build.gradle b/build.gradle
index 22c7c6d..6bf9df5 100644
--- a/build.gradle
+++ b/build.gradle
@@ -2,7 +2,7 @@ apply plugin: 'distribution'
// Common configuration //
allprojects {
- version='1.0.0'
+ version='2.0.0'
}
subprojects.each { subproject ->
@@ -10,17 +10,29 @@ subprojects.each { subproject ->
}
distributions {
- site {
+ distZip {
+ // Create JAR files before final ZIP file
+ dependsOn subprojects.tasks['jar']
+ // For each file, remove root directory
+ eachFile { file ->
+ String path = file.relativePath
+ file.setPath(path.substring(path.indexOf('/')+1, path.length()))
+ }
+ }
+
+ main {
contents {
into('features') {
- from { fileTree('jd.ide.eclipse.feature/build/libs') { include '*.jar' } }
+ from {
+ fileTree 'org.jd.ide.eclipse.feature/build/libs'
+ }
}
into('plugins') {
- from { fileTree('jd.ide.eclipse.plugin/build/libs') { include '*.jar' } }
+ from {
+ fileTree 'org.jd.ide.eclipse.plugin/build/libs'
+ }
}
- from 'jd.ide.eclipse.site/site.xml', 'LICENSE', 'NOTICE', 'README.md'
+ from 'org.jd.ide.eclipse.site/site.xml', 'LICENSE', 'NOTICE', 'README.md'
}
}
}
-
-installSiteDist.dependsOn subprojects.tasks['jar']
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 2322723..b5166da 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 5b79a30..1715e2b 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Mon Jul 06 16:38:55 CEST 2015
-distributionBase=GRADLE_USER_HOME
-distributionPath=wrapper/dists
-zipStoreBase=GRADLE_USER_HOME
-zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip
+#Sat Mar 02 11:11:32 CET 2019
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-bin.zip
diff --git a/org.jd.ide.eclipse.feature/.classpath b/org.jd.ide.eclipse.feature/.classpath
new file mode 100644
index 0000000..b7e2871
--- /dev/null
+++ b/org.jd.ide.eclipse.feature/.classpath
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/org.jd.ide.eclipse.feature/.project b/org.jd.ide.eclipse.feature/.project
new file mode 100644
index 0000000..2194f53
--- /dev/null
+++ b/org.jd.ide.eclipse.feature/.project
@@ -0,0 +1,21 @@
+
+
+ org.jd.ide.eclipse.feature
+
+
+
+ org.eclipse.pde.FeatureNature
+ org.eclipse.jdt.core.javanature
+
+
+
+ org.eclipse.pde.FeatureBuilder
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
diff --git a/org.jd.ide.eclipse.feature/build.gradle b/org.jd.ide.eclipse.feature/build.gradle
new file mode 100644
index 0000000..269e3be
--- /dev/null
+++ b/org.jd.ide.eclipse.feature/build.gradle
@@ -0,0 +1,6 @@
+apply plugin: 'java'
+
+jar {
+ from 'feature.xml'
+ archiveName baseName + '_' + version + '.' + extension
+}
diff --git a/org.jd.ide.eclipse.feature/build.properties b/org.jd.ide.eclipse.feature/build.properties
new file mode 100644
index 0000000..64f93a9
--- /dev/null
+++ b/org.jd.ide.eclipse.feature/build.properties
@@ -0,0 +1 @@
+bin.includes = feature.xml
diff --git a/org.jd.ide.eclipse.feature/feature.xml b/org.jd.ide.eclipse.feature/feature.xml
new file mode 100644
index 0000000..5680b88
--- /dev/null
+++ b/org.jd.ide.eclipse.feature/feature.xml
@@ -0,0 +1,90 @@
+
+
+
+
+ JD-Eclipse is a plug-in for the Eclipse platform. It allows you to display all the Java sources during your debugging process, even if you do not have them all.
+
+
+
+ Copyright (c) 2008, 2019 Emmanuel Dupuy
+
+
+
+ .
+ GNU GENERAL PUBLIC LICENSE
+
+ Version 3, 29 June 2007
+
+ <http://www.gnu.org/licenses/gpl-3.0.html>
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ JD-Eclipse is a plug-in for the Eclipse platform. It allows you to
+ display all the Java sources during your debugging process, even if you
+ do not have them all.
+ Copyright (c) 2008, 2019 Emmanuel Dupuy
+
+ 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 3 of the License, 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. If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ JD-Eclipse Copyright (c) 2008, 2019 Emmanuel Dupuy
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+
+
+
+
+
diff --git a/org.jd.ide.eclipse.plugin/.classpath b/org.jd.ide.eclipse.plugin/.classpath
new file mode 100644
index 0000000..a6d508d
--- /dev/null
+++ b/org.jd.ide.eclipse.plugin/.classpath
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/org.jd.ide.eclipse.plugin/.project b/org.jd.ide.eclipse.plugin/.project
new file mode 100644
index 0000000..e5dfac0
--- /dev/null
+++ b/org.jd.ide.eclipse.plugin/.project
@@ -0,0 +1,25 @@
+
+
+ org.jd.ide.eclipse.plugin
+
+
+
+ org.eclipse.pde.PluginNature
+ org.eclipse.jdt.core.javanature
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+
diff --git a/org.jd.ide.eclipse.plugin/META-INF/MANIFEST.MF b/org.jd.ide.eclipse.plugin/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..9f14a20
--- /dev/null
+++ b/org.jd.ide.eclipse.plugin/META-INF/MANIFEST.MF
@@ -0,0 +1,25 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: JD-Eclipse Plug-in
+Bundle-SymbolicName: org.jd.ide.eclipse.plugin;singleton:=true
+Bundle-Version: 2.0.0
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.ui.editors,
+ org.eclipse.jdt.ui,
+ org.eclipse.jdt.core,
+ org.eclipse.core.runtime,
+ org.eclipse.core.resources,
+ org.eclipse.ui.ide,
+ org.eclipse.jface.text
+Bundle-Vendor: Java Decompiler
+Bundle-Activator: org.jd.ide.eclipse.JavaDecompilerPlugin
+Bundle-ActivationPolicy: lazy
+Bundle-ClassPath: /lib/jd-core-1.0.7.jar,.
+Export-Package: org.jd.core.v1,
+ org.jd.ide.eclipse,
+ org.jd.ide.eclipse.editors,
+ org.jd.ide.eclipse.preferences,
+ org.jd.ide.eclipse.startup,
+ org.jd.ide.eclipse.util.loader,
+ org.jd.ide.eclipse.util.printer
diff --git a/org.jd.ide.eclipse.plugin/about.ini b/org.jd.ide.eclipse.plugin/about.ini
new file mode 100644
index 0000000..6892842
--- /dev/null
+++ b/org.jd.ide.eclipse.plugin/about.ini
@@ -0,0 +1,7 @@
+featureImage=icons/jd_32.png
+aboutText=Java Decompiler\n\
+\n\
+Web site: http://java-decompiler.github.io\n\
+Issues: https://github.com/java-decompiler/jd-eclipse/issues\n\
+\n\
+Copyright (c) 2008, 2019 Emmanuel Dupuy
diff --git a/org.jd.ide.eclipse.plugin/build.gradle b/org.jd.ide.eclipse.plugin/build.gradle
new file mode 100644
index 0000000..5a48efc
--- /dev/null
+++ b/org.jd.ide.eclipse.plugin/build.gradle
@@ -0,0 +1,81 @@
+apply plugin: 'java'
+
+repositories {
+ jcenter()
+}
+
+configurations {
+ provided
+ compile.extendsFrom provided
+}
+
+dependencies {
+ compile 'org.jd:jd-core:1.0.7'
+
+ provided 'org.eclipse.core:org.eclipse.core.commands:3.6.0'
+ provided 'org.eclipse.core:org.eclipse.core.resources:3.7.100'
+
+ provided('org.eclipse.jdt:org.eclipse.jdt.core:3.18.0') {
+ exclude group:'org.eclipse.platform'
+ }
+ provided('org.eclipse.jdt:org.eclipse.jdt.ui:3.18.0') {
+ exclude group:'org.eclipse.birt.runtime'
+ exclude group:'org.eclipse.emf'
+ exclude group:'org.eclipse.jdt'
+ exclude group:'org.eclipse.platform'
+ exclude group:'com.ibm.icu'
+ }
+ provided('org.eclipse.platform:org.eclipse.jface:3.15.0') {
+ exclude group:'org.eclipse.platform'
+ }
+ provided('org.eclipse.platform:org.eclipse.jface.text:3.15.0') {
+ exclude group:'org.eclipse.platform'
+ }
+ provided('org.eclipse.platform:org.eclipse.swt.win32.win32.x86_64:3.111.0') {
+ exclude group:'org.eclipse.platform'
+ }
+ provided('org.eclipse.platform:org.eclipse.ui.workbench:3.111.0') {
+ exclude group:'org.eclipse.emf'
+ exclude group:'org.eclipse.platform'
+ }
+ provided('org.eclipse.platform:org.eclipse.ui.workbench.texteditor:3.11.0') {
+ exclude group:'org.eclipse.platform'
+ }
+ provided('org.eclipse.platform:org.eclipse.ui.ide:3.15.0') {
+ exclude group:'org.eclipse.platform'
+ }
+ provided('org.eclipse.platform:org.eclipse.ui.editors:3.11.0') {
+ exclude group:'org.eclipse.platform'
+ }
+ provided('org.eclipse.platform:org.eclipse.ui.editors:3.11.0') {
+ exclude group:'org.eclipse.platform'
+ }
+}
+
+compileJava {
+ sourceCompatibility = '1.8'
+ targetCompatibility = '1.8'
+ source 'src'
+}
+
+jar {
+ archiveName baseName + '_' + version + '.' + extension
+ manifest {
+ from 'META-INF/MANIFEST.MF'
+ }
+ from fileTree('.') {
+ include 'icons/**'
+ include 'about.ini'
+ include 'plugin.xml'
+ }
+ into('lib') {
+ from project.configurations.runtime - project.configurations.provided
+ }
+}
+
+task copyDependencies(type: Copy) {
+ from project.configurations.runtime - project.configurations.provided
+ into 'lib'
+}
+
+build.finalizedBy copyDependencies
diff --git a/org.jd.ide.eclipse.plugin/build.properties b/org.jd.ide.eclipse.plugin/build.properties
new file mode 100644
index 0000000..290bd9f
--- /dev/null
+++ b/org.jd.ide.eclipse.plugin/build.properties
@@ -0,0 +1,9 @@
+bin.includes = META-INF/,\
+ plugin.xml,\
+ icons/,\
+ about.ini,\
+ lib/jd-core-1.0.7.jar,\
+ .
+source.. = src/
+jars.compile.order = .
+
diff --git a/org.jd.ide.eclipse.plugin/icons/jd_16.png b/org.jd.ide.eclipse.plugin/icons/jd_16.png
new file mode 100644
index 0000000..986fb1d
Binary files /dev/null and b/org.jd.ide.eclipse.plugin/icons/jd_16.png differ
diff --git a/org.jd.ide.eclipse.plugin/icons/jd_32.png b/org.jd.ide.eclipse.plugin/icons/jd_32.png
new file mode 100644
index 0000000..b49e06a
Binary files /dev/null and b/org.jd.ide.eclipse.plugin/icons/jd_32.png differ
diff --git a/org.jd.ide.eclipse.plugin/plugin.xml b/org.jd.ide.eclipse.plugin/plugin.xml
new file mode 100644
index 0000000..12b0d47
--- /dev/null
+++ b/org.jd.ide.eclipse.plugin/plugin.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/org.jd.ide.eclipse.plugin/src/org/jd/ide/eclipse/JavaDecompilerPlugin.java b/org.jd.ide.eclipse.plugin/src/org/jd/ide/eclipse/JavaDecompilerPlugin.java
new file mode 100644
index 0000000..223b082
--- /dev/null
+++ b/org.jd.ide.eclipse.plugin/src/org/jd/ide/eclipse/JavaDecompilerPlugin.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2008, 2019 Emmanuel Dupuy.
+ * This project is distributed under the GPLv3 license.
+ * This is a Copyleft license that gives the user the right to use,
+ * copy and modify the code freely for non-commercial purposes.
+ */
+
+package org.jd.ide.eclipse;
+
+import org.eclipse.jdt.ui.JavaUI;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IEditorDescriptor;
+import org.eclipse.ui.IFileEditorMapping;
+import org.eclipse.ui.internal.WorkbenchPlugin;
+import org.eclipse.ui.internal.registry.EditorDescriptor;
+import org.eclipse.ui.internal.registry.EditorRegistry;
+import org.eclipse.ui.internal.registry.FileEditorMapping;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ *
+ * @project Java Decompiler Eclipse Plugin
+ * @version 0.1.4
+ */
+@SuppressWarnings({ "restriction", "deprecation" })
+public class JavaDecompilerPlugin extends AbstractUIPlugin {
+ // The plug-in IDs
+ public static final String PLUGIN_ID = "jd.ide.eclipse";
+ private static final String EDITOR_ID = PLUGIN_ID + ".editors.JDClassFileEditor";
+
+ // Versions
+ public static final String VERSION_JD_ECLIPSE = "2.0.0";
+ public static final String VERSION_JD_CORE = "1.0.7";
+
+ // Preferences
+ public static final String PREF_ESCAPE_UNICODE_CHARACTERS = PLUGIN_ID + ".prefs.EscapeUnicodeCharacters";
+ public static final String PREF_REALIGN_LINE_NUMBERS = PLUGIN_ID + ".prefs.RealignLineNumbers";
+ public static final String PREF_SHOW_LINE_NUMBERS = PLUGIN_ID + ".prefs.ShowLineNumbers";
+ public static final String PREF_SHOW_METADATA = PLUGIN_ID + ".prefs.ShowMetadata";
+
+ // URLs
+ public static final String URL_JDECLIPSE = "https://github.com/java-decompiler/jd-eclipse";
+
+ // The shared instance
+ private static JavaDecompilerPlugin plugin;
+
+
+ /**
+ * The constructor
+ */
+ public JavaDecompilerPlugin() {}
+
+ /**
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+
+ // Setup ".class" file associations
+ Display.getDefault().syncExec(new SetupClassFileAssociationRunnable());
+ }
+
+ /*
+ * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+ */
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ plugin.savePluginPreferences();
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ * @return the shared instance
+ */
+ public static JavaDecompilerPlugin getDefault() {
+ return plugin;
+ }
+
+ protected static class SetupClassFileAssociationRunnable implements Runnable {
+ public void run() {
+ EditorRegistry registry = (EditorRegistry)WorkbenchPlugin.getDefault().getEditorRegistry();
+
+ IFileEditorMapping[] mappings = registry.getFileEditorMappings();
+ IFileEditorMapping c = null;
+ IFileEditorMapping cws = null;
+
+ // Search Class file editor mappings
+ for (IFileEditorMapping mapping : mappings) {
+ if (mapping.getExtension().equals("class")) {
+ // ... Helios 3.6, Indigo 3.7, Juno 4.2, Kepler 4.3, ...
+ c = mapping;
+ } else if (mapping.getExtension().equals("class without source")) {
+ // Juno 4.2, Kepler 4.3, ...
+ cws = mapping;
+ }
+ }
+
+ if ((c != null) && (cws != null)) {
+ // Search JD editor descriptor on "class" extension
+ for (IEditorDescriptor descriptor : c.getEditors()) {
+ if (descriptor.getId().equals(EDITOR_ID)) {
+ // Remove JD editor on "class" extension
+ ((FileEditorMapping)c).removeEditor((EditorDescriptor)descriptor);
+
+ // Set JD as default editor on "class without source" extension
+ registry.setDefaultEditor("." + cws.getExtension(), descriptor.getId());
+ break;
+ }
+ }
+
+ // Restore the default editor for "class" extension
+ IEditorDescriptor defaultClassFileEditor = registry.findEditor(JavaUI.ID_CF_EDITOR);
+
+ if (defaultClassFileEditor != null) {
+ registry.setDefaultEditor("." + c.getExtension(), JavaUI.ID_CF_EDITOR);
+ }
+
+ registry.setFileEditorMappings((FileEditorMapping[]) mappings);
+ registry.saveAssociations();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/org.jd.ide.eclipse.plugin/src/org/jd/ide/eclipse/editors/JDClassFileEditor.java b/org.jd.ide.eclipse.plugin/src/org/jd/ide/eclipse/editors/JDClassFileEditor.java
new file mode 100644
index 0000000..b0d94e6
--- /dev/null
+++ b/org.jd.ide.eclipse.plugin/src/org/jd/ide/eclipse/editors/JDClassFileEditor.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2008, 2019 Emmanuel Dupuy.
+ * This project is distributed under the GPLv3 license.
+ * This is a Copyleft license that gives the user the right to use,
+ * copy and modify the code freely for non-commercial purposes.
+ */
+
+package org.jd.ide.eclipse.editors;
+
+import java.io.File;
+import java.lang.reflect.Method;
+import java.net.URI;
+import java.util.Map;
+
+import org.jd.ide.eclipse.JavaDecompilerPlugin;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.core.IBuffer;
+import org.eclipse.jdt.core.IClassFile;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.internal.core.BufferManager;
+import org.eclipse.jdt.internal.core.ClassFile;
+import org.eclipse.jdt.internal.core.PackageFragment;
+import org.eclipse.jdt.internal.core.PackageFragmentRoot;
+import org.eclipse.jdt.internal.ui.javaeditor.ClassFileEditor;
+import org.eclipse.jdt.internal.ui.javaeditor.IClassFileEditorInput;
+import org.eclipse.jface.util.IPropertyChangeListener;
+import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.ide.FileStoreEditorInput;
+import org.eclipse.ui.ide.ResourceUtil;
+
+
+/**
+ * JDClassFileEditor
+ *
+ * @project Java Decompiler Eclipse Plugin
+ * @version 0.1.4
+ * @see org.eclipse.jdt.internal.ui.javaeditor.ClassFileEditor
+ */
+@SuppressWarnings("restriction")
+public class JDClassFileEditor extends ClassFileEditor implements IPropertyChangeListener {
+ public JDClassFileEditor() {
+ JavaDecompilerPlugin
+ .getDefault()
+ .getPreferenceStore()
+ .addPropertyChangeListener(this);
+ }
+
+ @Override
+ protected void doSetInput(IEditorInput input) throws CoreException {
+ if (input instanceof IFileEditorInput) {
+ IFile file = ((IFileEditorInput)input).getFile();
+
+ if (file instanceof IClassFile) {
+ IClassFile classFile = (IClassFile)file;
+ cleanupBuffer(classFile);
+ setupSourceMapper(classFile);
+ }
+ } else if (input instanceof IClassFileEditorInput) {
+ IClassFileEditorInput classFileEditorInput = (IClassFileEditorInput)input;
+ IClassFile classFile = classFileEditorInput.getClassFile();
+ cleanupBuffer(classFile);
+ setupSourceMapper(classFile);
+ }
+
+ super.doSetInput(input);
+ }
+
+ protected static void cleanupBuffer(IClassFile file) {
+ IBuffer buffer = BufferManager.getDefaultBufferManager().getBuffer(file);
+
+ if (buffer != null) {
+ try {
+ // Remove the buffer
+ Method method = BufferManager.class.getDeclaredMethod("removeBuffer", new Class[] {IBuffer.class});
+ method.setAccessible(true);
+ method.invoke(BufferManager.getDefaultBufferManager(), new Object[] {buffer});
+ } catch (Exception e) {
+ JavaDecompilerPlugin.getDefault().getLog().log(new Status(
+ Status.ERROR, JavaDecompilerPlugin.PLUGIN_ID,
+ 0, e.getMessage(), e));
+ }
+ }
+ }
+
+ @SuppressWarnings("rawtypes")
+ protected void setupSourceMapper(IClassFile classFile) {
+ try {
+ // Search package fragment root and classPath
+ IJavaElement packageFragment = classFile.getParent();
+ IJavaElement packageFragmentRoot = packageFragment.getParent();
+
+ if (packageFragmentRoot instanceof PackageFragmentRoot) {
+ // Setup a new source mapper.
+ PackageFragmentRoot root = (PackageFragmentRoot)packageFragmentRoot;
+
+ // Location of the archive file containing classes.
+ IPath basePath = root.getPath();
+ File baseFile = basePath.makeAbsolute().toFile();
+
+ if (!baseFile.exists()) {
+ IResource resource = root.getCorrespondingResource();
+ basePath = resource.getLocation();
+ baseFile = basePath.makeAbsolute().toFile();
+ }
+
+ // Class path
+ String classPath = classFile.getElementName();
+ String packageName = packageFragment.getElementName();
+ if ((packageName != null) && (packageName.length() > 0)) {
+ classPath = packageName.replace('.', '/') + '/' + classPath;
+ }
+
+ // Location of the archive file containing source.
+ IPath sourcePath = root.getSourceAttachmentPath();
+ if (sourcePath == null) {
+ sourcePath = basePath;
+ }
+
+ // Location of the package fragment root within the zip
+ // (empty specifies the default root).
+ IPath sourceAttachmentRootPath = root.getSourceAttachmentRootPath();
+ String sourceRootPath;
+
+ if (sourceAttachmentRootPath == null) {
+ sourceRootPath = null;
+ } else {
+ sourceRootPath = sourceAttachmentRootPath.toString();
+ if ((sourceRootPath != null) && (sourceRootPath.length() == 0))
+ sourceRootPath = null;
+ }
+
+ // Options
+ Map options = root.getJavaProject().getOptions(true);
+
+ root.setSourceMapper(new JDSourceMapper(baseFile, sourcePath, sourceRootPath, options));
+ }
+ } catch (CoreException e) {
+ JavaDecompilerPlugin.getDefault().getLog().log(new Status(
+ Status.ERROR, JavaDecompilerPlugin.PLUGIN_ID,
+ 0, e.getMessage(), e));
+ }
+ }
+
+ @Override public boolean isEditable() { return false; }
+ @Override public boolean isDirty() { return false; }
+ @Override public boolean isEditorInputReadOnly() { return false; }
+
+ @Override
+ public void dispose() {
+ JavaDecompilerPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(this);
+ }
+
+ /**
+ * Refresh decompiled source code.
+ * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
+ */
+ public void propertyChange(PropertyChangeEvent event) {
+ if (getSourceViewer() != null) {
+ setInput(getEditorInput());
+ }
+ }
+}
diff --git a/org.jd.ide.eclipse.plugin/src/org/jd/ide/eclipse/editors/JDSourceMapper.java b/org.jd.ide.eclipse.plugin/src/org/jd/ide/eclipse/editors/JDSourceMapper.java
new file mode 100644
index 0000000..b3339ed
--- /dev/null
+++ b/org.jd.ide.eclipse.plugin/src/org/jd/ide/eclipse/editors/JDSourceMapper.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2008, 2019 Emmanuel Dupuy.
+ * This project is distributed under the GPLv3 license.
+ * This is a Copyleft license that gives the user the right to use,
+ * copy and modify the code freely for non-commercial purposes.
+ */
+
+package org.jd.ide.eclipse.editors;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.jd.core.v1.ClassFileToJavaSourceDecompiler;
+import org.jd.core.v1.api.loader.Loader;
+import org.jd.ide.eclipse.JavaDecompilerPlugin;
+import org.jd.ide.eclipse.util.loader.DirectoryLoader;
+import org.jd.ide.eclipse.util.loader.ZipLoader;
+import org.jd.ide.eclipse.util.printer.LineNumberStringBuilderPrinter;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jdt.internal.core.SourceMapper;
+import org.eclipse.jface.preference.IPreferenceStore;
+
+
+/**
+ * JDSourceMapper
+ *
+ * @project Java Decompiler Eclipse Plugin
+ * @version 0.1.4
+ * @see org.eclipse.jdt.internal.core.SourceMapper
+ */
+@SuppressWarnings("restriction")
+public class JDSourceMapper extends SourceMapper {
+ private final static String JAVA_CLASS_SUFFIX = ".class";
+ private final static String JAVA_SOURCE_SUFFIX = ".java";
+ private final static int JAVA_SOURCE_SUFFIX_LENGTH = 5;
+
+ private final static ClassFileToJavaSourceDecompiler DECOMPILER = new ClassFileToJavaSourceDecompiler();
+
+ private File basePath;
+
+ private LineNumberStringBuilderPrinter printer = new LineNumberStringBuilderPrinter();
+
+ @SuppressWarnings("rawtypes")
+ public JDSourceMapper(File basePath, IPath sourcePath, String sourceRootPath, Map options) {
+ super(sourcePath, sourceRootPath, options);
+ this.basePath = basePath;
+ }
+
+ @Override
+ @SuppressWarnings("rawtypes")
+ public char[] findSource(String javaSourcePath) {
+ char[] source = null;
+
+ // Search source file
+ if (this.rootPaths == null) {
+ source = super.findSource(javaSourcePath);
+ } else {
+ Iterator iterator = this.rootPaths.iterator();
+
+ while (iterator.hasNext() && (source == null)) {
+ String sourcesRootPath = (String)iterator.next();
+ source = super.findSource(sourcesRootPath + IPath.SEPARATOR + javaSourcePath);
+ }
+ }
+
+ if ((source == null) && javaSourcePath.toLowerCase().endsWith(JAVA_SOURCE_SUFFIX)) {
+ String internalTypeName = javaSourcePath.substring(0, javaSourcePath.length()-JAVA_SOURCE_SUFFIX_LENGTH);
+
+ // Decompile class file
+ try {
+ source = decompile(this.basePath.getAbsolutePath(), internalTypeName);
+ } catch (Exception e) {
+ JavaDecompilerPlugin.getDefault().getLog().log(new Status(
+ Status.ERROR, JavaDecompilerPlugin.PLUGIN_ID,
+ 0, e.getMessage(), e));
+ }
+ }
+
+ return source;
+ }
+
+ /**
+ * @param basePath Path to the root of the classpath, either a
+ * path to a directory or a path to a jar file.
+ * @param internalClassName internal name of the class.
+ * @return Decompiled class text.
+ */
+ protected char[] decompile(String basePath, String internalTypeName) throws Exception {
+ // Load preferences
+ IPreferenceStore store = JavaDecompilerPlugin.getDefault().getPreferenceStore();
+
+ boolean realignmentLineNumber = store.getBoolean(JavaDecompilerPlugin.PREF_REALIGN_LINE_NUMBERS);
+ boolean unicodeEscape = store.getBoolean(JavaDecompilerPlugin.PREF_ESCAPE_UNICODE_CHARACTERS);
+ boolean showLineNumbers = store.getBoolean(JavaDecompilerPlugin.PREF_SHOW_LINE_NUMBERS);
+ boolean showMetaData = store.getBoolean(JavaDecompilerPlugin.PREF_SHOW_METADATA);
+
+ Map configuration = new HashMap<>();
+ configuration.put("realignLineNumbers", realignmentLineNumber);
+
+ // Initialize loader
+ Loader loader;
+ File base = new File(basePath);
+
+ if (base.isFile()) {
+ if (basePath.toLowerCase().endsWith(".jar") || basePath.toLowerCase().endsWith(".zip")) {
+ loader = new ZipLoader(base);
+ } else {
+ JavaDecompilerPlugin.getDefault().getLog().log(new Status(
+ Status.ERROR, JavaDecompilerPlugin.PLUGIN_ID,
+ "Unexpected container type file: " + basePath));
+ return null;
+ }
+ } else {
+ loader = new DirectoryLoader(base);
+ }
+
+ // Initialize printer
+ printer.setRealignmentLineNumber(realignmentLineNumber);
+ printer.setUnicodeEscape(unicodeEscape);
+ printer.setShowLineNumbers(showLineNumbers);
+
+ // Decompile class file
+ DECOMPILER.decompile(loader, printer, internalTypeName, configuration);
+
+ StringBuilder stringBuffer = printer.getStringBuffer();
+
+ // Metadata
+ if (showMetaData) {
+ // Add location
+ stringBuffer.append("\n\n/* Location: ");
+ String classPath = internalTypeName + JAVA_CLASS_SUFFIX;
+ String location = base.isFile() ? base.getPath() + "!/" + classPath : new File(base, classPath).getPath();
+ // Escape "\ u" sequence to prevent "Invalid unicode" errors
+ stringBuffer.append(location.replaceAll("(^|[^\\\\])\\\\u", "\\\\\\\\u"));
+ // Add Java compiler version
+ int majorVersion = printer.getMajorVersion();
+ if (majorVersion >= 45) {
+ stringBuffer.append("\n * Java compiler version: ");
+
+ if (majorVersion >= 49) {
+ stringBuffer.append(majorVersion - (49 - 5));
+ } else {
+ stringBuffer.append(majorVersion - (45 - 1));
+ }
+
+ stringBuffer.append(" (");
+ stringBuffer.append(majorVersion);
+ stringBuffer.append('.');
+ stringBuffer.append(printer.getMinorVersion());
+ stringBuffer.append(')');
+ }
+ // Add JD-Core version
+ stringBuffer.append("\n * JD-Core Version: ");
+ stringBuffer.append(JavaDecompilerPlugin.VERSION_JD_CORE);
+ stringBuffer.append("\n */");
+ }
+
+ return stringBuffer.toString().toCharArray();
+ }
+}
diff --git a/org.jd.ide.eclipse.plugin/src/org/jd/ide/eclipse/preferences/PreferenceInitializer.java b/org.jd.ide.eclipse.plugin/src/org/jd/ide/eclipse/preferences/PreferenceInitializer.java
new file mode 100644
index 0000000..2806c75
--- /dev/null
+++ b/org.jd.ide.eclipse.plugin/src/org/jd/ide/eclipse/preferences/PreferenceInitializer.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2008, 2019 Emmanuel Dupuy.
+ * This project is distributed under the GPLv3 license.
+ * This is a Copyleft license that gives the user the right to use,
+ * copy and modify the code freely for non-commercial purposes.
+ */
+
+package org.jd.ide.eclipse.preferences;
+
+import org.jd.ide.eclipse.JavaDecompilerPlugin;
+
+import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
+import org.eclipse.jface.preference.IPreferenceStore;
+
+/**
+ * Class used to initialize default preference values.
+ *
+ * @project Java Decompiler Eclipse Plugin
+ * @version 0.1.3
+ */
+public class PreferenceInitializer extends AbstractPreferenceInitializer {
+ /**
+ * @see org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer#initializeDefaultPreferences()
+ */
+ public void initializeDefaultPreferences() {
+ IPreferenceStore store = JavaDecompilerPlugin.getDefault().getPreferenceStore();
+ store.setDefault(JavaDecompilerPlugin.PREF_ESCAPE_UNICODE_CHARACTERS, false);
+ store.setDefault(JavaDecompilerPlugin.PREF_REALIGN_LINE_NUMBERS, true);
+ store.setDefault(JavaDecompilerPlugin.PREF_SHOW_LINE_NUMBERS, true);
+ store.setDefault(JavaDecompilerPlugin.PREF_SHOW_METADATA, true);
+ }
+}
diff --git a/org.jd.ide.eclipse.plugin/src/org/jd/ide/eclipse/preferences/PreferencePage.java b/org.jd.ide.eclipse.plugin/src/org/jd/ide/eclipse/preferences/PreferencePage.java
new file mode 100644
index 0000000..7a092a8
--- /dev/null
+++ b/org.jd.ide.eclipse.plugin/src/org/jd/ide/eclipse/preferences/PreferencePage.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2008, 2019 Emmanuel Dupuy.
+ * This project is distributed under the GPLv3 license.
+ * This is a Copyleft license that gives the user the right to use,
+ * copy and modify the code freely for non-commercial purposes.
+ */
+
+package org.jd.ide.eclipse.preferences;
+
+import org.jd.ide.eclipse.JavaDecompilerPlugin;
+
+import org.eclipse.jface.preference.BooleanFieldEditor;
+import org.eclipse.jface.preference.FieldEditorPreferencePage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+
+/**
+ * PreferencePage
+ *
+ * @project Java Decompiler Eclipse Plugin
+ * @version 0.1.3
+ */
+public class PreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage {
+ public PreferencePage() {
+ super(SWT.NONE);
+ setDescription("JD-Eclipse preference page");
+ }
+
+ /**
+ * Creates the field editors. Field editors are abstractions of
+ * the common GUI blocks needed to manipulate various types
+ * of preferences. Each field editor knows how to save and
+ * restore itself.
+ */
+ public void createFieldEditors() {
+ Composite fieldEditorParent = getFieldEditorParent();
+
+ new Label(fieldEditorParent, SWT.NONE);
+
+ addField(new BooleanFieldEditor(
+ JavaDecompilerPlugin.PREF_ESCAPE_UNICODE_CHARACTERS,
+ "Escape unicode characters", fieldEditorParent));
+ addField(new BooleanFieldEditor(
+ JavaDecompilerPlugin.PREF_REALIGN_LINE_NUMBERS,
+ "Realign line numbers", fieldEditorParent));
+ addField(new BooleanFieldEditor(
+ JavaDecompilerPlugin.PREF_SHOW_LINE_NUMBERS,
+ "Show original line numbers", fieldEditorParent));
+ addField(new BooleanFieldEditor(
+ JavaDecompilerPlugin.PREF_SHOW_METADATA,
+ "Show metadata", fieldEditorParent));
+ }
+
+ /**
+ * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
+ */
+ public void init(IWorkbench workbench) {
+ setPreferenceStore(JavaDecompilerPlugin.getDefault().getPreferenceStore());
+ }
+}
\ No newline at end of file
diff --git a/org.jd.ide.eclipse.plugin/src/org/jd/ide/eclipse/startup/JDStartupClass.java b/org.jd.ide.eclipse.plugin/src/org/jd/ide/eclipse/startup/JDStartupClass.java
new file mode 100644
index 0000000..28b18bf
--- /dev/null
+++ b/org.jd.ide.eclipse.plugin/src/org/jd/ide/eclipse/startup/JDStartupClass.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2008, 2019 Emmanuel Dupuy.
+ * This project is distributed under the GPLv3 license.
+ * This is a Copyleft license that gives the user the right to use,
+ * copy and modify the code freely for non-commercial purposes.
+ */
+
+package org.jd.ide.eclipse.startup;
+
+import org.eclipse.ui.IStartup;
+
+/**
+ * JDStartupClass
+ *
+ * @project Java Decompiler Eclipse Plugin
+ * @version 0.1.4
+ */
+public class JDStartupClass implements IStartup {
+ public void earlyStartup() {}
+}
diff --git a/org.jd.ide.eclipse.plugin/src/org/jd/ide/eclipse/util/loader/DirectoryLoader.java b/org.jd.ide.eclipse.plugin/src/org/jd/ide/eclipse/util/loader/DirectoryLoader.java
new file mode 100644
index 0000000..9f184cd
--- /dev/null
+++ b/org.jd.ide.eclipse.plugin/src/org/jd/ide/eclipse/util/loader/DirectoryLoader.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2008, 2019 Emmanuel Dupuy.
+ * This project is distributed under the GPLv3 license.
+ * This is a Copyleft license that gives the user the right to use,
+ * copy and modify the code freely for non-commercial purposes.
+ */
+
+package org.jd.ide.eclipse.util.loader;
+
+import org.jd.core.v1.api.loader.Loader;
+import org.jd.core.v1.api.loader.LoaderException;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+public class DirectoryLoader implements Loader {
+ protected File root;
+
+ public DirectoryLoader(File root) throws LoaderException {
+ this.root = root;
+ }
+
+ @Override
+ public byte[] load(String internalName) throws LoaderException {
+ File file = new File(root, internalName + ".class");
+
+ try (FileInputStream in=new FileInputStream(file); ByteArrayOutputStream out=new ByteArrayOutputStream()) {
+ byte[] buffer = new byte[1024];
+ int read = in.read(buffer);
+
+ while (read > 0) {
+ out.write(buffer, 0, read);
+ read = in.read(buffer);
+ }
+
+ return out.toByteArray();
+ } catch (IOException e) {
+ throw new LoaderException(e);
+ }
+ }
+
+ @Override
+ public boolean canLoad(String internalName) {
+ return new File(root, internalName + ".class").exists();
+ }
+}
diff --git a/org.jd.ide.eclipse.plugin/src/org/jd/ide/eclipse/util/loader/ZipLoader.java b/org.jd.ide.eclipse.plugin/src/org/jd/ide/eclipse/util/loader/ZipLoader.java
new file mode 100644
index 0000000..dab834d
--- /dev/null
+++ b/org.jd.ide.eclipse.plugin/src/org/jd/ide/eclipse/util/loader/ZipLoader.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2008, 2019 Emmanuel Dupuy.
+ * This project is distributed under the GPLv3 license.
+ * This is a Copyleft license that gives the user the right to use,
+ * copy and modify the code freely for non-commercial purposes.
+ */
+
+package org.jd.ide.eclipse.util.loader;
+
+import org.jd.core.v1.api.loader.Loader;
+import org.jd.core.v1.api.loader.LoaderException;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+public class ZipLoader implements Loader {
+ protected HashMap map = new HashMap<>();
+
+ public ZipLoader(File zip) throws LoaderException {
+ byte[] buffer = new byte[1024 * 2];
+
+ try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zip))) {
+ ZipEntry ze = zis.getNextEntry();
+
+ while (ze != null) {
+ if (ze.isDirectory() == false) {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ int read = zis.read(buffer);
+
+ while (read > 0) {
+ out.write(buffer, 0, read);
+ read = zis.read(buffer);
+ }
+
+ map.put(ze.getName(), out.toByteArray());
+ }
+
+ ze = zis.getNextEntry();
+ }
+
+ zis.closeEntry();
+ } catch (IOException e) {
+ throw new LoaderException(e);
+ }
+ }
+
+ @Override
+ public byte[] load(String internalName) throws LoaderException {
+ return map.get(internalName + ".class");
+ }
+
+ @Override
+ public boolean canLoad(String internalName) {
+ return map.containsKey(internalName + ".class");
+ }
+}
diff --git a/org.jd.ide.eclipse.plugin/src/org/jd/ide/eclipse/util/printer/LineNumberStringBuilderPrinter.java b/org.jd.ide.eclipse.plugin/src/org/jd/ide/eclipse/util/printer/LineNumberStringBuilderPrinter.java
new file mode 100644
index 0000000..1930949
--- /dev/null
+++ b/org.jd.ide.eclipse.plugin/src/org/jd/ide/eclipse/util/printer/LineNumberStringBuilderPrinter.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2008, 2019 Emmanuel Dupuy.
+ * This project is distributed under the GPLv3 license.
+ * This is a Copyleft license that gives the user the right to use,
+ * copy and modify the code freely for non-commercial purposes.
+ */
+
+package org.jd.ide.eclipse.util.printer;
+
+public class LineNumberStringBuilderPrinter extends StringBuilderPrinter {
+ protected boolean showLineNumbers = false;
+
+ protected int maxLineNumber = 0;
+ protected int digitCount = 0;
+
+ protected String lineNumberBeginPrefix;
+ protected String lineNumberEndPrefix;
+ protected String unknownLineNumberPrefix;
+
+ public void setShowLineNumbers(boolean showLineNumbers) { this.showLineNumbers = showLineNumbers; }
+
+ protected int printDigit(int dcv, int lineNumber, int divisor, int left) {
+ if (digitCount >= dcv) {
+ if (lineNumber < divisor) {
+ stringBuffer.append(' ');
+ } else {
+ int e = (lineNumber-left) / divisor;
+ stringBuffer.append((char)('0' + e));
+ left += e*divisor;
+ }
+ }
+
+ return left;
+ }
+
+ // --- Printer --- //
+ @Override
+ public void start(int maxLineNumber, int majorVersion, int minorVersion) {
+ super.start(maxLineNumber, majorVersion, minorVersion);
+
+ if (showLineNumbers) {
+ this.maxLineNumber = maxLineNumber;
+
+ if (maxLineNumber > 0) {
+ digitCount = 1;
+ unknownLineNumberPrefix = " ";
+ int maximum = 9;
+
+ while (maximum < maxLineNumber) {
+ digitCount++;
+ unknownLineNumberPrefix += ' ';
+ maximum = maximum*10 + 9;
+ }
+
+ lineNumberBeginPrefix = "/* ";
+ lineNumberEndPrefix = " */ ";
+ } else {
+ unknownLineNumberPrefix = "";
+ lineNumberBeginPrefix = "";
+ lineNumberEndPrefix = "";
+ }
+ } else {
+ this.maxLineNumber = 0;
+ unknownLineNumberPrefix = "";
+ lineNumberBeginPrefix = "";
+ lineNumberEndPrefix = "";
+ }
+ }
+
+ @Override public void startLine(int lineNumber) {
+ if (maxLineNumber > 0) {
+ stringBuffer.append(lineNumberBeginPrefix);
+
+ if (lineNumber == UNKNOWN_LINE_NUMBER) {
+ stringBuffer.append(unknownLineNumberPrefix);
+ } else {
+ int left = 0;
+
+ left = printDigit(5, lineNumber, 10000, left);
+ left = printDigit(4, lineNumber, 1000, left);
+ left = printDigit(3, lineNumber, 100, left);
+ left = printDigit(2, lineNumber, 10, left);
+ stringBuffer.append((char)('0' + (lineNumber-left)));
+ }
+
+ stringBuffer.append(lineNumberEndPrefix);
+ }
+
+ for (int i=0; i 0) {
+ if (maxLineNumber > 0) {
+ stringBuffer.append(lineNumberBeginPrefix);
+ stringBuffer.append(unknownLineNumberPrefix);
+ stringBuffer.append(lineNumberEndPrefix);
+ }
+
+ stringBuffer.append(NEWLINE);
+ }
+ }
+ }
+}
diff --git a/org.jd.ide.eclipse.plugin/src/org/jd/ide/eclipse/util/printer/StringBuilderPrinter.java b/org.jd.ide.eclipse.plugin/src/org/jd/ide/eclipse/util/printer/StringBuilderPrinter.java
new file mode 100644
index 0000000..118720c
--- /dev/null
+++ b/org.jd.ide.eclipse.plugin/src/org/jd/ide/eclipse/util/printer/StringBuilderPrinter.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2008, 2019 Emmanuel Dupuy.
+ * This project is distributed under the GPLv3 license.
+ * This is a Copyleft license that gives the user the right to use,
+ * copy and modify the code freely for non-commercial purposes.
+ */
+
+package org.jd.ide.eclipse.util.printer;
+
+import org.jd.core.v1.api.printer.Printer;
+
+public class StringBuilderPrinter implements Printer {
+ protected static final String TAB = " ";
+ protected static final String NEWLINE = "\n";
+
+ protected StringBuilder stringBuffer = new StringBuilder(10*1024);
+
+ protected boolean unicodeEscape = true;
+ protected boolean realignmentLineNumber = false;
+
+ protected int majorVersion = 0;
+ protected int minorVersion = 0;
+ protected int indentationCount;
+
+ public void setUnicodeEscape(boolean unicodeEscape) { this.unicodeEscape = unicodeEscape; }
+ public void setRealignmentLineNumber(boolean realignmentLineNumber) { this.realignmentLineNumber = realignmentLineNumber; }
+
+ public int getMajorVersion() { return majorVersion; }
+ public int getMinorVersion() { return minorVersion; }
+ public StringBuilder getStringBuffer() { return stringBuffer; }
+
+ protected void escape(String s) {
+ if (unicodeEscape && (s != null)) {
+ int length = s.length();
+
+ for (int i=0; i> 3)));
+ stringBuffer.append((char) ('0' + (c & 0x7)));
+ } else if (c > 127) {
+ // Write octal format
+ stringBuffer.append("\\u");
+
+ int z = (c >> 12);
+ stringBuffer.append((char) ((z <= 9) ? ('0' + z) : (('A' - 10) + z)));
+ z = ((c >> 8) & 0xF);
+ stringBuffer.append((char) ((z <= 9) ? ('0' + z) : (('A' - 10) + z)));
+ z = ((c >> 4) & 0xF);
+ stringBuffer.append((char) ((z <= 9) ? ('0' + z) : (('A' - 10) + z)));
+ z = (c & 0xF);
+ stringBuffer.append((char) ((z <= 9) ? ('0' + z) : (('A' - 10) + z)));
+ } else {
+ stringBuffer.append(c);
+ }
+ }
+ } else {
+ stringBuffer.append(s);
+ }
+ }
+
+ // --- Printer --- //
+ @Override
+ public void start(int maxLineNumber, int majorVersion, int minorVersion) {
+ this.stringBuffer.setLength(0);
+ this.majorVersion = majorVersion;
+ this.minorVersion = minorVersion;
+ this.indentationCount = 0;
+ }
+
+ @Override public void end() {}
+
+ @Override public void printText(String text) { escape(text); }
+ @Override public void printNumericConstant(String constant) { escape(constant); }
+ @Override public void printStringConstant(String constant, String ownerInternalName) { escape(constant); }
+ @Override public void printKeyword(String keyword) { stringBuffer.append(keyword); }
+
+ @Override public void printDeclaration(int type, String internalTypeName, String name, String descriptor) { escape(name); }
+ @Override public void printReference(int type, String internalTypeName, String name, String descriptor, String ownerInternalName) { escape(name); }
+
+ @Override public void indent() { indentationCount++; }
+ @Override public void unindent() { if (indentationCount > 0) indentationCount--; }
+
+ @Override public void startLine(int lineNumber) { for (int i=0; i 0) stringBuffer.append(NEWLINE); }
+
+ @Override public void startMarker(int type) {}
+ @Override public void endMarker(int type) {}
+}
diff --git a/org.jd.ide.eclipse.site/.project b/org.jd.ide.eclipse.site/.project
new file mode 100644
index 0000000..7862459
--- /dev/null
+++ b/org.jd.ide.eclipse.site/.project
@@ -0,0 +1,17 @@
+
+
+ jd.ide.eclipse.site
+
+
+
+
+
+ org.eclipse.pde.UpdateSiteBuilder
+
+
+
+
+
+ org.eclipse.pde.UpdateSiteNature
+
+
diff --git a/org.jd.ide.eclipse.site/site.xml b/org.jd.ide.eclipse.site/site.xml
new file mode 100644
index 0000000..91c5031
--- /dev/null
+++ b/org.jd.ide.eclipse.site/site.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/settings.gradle b/settings.gradle
index ea0e698..65c50a0 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1 +1 @@
-include 'jd.ide.eclipse.plugin', 'jd.ide.eclipse.feature'
+include 'org.jd.ide.eclipse.plugin', 'org.jd.ide.eclipse.feature'