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;
/**
* 把业务数据集合转换成树节点对象的生成器实现。
* 通常在业务中,从数据库查询出来记录,这些记录带有上下级关系,如:树分类等。
* 把数据集合传递进来,就可以转换成树对象,子类必须实现抽象方法。
* @author shikeying
* @date 2014-9-2
*
* @param
*/
public abstract class AbstractTreeGenerator {
private boolean multiRoot = false;
/* 虚拟的根节点,可以显示用户指定的名称,可以不设置 */
private CacheTreeNode dummyRoot = null;
private Map rootMap = new TreeMap();
private Map childMap = new TreeMap();
/**
* 默认构造函数,设置虚拟根节点名称,如果不需要则设置为null
* @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 getTreeRootList(){
if(!multiRoot)
throw new IllegalStateException("存在多个根节点,请调用方法:getTreeRoot().");
List list = new ArrayList();
for(CacheTreeNode node : rootMap.values()){
list.add(node);
}
return list;
}
public void setMultiRoot(boolean multiRoot){
this.multiRoot = multiRoot;
}
/**
* 设置数据实体集合,通过此方法可以组织树结构。
* @param datas
*/
public void setEntityList(List 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 childMap){
CacheTreeNode _node = null;
for(Iterator i = childMap.values().iterator(); i.hasNext();){
_node = i.next();
mountMiddleNode(_node, childMap);
}
}
private void mountMiddleNode(CacheTreeNode currentNode
, Map 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);
}
}
}