/*
* 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.gui.view.component;
import org.jd.gui.api.API;
import org.jd.gui.api.feature.*;
import org.jd.gui.api.model.Container;
import org.jd.gui.api.model.Indexes;
import javax.swing.*;
import java.awt.*;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.Future;
public class DynamicPage
extends JPanel
implements ContentCopyable, ContentSavable, ContentSearchable, ContentSelectable, FocusedTypeGettable,
IndexesChangeListener, LineNumberNavigable, PreferencesChangeListener, UriGettable, UriOpenable,
API.LoadSourceListener
{
protected API api;
protected Container.Entry entry;
protected TypePage page;
protected URI lastOpenedUri;
protected Collection<Future<Indexes>> lastCollectionOfFutureIndexes;
public DynamicPage(API api, Container.Entry entry) {
super(new BorderLayout());
this.api = api;
this.entry = entry;
String source = api.getSource(entry);
if (source == null) {
// Display the decompiled source code
add(page = new ClassFilePage(api, entry));
// Try to load source in background
api.loadSource(entry, this);
} else {
// Display original source code
add(page = new JavaFilePage(api, new DelegatedEntry(entry, source)));
}
}
// --- ContentCopyable --- //
@Override public void copy() { page.copy(); }
// --- ContentSavable --- //
@Override public String getFileName() { return page.getFileName(); }
@Override public void save(API api, OutputStream outputStream) { page.save(api, outputStream); }
// --- ContentSearchable --- //
@Override public boolean highlightText(String text, boolean caseSensitive) { return page.highlightText(text, caseSensitive); }
@Override public void findNext(String text, boolean caseSensitive) { page.findNext(text, caseSensitive); }
@Override public void findPrevious(String text, boolean caseSensitive) { page.findPrevious(text, caseSensitive); }
// --- ContentSelectable --- //
@Override public void selectAll() { page.selectAll(); }
// --- FocusedTypeGettable --- //
@Override public String getFocusedTypeName() { return page.getFocusedTypeName(); }
// --- ContainerEntryGettable --- //
@Override public Container.Entry getEntry() { return entry; }
// --- IndexesChangeListener --- //
@Override public void indexesChanged(Collection<Future<Indexes>> collectionOfFutureIndexes) {
page.indexesChanged(lastCollectionOfFutureIndexes = collectionOfFutureIndexes);
}
// --- LineNumberNavigable --- //
@Override public int getMaximumLineNumber() { return page.getMaximumLineNumber(); }
@Override public void goToLineNumber(int lineNumber) { page.goToLineNumber(lineNumber); }
@Override public boolean checkLineNumber(int lineNumber) { return page.checkLineNumber(lineNumber); }
// --- PreferencesChangeListener --- //
@Override public void preferencesChanged(Map<String, String> preferences) { page.preferencesChanged(preferences); }
// --- UriGettable --- //
@Override public URI getUri() { return entry.getUri(); }
// --- UriOpenable --- //
@Override public boolean openUri(URI uri) { return page.openUri(lastOpenedUri = uri); }
// --- LoadSourceListener --- //
@Override public void sourceLoaded(String source) {
SwingUtilities.invokeLater(() -> {
// Replace the decompiled source code by the original
Point viewPosition = page.getScrollPane().getViewport().getViewPosition();
removeAll();
add(page = new JavaFilePage(api, new DelegatedEntry(entry, source)));
page.getScrollPane().getViewport().setViewPosition(viewPosition);
if (lastOpenedUri != null) {
page.openUri(lastOpenedUri);
}
if (lastCollectionOfFutureIndexes != null) {
page.indexesChanged(lastCollectionOfFutureIndexes);
}
});
}
protected static class DelegatedEntry implements Container.Entry {
protected Container.Entry entry;
protected String source;
DelegatedEntry(Container.Entry entry, String source) {
this.entry = entry;
this.source = source;
}
@Override public Container getContainer() { return entry.getContainer(); }
@Override public Container.Entry getParent() { return entry.getParent(); }
@Override public URI getUri() { return entry.getUri(); }
@Override public String getPath() { return entry.getPath(); }
@Override public boolean isDirectory() { return entry.isDirectory(); }
@Override public long length() { return entry.length(); }
@Override public InputStream getInputStream() { return new ByteArrayInputStream(source.getBytes()); }
@Override public Collection<Container.Entry> getChildren() { return entry.getChildren(); }
}
}