All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.penglecode.codeforce.common.support.ObjectTreeBuilder Maven / Gradle / Ivy

The newest version!
package com.penglecode.codeforce.common.support;

import com.penglecode.codeforce.common.util.StringUtils;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 通用对象树Builder
 * 
 * @param 
 * @param 
 * @author 	pengpeng
 * @version 	1.0
 */
public abstract class ObjectTreeBuilder> {

	private final Integer defaultRootLevel;

	public ObjectTreeBuilder() {
		this(0);
	}

	public ObjectTreeBuilder(Integer defaultRootLevel) {
		this.defaultRootLevel = defaultRootLevel;
	}

	/**
	 * 根据parentTreeNodeId及全部树节点列表来渲染一颗具有父子关系的对象树
	 * parentTreeNodeId在一般情况下它应该是一个根节点的父节点ID
	 *
	 * @param parentTreeNodeIds		- 父节点ID列表
	 * @param allTreeNodeList		- 需要构造对象树的所有节点列表
	 * @return
	 */
	public List buildObjectTree(List parentTreeNodeIds, List allTreeNodeList) {
		Assert.notEmpty(parentTreeNodeIds, "Parameter 'parentTreeNodeIds' can not be empty!");
		Assert.notEmpty(allTreeNodeList, "Parameter 'allTreeNodeList' can not be empty!");
		//1、找顶层节点列表
		List parentTreeNodeList = new ArrayList<>();
		for(I parentNodeId : parentTreeNodeIds) {
			T parentNode = getTreeNodeById(parentNodeId, allTreeNodeList);
			if(parentNode != null) { //parentNodeId对应的TreeNode不存在?
				parentTreeNodeList.add(parentNode);
			} else {
				//走到这里说明parentTreeNodeIds是根节点
				List rootTreeNodeList = getDirectChildNodeList(parentNodeId, allTreeNodeList);
				if(!CollectionUtils.isEmpty(rootTreeNodeList)) {
					parentTreeNodeList.addAll(rootTreeNodeList);
				}
			}
		}
		//2、加载下层节点列表
		if(!CollectionUtils.isEmpty(parentTreeNodeList)) {
			for(T parentNode : parentTreeNodeList) {
				recursiveLoadChildTreeNodes(parentNode, allTreeNodeList, getDefaultRootLevel());
			}
		}
		return parentTreeNodeList;
	}
	
	/**
	 * 根据parentTreeNodeId及全部树节点列表来渲染一颗具有父子关系的对象树,同时提供对树节点数据类型的转换
	 * parentTreeNodeId在一般情况下它应该是一个根节点的父节点ID
	 *
	 * @param parentTreeNodeIds		- 父节点ID列表
	 * @param allTreeNodeList		- 需要构造对象树的所有节点列表
	 * @param treeNodeConverter		- 树节点数据结构转换器
	 * @return
	 */
	public  List buildObjectTree(List parentTreeNodeIds, List allTreeNodeList, TreeNodeConverter treeNodeConverter) {
		Assert.notEmpty(parentTreeNodeIds, "Parameter 'parentTreeNodeIds' can not be empty!");
		Assert.notEmpty(allTreeNodeList, "Parameter 'allTreeNodeList' can not be empty!");
		Assert.notNull(treeNodeConverter, "Parameter 'treeNodeConverter' can not be null!");
		List sourceTreeNodeList = buildObjectTree(parentTreeNodeIds, allTreeNodeList);
		List targetTreeNodeList = new ArrayList<>();
		if(!CollectionUtils.isEmpty(sourceTreeNodeList)){
			for(T sourceTreeNode : sourceTreeNodeList){
				R targetTreeNode = treeNodeConverter.convertTreeNode(sourceTreeNode);
				targetTreeNodeList.add(targetTreeNode);
				recursiveConvertTreeNode(sourceTreeNode, targetTreeNode, treeNodeConverter);
			}
		}
		return targetTreeNodeList;
	}

	/**
	 * 获取指定parentTreeNodeId的直接子节点列表
	 *
	 * @param parentTreeNodeId	- 父节点ID
	 * @param allTreeNodeList	- 所有节点列表
	 * @return
	 */
	public List getDirectChildNodeList(I parentTreeNodeId, List allTreeNodeList) {
		List childTreeNodeList = new ArrayList<>();
		if(!CollectionUtils.isEmpty(allTreeNodeList) && !ObjectUtils.isEmpty(parentTreeNodeId)){
			for(T treeNode : allTreeNodeList){
				if(treeNode != null && parentTreeNodeId.equals(getParentTreeNodeId(treeNode))){
					childTreeNodeList.add(treeNode);
				}
			}
		}
		return childTreeNodeList;
	}

	/**
	 * 获取指定parentNodeId的直接子节点列表,同时提供对树节点数据类型的转换
	 *
	 * @param parentTreeNodeId		- 父节点ID
	 * @param allTreeNodeList		- 所有节点列表
	 * @param treeNodeConverter		- 树节点数据转换器
	 * @param 
	 * @return
	 */
	public  List getDirectChildNodeList(I parentTreeNodeId, List allTreeNodeList, TreeNodeConverter treeNodeConverter) {
		List childTreeNodeList = new ArrayList<>();
		if(!CollectionUtils.isEmpty(allTreeNodeList) && !ObjectUtils.isEmpty(parentTreeNodeId) && treeNodeConverter != null){
			for(T treeNode : allTreeNodeList){
				if(treeNode != null && parentTreeNodeId.equals(getParentTreeNodeId(treeNode))){
					childTreeNodeList.add(treeNodeConverter.convertTreeNode(treeNode));
				}
			}
		}
		return childTreeNodeList;
	}

	/**
	 * 递归构转换对象树
	 *
	 * @param sourceTreeNode	- 源节点对象
	 * @param targetTreeNode	- 目标节点对象
	 * @param treeNodeConverter	- 树节点数据转换器
	 * @param 
	 */
	public  void recursiveConvertTreeNode(T sourceTreeNode, R targetTreeNode, TreeNodeConverter treeNodeConverter) {
		if(sourceTreeNode != null && targetTreeNode != null) {
			List sourceChildNodeList = getChildTreeNodeList(sourceTreeNode);
			if(!CollectionUtils.isEmpty(sourceChildNodeList)) {
				List resultTreeNodeChildList = new ArrayList<>();
				for(T sourceChildNode : sourceChildNodeList) {
					R resultTreeNode = treeNodeConverter.convertTreeNode(sourceChildNode);
					resultTreeNodeChildList.add(resultTreeNode);
					recursiveConvertTreeNode(sourceChildNode, resultTreeNode, treeNodeConverter);
				}
				treeNodeConverter.setChildTreeNodeList(targetTreeNode, resultTreeNodeChildList);
			}
		}
	}

	/**
	 * 递归构加载子对象树
	 *
	 * @param currentTreeNode	- 当前树节点
	 * @param allTreeNodeList	- 所有树节点列表
	 * @param level				- 层级值
	 */
	public void recursiveLoadChildTreeNodes(T currentTreeNode, List allTreeNodeList, int level) {
		if(currentTreeNode != null && !CollectionUtils.isEmpty(allTreeNodeList)) {
			setTreeNodeLevel(currentTreeNode, level);
			attachTreeNodePath(currentTreeNode, allTreeNodeList);
			List directChildList = getDirectChildNodeList(getTreeNodeId(currentTreeNode), allTreeNodeList);
			if(!CollectionUtils.isEmpty(directChildList)) {
				Collections.sort(directChildList);
			}
			setChildTreeNodeList(currentTreeNode, directChildList);
			if(!CollectionUtils.isEmpty(directChildList)) {
				for(T childTreeNode : directChildList){
					recursiveLoadChildTreeNodes(childTreeNode, allTreeNodeList, level + 1);
				}
			}
		}
	}

	/**
	 * 附加上树节点的tree-path
	 *
	 * @param currentTreeNode
	 * @param allTreeNodeList
	 */
	protected void attachTreeNodePath(T currentTreeNode, List allTreeNodeList) {
		String parentPath = "";
		I parentTreeNodeId = getParentTreeNodeId(currentTreeNode);
		if(parentTreeNodeId != null){
			T parentTreeNode = getTreeNodeById(parentTreeNodeId, allTreeNodeList);
			if(parentTreeNode != null){
				parentPath = StringUtils.defaultIfEmpty(getTreeNodePath(parentTreeNode), "");
			}
		}
		String currentPath = parentPath + "/" + getTreeNodeId(currentTreeNode);
		setTreeNodePath(currentTreeNode, currentPath);
	}

	/**
	 * 根据treeNodeId获取TreeNode对象
	 *
	 * @param treeNodeId
	 * @param allTreeNodeList
	 * @return
	 */
	protected T getTreeNodeById(I treeNodeId, List allTreeNodeList) {
		if(!CollectionUtils.isEmpty(allTreeNodeList) && !ObjectUtils.isEmpty(treeNodeId)){
			for(T treeNode : allTreeNodeList){
				if(treeNode != null && treeNodeId.equals(getTreeNodeId(treeNode))){
					return treeNode;
				}
			}
		}
		return null;
	}

	protected Integer getDefaultRootLevel() {
		return defaultRootLevel;
	}

	/**
	 * 返回指定treeNode的ID
	 *
	 * @param treeNode
	 * @return
	 */
	protected abstract I getTreeNodeId(T treeNode);

	/**
	 * 返回指定treeNode的父节点ID
	 *
	 * @param treeNode
	 * @return
	 */
	protected abstract I getParentTreeNodeId(T treeNode);

	/**
	 * 设置指定treeNode的直接子节点列表
	 *
	 * @param treeNode
	 * @param directChildList
	 */
	protected abstract void setChildTreeNodeList(T treeNode, List directChildList);

	/**
	 * 返回指定treeNode的直接子节点列表
	 *
	 * @param treeNode
	 * @return
	 */
	protected abstract List getChildTreeNodeList(T treeNode);

	/**
	 * 设置指定treeNode的层级
	 * @param treeNode
	 * @param level
	 */
	protected abstract void setTreeNodeLevel(T treeNode, Integer level);

	/**
	 * 设置指定treeNode的tree-path值
	 * @param treeNode
	 * @param treePath
	 */
	protected abstract void setTreeNodePath(T treeNode, String treePath);

	/**
	 * 返回指定treeNode的tree-path值
	 * @param treeNode
	 * @return
	 */
	protected abstract String getTreeNodePath(T treeNode);


	/**
	 * 树节点数据结构转换器
	 *
	 * @param 
	 * @param 
	 * @author 	pengpeng
	 * @version 1.0
	 */
	public interface TreeNodeConverter {

		R convertTreeNode(T targetTreeNode);

		void setChildTreeNodeList(R resultTreeNode, List subTreeNodeList);

	}

}