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

org.codetracker.GraphImpl Maven / Gradle / Ivy

Go to download

A refactoring-aware tool that can generate the commit change history of code elements with a very high accuracy.

There is a newer version: 2.6
Show newest version
package org.codetracker;

import com.google.common.graph.*;
import org.refactoringminer.api.RefactoringType;
import org.codetracker.api.CodeElement;
import org.codetracker.api.Edge;
import org.codetracker.api.Graph;

import java.util.*;

/**
 * @param  Node Type
 * @param  Edge Type
 */
public class GraphImpl implements org.codetracker.api.Graph {
    private static final List CTR = Arrays.asList(RefactoringType.CHANGE_ATTRIBUTE_TYPE.getDisplayName(),
            RefactoringType.CHANGE_PARAMETER_TYPE.getDisplayName(), RefactoringType.CHANGE_RETURN_TYPE.getDisplayName(), RefactoringType.CHANGE_VARIABLE_TYPE.getDisplayName());

    private final MutableValueGraph graph;

    /**
     * @param graph
     */
    private GraphImpl(ValueGraph graph) {
        this.graph = Graphs.copyOf(graph);
    }

    public GraphImpl() {
        this.graph = ValueGraphBuilder.directed().allowsSelfLoops(true).build();
    }

    public static  GraphImpl of(ValueGraph graph) {
        return new GraphImpl<>(graph);
    }

    public static  Graph subGraph(ValueGraph graph, N startNode) {
        if (graph == null || startNode == null)
            return null;
        Set connectedNodes = new HashSet<>();
        Queue queue = new LinkedList<>();
        queue.add(startNode);
        while (!queue.isEmpty()) {
            N visitingNode = queue.poll();
            if (!connectedNodes.contains(visitingNode)) {
                connectedNodes.add(visitingNode);
                queue.addAll(graph.successors(visitingNode));
                queue.addAll(graph.predecessors(visitingNode));
            }
        }

        return new GraphImpl(Graphs.inducedSubgraph(graph, connectedNodes));
    }

    public static  Set> setOf(ValueGraph graph) {
        Set> graphs = new HashSet<>();
        for (Set nodes : induceDisconnectedSubGraphs(graph)) {
            graphs.add(new GraphImpl(Graphs.inducedSubgraph(graph, nodes)));
        }
        return graphs;
    }

    public static  Set> setOf(Graph graph) {
        Set> graphs = new HashSet<>();
        for (Set nodes : induceDisconnectedSubGraphs(((GraphImpl) graph).graph)) {
            graphs.add(new GraphImpl(Graphs.inducedSubgraph(((GraphImpl) graph).graph, nodes)));
        }
        return graphs;
    }

    public static  List> induceDisconnectedSubGraphs(ValueGraph graph) {
        List> inducedSubGraphNodes = new ArrayList<>();
        HashMap> visitedNodes = new HashMap<>();
        for (N node : graph.nodes()) {
            if (graph.predecessors(node).isEmpty()) {
                if (!visitedNodes.containsKey(node)) {
                    Set reachable = findReachable(graph, node);
                    reachable.add(node);

                    Set relatedReachable = null;
                    for (N reachableNode : reachable) {
                        if (visitedNodes.containsKey(reachableNode)) {
                            relatedReachable = visitedNodes.get(reachableNode);
                            break;
                        }
                    }
                    if (relatedReachable == null) {
                        inducedSubGraphNodes.add(reachable);
                        relatedReachable = reachable;
                    }
                    for (N reachableNode : reachable) {
                        visitedNodes.put(reachableNode, relatedReachable);
                    }
                }
            }
        }
        return inducedSubGraphNodes;
    }

    private static  Set findReachable(ValueGraph graph, N node) {
        Set reachable = new HashSet<>();
        Traverser.forGraph(graph).breadthFirst(node).forEach(reachable::add);
        return reachable;
    }

//    public static  Map getEdgesContainingCTR(GraphImpl graph) {
//        return graph.graph.edges().stream()
//                .filter(x -> graph.graph.edgeValue(x).get().numberOfRefactoring() > 1)
//                .filter(x -> Arrays.stream(graph.graph.edgeValue(x).get().toString().split(",")).anyMatch(r -> CTR.contains(r)))
//                .collect(toMap(x -> x.nodeU(), x -> graph.graph.edgeValue(x).get(), (e1, e2) -> e1));
//    }

    public void merge(GraphImpl toMergeGraph) {
        for (EndpointPair edge : toMergeGraph.graph.edges()) {
            E e = toMergeGraph.graph.edgeValueOrDefault(edge, null);
            if (e != null)
                graph.putEdgeValue(edge, e);
        }
    }

    @Override
    public Set getNodeList() {
        return graph.nodes();
    }

    @Override
    public Set> getEdges() {
        return graph.edges();
    }

    @Override
    public Optional getEdgeValue(EndpointPair e) {
        return graph.edgeValue(e);
    }

    /**
     * @return true if the chain is empty
     */
    public boolean isEmpty() {
        return graph.nodes().isEmpty();
    }

    @Override
    public Set predecessors(N n) {
        return graph.predecessors(n);
    }

    @Override
    public Set successors(N n) {
        return graph.successors(n);
    }

//    public boolean isMultiContainer() {
//        return graph.nodes().stream().map(n -> n.getContainerName()).collect(Collectors.toSet()).size() > 1;
//    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy