Node.placeNodeIn(): add node to tree under the path of named elements

Any intervening nodes that don't exist will be created.

e.g. placeNodeIn(node, "alpha", "beta")

Will add node:

[root]
    "alpha"
        "beta"
            node
This commit is contained in:
Paul Campbell 2016-05-24 11:35:33 +01:00
parent 9fca56b4c6
commit 45bd77bbca
2 changed files with 49 additions and 0 deletions

View file

@ -127,6 +127,14 @@ public interface Node<T> {
Optional<Node<T>> walkTree(final List<T> path);
/**
* Places the node in the tree under by the path. Intervening empty
* nodes are created as needed.
*
* @param node the node to place
* @param path the path to contain the new node
*/
void placeNodeIn(Node<T> node, String... path);
/**
* Searches for a child with the name given.
*

View file

@ -1,5 +1,6 @@
package net.kemitix.node;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
@ -325,6 +326,46 @@ public class NodeItem<T> implements Node<T> {
}
}
@Override
public void placeNodeIn(final Node<T> nodeItem, final String... path) {
if (path.length == 0) {
if (nodeItem.isNamed()) {
final Optional<Node<T>> childNamed = findChildNamed(
nodeItem.getName());
if (childNamed.isPresent()) {
final Node<T> existing = childNamed.get();
if (!existing.isEmpty()) {
throw new NodeException(
"A non-empty node with that name already "
+ "exists here");
} else {
existing.getChildren().forEach(nodeItem::addChild);
existing.removeParent();
nodeItem.setParent(this);
return;
}
}
}
addChild(nodeItem);
return;
}
String item = path[0];
final Optional<Node<T>> childNamed = findChildNamed(item);
Node<T> child;
if (!childNamed.isPresent()) {
child = new NodeItem<>(null, item, this);
} else {
child = childNamed.get();
if (child.isEmpty()) {
if (path.length == 1) {
getChildren().forEach(nodeItem::addChild);
nodeItem.setParent(this);
}
}
}
child.placeNodeIn(nodeItem, Arrays.copyOfRange(path, 1, path.length));
}
@Override
public String drawTree(final int depth) {
final StringBuilder sb = new StringBuilder();