2021-07-30 03:28:10 +00:00
|
|
|
package the.bytecode.club.bytecodeviewer.gui.contextmenu.resourcelist;
|
2021-07-27 11:05:11 +00:00
|
|
|
|
2021-08-26 21:59:07 +00:00
|
|
|
import java.util.Enumeration;
|
|
|
|
import javax.swing.JMenu;
|
|
|
|
import javax.swing.JMenuItem;
|
|
|
|
import javax.swing.tree.DefaultMutableTreeNode;
|
|
|
|
import javax.swing.tree.TreeNode;
|
|
|
|
import javax.swing.tree.TreePath;
|
2021-07-27 11:05:11 +00:00
|
|
|
import org.apache.commons.io.FilenameUtils;
|
2021-07-27 12:02:40 +00:00
|
|
|
import org.objectweb.asm.tree.ClassNode;
|
2021-07-27 11:05:11 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
2021-07-27 12:02:40 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.Constants;
|
|
|
|
import the.bytecode.club.bytecodeviewer.api.ASMUtil;
|
2021-07-30 03:28:10 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.gui.contextmenu.ContextMenuItem;
|
|
|
|
import the.bytecode.club.bytecodeviewer.gui.contextmenu.ContextMenuType;
|
2021-07-27 11:05:11 +00:00
|
|
|
import the.bytecode.club.bytecodeviewer.translation.TranslatedStrings;
|
|
|
|
|
|
|
|
/***************************************************************************
|
|
|
|
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
|
|
|
|
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
|
|
|
|
* *
|
|
|
|
* 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/>. *
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @author Konloch
|
|
|
|
* @since 7/27/2021
|
|
|
|
*/
|
|
|
|
public class New extends ContextMenuItem
|
|
|
|
{
|
|
|
|
public New()
|
|
|
|
{
|
2021-07-30 03:28:10 +00:00
|
|
|
super(ContextMenuType.RESOURCE_LIST, ((tree, selPath, result, menu) ->
|
2021-07-27 11:05:11 +00:00
|
|
|
{
|
|
|
|
JMenu quickOpen = new JMenu(TranslatedStrings.NEW.toString());
|
|
|
|
quickOpen.add(createMenu("Class", FileType.CLASS, selPath));
|
2021-07-27 12:02:40 +00:00
|
|
|
|
|
|
|
//TODO
|
|
|
|
// + directory isn't finished
|
|
|
|
// + file has no purpose until the plugin writer code is added for newly created resources
|
|
|
|
// ^ this will allow users to edit the files they have created
|
|
|
|
if(Constants.DEV_MODE)
|
|
|
|
{
|
|
|
|
quickOpen.add(createMenu("File", FileType.FILE, selPath));
|
|
|
|
quickOpen.add(createMenu("Directory", FileType.DIRECTORY, selPath));
|
|
|
|
}
|
2021-07-27 11:05:11 +00:00
|
|
|
menu.add(quickOpen);
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
|
|
|
private static JMenuItem createMenu(String name, FileType fileType, TreePath selPath)
|
|
|
|
{
|
|
|
|
JMenuItem menu = new JMenuItem(name);
|
|
|
|
|
2021-07-27 12:02:40 +00:00
|
|
|
String separator = fileType == FileType.CLASS ? "." : "/";
|
|
|
|
String firstPath = buildPath(0, 2, selPath, "/");
|
2021-07-27 11:05:11 +00:00
|
|
|
String path = buildPath(2, selPath.getPathCount(), selPath, separator);
|
|
|
|
String containerName = selPath.getPathComponent(1).toString();
|
|
|
|
|
|
|
|
menu.addActionListener((e)->{
|
2021-07-27 12:02:40 +00:00
|
|
|
String newPath = BytecodeViewer.showInput("Name",
|
|
|
|
fileType == FileType.CLASS ? "Enter the class name" : "Enter the file name",
|
|
|
|
FilenameUtils.removeExtension(path));
|
2021-07-27 11:05:11 +00:00
|
|
|
|
|
|
|
if(newPath == null || newPath.isEmpty())
|
|
|
|
return;
|
|
|
|
|
2021-07-27 12:02:40 +00:00
|
|
|
byte[] contents = new byte[0];
|
2021-12-19 23:24:17 +00:00
|
|
|
|
2021-07-27 11:05:11 +00:00
|
|
|
switch(fileType)
|
|
|
|
{
|
|
|
|
case CLASS:
|
2021-07-27 12:02:40 +00:00
|
|
|
ClassNode cn = new ClassNode();
|
|
|
|
|
|
|
|
//TODO this should be a dialog
|
|
|
|
cn.version = 52;
|
|
|
|
|
|
|
|
//TODO santize newPath and remove extension if added
|
|
|
|
cn.name = newPath;
|
2021-12-19 23:24:17 +00:00
|
|
|
String oldResourcePath = newPath.replace(".", "/");
|
2021-07-29 18:41:04 +00:00
|
|
|
String newResourcePath = oldResourcePath + ".class";
|
2021-07-27 12:02:40 +00:00
|
|
|
|
|
|
|
contents = ASMUtil.nodeToBytes(cn);
|
|
|
|
|
2021-07-29 18:41:04 +00:00
|
|
|
BytecodeViewer.resourceContainers.get(containerName).resourceClasses.put(oldResourcePath, cn);
|
|
|
|
BytecodeViewer.resourceContainers.get(containerName).resourceClassBytes.put(newResourcePath, contents);
|
|
|
|
searchAndInsert(firstPath + "/" + newResourcePath, BytecodeViewer.resourceContainers.get(containerName).treeNode, "/");
|
2021-07-27 12:02:40 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
case FILE:
|
2021-12-19 23:24:17 +00:00
|
|
|
BytecodeViewer.resourceContainers.get(containerName).resourceFiles.put(newPath, contents);
|
2021-07-27 12:02:40 +00:00
|
|
|
searchAndInsert(firstPath + separator +newPath, BytecodeViewer.resourceContainers.get(containerName).treeNode, separator);
|
2021-07-27 11:05:11 +00:00
|
|
|
break;
|
|
|
|
}
|
2021-07-27 12:02:40 +00:00
|
|
|
|
|
|
|
BytecodeViewer.viewer.resourcePane.tree.updateUI();
|
2021-07-27 11:05:11 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
return menu;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static String buildPath(int startsAt, int max, TreePath selPath, String separator)
|
|
|
|
{
|
|
|
|
StringBuilder tempSpot = new StringBuilder();
|
|
|
|
|
2021-12-19 23:24:17 +00:00
|
|
|
for(int counter = startsAt; counter < max; counter++)
|
2021-07-27 11:05:11 +00:00
|
|
|
{
|
|
|
|
if(counter > startsAt)
|
|
|
|
tempSpot.append(separator);
|
|
|
|
tempSpot.append(selPath.getPathComponent(counter));
|
|
|
|
}
|
|
|
|
|
|
|
|
return tempSpot.toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
public static String buildPath(int startsAt, int max, DefaultMutableTreeNode treeNode, String separator)
|
|
|
|
{
|
|
|
|
StringBuilder tempSpot = new StringBuilder();
|
|
|
|
|
2021-12-19 23:24:17 +00:00
|
|
|
for(int counter = startsAt; counter < max; counter++)
|
2021-07-27 11:05:11 +00:00
|
|
|
{
|
|
|
|
if(counter > startsAt)
|
|
|
|
tempSpot.append(separator);
|
|
|
|
tempSpot.append(treeNode.getPath()[counter]);
|
|
|
|
}
|
|
|
|
|
|
|
|
return tempSpot.toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
//TODO this needs to be rewritten to support creating parent nodes that don't exist
|
2021-12-19 23:24:17 +00:00
|
|
|
@SuppressWarnings("unchecked")
|
2021-07-27 12:02:40 +00:00
|
|
|
public static boolean searchAndInsert(String path, DefaultMutableTreeNode treeNode, String separator)
|
2021-07-27 11:05:11 +00:00
|
|
|
{
|
2021-07-29 18:50:15 +00:00
|
|
|
Enumeration<TreeNode> children = treeNode.children();
|
2021-07-27 11:05:11 +00:00
|
|
|
|
|
|
|
String findPath = FilenameUtils.getPath(path);
|
2021-07-27 12:02:40 +00:00
|
|
|
String currentPath = buildPath(0, treeNode.getPath().length, treeNode, separator);
|
2021-07-27 11:05:11 +00:00
|
|
|
String directory = FilenameUtils.getPath(currentPath);
|
|
|
|
|
|
|
|
if(currentPath.startsWith(findPath))
|
|
|
|
{
|
|
|
|
//TODO this can be written without the need for .getParent
|
|
|
|
((DefaultMutableTreeNode)treeNode.getParent()).add(new DefaultMutableTreeNode(FilenameUtils.getName(path)));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
while(children.hasMoreElements())
|
|
|
|
{
|
2021-07-29 18:50:15 +00:00
|
|
|
DefaultMutableTreeNode child = (DefaultMutableTreeNode) children.nextElement();
|
2021-07-27 12:02:40 +00:00
|
|
|
if(searchAndInsert(path, child, separator))
|
2021-07-27 11:05:11 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public enum FileType
|
|
|
|
{
|
|
|
|
CLASS,
|
|
|
|
FILE,
|
2021-07-27 12:02:40 +00:00
|
|
|
DIRECTORY,
|
2021-07-27 11:05:11 +00:00
|
|
|
}
|
2021-08-26 21:59:07 +00:00
|
|
|
}
|