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
package com.walker.cache.tree;
 
import com.walker.infrastructure.utils.StringUtils;
 
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
 
/**
 * 把业务数据集合转换成树节点对象的生成器实现。</p>
 * 通常在业务中,从数据库查询出来记录,这些记录带有上下级关系,如:树分类等。<br>
 * 把数据集合传递进来,就可以转换成树对象,子类必须实现抽象方法。
 * @author shikeying
 * @date 2014-9-2
 *
 * @param <T>
 */
public abstract class AbstractTreeGenerator<T> {
 
    private boolean multiRoot = false;
    
    /* 虚拟的根节点,可以显示用户指定的名称,可以不设置 */
    private CacheTreeNode dummyRoot = null;
    
    private Map<String, CacheTreeNode> rootMap = new TreeMap<String, CacheTreeNode>();
    private Map<String, CacheTreeNode> childMap = new TreeMap<String, CacheTreeNode>();
    
    /**
     * 默认构造函数,设置虚拟根节点名称,如果不需要则设置为<code>null</code>
     * @param dummyRootName
     */
    public AbstractTreeGenerator(String dummyRootName){
        if(StringUtils.isNotEmpty(dummyRootName)){
            dummyRoot = new DefaultCacheTreeNode("root", dummyRootName, null, "0");
        }
    }
    
    public CacheTreeNode getTreeRoot(){
        if(multiRoot)
            throw new IllegalStateException("存在多个根节点,请调用方法:getTreeRootList().");
        if(dummyRoot != null){
            return dummyRoot;
        } else {
            return rootMap.values().iterator().next();
        }
    }
    
    public List<CacheTreeNode> getTreeRootList(){
        if(!multiRoot)
            throw new IllegalStateException("存在多个根节点,请调用方法:getTreeRoot().");
        List<CacheTreeNode> list = new ArrayList<CacheTreeNode>();
        for(CacheTreeNode node : rootMap.values()){
            list.add(node);
        }
        return list;
    }
    
    public void setMultiRoot(boolean multiRoot){
        this.multiRoot = multiRoot;
    }
    
    /**
     * 设置数据实体集合,通过此方法可以组织树结构。
     * @param datas
     */
    public void setEntityList(List<T> datas){
        if(StringUtils.isEmptyList(datas)) return;
        CacheTreeNode node = null;
        for(T obj : datas){
            node = toCacheTreeNode(obj);
            if(StringUtils.isNotEmpty(node.getParentId()) 
                    && parentIsRoot(node.getParentId())){
                // 根节点
                rootMap.put(node.getKey(), node);
            } else {
                childMap.put(node.getKey(), node);
            }
        }
        if(rootMap.size() == 0)
            throw new IllegalArgumentException("未找到根节点。");
        
        // 组织成树结构
        if(childMap != null && childMap.size() > 0){
            mountTree(childMap);
        }
        
        // 如果存在虚拟根节点就把所有用户数据中的根节点加进去。
        if(dummyRoot != null){
            for(CacheTreeNode n : rootMap.values()){
                n.setParentId(CacheTree.ROOT_FLAG_NAME);
                dummyRoot.addChild(n);
            }
        }
    }
    
    public void destroy(){
        dummyRoot = null;
        rootMap.clear();
        childMap.clear();
    }
    
    protected abstract CacheTreeNode toCacheTreeNode(T entity);
    
    private boolean parentIsRoot(String parentId){
        if(parentId.equalsIgnoreCase(CacheTree.ROOT_FLAG_NAME) || parentId.equals(CacheTree.ROOT_FLAG_ZERO))
            return true;
        return false;
    }
    
    private void mountTree(Map<String, CacheTreeNode> childMap){
        CacheTreeNode _node = null;
        for(Iterator<CacheTreeNode> i = childMap.values().iterator(); i.hasNext();){
            _node = i.next();
            mountMiddleNode(_node, childMap);
        }
    }
    
    private void mountMiddleNode(CacheTreeNode currentNode
            , Map<String, CacheTreeNode> childMap){
//        logger.debug("-------------> cache = " + cache);
//        logger.debug("-------------> currentNode = " + currentNode);
        CacheTreeNode _parentNode = (CacheTreeNode)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(parentIsRoot(_parentNode.getParentId())) {
            // 父对象是根节点
            _parentNode.addChild(currentNode);
//            logger.debug("找到了挂在root下的子节点:" + _parentNode);
        }
    }
}