刘光辉
3 小时以前 06f314545ac3514d7ce28939920866ae8188d31c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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);
    }
}