Skip to content

Commit

Permalink
Fixes java-decompiler#35, "Save All source dose not work"
Browse files Browse the repository at this point in the history
  • Loading branch information
emmanue1 committed Aug 11, 2015
1 parent 64442bb commit 12c9c35
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 57 deletions.
14 changes: 13 additions & 1 deletion api/src/main/java/org/jd/gui/spi/SourceSaver.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,19 @@ public interface SourceSaver {

public int getFileCount(API api, Container.Entry entry);

public void save(API api, Controller controller, Listener listener, Path path, Container.Entry entry);
/**
* Check parent path, build source file name, create NIO path and save the content.
*/
public void save(API api, Controller controller, Listener listener, Path rootPath, Container.Entry entry);

/**
* Save content:
* <ul>
* <li>For file, save the source content.</li>
* <li>For directory, call 'save' for each children.</li>
* </ul>
*/
public void saveContent(API api, Controller controller, Listener listener, Path rootPath, Path path, Container.Entry entry);

public interface Controller {
public boolean isCancelled();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,15 @@ import org.jd.gui.view.component.panel.TreeTabbedPanel
import javax.swing.JComponent
import javax.swing.tree.DefaultMutableTreeNode
import javax.swing.tree.DefaultTreeModel
import java.nio.file.FileSystems
import java.nio.file.Files
import java.nio.file.Path

class ContainerPanelFactoryProvider implements PanelFactory {

String[] getTypes() { ['default'] }
@Override String[] getTypes() { ['default'] }

@Override
public <T extends JComponent & UriGettable> T make(API api, Container container) {
return new ContainerPanel(api, container)
}
Expand All @@ -53,6 +56,7 @@ class ContainerPanelFactoryProvider implements PanelFactory {
}

// --- ContentIndexable --- //
@Override
@CompileStatic
Indexes index(API api) {
// Classic map
Expand All @@ -71,40 +75,54 @@ class ContainerPanelFactoryProvider implements PanelFactory {
}
// Index populating value automatically
def indexesWithDefault = new Indexes() {
void waitIndexers() {}
Map<String, Collection> getIndex(String name) {
mapWithDefault.get(name)
}
@Override void waitIndexers() {}
@Override Map<String, Collection> getIndex(String name) { mapWithDefault.get(name) }
}

api.getIndexer(entry)?.index(api, entry, indexesWithDefault)

// To prevent memory leaks, return an index without the 'populate' behaviour
return new Indexes() {
void waitIndexers() {}
Map<String, Collection> getIndex(String name) { map.get(name) }
@Override void waitIndexers() {}
@Override Map<String, Collection> getIndex(String name) { map.get(name) }
}
}

// --- SourcesSavable --- //
@Override
String getSourceFileName() {
def path = api.getSourceSaver(entry)?.getSourcePath(entry)
int index = path.lastIndexOf('/')
return path.substring(index+1)
}

int getFileCount() { api.getSourceSaver(entry)?.getFileCount(api, entry) }
@Override int getFileCount() { api.getSourceSaver(entry)?.getFileCount(api, entry) }

@Override
void save(API api, Controller controller, Listener listener, Path path) {
api.getSourceSaver(entry)?.save(
def parentPath = path.parent

if (parentPath && !Files.exists(parentPath)) {
Files.createDirectories(parentPath)
}

def uri = path.toUri()
def archiveUri = new URI('jar:' + uri.scheme, uri.host, uri.path + '!/', null)
def archiveFs = FileSystems.newFileSystem(archiveUri, [create: 'true'])
def archiveRootPath = archiveFs.getPath('/')

api.getSourceSaver(entry)?.saveContent(
api,
new SourceSaver.Controller() {
boolean isCancelled() { controller.isCancelled() }
},
new SourceSaver.Listener() {
void pathSaved(Path p) { listener.pathSaved(p) }
},
path, entry)
archiveRootPath, archiveRootPath, entry
)

archiveFs.close()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ class DirectorySourceSaverProvider extends AbstractSourceSaverProvider {
/**
* @return local + optional external selectors
*/
String[] getSelectors() { ['*:dir:*'] + externalSelectors }
@Override String[] getSelectors() { ['*:dir:*'] + externalSelectors }

String getSourcePath(Container.Entry entry) { entry.path }
@Override String getSourcePath(Container.Entry entry) { entry.path + '.src.zip' }

int getFileCount(API api, Container.Entry entry) { getFileCount(api, entry.children) }
@Override int getFileCount(API api, Container.Entry entry) { getFileCount(api, entry.children) }

@CompileStatic
protected int getFileCount(API api, Collection<Container.Entry> entries) {
Expand All @@ -35,26 +35,27 @@ class DirectorySourceSaverProvider extends AbstractSourceSaverProvider {
return count
}

void save(API api, SourceSaver.Controller controller, SourceSaver.Listener listener, Path path, Container.Entry entry) {
save(api, controller, listener, path, entry.children)
}

@Override
@CompileStatic
protected void save(API api, SourceSaver.Controller controller, SourceSaver.Listener listener, Path path, Collection<Container.Entry> entries) {
public void save(API api, SourceSaver.Controller controller, SourceSaver.Listener listener, Path rootPath, Container.Entry entry) {
Path path = rootPath.resolve(entry.getPath())

Files.createDirectories(path)

for (def e : entries) {
saveContent(api, controller, listener, rootPath, path, entry);
}

@Override
@CompileStatic
public void saveContent(API api, SourceSaver.Controller controller, SourceSaver.Listener listener, Path rootPath, Path path, Container.Entry entry) {
for (def e : getChildren(entry)) {
if (controller.isCancelled()) {
break
}

def saver = api.getSourceSaver(e)

if (saver) {
def sp = saver.getSourcePath(e)
def p = path.fileSystem.getPath(sp)
saver.save(api, controller, listener, p, e)
}
api.getSourceSaver(e)?.save(api, controller, listener, rootPath, e)
}
}

protected Collection<Container.Entry> getChildren(Container.Entry entry) { entry.children }
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,21 @@ class FileSourceSaverProvider extends AbstractSourceSaverProvider {
/**
* @return local + optional external selectors
*/
String[] getSelectors() { ['*:file:*'] + externalSelectors }
@Override String[] getSelectors() { ['*:file:*'] + externalSelectors }

String getSourcePath(Container.Entry entry) { entry.path }
@Override String getSourcePath(Container.Entry entry) { entry.path }

int getFileCount(API api, Container.Entry entry) { 1 }
@Override int getFileCount(API api, Container.Entry entry) { 1 }

@Override
@CompileStatic
void save(API api, SourceSaver.Controller controller, SourceSaver.Listener listener, Path path, Container.Entry entry) {
public void save(API api, SourceSaver.Controller controller, SourceSaver.Listener listener, Path rootPath, Container.Entry entry) {
saveContent(api, controller, listener, rootPath, rootPath.resolve(entry.getPath()), entry);
}

@Override
@CompileStatic
void saveContent(API api, SourceSaver.Controller controller, SourceSaver.Listener listener, Path rootPath, Path path, Container.Entry entry) {
listener.pathSaved(path)

entry.inputStream.withStream { InputStream is ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,17 @@

package org.jd.gui.service.sourcesaver

import org.jd.gui.api.API
import org.jd.gui.api.model.Container
import org.jd.gui.spi.SourceSaver
import org.jd.gui.util.JarContainerEntryUtil

import java.nio.file.Path

class PackageSourceSaverProvider extends DirectorySourceSaverProvider {
/**
* @return local + optional external selectors
*/
String[] getSelectors() { ['jar:dir:*', 'war:dir:*', 'ear:dir:*'] + externalSelectors }
@Override String[] getSelectors() { ['jar:dir:*', 'war:dir:*', 'ear:dir:*'] + externalSelectors }

void save(API api, SourceSaver.Controller controller, SourceSaver.Listener listener, Path path, Container.Entry entry) {
save(api, controller, listener, path, JarContainerEntryUtil.removeInnerTypeEntries(entry.children))
@Override
protected Collection<Container.Entry> getChildren(Container.Entry entry) {
JarContainerEntryUtil.removeInnerTypeEntries(entry.children)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,31 +20,32 @@ class ZipFileSourceSaverProvider extends DirectorySourceSaverProvider {
/**
* @return local + optional external selectors
*/
String[] getSelectors() { ['*:file:*.zip', '*:file:*.jar', '*:file:*.war', '*:file:*.ear'] + externalSelectors }

String getSourcePath(Container.Entry entry) { entry.path + '.src.zip' }
@Override String[] getSelectors() { ['*:file:*.zip', '*:file:*.jar', '*:file:*.war', '*:file:*.ear'] + externalSelectors }

@Override
@CompileStatic
void save(API api, SourceSaver.Controller controller, SourceSaver.Listener listener, Path path, Container.Entry entry) {
public void save(API api, SourceSaver.Controller controller, SourceSaver.Listener listener, Path rootPath, Container.Entry entry) {
def sourcePath = getSourcePath(entry)
def path = rootPath.resolve(sourcePath)
def parentPath = path.parent

if (parentPath && !Files.exists(parentPath)) {
Files.createDirectories(parentPath)
}

def tmpFile = File.createTempFile('jd-gui.', '.tmp.zip')
tmpFile.delete()

def env = new HashMap<String, String>()
env.put('create', 'true')

def tmpFileUri = tmpFile.toURI()
def tmpURI = new URI('jar:' + tmpFileUri.scheme, tmpFileUri.host, tmpFileUri.path + '!/', null)
def tmpFs = FileSystems.newFileSystem(tmpURI, env);
def tmpArchiveUri = new URI('jar:' + tmpFileUri.scheme, tmpFileUri.host, tmpFileUri.path + '!/', null)
def tmpArchiveFs = FileSystems.newFileSystem(tmpArchiveUri, [create: 'true']);
def tmpArchiveRootPath = tmpArchiveFs.getPath('/')

super.save(api, controller, listener, tmpFs.getPath('/'), entry)
tmpFs.close()
saveContent(api, controller, listener, tmpArchiveRootPath, tmpArchiveRootPath, entry)

def tmpPath = Paths.get(tmpFile.absolutePath)
def srcZipParentPath = path.parent
tmpArchiveFs.close()

if (srcZipParentPath && !Files.exists(srcZipParentPath)) {
Files.createDirectories(srcZipParentPath)
}
def tmpPath = Paths.get(tmpFile.absolutePath)

Files.move(tmpPath, path)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

package org.jd.gui.service.sourcesaver;

import groovy.transform.CompileStatic;
import jd.core.CoreConstants;
import jd.core.Decompiler;
import jd.core.process.DecompilerImpl;
Expand Down Expand Up @@ -41,6 +40,7 @@ public class ClassFileSourceSaverProvider extends AbstractSourceSaverProvider {
/**
* @return local + optional external selectors
*/
@Override
public String[] getSelectors() {
List<String> externalSelectors = getExternalSelectors();

Expand All @@ -55,13 +55,15 @@ public String[] getSelectors() {
}
}

@Override
public String getSourcePath(Container.Entry entry) {
String path = entry.getPath();
int index = path.lastIndexOf('.');
String prefix = (index == -1) ? path : path.substring(0, index);
return prefix + ".java";
}

@Override
public int getFileCount(API api, Container.Entry entry) {
if (entry.getPath().indexOf('$') == -1) {
return 1;
Expand All @@ -70,7 +72,16 @@ public int getFileCount(API api, Container.Entry entry) {
}
}

public void save(API api, Controller controller, Listener listener, Path path, Container.Entry entry) {
@Override
public void save(API api, Controller controller, Listener listener, Path rootPath, Container.Entry entry) {
String sourcePath = getSourcePath(entry);
Path path = rootPath.resolve(sourcePath);

saveContent(api, controller, listener, rootPath, path, entry);
}

@Override
public void saveContent(API api, Controller controller, Listener listener, Path rootPath, Path path, Container.Entry entry) {
try {
// Call listener
if (path.toString().indexOf('$') == -1) {
Expand Down Expand Up @@ -137,7 +148,6 @@ public void save(API api, Controller controller, Listener listener, Path path, C
}
}

@CompileStatic
protected static boolean getPreferenceValue(Map<String, String> preferences, String key, boolean defaultValue) {
String v = preferences.get(key);

Expand Down

0 comments on commit 12c9c35

Please sign in to comment.