All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.md_5.specialsource.InheritanceMap Maven / Gradle / Ivy

Go to download

A jar compare and renaming engine designed for comparing and remapping 2 jars of differnent obfuscation mappings. Can also be useful for reobfuscation.

The newest version!
/**
 * Copyright (c) 2012, md_5. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * The name of the author may not be used to endorse or promote products derived
 * from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
package net.md_5.specialsource;

import net.md_5.specialsource.provider.InheritanceProvider;
import com.google.common.base.Joiner;
import com.google.common.collect.BiMap;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;

public class InheritanceMap implements InheritanceProvider {

    private final Map> inheritanceMap = new HashMap>();
    public static final InheritanceMap EMPTY = new InheritanceMap();

    /**
     * Generate an inheritance map for the given classes
     */
    public void generate(InheritanceProvider inheritanceProvider, Collection classes) {
        for (String className : classes) {
            Collection parents = inheritanceProvider.getParents(className);

            if (parents == null) {
                System.out.println("No inheritance information found for " + className);
            } else {
                ArrayList filteredParents = new ArrayList();

                // Include only classes requested
                for (String parent : parents) {
                    if (classes.contains(parent)) {
                        filteredParents.add(parent);
                    }
                }

                // If there are parents we care about, add to map
                if (filteredParents.size() > 0) {
                    setParents(className, filteredParents);
                }
            }
        }
    }

    public void save(PrintWriter writer) {
        List classes = new ArrayList(inheritanceMap.keySet());
        Collections.sort(classes);

        for (String className : classes) {
            writer.print(className);
            writer.print(' ');

            List parents = getParents(className);
            writer.println(Joiner.on(' ').join(parents));
        }
    }

    public void load(BufferedReader reader, BiMap classMap) throws IOException {
        String line;

        while ((line = reader.readLine()) != null) {
            int commentIndex = line.indexOf('#');
            if (commentIndex != -1) {
                line = line.substring(0, commentIndex);
            }
            if (line.isEmpty()) {
                continue;
            }
            String[] tokens = line.split(" ");

            if (tokens.length < 2) {
                throw new IOException("Invalid inheritance map file line: " + line);
            }

            String className = tokens[0];
            List parents = Arrays.asList(tokens).subList(1, tokens.length);

            if (classMap == null) {
                setParents(className, new ArrayList(parents));
            } else {
                String remappedClassName = JarRemapper.mapTypeName(className, /*packageMap*/ null, classMap, /*defaultIfUnmapped*/ null);
                if (remappedClassName == null) {
                    throw new IOException("Inheritance map input class not remapped: " + className);
                }

                ArrayList remappedParents = new ArrayList();
                for (String parent : parents) {
                    String remappedParent = JarRemapper.mapTypeName(parent, /*packageMap*/ null, classMap, /*defaultIfUnmapped*/ null);
                    if (remappedParent == null) {
                        throw new IOException("Inheritance map parent class not remapped: " + parent);
                    }

                    remappedParents.add(remappedParent);
                }

                setParents(remappedClassName, remappedParents);
            }
        }
    }

    public boolean hasParents(String className) {
        return inheritanceMap.containsKey(className);
    }

    public List getParents(String className) {
        return inheritanceMap.get(className);
    }

    public void setParents(String className, Collection parents) {
        if (parents == null) {
            inheritanceMap.put(className, new ArrayList());
        } else {
            inheritanceMap.put(className, new ArrayList(parents));
        }
    }

    public int size() {
        return inheritanceMap.size();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy