From 08b934a6d6f9d19e7946b7ec8e5645ecaf9168da Mon Sep 17 00:00:00 2001
From: Paul Campbell
Date: Mon, 22 Aug 2016 08:44:48 +0100
Subject: [PATCH 01/22] pom.xml: upgrade kemitix-parent to 2.0.0
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 3071a0d..9c0e8b4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -11,7 +11,7 @@
net.kemitix
kemitix-parent
- 0.6.0
+ 2.0.0
From acce849819baeb3df94c12e7eb9e09c036f817c4 Mon Sep 17 00:00:00 2001
From: Paul Campbell
Date: Mon, 22 Aug 2016 08:45:00 +0100
Subject: [PATCH 02/22] checkstyle.xml: removed
---
checkstyle.xml | 192 -------------------------------------------------
1 file changed, 192 deletions(-)
delete mode 100644 checkstyle.xml
diff --git a/checkstyle.xml b/checkstyle.xml
deleted file mode 100644
index e54bdb6..0000000
--- a/checkstyle.xml
+++ /dev/null
@@ -1,192 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
From e108d61ac51c0c66eb62a575fe0acafa017b793c Mon Sep 17 00:00:00 2001
From: Paul Campbell
Date: Mon, 22 Aug 2016 08:48:31 +0100
Subject: [PATCH 03/22] pom.xml: move lombok to compile scope
---
pom.xml | 1 -
1 file changed, 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 9c0e8b4..a502cc3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -50,7 +50,6 @@
org.projectlombok
lombok
1.16.8
- test
junit
From d99fcdcebeb8e8661af754923d5100591ca45185 Mon Sep 17 00:00:00 2001
From: Paul Campbell
Date: Mon, 22 Aug 2016 08:51:18 +0100
Subject: [PATCH 04/22] NodeItem: replace manual null checks with @NonNull
---
src/main/java/net/kemitix/node/NodeItem.java | 42 +++++---------------
1 file changed, 10 insertions(+), 32 deletions(-)
diff --git a/src/main/java/net/kemitix/node/NodeItem.java b/src/main/java/net/kemitix/node/NodeItem.java
index e688355..3f6f6bc 100644
--- a/src/main/java/net/kemitix/node/NodeItem.java
+++ b/src/main/java/net/kemitix/node/NodeItem.java
@@ -1,5 +1,7 @@
package net.kemitix.node;
+import lombok.NonNull;
+
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
@@ -128,10 +130,7 @@ class NodeItem implements Node {
* @param child the node to add
*/
@Override
- public void addChild(final Node child) {
- if (child == null) {
- throw new NullPointerException("child");
- }
+ public void addChild(@NonNull final Node child) {
if (this.equals(child) || isDescendantOf(child)) {
throw new NodeException("Child is an ancestor");
}
@@ -162,10 +161,7 @@ class NodeItem implements Node {
* @return the new child node
*/
@Override
- public Node createChild(final T child) {
- if (child == null) {
- throw new NullPointerException("child");
- }
+ public Node createChild(@NonNull final T child) {
return new NodeItem<>(child, this);
}
@@ -184,10 +180,7 @@ class NodeItem implements Node {
* @param descendants the line of descendants from the current node
*/
@Override
- public void createDescendantLine(final List descendants) {
- if (descendants == null) {
- throw new NullPointerException("descendants");
- }
+ public void createDescendantLine(@NonNull final List descendants) {
if (!descendants.isEmpty()) {
findOrCreateChild(descendants.get(0)).createDescendantLine(
descendants.subList(1, descendants.size()));
@@ -204,10 +197,7 @@ class NodeItem implements Node {
*/
@Override
@Deprecated
- public Node findOrCreateChild(final T child) {
- if (child == null) {
- throw new NullPointerException("child");
- }
+ public Node findOrCreateChild(@NonNull final T child) {
return findChild(child).orElseGet(() -> createChild(child));
}
@@ -219,10 +209,7 @@ class NodeItem implements Node {
* @return an {@link Optional} containing the child node if found
*/
@Override
- public Optional> findChild(final T child) {
- if (child == null) {
- throw new NullPointerException("child");
- }
+ public Optional> findChild(@NonNull final T child) {
return children.stream().filter(node -> {
final Optional d = node.getData();
return d.isPresent() && d.get().equals(child);
@@ -257,10 +244,7 @@ class NodeItem implements Node {
* @param parent the new parent node
*/
@Override
- public final void setParent(final Node parent) {
- if (parent == null) {
- throw new NullPointerException("parent");
- }
+ public final void setParent(@NonNull final Node parent) {
if (this.equals(parent) || parent.isDescendantOf(this)) {
throw new NodeException("Parent is a descendant");
}
@@ -279,10 +263,7 @@ class NodeItem implements Node {
* @return the child or null
*/
@Override
- public Optional> findInPath(final List path) {
- if (path == null) {
- throw new NullPointerException("path");
- }
+ public Optional> findInPath(@NonNull final List path) {
if (path.size() > 0) {
Optional> found = findChild(path.get(0));
if (found.isPresent()) {
@@ -330,10 +311,7 @@ class NodeItem implements Node {
}
@Override
- public Optional> findChildByName(final String named) {
- if (named == null) {
- throw new NullPointerException("name");
- }
+ public Optional> findChildByName(@NonNull final String named) {
return children.stream()
.filter((Node t) -> t.getName().equals(named))
.findAny();
From b2130442e50a67f7bd58e8e7b8c702ad58acb713 Mon Sep 17 00:00:00 2001
From: Paul Campbell
Date: Mon, 22 Aug 2016 08:52:42 +0100
Subject: [PATCH 05/22] AbstractNodeItem: replace manual null checks with
@NonNull
---
.../java/net/kemitix/node/AbstractNodeItem.java | 17 +++++------------
1 file changed, 5 insertions(+), 12 deletions(-)
diff --git a/src/main/java/net/kemitix/node/AbstractNodeItem.java b/src/main/java/net/kemitix/node/AbstractNodeItem.java
index 6aa90e7..4815d93 100644
--- a/src/main/java/net/kemitix/node/AbstractNodeItem.java
+++ b/src/main/java/net/kemitix/node/AbstractNodeItem.java
@@ -1,5 +1,7 @@
package net.kemitix.node;
+import lombok.NonNull;
+
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
@@ -65,10 +67,7 @@ abstract class AbstractNodeItem implements Node {
* @return an {@link Optional} containing the child node if found
*/
@Override
- public Optional> findChild(final T child) {
- if (child == null) {
- throw new NullPointerException("child");
- }
+ public Optional> findChild(@NonNull final T child) {
return children.stream().filter(node -> {
final Optional d = node.getData();
return d.isPresent() && d.get().equals(child);
@@ -102,10 +101,7 @@ abstract class AbstractNodeItem implements Node {
* @return the child or null
*/
@Override
- public Optional> findInPath(final List path) {
- if (path == null) {
- throw new NullPointerException("path");
- }
+ public Optional> findInPath(@NonNull final List path) {
if (path.size() > 0) {
Optional> found = findChild(path.get(0));
if (found.isPresent()) {
@@ -119,10 +115,7 @@ abstract class AbstractNodeItem implements Node {
}
@Override
- public Optional> findChildByName(final String named) {
- if (named == null) {
- throw new NullPointerException("name");
- }
+ public Optional> findChildByName(@NonNull final String named) {
return children.stream()
.filter(n -> n.getName().equals(named))
.findAny();
From 2a435a849e74add511897a2545ccf37433ab368d Mon Sep 17 00:00:00 2001
From: Paul Campbell
Date: Mon, 22 Aug 2016 08:58:58 +0100
Subject: [PATCH 06/22] NodeItem: refactor formatting name by depth
Remove duplicate string literals.
---
src/main/java/net/kemitix/node/NodeItem.java | 11 ++++++-----
1 file 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 3f6f6bc..3afd79a 100644
--- a/src/main/java/net/kemitix/node/NodeItem.java
+++ b/src/main/java/net/kemitix/node/NodeItem.java
@@ -331,17 +331,18 @@ class NodeItem implements Node {
final StringBuilder sb = new StringBuilder();
final String unnamed = "(unnamed)";
if (isNamed()) {
- sb.append(String.format("[%1$" + (depth + name.length()) + "s]\n",
- name));
+ sb.append(formatByDepth(name, depth));
} else if (!children.isEmpty()) {
- sb.append(
- String.format("[%1$" + (depth + unnamed.length()) + "s]\n",
- unnamed));
+ sb.append(formatByDepth(unnamed, depth));
}
getChildren().stream().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() {
String currentName = getName();
From 6253a3226f6d7bd1a6f9559a215a762a5bc741b5 Mon Sep 17 00:00:00 2001
From: Paul Campbell
Date: Mon, 22 Aug 2016 08:59:52 +0100
Subject: [PATCH 07/22] NodeItem: simplify stream().forEach()
---
src/main/java/net/kemitix/node/NodeItem.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/net/kemitix/node/NodeItem.java b/src/main/java/net/kemitix/node/NodeItem.java
index 3afd79a..caa23e0 100644
--- a/src/main/java/net/kemitix/node/NodeItem.java
+++ b/src/main/java/net/kemitix/node/NodeItem.java
@@ -335,7 +335,7 @@ class NodeItem implements Node {
} else if (!children.isEmpty()) {
sb.append(formatByDepth(unnamed, depth));
}
- getChildren().stream().forEach(c -> sb.append(c.drawTree(depth + 1)));
+ getChildren().forEach(c -> sb.append(c.drawTree(depth + 1)));
return sb.toString();
}
From 3d94eaeb32647c8360d4185809a15b6384220ed2 Mon Sep 17 00:00:00 2001
From: Paul Campbell
Date: Mon, 22 Aug 2016 09:01:34 +0100
Subject: [PATCH 08/22] AbstractNodeItem: refactor formatting name by depth
Remove duplicate string literals.
---
src/main/java/net/kemitix/node/AbstractNodeItem.java | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/src/main/java/net/kemitix/node/AbstractNodeItem.java b/src/main/java/net/kemitix/node/AbstractNodeItem.java
index 4815d93..f177c73 100644
--- a/src/main/java/net/kemitix/node/AbstractNodeItem.java
+++ b/src/main/java/net/kemitix/node/AbstractNodeItem.java
@@ -132,17 +132,18 @@ abstract class AbstractNodeItem implements Node {
final StringBuilder sb = new StringBuilder();
final String unnamed = "(unnamed)";
if (isNamed()) {
- sb.append(String.format("[%1$" + (depth + name.length()) + "s]\n",
- name));
+ sb.append(formatByDepth(name, depth));
} else if (!children.isEmpty()) {
- sb.append(
- String.format("[%1$" + (depth + unnamed.length()) + "s]\n",
- unnamed));
+ 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;
From 5c129b54b8af4a127ef3eb30b7b209f97990ada2 Mon Sep 17 00:00:00 2001
From: Paul Campbell
Date: Mon, 22 Aug 2016 09:04:16 +0100
Subject: [PATCH 09/22] NodeItem: put trailing comments on their own line
---
src/main/java/net/kemitix/node/NodeItem.java | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/main/java/net/kemitix/node/NodeItem.java b/src/main/java/net/kemitix/node/NodeItem.java
index caa23e0..e5db2fd 100644
--- a/src/main/java/net/kemitix/node/NodeItem.java
+++ b/src/main/java/net/kemitix/node/NodeItem.java
@@ -279,13 +279,15 @@ class NodeItem implements Node {
@Override
public void insertInPath(final Node nodeItem, final String... path) {
if (path.length == 0) {
- if (!nodeItem.isNamed()) { // nothing to conflict with
+ if (!nodeItem.isNamed()) {
+ // nothing to conflict with
addChild(nodeItem);
return;
}
String nodeName = nodeItem.getName();
final Optional> childNamed = findChildByName(nodeName);
- if (!childNamed.isPresent()) { // nothing with the same name exists
+ if (!childNamed.isPresent()) {
+ // nothing with the same name exists
addChild(nodeItem);
return;
}
From 37247e93bc28ae8b0a36df8a7c1797c548192121 Mon Sep 17 00:00:00 2001
From: Paul Campbell
Date: Sun, 4 Sep 2016 18:44:29 +0100
Subject: [PATCH 10/22] node: change javadoc element order to Atclause order
The default configuration of the AtclauseOrder is a bit strange.
---
src/main/java/net/kemitix/node/AbstractNodeItem.java | 4 ++--
src/main/java/net/kemitix/node/ImmutableNodeItem.java | 4 ++--
src/main/java/net/kemitix/node/Node.java | 4 ++--
src/main/java/net/kemitix/node/NodeItem.java | 4 ++--
4 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/main/java/net/kemitix/node/AbstractNodeItem.java b/src/main/java/net/kemitix/node/AbstractNodeItem.java
index f177c73..f7efaf9 100644
--- a/src/main/java/net/kemitix/node/AbstractNodeItem.java
+++ b/src/main/java/net/kemitix/node/AbstractNodeItem.java
@@ -11,9 +11,9 @@ 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
*
- * @author pcampbell
+ * @param the type of data stored in each node
*/
abstract class AbstractNodeItem implements Node {
diff --git a/src/main/java/net/kemitix/node/ImmutableNodeItem.java b/src/main/java/net/kemitix/node/ImmutableNodeItem.java
index 7b80a59..dbc85ec 100644
--- a/src/main/java/net/kemitix/node/ImmutableNodeItem.java
+++ b/src/main/java/net/kemitix/node/ImmutableNodeItem.java
@@ -11,9 +11,9 @@ import java.util.Set;
* getData()} they could then modify the original data within the node. This
* wouldn't affect the integrity of the node tree structure, however.
*
- * @param the type of data stored in each node
+ * @author Paul Campbell
*
- * @author pcampbell
+ * @param the type of data stored in each node
*/
final class ImmutableNodeItem extends AbstractNodeItem {
diff --git a/src/main/java/net/kemitix/node/Node.java b/src/main/java/net/kemitix/node/Node.java
index 7cda730..f1fa7ba 100644
--- a/src/main/java/net/kemitix/node/Node.java
+++ b/src/main/java/net/kemitix/node/Node.java
@@ -7,9 +7,9 @@ import java.util.Set;
/**
* An interface for tree node items.
*
- * @param the type of data held in each node
+ * @author Paul Campbell
*
- * @author pcampbell
+ * @param the type of data held in each node
*/
public interface Node {
diff --git a/src/main/java/net/kemitix/node/NodeItem.java b/src/main/java/net/kemitix/node/NodeItem.java
index e5db2fd..812adf4 100644
--- a/src/main/java/net/kemitix/node/NodeItem.java
+++ b/src/main/java/net/kemitix/node/NodeItem.java
@@ -12,9 +12,9 @@ import java.util.function.Function;
/**
* Represents a tree of nodes.
*
- * @param the type of data stored in each node
+ * @author Paul Campbell
*
- * @author pcampbell
+ * @param the type of data stored in each node
*/
class NodeItem implements Node {
From 9f3aec202af31a3ef83f59da503e3ac0de099c40 Mon Sep 17 00:00:00 2001
From: Paul Campbell
Date: Sun, 4 Sep 2016 18:59:22 +0100
Subject: [PATCH 11/22] {Abstract}NodeItem: reduce nested if statements
---
.../net/kemitix/node/AbstractNodeItem.java | 15 ++++-----
src/main/java/net/kemitix/node/NodeItem.java | 31 +++++++++----------
2 files changed, 22 insertions(+), 24 deletions(-)
diff --git a/src/main/java/net/kemitix/node/AbstractNodeItem.java b/src/main/java/net/kemitix/node/AbstractNodeItem.java
index f7efaf9..3097d4a 100644
--- a/src/main/java/net/kemitix/node/AbstractNodeItem.java
+++ b/src/main/java/net/kemitix/node/AbstractNodeItem.java
@@ -102,14 +102,15 @@ abstract class AbstractNodeItem implements Node {
*/
@Override
public Optional> findInPath(@NonNull final List path) {
- if (path.size() > 0) {
- Optional> found = findChild(path.get(0));
- if (found.isPresent()) {
- if (path.size() > 1) {
- return found.get().findInPath(path.subList(1, path.size()));
- }
- return found;
+ if (path.isEmpty()) {
+ return Optional.empty();
+ }
+ Optional> found = findChild(path.get(0));
+ if (found.isPresent()) {
+ if (path.size() > 1) {
+ return found.get().findInPath(path.subList(1, path.size()));
}
+ return found;
}
return Optional.empty();
}
diff --git a/src/main/java/net/kemitix/node/NodeItem.java b/src/main/java/net/kemitix/node/NodeItem.java
index 812adf4..2ed9b02 100644
--- a/src/main/java/net/kemitix/node/NodeItem.java
+++ b/src/main/java/net/kemitix/node/NodeItem.java
@@ -2,19 +2,15 @@ package net.kemitix.node;
import lombok.NonNull;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
+import java.util.*;
import java.util.function.Function;
/**
* Represents a tree of nodes.
*
- * @author Paul Campbell
- *
* @param the type of data stored in each node
+ *
+ * @author Paul Campbell
*/
class NodeItem implements Node {
@@ -147,7 +143,7 @@ class NodeItem implements Node {
Optional> childParent = child.getParent();
boolean isOrphan = !childParent.isPresent();
boolean hasDifferentParent = !isOrphan && !childParent.get()
- .equals(this);
+ .equals(this);
if (isOrphan || hasDifferentParent) {
child.setParent(this);
}
@@ -264,14 +260,15 @@ class NodeItem implements Node {
*/
@Override
public Optional> findInPath(@NonNull final List path) {
- if (path.size() > 0) {
- Optional> found = findChild(path.get(0));
- if (found.isPresent()) {
- if (path.size() > 1) {
- return found.get().findInPath(path.subList(1, path.size()));
- }
- return found;
+ if (path.isEmpty()) {
+ return Optional.empty();
+ }
+ Optional> found = findChild(path.get(0));
+ if (found.isPresent()) {
+ if (path.size() > 1) {
+ return found.get().findInPath(path.subList(1, path.size()));
}
+ return found;
}
return Optional.empty();
}
@@ -315,8 +312,8 @@ class NodeItem implements Node {
@Override
public Optional> findChildByName(@NonNull final String named) {
return children.stream()
- .filter((Node t) -> t.getName().equals(named))
- .findAny();
+ .filter((Node t) -> t.getName().equals(named))
+ .findAny();
}
@Override
From 02d07605c0f6e818298869b4c55d37d3d32bd98d Mon Sep 17 00:00:00 2001
From: Paul Campbell
Date: Sun, 4 Sep 2016 19:20:16 +0100
Subject: [PATCH 12/22] NodeFindInPathTestsCategory: added
---
.../net/kemitix/node/NodeFindInPathTestsCategory.java | 9 +++++++++
1 file changed, 9 insertions(+)
create mode 100644 src/test/java/net/kemitix/node/NodeFindInPathTestsCategory.java
diff --git a/src/test/java/net/kemitix/node/NodeFindInPathTestsCategory.java b/src/test/java/net/kemitix/node/NodeFindInPathTestsCategory.java
new file mode 100644
index 0000000..979190f
--- /dev/null
+++ b/src/test/java/net/kemitix/node/NodeFindInPathTestsCategory.java
@@ -0,0 +1,9 @@
+package net.kemitix.node;
+
+/**
+ * Category marker for tests relating to implementations of Node.findInPath(...).
+ *
+ * @author Paul Campbell
+ */
+public interface NodeFindInPathTestsCategory {
+}
From 6987f927fe4e29a0c8f1594e0a0558554f8b620f Mon Sep 17 00:00:00 2001
From: Paul Campbell
Date: Sun, 4 Sep 2016 19:21:18 +0100
Subject: [PATCH 13/22] {Immutable}NodeItemTest: categorise findInPath tests
---
.../java/net/kemitix/node/ImmutableNodeItemTest.java | 9 +++++++--
src/test/java/net/kemitix/node/NodeItemTest.java | 9 +++++++--
2 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/src/test/java/net/kemitix/node/ImmutableNodeItemTest.java b/src/test/java/net/kemitix/node/ImmutableNodeItemTest.java
index 9475ff5..91eee8a 100644
--- a/src/test/java/net/kemitix/node/ImmutableNodeItemTest.java
+++ b/src/test/java/net/kemitix/node/ImmutableNodeItemTest.java
@@ -4,14 +4,15 @@ import lombok.val;
import org.assertj.core.api.SoftAssertions;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.experimental.categories.Category;
import org.junit.rules.ExpectedException;
-import static org.assertj.core.api.Assertions.assertThat;
-
import java.util.Arrays;
import java.util.Collections;
import java.util.Optional;
+import static org.assertj.core.api.Assertions.assertThat;
+
/**
* Test for {@link ImmutableNodeItem}.
*
@@ -141,6 +142,7 @@ public class ImmutableNodeItemTest {
* Test that we can walk a tree to the target node.
*/
@Test
+ @Category(NodeFindInPathTestsCategory.class)
public void shouldWalkTreeToNode() {
//given
val root = Nodes.unnamedRoot("root");
@@ -160,6 +162,7 @@ public class ImmutableNodeItemTest {
* doesn't exist.
*/
@Test
+ @Category(NodeFindInPathTestsCategory.class)
public void shouldNotFindNonExistentChildNode() {
//given
val root = Nodes.unnamedRoot("root");
@@ -176,6 +179,7 @@ public class ImmutableNodeItemTest {
* Test that when we pass null we get an exception.
*/
@Test
+ @Category(NodeFindInPathTestsCategory.class)
public void shouldThrowNEWhenWalkTreeNull() {
//given
immutableNode = Nodes.asImmutable(Nodes.unnamedRoot("subject"));
@@ -190,6 +194,7 @@ public class ImmutableNodeItemTest {
* a result.
*/
@Test
+ @Category(NodeFindInPathTestsCategory.class)
public void shouldReturnEmptyForEmptyWalkTreePath() {
//given
immutableNode = Nodes.asImmutable(Nodes.unnamedRoot("subject"));
diff --git a/src/test/java/net/kemitix/node/NodeItemTest.java b/src/test/java/net/kemitix/node/NodeItemTest.java
index 247e7fb..2702ae0 100644
--- a/src/test/java/net/kemitix/node/NodeItemTest.java
+++ b/src/test/java/net/kemitix/node/NodeItemTest.java
@@ -4,14 +4,15 @@ import lombok.val;
import org.assertj.core.api.SoftAssertions;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.experimental.categories.Category;
import org.junit.rules.ExpectedException;
-import static org.assertj.core.api.Assertions.assertThat;
-
import java.util.Arrays;
import java.util.Collections;
import java.util.Optional;
+import static org.assertj.core.api.Assertions.assertThat;
+
/**
* Test for {@link NodeItem}.
*
@@ -309,6 +310,7 @@ public class NodeItemTest {
* Test that we can walk a tree to the target node.
*/
@Test
+ @Category(NodeFindInPathTestsCategory.class)
public void shouldWalkTreeToNode() {
//given
val grandparent = "grandparent";
@@ -334,6 +336,7 @@ public class NodeItemTest {
* doesn't exist.
*/
@Test
+ @Category(NodeFindInPathTestsCategory.class)
public void shouldNotFindNonExistentChildNode() {
//given
val parent = "parent";
@@ -352,6 +355,7 @@ public class NodeItemTest {
* Test that when we pass null we get an exception.
*/
@Test
+ @Category(NodeFindInPathTestsCategory.class)
public void shouldThrowNEWhenWalkTreeNull() {
//given
node = Nodes.unnamedRoot("subject");
@@ -366,6 +370,7 @@ public class NodeItemTest {
* a result.
*/
@Test
+ @Category(NodeFindInPathTestsCategory.class)
public void shouldReturnEmptyForEmptyWalkTreePath() {
//given
node = Nodes.unnamedRoot("subject");
From 91c57f098e3feca06c2ca91d4af6c35db5838166 Mon Sep 17 00:00:00 2001
From: Paul Campbell
Date: Sun, 4 Sep 2016 19:21:41 +0100
Subject: [PATCH 14/22] {Abstract}NodeItem: rewrite findInPath to avoid
recursion
---
.../java/net/kemitix/node/AbstractNodeItem.java | 15 +++++++++------
src/main/java/net/kemitix/node/NodeItem.java | 15 +++++++++------
2 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/src/main/java/net/kemitix/node/AbstractNodeItem.java b/src/main/java/net/kemitix/node/AbstractNodeItem.java
index 3097d4a..1fe6eab 100644
--- a/src/main/java/net/kemitix/node/AbstractNodeItem.java
+++ b/src/main/java/net/kemitix/node/AbstractNodeItem.java
@@ -105,14 +105,17 @@ abstract class AbstractNodeItem implements Node {
if (path.isEmpty()) {
return Optional.empty();
}
- Optional> found = findChild(path.get(0));
- if (found.isPresent()) {
- if (path.size() > 1) {
- return found.get().findInPath(path.subList(1, path.size()));
+ Node current = this;
+ for (T item : path) {
+ final Optional> child = current.findChild(item);
+ if (child.isPresent()) {
+ current = child.get();
+ } else {
+ current = null;
+ break;
}
- return found;
}
- return Optional.empty();
+ return Optional.ofNullable(current);
}
@Override
diff --git a/src/main/java/net/kemitix/node/NodeItem.java b/src/main/java/net/kemitix/node/NodeItem.java
index 2ed9b02..519867f 100644
--- a/src/main/java/net/kemitix/node/NodeItem.java
+++ b/src/main/java/net/kemitix/node/NodeItem.java
@@ -263,14 +263,17 @@ class NodeItem implements Node {
if (path.isEmpty()) {
return Optional.empty();
}
- Optional> found = findChild(path.get(0));
- if (found.isPresent()) {
- if (path.size() > 1) {
- return found.get().findInPath(path.subList(1, path.size()));
+ Node current = this;
+ for (T item : path) {
+ final Optional> child = current.findChild(item);
+ if (child.isPresent()) {
+ current = child.get();
+ } else {
+ current = null;
+ break;
}
- return found;
}
- return Optional.empty();
+ return Optional.ofNullable(current);
}
@Override
From e28b140db82465965ae188ed3c5274a97847ee04 Mon Sep 17 00:00:00 2001
From: Paul Campbell
Date: Sun, 4 Sep 2016 19:28:20 +0100
Subject: [PATCH 15/22] NodeItem: simplify inserting child into path
---
src/main/java/net/kemitix/node/NodeItem.java | 13 ++++---------
1 file changed, 4 insertions(+), 9 deletions(-)
diff --git a/src/main/java/net/kemitix/node/NodeItem.java b/src/main/java/net/kemitix/node/NodeItem.java
index 519867f..067ef5e 100644
--- a/src/main/java/net/kemitix/node/NodeItem.java
+++ b/src/main/java/net/kemitix/node/NodeItem.java
@@ -301,15 +301,10 @@ class NodeItem implements Node {
}
return;
}
- String item = path[0];
- final Optional> childNamed = findChildByName(item);
- Node child;
- if (!childNamed.isPresent()) {
- child = new NodeItem<>(null, item, this);
- } else {
- child = childNamed.get();
- }
- child.insertInPath(nodeItem, Arrays.copyOfRange(path, 1, path.length));
+ val item = path[0];
+ findChildByName(item)
+ .orElseGet(() -> new NodeItem<>(null, item, this))
+ .insertInPath(nodeItem, Arrays.copyOfRange(path, 1, path.length));
}
@Override
From 40f49fd832db73cf8fd04260e4b4d249b8334dd6 Mon Sep 17 00:00:00 2001
From: Paul Campbell
Date: Sun, 4 Sep 2016 19:40:08 +0100
Subject: [PATCH 16/22] NodeItem: refactored insertInPath to be easier to
understand
---
src/main/java/net/kemitix/node/NodeItem.java | 59 +++++++++++---------
1 file changed, 34 insertions(+), 25 deletions(-)
diff --git a/src/main/java/net/kemitix/node/NodeItem.java b/src/main/java/net/kemitix/node/NodeItem.java
index 067ef5e..6c5f241 100644
--- a/src/main/java/net/kemitix/node/NodeItem.java
+++ b/src/main/java/net/kemitix/node/NodeItem.java
@@ -1,6 +1,7 @@
package net.kemitix.node;
import lombok.NonNull;
+import lombok.val;
import java.util.*;
import java.util.function.Function;
@@ -279,32 +280,40 @@ class NodeItem implements Node {
@Override
public void insertInPath(final Node nodeItem, final String... path) {
if (path.length == 0) {
- if (!nodeItem.isNamed()) {
- // nothing to conflict with
- addChild(nodeItem);
- return;
- }
- String nodeName = nodeItem.getName();
- final Optional> childNamed = findChildByName(nodeName);
- if (!childNamed.isPresent()) {
- // nothing with the same name exists
- addChild(nodeItem);
- return;
- }
- // we have an existing node with the same name
- final Node existing = childNamed.get();
- if (!existing.isEmpty()) {
- throw new NodeException("A non-empty node named '" + nodeName
- + "' already exists here");
- } else {
- nodeItem.getData().ifPresent(existing::setData);
- }
- return;
+ insertChild(nodeItem);
+ } else {
+ val item = path[0];
+ findChildByName(item)
+ .orElseGet(() -> new NodeItem<>(null, item, this))
+ .insertInPath(nodeItem, Arrays.copyOfRange(path, 1, path.length));
+ }
+ }
+
+ private void insertChild(final Node nodeItem) {
+ if (nodeItem.isNamed()) {
+ insertNamedChild(nodeItem);
+ } else {
+ // nothing to conflict with
+ addChild(nodeItem);
+ }
+ }
+
+ private void insertNamedChild(final Node nodeItem) {
+ val childByName = findChildByName(nodeItem.getName());
+ if (childByName.isPresent()) {
+ // we have an existing node with the same name
+ val existing = childByName.get();
+ if (existing.isEmpty()) {
+ // place any data in the new node into the existing empty node
+ nodeItem.getData().ifPresent(existing::setData);
+ } else {
+ throw new NodeException("A non-empty node named '" + nodeItem.getName()
+ + "' already exists here");
+ }
+ } else {
+ // nothing with the same name exists
+ addChild(nodeItem);
}
- val item = path[0];
- findChildByName(item)
- .orElseGet(() -> new NodeItem<>(null, item, this))
- .insertInPath(nodeItem, Arrays.copyOfRange(path, 1, path.length));
}
@Override
From 1da9d44a8b70f879bb17b35c242b2d7d645c066d Mon Sep 17 00:00:00 2001
From: Paul Campbell
Date: Sun, 4 Sep 2016 19:45:16 +0100
Subject: [PATCH 17/22] Node: add javadoc @deprecated to findOrCreateChild
---
src/main/java/net/kemitix/node/Node.java | 3 +++
src/main/java/net/kemitix/node/NodeItem.java | 3 +++
2 files changed, 6 insertions(+)
diff --git a/src/main/java/net/kemitix/node/Node.java b/src/main/java/net/kemitix/node/Node.java
index f1fa7ba..395ebb7 100644
--- a/src/main/java/net/kemitix/node/Node.java
+++ b/src/main/java/net/kemitix/node/Node.java
@@ -113,6 +113,9 @@ public interface Node {
* @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));
*/
@Deprecated
Node findOrCreateChild(T child);
diff --git a/src/main/java/net/kemitix/node/NodeItem.java b/src/main/java/net/kemitix/node/NodeItem.java
index 6c5f241..c41a3d7 100644
--- a/src/main/java/net/kemitix/node/NodeItem.java
+++ b/src/main/java/net/kemitix/node/NodeItem.java
@@ -191,6 +191,9 @@ class NodeItem implements Node {
* @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
From cd1afc6778b071fb3faba39d761f518d2ff66c20 Mon Sep 17 00:00:00 2001
From: Paul Campbell
Date: Sun, 4 Sep 2016 19:46:30 +0100
Subject: [PATCH 18/22] NodeItem: avoid import .*
---
src/main/java/net/kemitix/node/NodeItem.java | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/src/main/java/net/kemitix/node/NodeItem.java b/src/main/java/net/kemitix/node/NodeItem.java
index c41a3d7..7f0cd75 100644
--- a/src/main/java/net/kemitix/node/NodeItem.java
+++ b/src/main/java/net/kemitix/node/NodeItem.java
@@ -3,7 +3,11 @@ package net.kemitix.node;
import lombok.NonNull;
import lombok.val;
-import java.util.*;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
import java.util.function.Function;
/**
From e4c4fdf4bc2bb12cfeeddc6002a1b992855ef5ab Mon Sep 17 00:00:00 2001
From: Paul Campbell
Date: Sun, 4 Sep 2016 19:47:19 +0100
Subject: [PATCH 19/22] NodeItem,: use strange javadoc element ordering
---
src/main/java/net/kemitix/node/NodeItem.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/main/java/net/kemitix/node/NodeItem.java b/src/main/java/net/kemitix/node/NodeItem.java
index 7f0cd75..2ee8b97 100644
--- a/src/main/java/net/kemitix/node/NodeItem.java
+++ b/src/main/java/net/kemitix/node/NodeItem.java
@@ -13,9 +13,9 @@ import java.util.function.Function;
/**
* Represents a tree of nodes.
*
- * @param the type of data stored in each node
- *
* @author Paul Campbell
+ *
+ * @param the type of data stored in each node
*/
class NodeItem implements Node {
From 9ec2668802d34aed90d84384e31a3256b57e5839 Mon Sep 17 00:00:00 2001
From: Paul Campbell
Date: Sun, 4 Sep 2016 19:49:13 +0100
Subject: [PATCH 20/22] NodeItem: wrap lines at 80 columns
---
src/main/java/net/kemitix/node/NodeItem.java | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/main/java/net/kemitix/node/NodeItem.java b/src/main/java/net/kemitix/node/NodeItem.java
index 2ee8b97..979fddd 100644
--- a/src/main/java/net/kemitix/node/NodeItem.java
+++ b/src/main/java/net/kemitix/node/NodeItem.java
@@ -292,7 +292,8 @@ class NodeItem implements Node {
val item = path[0];
findChildByName(item)
.orElseGet(() -> new NodeItem<>(null, item, this))
- .insertInPath(nodeItem, Arrays.copyOfRange(path, 1, path.length));
+ .insertInPath(nodeItem,
+ Arrays.copyOfRange(path, 1, path.length));
}
}
@@ -314,8 +315,8 @@ class NodeItem implements Node {
// place any data in the new node into the existing empty node
nodeItem.getData().ifPresent(existing::setData);
} else {
- throw new NodeException("A non-empty node named '" + nodeItem.getName()
- + "' already exists here");
+ throw new NodeException("A non-empty node named '"
+ + nodeItem.getName() + "' already exists here");
}
} else {
// nothing with the same name exists
From 69be86ba074ccc8408d87185bf3baeb05bee5d8c Mon Sep 17 00:00:00 2001
From: Paul Campbell
Date: Sun, 4 Sep 2016 22:13:10 +0100
Subject: [PATCH 21/22] NodeItem: reduce complexity of addChild
---
src/main/java/net/kemitix/node/NodeItem.java | 38 +++++++++++---------
1 file changed, 22 insertions(+), 16 deletions(-)
diff --git a/src/main/java/net/kemitix/node/NodeItem.java b/src/main/java/net/kemitix/node/NodeItem.java
index 979fddd..f9ebf47 100644
--- a/src/main/java/net/kemitix/node/NodeItem.java
+++ b/src/main/java/net/kemitix/node/NodeItem.java
@@ -132,28 +132,34 @@ class NodeItem implements Node {
*/
@Override
public void addChild(@NonNull final Node child) {
- if (this.equals(child) || isDescendantOf(child)) {
- throw new NodeException("Child is an ancestor");
- }
- if (child.isNamed()) {
- final Optional> existingChild = findChildByName(
- child.getName());
- if (existingChild.isPresent() && existingChild.get() != child) {
- throw new NodeException(
- "Node with that name already exists here");
- }
- }
+ verifyChildIsNotAnAncestor(child);
+ verifyChildWithSameNameDoesNotAlreadyExist(child);
children.add(child);
// update the child's parent if they don't have one or it is not this
- Optional> childParent = child.getParent();
- boolean isOrphan = !childParent.isPresent();
- boolean hasDifferentParent = !isOrphan && !childParent.get()
- .equals(this);
- if (isOrphan || hasDifferentParent) {
+ val childParent = child.getParent();
+ if (!childParent.isPresent() || !childParent.get().equals(this)) {
child.setParent(this);
}
}
+ private void verifyChildWithSameNameDoesNotAlreadyExist(
+ final @NonNull Node child) {
+ if (child.isNamed()) {
+ findChildByName(child.getName())
+ .filter(existingChild -> existingChild != child)
+ .ifPresent(existingChild -> {
+ throw new NodeException(
+ "Node with that name already exists here");
+ });
+ }
+ }
+
+ private void verifyChildIsNotAnAncestor(final @NonNull Node child) {
+ if (this.equals(child) || isDescendantOf(child)) {
+ throw new NodeException("Child is an ancestor");
+ }
+ }
+
/**
* Creates a new node and adds it as a child of the current node.
*
From 29a5ceca827430896bab8952961100d1c9dd88d5 Mon Sep 17 00:00:00 2001
From: Paul Campbell
Date: Sun, 4 Sep 2016 22:19:22 +0100
Subject: [PATCH 22/22] NodeItem: remove support for dynamic names
---
src/main/java/net/kemitix/node/NodeItem.java | 26 --------------------
1 file changed, 26 deletions(-)
diff --git a/src/main/java/net/kemitix/node/NodeItem.java b/src/main/java/net/kemitix/node/NodeItem.java
index f9ebf47..12a7cef 100644
--- a/src/main/java/net/kemitix/node/NodeItem.java
+++ b/src/main/java/net/kemitix/node/NodeItem.java
@@ -8,7 +8,6 @@ import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
-import java.util.function.Function;
/**
* Represents a tree of nodes.
@@ -23,8 +22,6 @@ class NodeItem implements Node {
private final Set> children = new HashSet<>();
- private Function, String> nameSupplier;
-
private Node parent;
private String name;
@@ -47,7 +44,6 @@ class NodeItem implements Node {
*/
NodeItem(final T data) {
this.data = data;
- this.nameSupplier = (n) -> null;
}
/**
@@ -74,24 +70,8 @@ class NodeItem implements Node {
setParent(parent);
}
- private String generateName() {
- return getNameSupplier().apply(this);
- }
-
- private Function, String> getNameSupplier() {
- if (nameSupplier != null) {
- return nameSupplier;
- }
- // no test for parent as root nodes will always have a default name
- // supplier
- return ((NodeItem) parent).getNameSupplier();
- }
-
@Override
public String getName() {
- if (name == null) {
- return generateName();
- }
return name;
}
@@ -380,14 +360,8 @@ class NodeItem implements Node {
public void removeParent() {
if (parent != null) {
Node oldParent = parent;
- Function, String> supplier = getNameSupplier();
parent = null;
oldParent.removeChild(this);
- if (this.nameSupplier == null) {
- // this is now a root node, so must provide a default name
- // supplier
- this.nameSupplier = supplier;
- }
}
}