package com.opensymphony.xwork2.config.providers;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class CycleDetector<T> {
private static final String marked = "marked";
private static final String complete = "complete";
private DirectedGraph<T> graph;
private Map<T, String> marks;
private List<T> verticesInCycles;
public CycleDetector(DirectedGraph<T> graph) {
this.graph = graph;
marks = new HashMap<T, String>();
verticesInCycles = new ArrayList<T>();
}
public boolean containsCycle() {
for (T v : graph) {
if (!marks.containsKey(v)) {
if (mark(v)) {
// return true;
}
}
}
// return false;
return !verticesInCycles.isEmpty();
}
private boolean mark(T vertex) {
/*
* return statements commented out for fail slow behavior detect all nodes in cycles instead of just the first one
*/
List<T> localCycles = new ArrayList<T>();
marks.put(vertex, marked);
for (T u : graph.edgesFrom(vertex)) {
if (marks.containsKey(u) && marks.get(u).equals(marked)) {
localCycles.add(vertex);
// return true;
} else if (!marks.containsKey(u)) {
if (mark(u)) {
localCycles.add(vertex);
// return true;
}
}
}
marks.put(vertex, complete);
// return false;
verticesInCycles.addAll(localCycles);
return !localCycles.isEmpty();
}
public List<T> getVerticesInCycles() {
return verticesInCycles;
}
}