Resource Refactoring

This introduces the Resource object which can be either a ClassFile or any other File type

ClassFiles get opened as a ClassViewer with mutliple BytecodeViewPanels

Everything else gets opened as a FileViewer
This commit is contained in:
Konloch 2021-07-14 04:58:35 -07:00
parent b9b8d44cc1
commit d8e2e6ab0f
12 changed files with 81 additions and 75 deletions

View file

@ -313,7 +313,7 @@ public class BytecodeViewer
*/
public static ClassNode getCurrentlyOpenedClassNode()
{
return getActiveResource().viewerClassNode;
return getActiveResource().resource.getResourceClassNode();
}
/**

View file

@ -785,14 +785,6 @@ public class MainViewerGUI extends JFrame
rootMenu.updateUI();
});
}
public void openClassFile(final ResourceContainer container, final String name, final ClassNode cn) {
workPane.addClassResource(container, name, cn);
}
public void openFile(final ResourceContainer container, final String name, byte[] content) {
workPane.addFileResource(container, name, content);
}
public void compileOnNewThread()
{

View file

@ -304,21 +304,20 @@ public class ResourceListPane extends TranslatedVisibleComponent implements File
String name = nameBuffer.toString();
//TODO add file header check
if (name.endsWith(".class"))
{
final ClassNode cn = container.getClassNode(
name.substring(0, name.length() - ".class".length()));
if (cn != null)
BytecodeViewer.viewer.openClassFile(container, nameBuffer.toString(), cn);
BytecodeViewer.viewer.workPane.addClassResource(container, nameBuffer.toString());
else
BytecodeViewer.viewer.openFile(container, nameBuffer.toString(),
BytecodeViewer.getFileContents(nameBuffer.toString()));
BytecodeViewer.viewer.workPane.addFileResource(container, nameBuffer.toString());
}
else
{
BytecodeViewer.viewer.openFile(container, nameBuffer.toString(),
BytecodeViewer.getFileContents(nameBuffer.toString()));
BytecodeViewer.viewer.workPane.addFileResource(container, nameBuffer.toString());
}
}

View file

@ -149,7 +149,7 @@ public class SearchBoxPane extends TranslatedVisibleComponent
final ClassNode fN = Objects.requireNonNull(container).getClassNode(className);
if (fN != null)
BytecodeViewer.viewer.openClassFile(container, className + ".class", fN);
BytecodeViewer.viewer.workPane.addClassResource(container, className + ".class");
}
catch (Exception e)
{
@ -188,7 +188,7 @@ public class SearchBoxPane extends TranslatedVisibleComponent
final ResourceViewer cv = BytecodeViewer.getActiveResource();
if (cv != null)
searchType.details.search(cv.container, cv.viewerClassNode, srn, exact.isSelected());
searchType.details.search(cv.resource.container, cv.resource.getResourceClassNode(), srn, exact.isSelected());
}
}

View file

@ -61,7 +61,7 @@ public class BytecodeViewPanel
panel.removeAll();
textArea = null;
if(viewer.viewerClassNode == null)
if(viewer.resource == null || viewer.resource.getResourceClassNode() == null)
panel.add(new JLabel("ERROR: Resource Viewer Corrupt ClassNode"));
}
@ -76,7 +76,7 @@ public class BytecodeViewPanel
return true;
SystemConsole errConsole = new SystemConsole("Java Compile Issues");
errConsole.setText("Error compiling class: " + viewer.viewerClassNode.name +
errConsole.setText("Error compiling class: " + viewer.resource.getResourceClassNode().name +
nl + "Keep in mind most decompilers cannot produce compilable classes" +
nl + nl + TranslatedStrings.SUGGESTED_FIX_COMPILER_ERROR +
nl + nl);
@ -84,12 +84,12 @@ public class BytecodeViewPanel
try
{
String text = textArea.getText();
byte[] compiledClass = compiler.getCompiler().compile(text, viewer.viewerClassNode.name);
byte[] compiledClass = compiler.getCompiler().compile(text, viewer.resource.getResourceClassNode().name);
if (compiledClass != null)
{
ClassNode newNode = JarUtils.getNode(compiledClass);
viewer.container.updateNode(viewer.name, newNode);
viewer.resource.container.updateNode(viewer.resource.name, newNode);
errConsole.finished();
return true;
}

View file

@ -3,6 +3,8 @@ package the.bytecode.club.bytecodeviewer.gui.resourceviewer;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer.ClassViewer;
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer.FileViewer;
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer.ResourceViewer;
import the.bytecode.club.bytecodeviewer.resources.Resource;
import java.awt.*;
import java.awt.event.ContainerEvent;
@ -21,16 +23,7 @@ public class TabRemovalEvent implements ContainerListener
public void componentRemoved(ContainerEvent e)
{
final Component c = e.getChild();
if (c instanceof ClassViewer)
{
String workingName = ((ClassViewer) c).workingName;
BytecodeViewer.viewer.workPane.openedTabs.remove(workingName);
}
else if (c instanceof FileViewer)
{
String workingName = ((FileViewer) c).workingName;
BytecodeViewer.viewer.workPane.openedTabs.remove(workingName);
}
String workingName = ((ResourceViewer) c).resource.workingName;
BytecodeViewer.viewer.workPane.openedTabs.remove(workingName);
}
}

View file

@ -161,18 +161,15 @@ public class WorkPaneMainComponent extends TranslatedVisibleComponent
}
//load class resources
public void addClassResource(final ResourceContainer container, final String name, final ClassNode cn)
public void addClassResource(final ResourceContainer container, final String name)
{
addResource(container, name, new ClassViewer(container, name, cn));
addResource(container, name, new ClassViewer(container, name));
}
//Load file resources
public void addFileResource(final ResourceContainer container, final String name, byte[] contents)
public void addFileResource(final ResourceContainer container, final String name)
{
if (contents == null) //a directory
return;
addResource(container, name, new FileViewer(container, name, contents));
addResource(container, name, new FileViewer(container, name));
}
private void addResource(final ResourceContainer container, final String name, final ResourceViewer resourceView)
@ -187,7 +184,7 @@ public class WorkPaneMainComponent extends TranslatedVisibleComponent
((ClassViewer)resourceView).refresh(null);
}
resourceView.workingName = workingName;
resourceView.resource.workingName = workingName;
tabs.add(resourceView);
final int tabIndex = tabs.indexOfComponent(resourceView);
@ -205,7 +202,7 @@ public class WorkPaneMainComponent extends TranslatedVisibleComponent
for(int i = 0; i < tabs.getTabCount(); i++)
{
ResourceViewer tab = ((TabbedPane)tabs.getTabComponentAt(i)).resource;
if(tab.workingName.equals(workingName))
if(tab.resource.workingName.equals(workingName))
{
tabs.setSelectedIndex(i);
break;

View file

@ -24,6 +24,7 @@ import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.Configuration;
import the.bytecode.club.bytecodeviewer.SettingsSerializer;
import the.bytecode.club.bytecodeviewer.resources.Resource;
import the.bytecode.club.bytecodeviewer.resources.ResourceContainer;
import the.bytecode.club.bytecodeviewer.util.MethodParser;
@ -64,18 +65,13 @@ public class ClassViewer extends ResourceViewer
public BytecodeViewPanel bytecodeViewPanel3 = new BytecodeViewPanel(2, this);
public List<MethodParser> methods = Arrays.asList(new MethodParser(), new MethodParser(), new MethodParser());
public final String workingName;
public ClassViewer(final ResourceContainer container, final String name, final ClassNode cn)
public ClassViewer(final ResourceContainer container, final String name)
{
this.workingName = container.getWorkingName(name);
this.container = container;
super(new Resource(name, container.getWorkingName(name), container));
this.name = name;
this.viewerClassNode = cn;
this.setName(name);
this.setLayout(new BorderLayout());
this.sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, bytecodeViewPanel1.panel, bytecodeViewPanel2.panel);
this.sp2 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, sp, bytecodeViewPanel3.panel);
this.add(sp2, BorderLayout.CENTER);
@ -91,8 +87,6 @@ public class ClassViewer extends ResourceViewer
@Override
public void refresh(final JButton button)
{
this.viewerClassNode = container.getClassNode(name); //update the classnode
setPanes();
refreshTitle();
@ -113,7 +107,7 @@ public class ClassViewer extends ResourceViewer
System.err.println("TODO: Update it to use the FileContainerImporter");
}
classBytes = ASMUtil.nodeToBytes(viewerClassNode);
classBytes = ASMUtil.nodeToBytes(resource.getResourceClassNode());
}
bytecodeViewPanel1.updatePane(this, classBytes, button, isPanel1Editable());

View file

@ -14,6 +14,7 @@ import the.bytecode.club.bytecodeviewer.Configuration;
import the.bytecode.club.bytecodeviewer.gui.components.ImageJLabel;
import the.bytecode.club.bytecodeviewer.gui.components.SearchableRSyntaxTextArea;
import the.bytecode.club.bytecodeviewer.gui.hexviewer.JHexEditor;
import the.bytecode.club.bytecodeviewer.resources.Resource;
import the.bytecode.club.bytecodeviewer.resources.ResourceContainer;
import the.bytecode.club.bytecodeviewer.resources.ResourceType;
import the.bytecode.club.bytecodeviewer.util.MiscUtils;
@ -45,22 +46,16 @@ import the.bytecode.club.bytecodeviewer.util.SyntaxLanguage;
public class FileViewer extends ResourceViewer
{
public final byte[] contents;
public final String workingName;
public final SearchableRSyntaxTextArea textArea = (SearchableRSyntaxTextArea)
Configuration.rstaTheme.apply(new SearchableRSyntaxTextArea());
public final JPanel mainPanel = new JPanel(new BorderLayout());
public BufferedImage image;
public boolean canRefresh;
public FileViewer(final ResourceContainer container, final String name, final byte[] contents)
public FileViewer(final ResourceContainer container, final String name)
{
this.name = name;
this.contents = contents;
this.workingName = container.getWorkingName(name);
this.container = container;
super(new Resource(name, container.getWorkingName(name), container));
this.setName(name);
this.setLayout(new BorderLayout());
@ -71,7 +66,8 @@ public class FileViewer extends ResourceViewer
public void setContents()
{
final String nameLowerCase = this.name.toLowerCase();
final byte[] contents = resource.getResourceBytes();
final String nameLowerCase = this.resource.name.toLowerCase();
final String onlyName = FilenameUtils.getName(nameLowerCase);
final String contentsAsString = new String(contents);
@ -144,7 +140,7 @@ public class FileViewer extends ResourceViewer
mainPanel.removeAll();
image = MiscUtils.loadImage(image, contents);
image = MiscUtils.loadImage(image, resource.getResourceBytes());
JLabel label = new JLabel("", new ImageIcon(image), JLabel.CENTER);
mainPanel.add(label, BorderLayout.CENTER);

View file

@ -2,10 +2,9 @@ package the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer;
import javax.swing.*;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.Configuration;
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.TabbedPane;
import the.bytecode.club.bytecodeviewer.resources.ResourceContainer;
import the.bytecode.club.bytecodeviewer.resources.Resource;
import the.bytecode.club.bytecodeviewer.util.MiscUtils;
/***************************************************************************
@ -34,23 +33,22 @@ import the.bytecode.club.bytecodeviewer.util.MiscUtils;
public abstract class ResourceViewer extends JPanel
{
public ClassNode viewerClassNode;
public String name;
public String workingName;
public ResourceContainer container;
public final Resource resource;
public TabbedPane tabbedPane;
protected ResourceViewer(Resource resource) {this.resource = resource;}
/**
* Returns the tab name
*/
public String getTabName()
{
String tabName = name;
String tabName = resource.name;
if (Configuration.simplifiedTabNames)
tabName = MiscUtils.getChildFromPath(tabName);
if (Configuration.displayParentInTab)
tabName = container.name + ">" + tabName;
tabName = resource.container.name + ">" + tabName;
return tabName;
}
@ -60,7 +58,7 @@ public abstract class ResourceViewer extends JPanel
*/
public byte[] getResourceBytes()
{
return container.getFileContents(name);
return resource.getResourceBytes();
}

View file

@ -60,7 +60,7 @@ public class BytecodeViewPanelUpdater implements Runnable
public final ClassViewer viewer;
public final BytecodeViewPanel bytecodeViewPanel;
private final JButton button;
private final byte[] b;
private final byte[] classBytes;
public SearchableRSyntaxTextArea updateUpdaterTextArea;
@ -69,11 +69,11 @@ public class BytecodeViewPanelUpdater implements Runnable
public boolean waitingFor;
private Thread thread;
public BytecodeViewPanelUpdater(BytecodeViewPanel bytecodeViewPanel, ClassViewer cv, byte[] b, boolean isPanelEditable, JButton button)
public BytecodeViewPanelUpdater(BytecodeViewPanel bytecodeViewPanel, ClassViewer cv, byte[] classBytes, boolean isPanelEditable, JButton button)
{
this.viewer = cv;
this.bytecodeViewPanel = bytecodeViewPanel;
this.b = b;
this.classBytes = classBytes;
this.isPanelEditable = isPanelEditable;
this.button = button;
waitingFor = true;
@ -91,7 +91,7 @@ public class BytecodeViewPanelUpdater implements Runnable
if (bytecodeViewPanel.decompiler == Decompiler.HEXCODE_VIEWER)
{
final ClassWriter cw = new ClassWriter(0);
viewer.viewerClassNode.accept(cw);
viewer.resource.getResourceClassNode().accept(cw);
SwingUtilities.invokeLater(() ->
{
@ -106,7 +106,7 @@ public class BytecodeViewPanelUpdater implements Runnable
final Decompiler decompiler = bytecodeViewPanel.decompiler;
//perform decompiling inside of this thread
final String decompiledSource = decompiler.getDecompiler().decompileClassNode(viewer.viewerClassNode, b);
final String decompiledSource = decompiler.getDecompiler().decompileClassNode(viewer.resource.getResourceClassNode(), classBytes);
//set the swing components on the swing thread
SwingUtilities.invokeLater(() ->

View file

@ -0,0 +1,37 @@
package the.bytecode.club.bytecodeviewer.resources;
import org.objectweb.asm.tree.ClassNode;
/**
* @author Konloch
* @since 7/14/2021
*/
public class Resource
{
public final String name;
public String workingName;
public final ResourceContainer container;
public Resource(String name, String workingName, ResourceContainer container)
{
this.name = name;
this.workingName = workingName;
this.container = container;
}
/**
* Returns the resource bytes from the resource container
*/
public byte[] getResourceBytes()
{
return container.getFileContents(name);
}
/**
* Returns the resource bytes from the resource container
*/
public ClassNode getResourceClassNode()
{
return container.getClassNode(name);
}
}