From 7f0f0d1bf9c33576ea5edf9c3a772ddc724a098c Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Tue, 20 Sep 2016 22:12:29 +0100 Subject: [PATCH 01/13] NodeItem: add all args constructor --- src/main/java/net/kemitix/node/NodeItem.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/main/java/net/kemitix/node/NodeItem.java b/src/main/java/net/kemitix/node/NodeItem.java index 0e92dfb..c3d87f7 100644 --- a/src/main/java/net/kemitix/node/NodeItem.java +++ b/src/main/java/net/kemitix/node/NodeItem.java @@ -50,6 +50,23 @@ class NodeItem implements Node { private String name; + /** + * Constructor. + * + * @param data the data of the node + * @param name the name of the node + * @param parent the parent of the node, or null for a root node + * @param children the children of the node - must not be null + */ + NodeItem( + final T data, final String name, final Node parent, @NonNull final Set> children + ) { + this.data = data; + this.name = name; + this.parent = parent; + this.children.addAll(children); + } + /** * Create named root node. * From dda6acc047f945b2fcaeaa9973f227212bf777da Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Tue, 20 Sep 2016 22:17:00 +0100 Subject: [PATCH 02/13] Nodes: use new NodeItem constructor --- src/main/java/net/kemitix/node/NodeItem.java | 2 +- src/main/java/net/kemitix/node/Nodes.java | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/net/kemitix/node/NodeItem.java b/src/main/java/net/kemitix/node/NodeItem.java index c3d87f7..86c66ed 100644 --- a/src/main/java/net/kemitix/node/NodeItem.java +++ b/src/main/java/net/kemitix/node/NodeItem.java @@ -208,7 +208,7 @@ class NodeItem implements Node { */ @Override public Node createChild(@NonNull final T child) { - return new NodeItem<>(child, this); + return new NodeItem<>(child, "", this, new HashSet<>()); } @Override diff --git a/src/main/java/net/kemitix/node/Nodes.java b/src/main/java/net/kemitix/node/Nodes.java index 7093c07..0a6fa96 100644 --- a/src/main/java/net/kemitix/node/Nodes.java +++ b/src/main/java/net/kemitix/node/Nodes.java @@ -24,6 +24,7 @@ SOFTWARE. package net.kemitix.node; +import java.util.HashSet; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -47,7 +48,7 @@ public final class Nodes { * @return the new node */ public static Node unnamedRoot(final T data) { - return new NodeItem<>(data); + return new NodeItem<>(data, "", null, new HashSet<>()); } /** @@ -60,7 +61,7 @@ public final class Nodes { * @return the new node */ public static Node namedRoot(final T data, final String name) { - return new NodeItem<>(data, name); + return new NodeItem<>(data, name, null, new HashSet<>()); } /** @@ -73,7 +74,7 @@ public final class Nodes { * @return the new node */ public static Node unnamedChild(final T data, final Node parent) { - return new NodeItem<>(data, parent); + return new NodeItem<>(data, "", parent, new HashSet<>()); } /** @@ -89,7 +90,7 @@ public final class Nodes { public static Node namedChild( final T data, final String name, final Node parent ) { - return new NodeItem<>(data, name, parent); + return new NodeItem<>(data, name, parent, new HashSet<>()); } /** From f34f2a72009144f9689a2b1d24ea017198f5b9b9 Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Tue, 20 Sep 2016 22:17:15 +0100 Subject: [PATCH 03/13] NodeItem: remove old constructors --- src/main/java/net/kemitix/node/NodeItem.java | 44 -------------------- 1 file changed, 44 deletions(-) diff --git a/src/main/java/net/kemitix/node/NodeItem.java b/src/main/java/net/kemitix/node/NodeItem.java index 86c66ed..b4a6eeb 100644 --- a/src/main/java/net/kemitix/node/NodeItem.java +++ b/src/main/java/net/kemitix/node/NodeItem.java @@ -67,50 +67,6 @@ class NodeItem implements Node { this.children.addAll(children); } - /** - * Create named root node. - * - * @param data the data or null - * @param name the name - */ - NodeItem(final T data, final String name) { - this(data); - this.name = name; - } - - /** - * Create unnamed root node. - * - * @param data the data or null - */ - NodeItem(final T data) { - this.data = data; - } - - /** - * Creates a node with a parent. - * - * @param data the data or null - * @param parent the parent node - */ - NodeItem(final T data, final Node parent) { - this.data = data; - setParent(parent); - } - - /** - * Creates a named node with a parent. - * - * @param data the data or null - * @param name the name - * @param parent the parent node - */ - NodeItem(final T data, final String name, final Node parent) { - this.data = data; - this.name = name; - setParent(parent); - } - @Override public String getName() { return name; From f9aba88d0cf97c9dd448d9cb273f746fef2d53c6 Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Tue, 20 Sep 2016 22:18:00 +0100 Subject: [PATCH 04/13] NodeItem::getChild: simplify method --- src/main/java/net/kemitix/node/NodeItem.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/net/kemitix/node/NodeItem.java b/src/main/java/net/kemitix/node/NodeItem.java index b4a6eeb..ea26858 100644 --- a/src/main/java/net/kemitix/node/NodeItem.java +++ b/src/main/java/net/kemitix/node/NodeItem.java @@ -224,11 +224,7 @@ class NodeItem implements Node { @Override public Node getChild(final T child) { - Optional> optional = findChild(child); - if (optional.isPresent()) { - return optional.get(); - } - throw new NodeException("Child not found"); + return findChild(child).orElseThrow(() -> new NodeException("Child not found")); } /** From 753b37cc1dfed14cadc4835653196e38e7d95838 Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Tue, 20 Sep 2016 22:24:28 +0100 Subject: [PATCH 05/13] NodeItem::insertInPath: clarify local variable name --- src/main/java/net/kemitix/node/NodeItem.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/kemitix/node/NodeItem.java b/src/main/java/net/kemitix/node/NodeItem.java index ea26858..a0c330d 100644 --- a/src/main/java/net/kemitix/node/NodeItem.java +++ b/src/main/java/net/kemitix/node/NodeItem.java @@ -264,9 +264,9 @@ class NodeItem implements Node { if (path.length == 0) { insertChild(nodeItem); } else { - val item = path[0]; - findChildByName(item).orElseGet(() -> new NodeItem<>(null, item, this)) - .insertInPath(nodeItem, Arrays.copyOfRange(path, 1, path.length)); + val nextInPath = path[0]; + findChildByName(nextInPath).orElseGet(() -> new NodeItem<>(null, nextInPath, this, new HashSet<>())) + .insertInPath(nodeItem, Arrays.copyOfRange(path, 1, path.length)); } } From 77a7946e9c9b4d652037334248665d9c6289d2cb Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Tue, 20 Sep 2016 22:26:49 +0100 Subject: [PATCH 06/13] NodeItem::findChild: improved Optional idiom --- src/main/java/net/kemitix/node/NodeItem.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/kemitix/node/NodeItem.java b/src/main/java/net/kemitix/node/NodeItem.java index a0c330d..f4f69b6 100644 --- a/src/main/java/net/kemitix/node/NodeItem.java +++ b/src/main/java/net/kemitix/node/NodeItem.java @@ -214,12 +214,9 @@ class NodeItem implements Node { @Override public Optional> findChild(@NonNull final T child) { return children.stream() - .filter(node -> { - final Optional d = node.getData(); - return d.isPresent() && d.get() - .equals(child); - }) - .findAny(); + .filter(node -> child.equals(node.getData() + .orElseGet(() -> null))) + .findFirst(); } @Override From d73a46b9054235ec73f846a3c339174241ffd01a Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Tue, 20 Sep 2016 22:39:30 +0100 Subject: [PATCH 07/13] NodeItemTest: check that child is added to parent --- src/test/java/net/kemitix/node/NodeItemTest.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/test/java/net/kemitix/node/NodeItemTest.java b/src/test/java/net/kemitix/node/NodeItemTest.java index 2702ae0..653ada5 100644 --- a/src/test/java/net/kemitix/node/NodeItemTest.java +++ b/src/test/java/net/kemitix/node/NodeItemTest.java @@ -10,6 +10,7 @@ import org.junit.rules.ExpectedException; import java.util.Arrays; import java.util.Collections; import java.util.Optional; +import java.util.Set; import static org.assertj.core.api.Assertions.assertThat; @@ -84,6 +85,17 @@ public class NodeItemTest { .contains(parent); } + @Test + public void shouldAddAsChildWhenCreatedWithParent() { + //given + final Node root = Nodes.namedRoot("root data", "root name"); + //when + final Node child = Nodes.namedChild("child data", "child name", root); + //then + final Set> children = root.getChildren(); + assertThat(children).containsExactly(child); + } + /** * Test that setting the parent on a node where the proposed parent is a * child of the node throws an exception. From 93a3f2ad4252c177f1ca47ab5d880dde744c5261 Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Tue, 20 Sep 2016 22:39:54 +0100 Subject: [PATCH 08/13] NodesTest: unnamed nodes have an empty string --- src/test/java/net/kemitix/node/NodesTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/net/kemitix/node/NodesTest.java b/src/test/java/net/kemitix/node/NodesTest.java index ace4f79..6c9aee4 100644 --- a/src/test/java/net/kemitix/node/NodesTest.java +++ b/src/test/java/net/kemitix/node/NodesTest.java @@ -24,7 +24,7 @@ public class NodesTest { val node = Nodes.unnamedRoot("data"); SoftAssertions softly = new SoftAssertions(); softly.assertThat(node.getData()).contains("data"); - softly.assertThat(node.getName()).isNull(); + softly.assertThat(node.getName()).isEmpty(); softly.assertAll(); } @@ -43,7 +43,7 @@ public class NodesTest { val node = Nodes.unnamedChild("data", parent); SoftAssertions softly = new SoftAssertions(); softly.assertThat(node.getData()).contains("data"); - softly.assertThat(node.getName()).isNull(); + softly.assertThat(node.getName()).isEmpty(); softly.assertThat(node.getParent()).contains(parent); softly.assertAll(); } From ff3a45665798fdad0344d7e891e1e812367e1e01 Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Tue, 20 Sep 2016 22:40:32 +0100 Subject: [PATCH 09/13] NodeItem: new constructor sets parent properly --- src/main/java/net/kemitix/node/NodeItem.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/kemitix/node/NodeItem.java b/src/main/java/net/kemitix/node/NodeItem.java index f4f69b6..efdb49a 100644 --- a/src/main/java/net/kemitix/node/NodeItem.java +++ b/src/main/java/net/kemitix/node/NodeItem.java @@ -63,7 +63,9 @@ class NodeItem implements Node { ) { this.data = data; this.name = name; - this.parent = parent; + if (parent != null) { + setParent(parent); + } this.children.addAll(children); } From 48c5b157204498562615b0845ad1652d62a0099b Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Tue, 20 Sep 2016 22:59:50 +0100 Subject: [PATCH 10/13] ImmutableNodeItem: now extends NodeItem The AbstractNodeItem is now redundant and is removed. --- .../net/kemitix/node/AbstractNodeItem.java | 183 ------------------ .../net/kemitix/node/ImmutableNodeItem.java | 6 +- src/main/java/net/kemitix/node/NodeItem.java | 6 +- 3 files changed, 8 insertions(+), 187 deletions(-) delete mode 100644 src/main/java/net/kemitix/node/AbstractNodeItem.java diff --git a/src/main/java/net/kemitix/node/AbstractNodeItem.java b/src/main/java/net/kemitix/node/AbstractNodeItem.java deleted file mode 100644 index 5f6e5d5..0000000 --- a/src/main/java/net/kemitix/node/AbstractNodeItem.java +++ /dev/null @@ -1,183 +0,0 @@ -/* -The MIT License (MIT) - -Copyright (c) 2016 Paul Campbell - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -package net.kemitix.node; - -import lombok.NonNull; - -import java.util.HashSet; -import java.util.List; -import java.util.Optional; -import java.util.Set; - -/** - * An abstract node item, providing default implementations for most read-only - * operations. - * - * @param the type of data stored in each node - * - * @author Paul Campbell (pcampbell@kemitix.net) - */ -abstract class AbstractNodeItem implements Node { - - private final Set> children; - - private T data; - - private String name; - - private Node parent; - - /** - * Constructor. - * - * @param data the data of the node - * @param name the name of the node - * @param parent the parent of the node, or null for a root node - * @param children the children of the node - must not be null - */ - protected AbstractNodeItem( - final T data, final String name, final Node parent, @NonNull final Set> children - ) { - this.data = data; - this.name = name; - this.parent = parent; - this.children = children; - } - - @Override - public String getName() { - return name; - } - - @Override - public Optional getData() { - return Optional.ofNullable(data); - } - - @Override - public boolean isEmpty() { - return data == null; - } - - @Override - public Optional> getParent() { - return Optional.ofNullable(parent); - } - - @Override - public Set> getChildren() { - return new HashSet<>(children); - } - - /** - * Fetches the node for the child if present. - * - * @param child the child's data to search for - * - * @return an {@link Optional} containing the child node if found - */ - @Override - public Optional> findChild(@NonNull final T child) { - return children.stream() - .filter(node -> { - final Optional d = node.getData(); - return d.isPresent() && d.get() - .equals(child); - }) - .findAny(); - } - - @Override - public Node getChild(final T child) { - return findChild(child).orElseThrow(() -> new NodeException("Child not found")); - } - - /** - * Checks if the node is an ancestor. - * - * @param node the potential ancestor - * - * @return true if the node is an ancestor - */ - @Override - public boolean isDescendantOf(final Node node) { - return parent != null && (node.equals(parent) || parent.isDescendantOf(node)); - } - - /** - * Walks the node tree using the path to select each child. - * - * @param path the path to the desired child - * - * @return the child or null - */ - @Override - public Optional> findInPath(@NonNull final List path) { - if (path.isEmpty()) { - return Optional.empty(); - } - Node current = this; - for (int i = 0, pathSize = path.size(); i < pathSize && current != null; i++) { - current = current.findChild(path.get(i)) - .orElse(null); - } - return Optional.ofNullable(current); - } - - @Override - public Optional> findChildByName(@NonNull final String named) { - return children.stream() - .filter(n -> n.getName() - .equals(named)) - .findAny(); - } - - @Override - public Node getChildByName(final String named) { - return findChildByName(named).orElseThrow(() -> new NodeException("Named child not found")); - } - - @Override - public String drawTree(final int depth) { - final StringBuilder sb = new StringBuilder(); - final String unnamed = "(unnamed)"; - if (isNamed()) { - sb.append(formatByDepth(name, depth)); - } else if (!children.isEmpty()) { - sb.append(formatByDepth(unnamed, depth)); - } - getChildren().forEach(c -> sb.append(c.drawTree(depth + 1))); - return sb.toString(); - } - - private String formatByDepth(final String value, final int depth) { - return String.format("[%1$" + (depth + value.length()) + "s]\n", value); - } - - @Override - public boolean isNamed() { - return name != null && name.length() > 0; - } -} diff --git a/src/main/java/net/kemitix/node/ImmutableNodeItem.java b/src/main/java/net/kemitix/node/ImmutableNodeItem.java index 009d2af..fc4d159 100644 --- a/src/main/java/net/kemitix/node/ImmutableNodeItem.java +++ b/src/main/java/net/kemitix/node/ImmutableNodeItem.java @@ -39,14 +39,15 @@ import java.util.Set; * * @author Paul Campbell (pcampbell@kemitix.net) */ -final class ImmutableNodeItem extends AbstractNodeItem { +final class ImmutableNodeItem extends NodeItem { private static final String IMMUTABLE_OBJECT = "Immutable object"; private ImmutableNodeItem( final T data, final String name, final Node parent, final Set> children ) { - super(data, name, parent, children); + super(data, name, null, children); + forceParent(parent); } /** @@ -136,5 +137,4 @@ final class ImmutableNodeItem extends AbstractNodeItem { public void removeParent() { throw new UnsupportedOperationException(IMMUTABLE_OBJECT); } - } diff --git a/src/main/java/net/kemitix/node/NodeItem.java b/src/main/java/net/kemitix/node/NodeItem.java index efdb49a..d933770 100644 --- a/src/main/java/net/kemitix/node/NodeItem.java +++ b/src/main/java/net/kemitix/node/NodeItem.java @@ -69,6 +69,10 @@ class NodeItem implements Node { this.children.addAll(children); } + protected void forceParent(final Node parent) { + this.parent = parent; + } + @Override public String getName() { return name; @@ -105,7 +109,7 @@ class NodeItem implements Node { * @param parent the new parent node */ @Override - public final void setParent(@NonNull final Node parent) { + public void setParent(@NonNull final Node parent) { if (this.equals(parent) || parent.isDescendantOf(this)) { throw new NodeException("Parent is a descendant"); } From c77f9c29d399ce71ee813d3c21c0c21d6b8bf9f8 Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Tue, 20 Sep 2016 23:09:45 +0100 Subject: [PATCH 11/13] NodeItem: don't call overridable method from constructor --- src/main/java/net/kemitix/node/NodeItem.java | 21 ++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/main/java/net/kemitix/node/NodeItem.java b/src/main/java/net/kemitix/node/NodeItem.java index d933770..9921dc2 100644 --- a/src/main/java/net/kemitix/node/NodeItem.java +++ b/src/main/java/net/kemitix/node/NodeItem.java @@ -64,13 +64,18 @@ class NodeItem implements Node { this.data = data; this.name = name; if (parent != null) { - setParent(parent); + doSetParent(parent); } this.children.addAll(children); } - protected void forceParent(final Node parent) { - this.parent = parent; + /** + * Sets the parent of a node without updating the parent in the process as {@link #setParent(Node)} does. + * + * @param newParent The new parent node + */ + protected void forceParent(final Node newParent) { + this.parent = newParent; } @Override @@ -110,15 +115,19 @@ class NodeItem implements Node { */ @Override public void setParent(@NonNull final Node parent) { - if (this.equals(parent) || parent.isDescendantOf(this)) { + doSetParent(parent); + } + + private void doSetParent(@NonNull final Node newParent) { + if (this.equals(newParent) || newParent.isDescendantOf(this)) { throw new NodeException("Parent is a descendant"); } if (this.parent != null) { this.parent.getChildren() .remove(this); } - this.parent = parent; - parent.addChild(this); + this.parent = newParent; + newParent.addChild(this); } @Override From 6a93ed9199db57337a0182a84025d3fcbb841533 Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Tue, 20 Sep 2016 23:10:15 +0100 Subject: [PATCH 12/13] ImmutableNodeItemTest:: don't pass null to setParent in test --- src/test/java/net/kemitix/node/ImmutableNodeItemTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/net/kemitix/node/ImmutableNodeItemTest.java b/src/test/java/net/kemitix/node/ImmutableNodeItemTest.java index 91eee8a..c4c4bc7 100644 --- a/src/test/java/net/kemitix/node/ImmutableNodeItemTest.java +++ b/src/test/java/net/kemitix/node/ImmutableNodeItemTest.java @@ -126,7 +126,7 @@ public class ImmutableNodeItemTest { immutableNode = Nodes.asImmutable(Nodes.unnamedRoot("subject")); expectImmutableException(); //when - immutableNode.setParent(null); + immutableNode.setParent(Nodes.unnamedRoot("child")); } @Test From 76c4d4ceeba7c7e74af53cb692ade4759625f0cd Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Tue, 20 Sep 2016 23:10:33 +0100 Subject: [PATCH 13/13] Node: drop findOrCreateChild() --- .../net/kemitix/node/ImmutableNodeItem.java | 5 -- src/main/java/net/kemitix/node/Node.java | 13 ------ src/main/java/net/kemitix/node/NodeItem.java | 21 ++------- .../kemitix/node/ImmutableNodeItemTest.java | 33 ------------- .../java/net/kemitix/node/NodeItemTest.java | 46 ------------------- 5 files changed, 4 insertions(+), 114 deletions(-) diff --git a/src/main/java/net/kemitix/node/ImmutableNodeItem.java b/src/main/java/net/kemitix/node/ImmutableNodeItem.java index fc4d159..547dde3 100644 --- a/src/main/java/net/kemitix/node/ImmutableNodeItem.java +++ b/src/main/java/net/kemitix/node/ImmutableNodeItem.java @@ -118,11 +118,6 @@ final class ImmutableNodeItem extends NodeItem { throw new UnsupportedOperationException(IMMUTABLE_OBJECT); } - @Override - public Node findOrCreateChild(final T child) { - return findChild(child).orElseThrow(() -> new UnsupportedOperationException(IMMUTABLE_OBJECT)); - } - @Override public void insertInPath(final Node node, final String... path) { throw new UnsupportedOperationException(IMMUTABLE_OBJECT); diff --git a/src/main/java/net/kemitix/node/Node.java b/src/main/java/net/kemitix/node/Node.java index 029d536..e354227 100644 --- a/src/main/java/net/kemitix/node/Node.java +++ b/src/main/java/net/kemitix/node/Node.java @@ -129,19 +129,6 @@ public interface Node { */ void createDescendantLine(List descendants); - /** - * Looks for a child node and returns it, creating a new child node if one - * isn't found. - * - * @param child the child's data to search or create with - * - * @return the found or created child node - * - * @deprecated use {@code node.findChild(child).orElseGet(() -> node.createChild(child))}; - */ - @Deprecated - Node findOrCreateChild(T child); - /** * Fetches the node for the child if present. * diff --git a/src/main/java/net/kemitix/node/NodeItem.java b/src/main/java/net/kemitix/node/NodeItem.java index 9921dc2..e4d605a 100644 --- a/src/main/java/net/kemitix/node/NodeItem.java +++ b/src/main/java/net/kemitix/node/NodeItem.java @@ -199,26 +199,13 @@ class NodeItem implements Node { @Override public void createDescendantLine(@NonNull final List descendants) { if (!descendants.isEmpty()) { - findOrCreateChild(descendants.get(0)).createDescendantLine(descendants.subList(1, descendants.size())); + val child = descendants.get(0); + val remainingLine = descendants.subList(1, descendants.size()); + findChild(child).orElseGet(() -> createChild(child)) + .createDescendantLine(remainingLine); } } - /** - * Looks for a child node and returns it, creating a new child node if one - * isn't found. - * - * @param child the child's data to search or create with - * - * @return the found or created child node - * - * @deprecated use node.findChild(child).orElseGet(() -> node.createChild (child)); - */ - @Override - @Deprecated - public Node findOrCreateChild(@NonNull final T child) { - return findChild(child).orElseGet(() -> createChild(child)); - } - /** * Fetches the node for the child if present. * diff --git a/src/test/java/net/kemitix/node/ImmutableNodeItemTest.java b/src/test/java/net/kemitix/node/ImmutableNodeItemTest.java index c4c4bc7..411e9e5 100644 --- a/src/test/java/net/kemitix/node/ImmutableNodeItemTest.java +++ b/src/test/java/net/kemitix/node/ImmutableNodeItemTest.java @@ -222,19 +222,6 @@ public class ImmutableNodeItemTest { } } - /** - * Test that if we pass null we get an exception. - */ - @Test - public void findOrCreateChildShouldThrowNPEFWhenChildIsNull() { - //given - immutableNode = Nodes.asImmutable(Nodes.unnamedRoot("subject")); - exception.expect(NullPointerException.class); - exception.expectMessage("child"); - //when - immutableNode.findOrCreateChild(null); - } - /** * Test that we throw an exception when passed null. */ @@ -431,24 +418,4 @@ public class ImmutableNodeItemTest { //when immutableNode.insertInPath(null, ""); } - - @Test - public void findOrCreateChildShouldReturnChildWhenChildIsFound() { - //given - val root = Nodes.unnamedRoot(""); - Nodes.namedChild("child", "child", root); - immutableNode = Nodes.asImmutable(root); - //when - val found = immutableNode.findOrCreateChild("child"); - assertThat(found).extracting(Node::getName).contains("child"); - } - - @Test - public void findOrCreateChildShouldThrowExceptionWhenChildNotFound() { - //given - immutableNode = Nodes.asImmutable(Nodes.unnamedRoot("")); - expectImmutableException(); - //when - immutableNode.findOrCreateChild("child"); - } } diff --git a/src/test/java/net/kemitix/node/NodeItemTest.java b/src/test/java/net/kemitix/node/NodeItemTest.java index 653ada5..0a92e75 100644 --- a/src/test/java/net/kemitix/node/NodeItemTest.java +++ b/src/test/java/net/kemitix/node/NodeItemTest.java @@ -469,52 +469,6 @@ public class NodeItemTest { + "is created").isEmpty(); } - /** - * Test that we can find a child of a node. - */ - @Test - public void shouldFindExistingChildNode() { - //given - node = Nodes.unnamedRoot("subject"); - val childData = "child"; - val child = Nodes.unnamedChild(childData, node); - //when - val found = node.findOrCreateChild(childData); - //then - assertThat(found).as( - "when searching for a child by data, the matching child is " - + "found").isSameAs(child); - } - - /** - * Test that we create a missing child of a node. - */ - @Test - public void shouldFindCreateNewChildNode() { - //given - node = Nodes.unnamedRoot("subject"); - val childData = "child"; - //when - val found = node.findOrCreateChild(childData); - //then - assertThat(found.getData()).as( - "when searching for a non-existent child by data, a new node " - + "is created").contains(childData); - } - - /** - * Test that if we pass null we get an exception. - */ - @Test - public void findOrCreateChildShouldThrowNPEFWhenChildIsNull() { - //given - node = Nodes.unnamedRoot("subject"); - exception.expect(NullPointerException.class); - exception.expectMessage("child"); - //when - node.findOrCreateChild(null); - } - /** * Test that we can get the node for a child. */