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
|
*/
|
public abstract class AbstractTreeGenerator<T> {
|
|
protected final transient Logger logger = LoggerFactory.getLogger(this.getClass());
|
|
private boolean multiRoot = true;
|
|
/* 虚拟的根节点,可以显示用户指定的名称,可以不设置 */
|
private TreeNode dummyRoot = null;
|
|
private Map<Long, TreeNode> rootMap = new TreeMap<>();
|
private Map<Long, TreeNode> childMap = new TreeMap<>();
|
|
/**
|
* 默认构造函数,设置虚拟根节点名称,如果不需要则设置为<code>null</code>
|
* @param dummyRootName
|
*/
|
public AbstractTreeGenerator(String dummyRootName){
|
if(StringUtils.isNotEmpty(dummyRootName)){
|
dummyRoot = new TreeNode(0, dummyRootName, null, 0);
|
}
|
}
|
|
public void setMultiRoot(boolean multiRoot){
|
this.multiRoot = multiRoot;
|
}
|
|
public TreeNode getTreeRoot(){
|
if(multiRoot)
|
throw new IllegalStateException("存在多个根节点,请调用方法:getTreeRootList().");
|
if(dummyRoot != null){
|
return dummyRoot;
|
} else {
|
return rootMap.values().iterator().next();
|
}
|
}
|
|
public List<TreeNode> getTreeRootList(){
|
if(!multiRoot)
|
throw new IllegalStateException("存在多个根节点,请调用方法:getTreeRoot().");
|
List<TreeNode> list = new ArrayList<TreeNode>();
|
for(TreeNode node : rootMap.values()){
|
list.add(node);
|
}
|
return list;
|
}
|
|
/**
|
* 设置数据实体集合,通过此方法可以组织树结构。
|
* @param datas
|
*/
|
public void setEntityList(List<T> datas){
|
if(StringUtils.isEmptyList(datas)) return;
|
TreeNode node = null;
|
for(T obj : datas){
|
node = toTreeNode(obj);
|
// if(node.getParentId() == 0){
|
if(node.getParentId() == 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(TreeNode n : rootMap.values()){
|
// n.setParentId(0);
|
n.setParentId(this.defaultParentId);
|
dummyRoot.addChild(n);
|
}
|
}
|
}
|
|
private void mountTree(Map<Long, TreeNode> childMap){
|
TreeNode _node = null;
|
for(Iterator<TreeNode> i = childMap.values().iterator(); i.hasNext();){
|
_node = i.next();
|
mountMiddleNode(_node, childMap);
|
}
|
}
|
|
private void mountMiddleNode(TreeNode currentNode, Map<Long, TreeNode> childMap){
|
// logger.debug("-------------> cache = " + cache);
|
// logger.debug("-------------> currentNode = " + currentNode);
|
TreeNode _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() == this.defaultParentId) {
|
// 父对象是根节点
|
_parentNode.addChild(currentNode);
|
// logger.debug("找到了挂在root下的子节点:" + _parentNode);
|
}
|
}
|
|
protected abstract TreeNode toTreeNode(T entity);
|
|
public long getDefaultParentId() {
|
return defaultParentId;
|
}
|
|
/**
|
* 设置默认父节点值,如:代码表中父节点为特定值的(代码表)才是根节点。
|
* @param defaultParentId
|
*/
|
public void setDefaultParentId(long defaultParentId) {
|
this.defaultParentId = defaultParentId;
|
}
|
|
private long defaultParentId = 0L;
|
}
|