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);
|
}
|
}
|
}
|