diff --git a/src/main/java/net/kemitix/node/Node.java b/src/main/java/net/kemitix/node/Node.java index 4d95501..5ce9d56 100644 --- a/src/main/java/net/kemitix/node/Node.java +++ b/src/main/java/net/kemitix/node/Node.java @@ -127,6 +127,14 @@ public interface Node { Optional> walkTree(final List 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 node, String... path); + /** * Searches for a child with the name given. * diff --git a/src/main/java/net/kemitix/node/NodeItem.java b/src/main/java/net/kemitix/node/NodeItem.java index c02cf86..f338e9a 100644 --- a/src/main/java/net/kemitix/node/NodeItem.java +++ b/src/main/java/net/kemitix/node/NodeItem.java @@ -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 implements Node { } } + @Override + public void placeNodeIn(final Node nodeItem, final String... path) { + if (path.length == 0) { + if (nodeItem.isNamed()) { + final Optional> childNamed = findChildNamed( + nodeItem.getName()); + if (childNamed.isPresent()) { + final Node 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> childNamed = findChildNamed(item); + Node 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();