tk.wurst_client.hooks.reader.JarDataReader.java Source code

Java tutorial

Introduction

Here is the source code for tk.wurst_client.hooks.reader.JarDataReader.java

Source

/*
 * Copyright  2015 | Alexander01998 | All rights reserved.
 * 
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */
package tk.wurst_client.hooks.reader;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;

import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.Opcodes;

import tk.wurst_client.hooks.reader.data.JarData;

public class JarDataReader {
    private JTree tree;

    public JarDataReader(JTree tree) {
        this.tree = tree;
    }

    public JarData read(File file) throws IOException {
        DefaultMutableTreeNode root = new DefaultMutableTreeNode(file.getName());
        JarData jarData = new JarData();
        JarInputStream input = new JarInputStream(new FileInputStream(file));
        for (JarEntry entry; (entry = input.getNextJarEntry()) != null;)
            if (entry.isDirectory())
                root.add(new DefaultMutableTreeNode(
                        entry.getName().substring(0, entry.getName().length() - 1).replace("/", "."), true));
            else if (entry.getName().endsWith(".class")) {
                ClassReader reader = new ClassReader(input);
                ClassDataReader wReader = new ClassDataReader(Opcodes.ASM4, jarData);
                reader.accept(wReader, 0);

                if (entry.getName().contains("/"))
                    getNode(root, entry.getName().substring(0, entry.getName().lastIndexOf("/")).replace("/", "."))
                            .add(new DefaultMutableTreeNode(
                                    entry.getName().substring(entry.getName().lastIndexOf("/") + 1), false));
                else
                    root.add(new DefaultMutableTreeNode(entry.getName(), false));
            } else if (entry.getName().contains("/"))
                getNode(root, entry.getName().substring(0, entry.getName().lastIndexOf("/")).replace("/", ".")).add(
                        new DefaultMutableTreeNode(entry.getName().substring(entry.getName().lastIndexOf("/") + 1),
                                false));
            else
                root.add(new DefaultMutableTreeNode(entry, false));
        input.close();
        getNode(root, "META-INF").add(new DefaultMutableTreeNode("MANIFEST.MF", false));
        sortNode(root);
        tree.setModel(new DefaultTreeModel(root));
        return jarData;
    }

    private DefaultMutableTreeNode getNode(DefaultMutableTreeNode root, String s) {
        @SuppressWarnings("unchecked")
        Enumeration<DefaultMutableTreeNode> nodes = root.depthFirstEnumeration();
        while (nodes.hasMoreElements()) {
            DefaultMutableTreeNode node = nodes.nextElement();
            if (node.toString().equalsIgnoreCase(s))
                return node;
        }
        DefaultMutableTreeNode node = new DefaultMutableTreeNode(s, true);
        root.add(node);
        return node;
    }

    private void sortNode(DefaultMutableTreeNode node) {
        List<DefaultMutableTreeNode> packages = new ArrayList<DefaultMutableTreeNode>();
        List<DefaultMutableTreeNode> classes = new ArrayList<DefaultMutableTreeNode>();
        List<DefaultMutableTreeNode> files = new ArrayList<DefaultMutableTreeNode>();
        for (Enumeration subnodes = node.children(); subnodes.hasMoreElements();) {
            DefaultMutableTreeNode subnode = (DefaultMutableTreeNode) subnodes.nextElement();
            if (subnode.getAllowsChildren()) {
                if (subnode.getChildCount() > 0) {
                    sortNode(subnode);
                    packages.add(subnode);
                }
            } else if (subnode.toString().endsWith(".class"))
                classes.add(new DefaultMutableTreeNode(
                        subnode.toString().substring(0, subnode.toString().length() - 6), false));
            else
                files.add(subnode);
        }

        node.removeAllChildren();
        packages.sort((DefaultMutableTreeNode o1, DefaultMutableTreeNode o2) -> o1.toString()
                .compareToIgnoreCase(o2.toString()));
        for (DefaultMutableTreeNode packageNode : packages)
            node.add(packageNode);

        classes.sort((DefaultMutableTreeNode o1, DefaultMutableTreeNode o2) -> o1.toString()
                .compareToIgnoreCase(o2.toString()));
        for (DefaultMutableTreeNode classNode : classes)
            node.add(classNode);

        files.sort((DefaultMutableTreeNode o1, DefaultMutableTreeNode o2) -> o1.toString()
                .compareToIgnoreCase(o2.toString()));
        for (DefaultMutableTreeNode fileNode : files)
            node.add(fileNode);
    }
}