package kr.ac.snu.selab.soot.graph.collectors; import java.util.ArrayList; import java.util.Collection; import java.util.Set; import kr.ac.snu.selab.soot.graph.Graph; import kr.ac.snu.selab.soot.graph.GraphPathCollector; import kr.ac.snu.selab.soot.graph.Node; import kr.ac.snu.selab.soot.graph.Path; import soot.SootMethod; public class TriggeringPathCollector<N extends Node> extends GraphPathCollector<N> { private Set<N> destinationSet; public TriggeringPathCollector(N aStartNode, Graph<N> aGraph, Set<N> aDestinationSet) { super(aStartNode, aGraph); destinationSet = aDestinationSet; } @Override protected boolean isForwardSearch() { return true; } @Override protected boolean isGoal(N aNode) { return destinationSet.contains(aNode); } protected int findPaths(N aNode, Graph<N> graph, ArrayList<Path<N>> output, final int pathThreshold) { if (aNode == null) return DONE; if (((SootMethod)aNode.getElement()).getName().equals("<init>")) { return DONE; } String nodeKey = aNode.key(); if (pathsMap.containsKey(nodeKey)) { output.addAll(pathsMap.get(nodeKey)); return DONE; } if (isGoal(aNode)) { Path<N> path = new Path<N>(); path.addTop(aNode); output.add(path); hitSet.add(nodeKey); pathsMap.put(nodeKey, output); return DONE; } if (hitSet.contains(nodeKey)) { return CYCLE; } else { hitSet.add(nodeKey); } Collection<N> nextNodes = getChildren(aNode); for (N node : nextNodes) { if (output.size() >= pathThreshold) { // For performance break; } if (node == null) continue; ArrayList<Path<N>> pathSet = new ArrayList<Path<N>>(); int result = findPaths(node, graph, pathSet, pathThreshold); if (result == CYCLE) { continue; } else { for (Path<N> p : pathSet) { Path<N> p1 = p.copy(); p1.addTop(aNode); output.add(p1); } } } pathsMap.put(nodeKey, output); return DONE; } }