package com.tianee.webframe.util.tree;
import java.beans.IntrospectionException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
public class TreeUtils {
/**
* 使用递归方法建树
*
* @param list
* 树的单个节点组成List,没有树结构(parent、children为null)
* @param idAttr
* 树节点id的属性名
* @param parentIdAttr
* 树节点的parentId的属性名
* @return tree<T>
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws NoSuchMethodException
* @throws IntrospectionException
*/
public static <T> List<T> buildTree(List<T> list, String idAttr, String parentIdAttr) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException, IntrospectionException {
List<T> trees = new ArrayList<>();
for (T treeNode : list) {
Method method = treeNode.getClass().getMethod("get" + firstUpperCase(parentIdAttr), null);
Object value = method.invoke(treeNode, null);
if (null == value) {
trees.add(findChildren(treeNode, list, idAttr, parentIdAttr));
}
}
return trees;
}
/**
*
* @param t
* @param treeNodes
* @return
* @throws NoSuchMethodException
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws IntrospectionException
*/
public static <T> T findChildren(T t, List<T> treeNodes, String idAttr, String parentIdAttr) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException,
IntrospectionException {
Method getIdMethod = t.getClass().getMethod("get" + firstUpperCase(idAttr));
String id = String.valueOf(getIdMethod.invoke(t, null));
for (T it : treeNodes) {
Method getParentIdMethod = it.getClass().getMethod("get" + firstUpperCase(parentIdAttr));
Object parentId = getParentIdMethod.invoke(it, null);
if (id.equals(String.valueOf(parentId))) {
Method getChildrenMethod = t.getClass().getMethod("getChildren");
Object children = getChildrenMethod.invoke(t, null);
if (null == children) {
Method setChildrenMethod = t.getClass().getMethod("setChildren", Set.class);
setChildrenMethod.invoke(t, new LinkedHashSet<T>());
}
((HashSet<T>) getChildrenMethod.invoke(t, null)).add(findChildren(it, treeNodes, idAttr, parentIdAttr));
}
}
return t;
}
/**
*
* @param childrens
* 叶子节点组成的List,没有树结构(parent、children为null)
* @param list
* 树所有的单个节点组成List,没有树结构(parent、children为null)
* @param idAttr
* 树节点id的属性名
* @param parentIdAttr
* 树节点的parentId的属性名
* @return
* @throws SecurityException
* @throws NoSuchMethodException
* @throws InvocationTargetException
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws IntrospectionException
*/
public static <T> List<T> reverseBuildTree(List<T> childrens, List<T> list, String idAttr, String parentIdAttr) throws NoSuchMethodException, SecurityException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException, IntrospectionException {
Set<Object> path = new HashSet<>();
for (T treeNode : childrens) {
findParent(treeNode, list, idAttr, parentIdAttr, path);
}
List<T> newList = new ArrayList<>();
for (T node : list) {
Method method = node.getClass().getMethod("get" + firstUpperCase(idAttr), null);
Object id = method.invoke(node, null);
for (Object nodeId : path) {
if (id.equals(nodeId)) {
newList.add(node);
}
}
}
List<T> trees = buildTree(newList, idAttr, parentIdAttr);
return trees;
}
/**
*
* @param <T>
* @param t
* 当前节点
* @param treeNodes
* 树所有的单个节点组成List,没有树结构(parent、children为null)
* @param idAttr
* @param parentIdAttr
* @return
* @throws InvocationTargetException
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws SecurityException
* @throws NoSuchMethodException
*/
public static <T> void findParent(T t, List<T> treeNodes, String idAttr, String parentIdAttr, Set<Object> path) throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException, NoSuchMethodException, SecurityException {
Method getTIdMethod = t.getClass().getMethod("get" + firstUpperCase(idAttr), null);
Object tId = getTIdMethod.invoke(t, null);
path.add(tId);
Method getParentIdMethod = t.getClass().getMethod("get" + firstUpperCase(parentIdAttr), null);
Object parentId = getParentIdMethod.invoke(t, null);
if (null == parentId) {
return;
}
for (T node : treeNodes) {
Method getIdMethod = node.getClass().getMethod("get" + firstUpperCase(idAttr));
Object id = getIdMethod.invoke(node, null);
if (parentId.equals(id)) {
/*
* Method getParentMethod = t.getClass().getMethod("getParent",
* null); T parent = (T) getParentMethod.invoke(t, null);
*
* if(null == parent){ }
*
* Method setParentMethod = t.getClass().getMethod("setParent",
* t.getClass()); setParentMethod.invoke(t, node);
*/
findParent(node, treeNodes, idAttr, parentIdAttr, path);
}
}
}
/**
* 字符串首字母大写
*
* @param str
* @return String 如果首位不是字母,返回空字符串
*/
public static String firstUpperCase(String str) {
char[] ch = str.toCharArray();
if (ch[0] >= 'a' && ch[0] <= 'z') {
ch[0] = (char) (ch[0] - 32);
} else if (ch[0] >= 'A' && ch[0] <= 'Z') {
} else {
return "";
}
return new String(ch);
}
}