package jnpf.flowable.util;
|
|
import jnpf.exception.WorkFlowException;
|
|
import java.util.ArrayList;
|
import java.util.Collection;
|
import java.util.Collections;
|
import java.util.HashSet;
|
import java.util.List;
|
import java.util.Set;
|
|
/**
|
* 按逆向拓扑顺序获取退回路径,目标节点不参与退回事件。
|
*/
|
final class BackEventPathResolver {
|
|
private BackEventPathResolver() {
|
}
|
|
@FunctionalInterface
|
interface PreviousNodes {
|
List<String> get(String nodeCode) throws WorkFlowException;
|
}
|
|
static List<String> resolve(String current, Collection<String> targets, Collection<String> afterTargets,
|
PreviousNodes previousNodes) throws WorkFlowException {
|
Set<String> allowed = new HashSet<>(afterTargets);
|
allowed.removeAll(targets);
|
allowed.add(current);
|
List<String> postOrder = new ArrayList<>();
|
visit(current, allowed, new HashSet<>(), previousNodes, postOrder);
|
Collections.reverse(postOrder);
|
return postOrder;
|
}
|
|
private static void visit(String current, Set<String> allowed, Set<String> visited,
|
PreviousNodes previousNodes, List<String> postOrder) throws WorkFlowException {
|
if (!allowed.contains(current) || !visited.add(current)) {
|
return;
|
}
|
for (String previous : previousNodes.get(current)) {
|
visit(previous, allowed, visited, previousNodes, postOrder);
|
}
|
postOrder.add(current);
|
}
|
}
|