diff --git a/src/main/java/net/kemitix/node/Nodes.java b/src/main/java/net/kemitix/node/Nodes.java index 24dc50e..ecc5f39 100644 --- a/src/main/java/net/kemitix/node/Nodes.java +++ b/src/main/java/net/kemitix/node/Nodes.java @@ -1,5 +1,9 @@ package net.kemitix.node; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + /** * Utility class for {@link Node} items. * @@ -52,7 +56,7 @@ public final class Nodes { * Creates a new named child node. * * @param data the data the node will contain - * @param name the name of the node + * @param name the name of the node * @param parent the parent of the node * @param the type of the data * @@ -63,4 +67,41 @@ public final class Nodes { return new NodeItem<>(data, name, parent); } + /** + * Creates an immutable copy of an existing node tree. + * + * @param root the root node of the source tree + * @param the type of the data + * + * @return the immutable copy of the tree + */ + public static Node asImmutable(final Node root) { + if (root.getParent().isPresent()) { + throw new IllegalArgumentException("source must be the root node"); + } + final Set> children = getImmutableChildren(root); + return ImmutableNodeItem.newRoot(root.getData().orElse(null), + root.getName(), children); + } + + private static Set> getImmutableChildren(final Node source) { + return source.getChildren() + .stream() + .map(Nodes::asImmutableChild) + .collect(Collectors.toSet()); + } + + private static Node asImmutableChild( + final Node source) { + final Optional> sourceParent = source.getParent(); + if (sourceParent.isPresent()) { + return ImmutableNodeItem.newChild(source.getData().orElse(null), + source.getName(), sourceParent.get(), + getImmutableChildren(source)); + } else { + throw new IllegalArgumentException( + "source must not be the root node"); + } + } + }