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() public static ClassNode getCurrentlyOpenedClassNode()
{ {
return getActiveResource().viewerClassNode; return getActiveResource().resource.getResourceClassNode();
} }
/** /**

View file

@ -786,14 +786,6 @@ public class MainViewerGUI extends JFrame
}); });
} }
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() public void compileOnNewThread()
{ {
Thread t = new Thread(() -> BytecodeViewer.compile(true, true), "Compile"); Thread t = new Thread(() -> BytecodeViewer.compile(true, true), "Compile");

View file

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

View file

@ -149,7 +149,7 @@ public class SearchBoxPane extends TranslatedVisibleComponent
final ClassNode fN = Objects.requireNonNull(container).getClassNode(className); final ClassNode fN = Objects.requireNonNull(container).getClassNode(className);
if (fN != null) if (fN != null)
BytecodeViewer.viewer.openClassFile(container, className + ".class", fN); BytecodeViewer.viewer.workPane.addClassResource(container, className + ".class");
} }
catch (Exception e) catch (Exception e)
{ {
@ -188,7 +188,7 @@ public class SearchBoxPane extends TranslatedVisibleComponent
final ResourceViewer cv = BytecodeViewer.getActiveResource(); final ResourceViewer cv = BytecodeViewer.getActiveResource();
if (cv != null) 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(); panel.removeAll();
textArea = null; textArea = null;
if(viewer.viewerClassNode == null) if(viewer.resource == null || viewer.resource.getResourceClassNode() == null)
panel.add(new JLabel("ERROR: Resource Viewer Corrupt ClassNode")); panel.add(new JLabel("ERROR: Resource Viewer Corrupt ClassNode"));
} }
@ -76,7 +76,7 @@ public class BytecodeViewPanel
return true; return true;
SystemConsole errConsole = new SystemConsole("Java Compile Issues"); 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 + "Keep in mind most decompilers cannot produce compilable classes" +
nl + nl + TranslatedStrings.SUGGESTED_FIX_COMPILER_ERROR + nl + nl + TranslatedStrings.SUGGESTED_FIX_COMPILER_ERROR +
nl + nl); nl + nl);
@ -84,12 +84,12 @@ public class BytecodeViewPanel
try try
{ {
String text = textArea.getText(); 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) if (compiledClass != null)
{ {
ClassNode newNode = JarUtils.getNode(compiledClass); ClassNode newNode = JarUtils.getNode(compiledClass);
viewer.container.updateNode(viewer.name, newNode); viewer.resource.container.updateNode(viewer.resource.name, newNode);
errConsole.finished(); errConsole.finished();
return true; 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.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer.ClassViewer; 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.FileViewer;
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer.ResourceViewer;
import the.bytecode.club.bytecodeviewer.resources.Resource;
import java.awt.*; import java.awt.*;
import java.awt.event.ContainerEvent; import java.awt.event.ContainerEvent;
@ -21,16 +23,7 @@ public class TabRemovalEvent implements ContainerListener
public void componentRemoved(ContainerEvent e) public void componentRemoved(ContainerEvent e)
{ {
final Component c = e.getChild(); final Component c = e.getChild();
String workingName = ((ResourceViewer) c).resource.workingName;
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); BytecodeViewer.viewer.workPane.openedTabs.remove(workingName);
} }
} }
}

View file

@ -161,18 +161,15 @@ public class WorkPaneMainComponent extends TranslatedVisibleComponent
} }
//load class resources //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 //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 addResource(container, name, new FileViewer(container, name));
return;
addResource(container, name, new FileViewer(container, name, contents));
} }
private void addResource(final ResourceContainer container, final String name, final ResourceViewer resourceView) 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); ((ClassViewer)resourceView).refresh(null);
} }
resourceView.workingName = workingName; resourceView.resource.workingName = workingName;
tabs.add(resourceView); tabs.add(resourceView);
final int tabIndex = tabs.indexOfComponent(resourceView); final int tabIndex = tabs.indexOfComponent(resourceView);
@ -205,7 +202,7 @@ public class WorkPaneMainComponent extends TranslatedVisibleComponent
for(int i = 0; i < tabs.getTabCount(); i++) for(int i = 0; i < tabs.getTabCount(); i++)
{ {
ResourceViewer tab = ((TabbedPane)tabs.getTabComponentAt(i)).resource; ResourceViewer tab = ((TabbedPane)tabs.getTabComponentAt(i)).resource;
if(tab.workingName.equals(workingName)) if(tab.resource.workingName.equals(workingName))
{ {
tabs.setSelectedIndex(i); tabs.setSelectedIndex(i);
break; break;

View file

@ -24,6 +24,7 @@ import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.BytecodeViewer; import the.bytecode.club.bytecodeviewer.BytecodeViewer;
import the.bytecode.club.bytecodeviewer.Configuration; import the.bytecode.club.bytecodeviewer.Configuration;
import the.bytecode.club.bytecodeviewer.SettingsSerializer; 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.resources.ResourceContainer;
import the.bytecode.club.bytecodeviewer.util.MethodParser; import the.bytecode.club.bytecodeviewer.util.MethodParser;
@ -64,18 +65,13 @@ public class ClassViewer extends ResourceViewer
public BytecodeViewPanel bytecodeViewPanel3 = new BytecodeViewPanel(2, this); public BytecodeViewPanel bytecodeViewPanel3 = new BytecodeViewPanel(2, this);
public List<MethodParser> methods = Arrays.asList(new MethodParser(), new MethodParser(), new MethodParser()); 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); super(new Resource(name, container.getWorkingName(name), container));
this.container = container;
this.name = name;
this.viewerClassNode = cn;
this.setName(name); this.setName(name);
this.setLayout(new BorderLayout()); this.setLayout(new BorderLayout());
this.sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, bytecodeViewPanel1.panel, bytecodeViewPanel2.panel); this.sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, bytecodeViewPanel1.panel, bytecodeViewPanel2.panel);
this.sp2 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, sp, bytecodeViewPanel3.panel); this.sp2 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, sp, bytecodeViewPanel3.panel);
this.add(sp2, BorderLayout.CENTER); this.add(sp2, BorderLayout.CENTER);
@ -91,8 +87,6 @@ public class ClassViewer extends ResourceViewer
@Override @Override
public void refresh(final JButton button) public void refresh(final JButton button)
{ {
this.viewerClassNode = container.getClassNode(name); //update the classnode
setPanes(); setPanes();
refreshTitle(); refreshTitle();
@ -113,7 +107,7 @@ public class ClassViewer extends ResourceViewer
System.err.println("TODO: Update it to use the FileContainerImporter"); 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()); 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.ImageJLabel;
import the.bytecode.club.bytecodeviewer.gui.components.SearchableRSyntaxTextArea; import the.bytecode.club.bytecodeviewer.gui.components.SearchableRSyntaxTextArea;
import the.bytecode.club.bytecodeviewer.gui.hexviewer.JHexEditor; 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.ResourceContainer;
import the.bytecode.club.bytecodeviewer.resources.ResourceType; import the.bytecode.club.bytecodeviewer.resources.ResourceType;
import the.bytecode.club.bytecodeviewer.util.MiscUtils; import the.bytecode.club.bytecodeviewer.util.MiscUtils;
@ -45,22 +46,16 @@ import the.bytecode.club.bytecodeviewer.util.SyntaxLanguage;
public class FileViewer extends ResourceViewer public class FileViewer extends ResourceViewer
{ {
public final byte[] contents;
public final String workingName;
public final SearchableRSyntaxTextArea textArea = (SearchableRSyntaxTextArea) public final SearchableRSyntaxTextArea textArea = (SearchableRSyntaxTextArea)
Configuration.rstaTheme.apply(new SearchableRSyntaxTextArea()); Configuration.rstaTheme.apply(new SearchableRSyntaxTextArea());
public final JPanel mainPanel = new JPanel(new BorderLayout()); public final JPanel mainPanel = new JPanel(new BorderLayout());
public BufferedImage image; public BufferedImage image;
public boolean canRefresh; 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; super(new Resource(name, container.getWorkingName(name), container));
this.contents = contents;
this.workingName = container.getWorkingName(name);
this.container = container;
this.setName(name); this.setName(name);
this.setLayout(new BorderLayout()); this.setLayout(new BorderLayout());
@ -71,7 +66,8 @@ public class FileViewer extends ResourceViewer
public void setContents() 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 onlyName = FilenameUtils.getName(nameLowerCase);
final String contentsAsString = new String(contents); final String contentsAsString = new String(contents);
@ -144,7 +140,7 @@ public class FileViewer extends ResourceViewer
mainPanel.removeAll(); mainPanel.removeAll();
image = MiscUtils.loadImage(image, contents); image = MiscUtils.loadImage(image, resource.getResourceBytes());
JLabel label = new JLabel("", new ImageIcon(image), JLabel.CENTER); JLabel label = new JLabel("", new ImageIcon(image), JLabel.CENTER);
mainPanel.add(label, BorderLayout.CENTER); mainPanel.add(label, BorderLayout.CENTER);

View file

@ -2,10 +2,9 @@ package the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer;
import javax.swing.*; import javax.swing.*;
import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.Configuration; import the.bytecode.club.bytecodeviewer.Configuration;
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.TabbedPane; 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; 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 abstract class ResourceViewer extends JPanel
{ {
public ClassNode viewerClassNode; public final Resource resource;
public String name;
public String workingName;
public ResourceContainer container;
public TabbedPane tabbedPane; public TabbedPane tabbedPane;
protected ResourceViewer(Resource resource) {this.resource = resource;}
/** /**
* Returns the tab name * Returns the tab name
*/ */
public String getTabName() public String getTabName()
{ {
String tabName = name; String tabName = resource.name;
if (Configuration.simplifiedTabNames) if (Configuration.simplifiedTabNames)
tabName = MiscUtils.getChildFromPath(tabName); tabName = MiscUtils.getChildFromPath(tabName);
if (Configuration.displayParentInTab) if (Configuration.displayParentInTab)
tabName = container.name + ">" + tabName; tabName = resource.container.name + ">" + tabName;
return tabName; return tabName;
} }
@ -60,7 +58,7 @@ public abstract class ResourceViewer extends JPanel
*/ */
public byte[] getResourceBytes() 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 ClassViewer viewer;
public final BytecodeViewPanel bytecodeViewPanel; public final BytecodeViewPanel bytecodeViewPanel;
private final JButton button; private final JButton button;
private final byte[] b; private final byte[] classBytes;
public SearchableRSyntaxTextArea updateUpdaterTextArea; public SearchableRSyntaxTextArea updateUpdaterTextArea;
@ -69,11 +69,11 @@ public class BytecodeViewPanelUpdater implements Runnable
public boolean waitingFor; public boolean waitingFor;
private Thread thread; 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.viewer = cv;
this.bytecodeViewPanel = bytecodeViewPanel; this.bytecodeViewPanel = bytecodeViewPanel;
this.b = b; this.classBytes = classBytes;
this.isPanelEditable = isPanelEditable; this.isPanelEditable = isPanelEditable;
this.button = button; this.button = button;
waitingFor = true; waitingFor = true;
@ -91,7 +91,7 @@ public class BytecodeViewPanelUpdater implements Runnable
if (bytecodeViewPanel.decompiler == Decompiler.HEXCODE_VIEWER) if (bytecodeViewPanel.decompiler == Decompiler.HEXCODE_VIEWER)
{ {
final ClassWriter cw = new ClassWriter(0); final ClassWriter cw = new ClassWriter(0);
viewer.viewerClassNode.accept(cw); viewer.resource.getResourceClassNode().accept(cw);
SwingUtilities.invokeLater(() -> SwingUtilities.invokeLater(() ->
{ {
@ -106,7 +106,7 @@ public class BytecodeViewPanelUpdater implements Runnable
final Decompiler decompiler = bytecodeViewPanel.decompiler; final Decompiler decompiler = bytecodeViewPanel.decompiler;
//perform decompiling inside of this thread //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 //set the swing components on the swing thread
SwingUtilities.invokeLater(() -> 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);
}
}