shikeying
2024-01-11 3b67e947e36133e2a40eb2737b15ea375e157ea0
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package com.walker.infrastructure.tree;
 
import com.walker.infrastructure.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
 
/**
 * 前端展示树结构,生成器对象,业务需要继承该抽象类实现自己的实体树结构。
 * @param <T>
 * @author 时克英
 * @date 2022-12-08
 * @date 2023-07-13 复制一份,使用字符串类型树节点。
 */
public abstract class AbstractTreeStringGenerator<T> {
 
    protected final transient Logger logger = LoggerFactory.getLogger(this.getClass());
 
    private boolean multiRoot = true;
 
    /* 虚拟的根节点,可以显示用户指定的名称,可以不设置 */
    private TreeNodeString dummyRoot = null;
 
    private Map<String, TreeNodeString> rootMap = new TreeMap<>();
    private Map<String, TreeNodeString> childMap = new TreeMap<>();
 
    /**
     * 默认构造函数,设置虚拟根节点名称,如果不需要则设置为<code>null</code>
     * @param dummyRootName
     */
    public AbstractTreeStringGenerator(String dummyRootName){
        if(StringUtils.isNotEmpty(dummyRootName)){
            dummyRoot = new TreeNodeString("0", dummyRootName, null, "0");
        }
    }
 
    public void setMultiRoot(boolean multiRoot){
        this.multiRoot = multiRoot;
    }
 
    public TreeNodeString getTreeRoot(){
        if(multiRoot)
            throw new IllegalStateException("存在多个根节点,请调用方法:getTreeRootList().");
        if(dummyRoot != null){
            return dummyRoot;
        } else {
            return rootMap.values().iterator().next();
        }
    }
 
    public List<TreeNodeString> getTreeRootList(){
        if(!multiRoot)
            throw new IllegalStateException("存在多个根节点,请调用方法:getTreeRoot().");
        List<TreeNodeString> list = new ArrayList<>();
        for(TreeNodeString node : rootMap.values()){
            list.add(node);
        }
        return list;
    }
 
    /**
     * 设置数据实体集合,通过此方法可以组织树结构。
     * @param datas
     */
    public void setEntityList(List<T> datas){
        if(StringUtils.isEmptyList(datas)) return;
        TreeNodeString node = null;
        for(T obj : datas){
            node = toTreeNode(obj);
//            if(node.getParentId() == 0){
            if(node.getParentId().equals(this.defaultParentId)){
                // 根节点
                rootMap.put(node.getId(), node);
            } else {
                childMap.put(node.getId(), node);
            }
        }
        if(rootMap.size() == 0)
            throw new IllegalArgumentException("未找到根节点。");
 
        // 组织成树结构
        if(childMap != null && childMap.size() > 0){
            mountTree(childMap);
        }
 
        // 如果存在虚拟根节点就把所有用户数据中的根节点加进去。
        if(dummyRoot != null){
            for(TreeNodeString n : rootMap.values()){
//                n.setParentId(0);
                n.setParentId(this.defaultParentId);
                dummyRoot.addChild(n);
            }
        }
    }
 
    private void mountTree(Map<String, TreeNodeString> childMap){
        TreeNodeString _node = null;
        for(Iterator<TreeNodeString> i = childMap.values().iterator(); i.hasNext();){
            _node = i.next();
            mountMiddleNode(_node, childMap);
        }
    }
 
    private void mountMiddleNode(TreeNodeString currentNode, Map<String, TreeNodeString> childMap){
//        logger.debug("-------------> cache = " + cache);
//        logger.debug("-------------> currentNode = " + currentNode);
        TreeNodeString _parentNode = rootMap.get(currentNode.getParentId());
        if(_parentNode == null){
            // 没有找到上级根节点,说明是比较靠下的子节点
            _parentNode = childMap.get(currentNode.getParentId());
            if(_parentNode == null)
                throw new NullPointerException("parent node not found, current: " + currentNode);
            _parentNode.addChild(currentNode);
            mountMiddleNode(_parentNode, childMap);
        } else if(_parentNode.getParentId().equals(this.defaultParentId)) {
            // 父对象是根节点
            _parentNode.addChild(currentNode);
//            logger.debug("找到了挂在root下的子节点:" + _parentNode);
        }
    }
 
    protected abstract TreeNodeString toTreeNode(T entity);
 
    public String getDefaultParentId() {
        return defaultParentId;
    }
 
    /**
     * 设置默认父节点值,如:代码表中父节点为特定值的(代码表)才是根节点。
     * @param defaultParentId
     */
    public void setDefaultParentId(String defaultParentId) {
        this.defaultParentId = defaultParentId;
    }
 
    private String defaultParentId = "0";
}