private static <T, CopyType> void copyMutableRecurse(TreeDef<T> def, T root, List<T> children, CopyType copiedRoot, BiFunction<T, CopyType, CopyType> mapper) { for (T child : children) { List<T> grandChildren = def.childrenOf(child); copyMutableRecurse(def, root, grandChildren, mapper.apply(child, copiedRoot), mapper); } }
/** * Copies the given tree of T to CopyType, starting at the root node * of the tree and moving out to the leaf nodes, which generally requires * CopyType to be mutable (if you want CopyType nodes to know who their * children are). * * @param def defines the structure of the tree * @param root root of the tree * @param nodeMapper given an unmapped node, and a parent CopyType which has already been mapped, return a mapped node. * This function must have the side effect that the returned node should be added as a child of its * parent node. * @return a CopyType with the same contents as the source tree */ public static <T, CopyType> CopyType copyRootOut(TreeDef<T> def, T root, BiFunction<T, CopyType, CopyType> mapper) { List<T> children = def.childrenOf(root); CopyType copyRoot = mapper.apply(root, null); copyMutableRecurse(def, root, children, copyRoot, mapper); return copyRoot; }