/** * Adds a path to this ParentOMatic and marks it. This might result in changes in tree that * actually tries to "optimize" the markings, and it may result in tree where the currently added * and marked path is not marked, but it's some parent is. */ public void addAndMarkPath(final String path) { final Node<Payload> currentNode = addPath(path, false); // rule A: unmark children if any if (applyRuleA) { applyRecursively( currentNode, new Function<Node<Payload>, Node<Payload>>() { @Override public Node<Payload> apply(Node<Payload> input) { input.getPayload().setMarked(false); return input; } }); } currentNode.getPayload().setMarked(true); // reorganize if needed final Node<Payload> flippedNode = reorganizeForRecursion(currentNode); // optimize tree size if asked for if (keepMarkedNodesOnly) { optimizeTreeSize(flippedNode); } }
/** Applies function recursively from the given node. */ public void applyRecursively( final Node<Payload> fromNode, final Function<Node<Payload>, Node<Payload>> modifier) { modifier.apply(fromNode); for (Node<Payload> child : fromNode.getChildren()) { applyRecursively(child, modifier); } }
/** * Returns the list of all path. * * @since 2.4 */ public List<String> getAllPaths() { // doing scanning final ArrayList<String> paths = new ArrayList<String>(); final Function<Node<Payload>, Node<Payload>> markedCollector = new Function<Node<Payload>, Node<Payload>>() { @Override public Node<Payload> apply(Node<Payload> input) { paths.add(input.getPath()); return null; } }; applyRecursively(ROOT, markedCollector); return paths; }
/** * Cuts down tree to given maxDepth. After this method returns, this instance guarantees that * there is no path deeper than passed in maxDepth (shallower than it might exists!). */ public void cutNodesDeeperThan(final int maxDepth) { applyRecursively( getRoot(), new Function<Node<Payload>, Node<Payload>>() { @Override public Node<Payload> apply(Node<Payload> input) { if (input.getDepth() == maxDepth) { // simply "cut off" children if any for (Node<Payload> child : input.getChildren()) { input.removeChild(child); } } return null; } }); }