1.树处理器
public abstract class AbstractTreeHandler implements InitializingBean { @Resource private TreeHandlerContext treeContext; @Override public void afterPropertiesSet() throws Exception { treeContext.putTreeHandler(getTreeClassPath(), this); } public abstract String getTreeClassPath(); /** * 搜索子节点的方法。 * 根据传入的节点,通过{@link AbstractTreeHandler#autoGenerateTree(Tree)}自动构件树。 * 该方法的作用是根据传入的节点,搜索该节点下的子节点。 * @param root 需要搜索子节点的父节点 * @return * @throws Exception */ protected abstract List<? extends Tree> searchChildren(Tree root) throws Exception; /** * 自动生成树的方法,根须抽象方法{@link AbstractTreeHandler#searchChildren(Tree)}自动生成 * @param root 根节点,自动生成该节点下的树 * @throws Exception */ public void autoGenerateTree(Tree root) throws Exception { if (this.isFinishSearch(root)) { return; } //noinspection unchecked List<Tree> children = (List<Tree>) this.searchChildren(root); root.setChildren(children); if (!CollectionUtils.isEmpty(children)) { for (Tree child : children) { this.autoGenerateTree(child); } root.setIsLeaf(false); } else { root.setIsLeaf(true); } } /** * 停止搜索子节点的方法,默认不停止,有需求需要实现 * @param tree * @return */ protected boolean isFinishSearch(Tree tree) { return false; } /** * 树排序方法,根据树的每一级的sort字段进行排序 * @param sourceTree 需要进行排序的树 * @param <T> {@link Tree} 的子类 */ public <T extends Tree> void sort(T sourceTree) { List<? extends Tree> children = sourceTree.getChildren(); if (!CollectionUtil.isEmpty(children)) { children.sort((i1, i2) -> { int sort1 = ObjectUtils.isEmpty(i1.getSort()) ? 0 : i1.getSort(); int sort2 = ObjectUtils.isEmpty(i2.getSort()) ? 0 : i2.getSort(); return sort1 - sort2; }); sourceTree.setChildren(children); for (Tree child : children) { this.sort(child); } } } /** * 树节点过滤器,如果需要特殊实现可重写该方法 * @param sourceTree 进行过滤的树 * @param jsonStr 树属性的JSON对象,对JSON内容进行like过滤 * @param <T> {@link Tree}的子类 * @return */ public <T extends Tree> boolean filter(T sourceTree, String jsonStr) { return filter(sourceTree, i -> { try { JSONObject paramMap = JSONObject.parseObject(jsonStr); boolean canRemove = true; Class<? extends Tree> treeClass = i.getClass(); for (String key : paramMap.keySet()) { if (StringUtils.hasLength(paramMap.get(key).toString())){ Field field = treeClass.getDeclaredField(key); field.setAccessible(true); String fieldValue; if (StringUtils.hasLength(field.get(i).toString())){ fieldValue = field.get(i).toString(); } else { fieldValue = ""; } canRemove &= fieldValue.contains(paramMap.get(key).toString()); } } return canRemove; } catch (Exception e){ return false; } }); } /** * 子节点过滤器。根据过滤条件从根节点开始逐级往下过滤,如果某一节点符合过滤条件, * 则自该节点往上全部保留,如果该节点下的节点都不符合过滤条件,则全部移除 * @param sourceTree 需要操作的根节点 * @param predicate 过滤条件 */ @SuppressWarnings("unchecked") public <T extends Tree> boolean filter(T sourceTree, Predicate<T> predicate) { boolean remove = true; if (sourceTree.getChildren() != null && sourceTree.getChildren().size() > 0) { Iterator<? extends Tree> iterator = sourceTree.getChildren().iterator(); for (sourceTree.getChildren().iterator(); iterator.hasNext(); ) { T next = (T) iterator.next(); boolean canRemove = this.filter(next, predicate); if (canRemove) { iterator.remove(); } if (predicate.test(sourceTree)) { canRemove = false; } remove = remove && canRemove; } } else { remove = !predicate.test(sourceTree); } return remove; } /** * 根据已经生成的树构建一个可供前端使用的级联对象,该方法会忽略根节点。 * 如果需要同时生成根节点的相关级联信息,可使用{@link AbstractTreeHandler#getCascader(Tree, Function, Function)}方法 * @param root 生成级联对象的树 * @param label 级联对象的展示文本 * @param value 级联对象的实际绑定的值 * @param <T> {@link Tree}的子类 * @return 一个默认键值对为label和value的map集合 */ public <T extends Tree> List<Map<String, Object>> getCascaderIgnoreRoot(T root, Function<T, String> label, Function<T, String> value) { List<Map<String, Object>> mapList = new ArrayList<>(); List<? extends Tree> children = root.getChildren(); if (!CollectionUtils.isEmpty(children)) { for (Tree child : children) { //noinspection unchecked Map<String, Object> cascader = this.getCascader((T) child, label, value); mapList.add(cascader); } } return mapList; } /** * @see AbstractTreeHandler#getCascaderIgnoreRoot(Tree, Function, Function) */ public <T extends Tree> Map<String, Object> getCascader(T root, Function<T, String> label, Function<T, String> value) { Map<String, Object> map = new HashMap<>(); map.put("label", label.apply(root)); map.put("value", value.apply(root)); List<? extends Tree> children = root.getChildren(); if (!CollectionUtils.isEmpty(children)) { List<Map<String, Object>> childrenMap = new ArrayList<>(); for (Tree child : children) { //noinspection unchecked Map<String, Object> cascader = this.getCascader((T) child, label, value); childrenMap.add(cascader); } map.put("children", childrenMap); } return map; } }View Code
2.TreeHandlerContext
@Component public class TreeHandlerContext { private final Map<String, AbstractTreeHandler> treeHandlerMap = new HashMap<>(); public void putTreeHandler(String treeClassPath, AbstractTreeHandler treeHandler) { treeHandlerMap.put(treeClassPath, treeHandler); } public AbstractTreeHandler getTreeHandler(String treeClassPath) { AbstractTreeHandler treeHandler = this.treeHandlerMap.get(treeClassPath); if (treeHandler == null) { throw new TreeNotFoundException("Can not found this tree: " + treeClassPath); } return treeHandler; } }
3.树的基础结构
@Data @Accessors(chain = true) public class Tree { private String id; private String name; private String code; private String remark; private String parentID; private Integer sort; private Boolean isLeaf; private List<? extends Tree> children; }
4.实现searchChildren自动生成树
4.1继承AbstractTreeHandler类实现抽象接口getTreeClassPath和searchChildren
@Component public class SomethingTreeHandler extends AbstractTreeHandler{ @Override public String getTreeClassPath() { return SomethingTree.class.getName(); } @Override protected List<? extends Tree> searchChildren(Tree root) throws Exception { List<SomethingTree> children = new ArrayList<>(); if (root.getId().length() <= 5){ for (int i = 0; i < 2; i++) { SomethingTree child = new SomethingTree(); child.setId(root.getId() + i) .setName(root.getName() + i) .setCode(root.getCode() + i); child.setSomething("something"); child.setIsLeaf(child.getId().length()>5); children.add(child); } } return children; } }
/**
* 具体实现的树需要继承树的基础结构
*/
@Data public class SomethingTree extends Tree{ private String something; }
4.2调用
@Autowired private TreeHandlerContext treeHandlerContext; @Test public void t0() throws Exception { SomethingTree root = new SomethingTree(); root.setId("0") .setName("Tree0") .setCode("Tree0"); AbstractTreeHandler treeHandler = treeHandlerContext.getTreeHandler(SomethingTree.class.getName()); treeHandler.autoGenerateTree(root); System.out.println(JSON.toJSONString(root)); }
在实现getTreeClassPath方法时使用的键名即获取该处理器的键名
返回的树结构如下
标签:return,树状,Tree,children,生成,自动,节点,root,public From: https://www.cnblogs.com/ffaann/p/16734322.html