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

live.document.mavenplugin.rootmethod.DuplicatedRootMethodRemover Maven / Gradle / Ivy

package live.document.mavenplugin.rootmethod;

import live.document.scanner.CallGraph;
import live.document.scanner.ClassObject;
import live.document.scanner.MethodObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

public class DuplicatedRootMethodRemover {
    private final CallGraph callGraph;

    public DuplicatedRootMethodRemover(CallGraph callGraph) {
        this.callGraph = callGraph;
    }

    public List removeDuplicatedRootMethodOperator(List methodOperators) {
        List results = new ArrayList<>(methodOperators);

        List methods = methodOperators.stream()
                .map(n -> new Method(n.getName()))
                .collect(Collectors.toList());
        Set distinctMethods = new HashSet<>(removeDuplicated(methods));

        Iterator iterator = results.iterator();
        while (iterator.hasNext()) {
            RootMethodOperator next = iterator.next();
            if (! distinctMethods.contains(new Method(next.getName()))) {
                iterator.remove();
            }
        }

        return results;
    }

    public List removeDuplicatedMethods(List rootMethodNames) {
        List methods = rootMethodNames.stream()
                .map(n -> new Method(n))
                .collect(Collectors.toList());

        List results = removeDuplicated(methods);

        return results.stream().map(m -> m.fullMethodName).sorted().collect(Collectors.toList());
    }

    private List removeDuplicated(List methods) {
        Map> callerCalleeMap = generateCallerCalleeMap(methods);

        List results = new ArrayList<>(methods);
        Iterator iterator = results.iterator();
        while (iterator.hasNext()) {
            Method method = iterator.next();
            for (Map.Entry> methodSetEntry : callerCalleeMap.entrySet()) {
                if (methodSetEntry.getKey().equals(method.fullMethodName)) {
                    continue;
                }

                Set methodObjects = new HashSet<>(findMethodObjects(method));
                if (methodObjects.removeAll(methodSetEntry.getValue())) {
                    iterator.remove();
                    break;
                }
            }
        }

        return results;
    }

    private Map> generateCallerCalleeMap(List methods) {
        Map> tmpResults = new HashMap<>();

        for (Method method : methods) {
            tmpResults.put(method.fullMethodName, new ArrayList<>());
            List methodObjects = findMethodObjects(method);

            for (MethodObject methodObject : methodObjects) {
                List children = findChildren(methodObject, new HashSet());
                tmpResults.get(method.fullMethodName).addAll(children);
            }
        }

        Map> results = new HashMap<>();
        for (Map.Entry> entry : tmpResults.entrySet()) {
            results.put(entry.getKey(), new HashSet<>(entry.getValue()));
        }
        return results;
    }

    private List findChildren(MethodObject method, Set scannedMethods) {
        if (scannedMethods.contains(method)) {
            return new ArrayList<>();
        }
        scannedMethods.add(method);

        List results = new ArrayList<>();
        method.calleeStream(MethodObject.class)
                        .forEach(results::add);

        method.calleeStream(MethodObject.class)
                .forEach(callee ->
                        results.addAll(findChildren(callee, scannedMethods))
                );

        return results;
    }

    private List findMethodObjects(Method method) {
        ClassObject calleeClass = callGraph.findClass(method.fullClassName);
        List calleeMethods = calleeClass.findMethod(method.shortMethodName);

        return calleeMethods;
    }

    static class Method {
        String packageName;
        String className;
        String fullClassName;
        String shortMethodName;
        String fullMethodName;

        public Method(String fullMethodName) {
            this.fullMethodName = fullMethodName;
            int i = fullMethodName.lastIndexOf(".");

            this.fullClassName = fullMethodName.substring(0, i);
            this.shortMethodName = fullMethodName.substring(i + 1);
            int j = this.fullClassName.lastIndexOf(".");
            this.packageName = this.fullClassName.substring(0, j);
            this.className = this.fullClassName.substring(j + 1);
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            Method method = (Method) o;

            return fullMethodName.equals(method.fullMethodName);
        }

        @Override
        public int hashCode() {
            return fullMethodName.hashCode();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy