diff --git a/CHANGELOG.org b/CHANGELOG.org index 8d68c43..2ad153e 100644 --- a/CHANGELOG.org +++ b/CHANGELOG.org @@ -5,42 +5,31 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -** [0.7.1] - unreleased - -Added - -- Add kemitix-maven-tiles 0.8.1 - -Changed - -- [checkstyle] suppress npath complexity issues -- [coverage] lower requirements - -Dependencies - -- Bump kemitix-parent to 5.2.0 -- Bump assertj from 3.11.1 -- Bump lombok from 1.18.2 - * 0.8.0 +** Added + +- Add kemitix-maven-tiles + ** Changed - - Replace Jenkins with Github Actions (#57) +- Replace Jenkins with Github Actions (#57) +- [checkstyle] suppress npath complexity issues +- [coverage] lower requirements ** Dependencies - * Bump hamcrest-core from 2.1 to 2.2 (#50) - * Bump lombok from 1.18.8 to 1.18.10 (#49) - * Bump assertj-core from 3.12.2 to 3.13.2 (#48) - * Bump tiles-maven-plugin from 2.14 to 2.15 (#45) - * Bump lombok from 1.18.6 to 1.18.8 (#44) - * Bump tiles-maven-plugin from 2.13 to 2.14 (#43) - * Bump assertj-core from 3.12.1 to 3.12.2 (#42) - * Bump lombok from 1.18.4 to 1.18.6 (#41) - * Bump tiles-maven-plugin from 2.12 to 2.13 (#40) - * Bump hamcrest-core from 1.3 to 2.1 (#37) - * Clean up changelog and readme, and remove external build dependencies (#38) +- Bump hamcrest-core from 2.1 to 2.2 (#50) +- Bump lombok from 1.18.8 to 1.18.10 (#49) +- Bump assertj-core from 3.12.2 to 3.13.2 (#48) +- Bump tiles-maven-plugin from 2.14 to 2.15 (#45) +- Bump lombok from 1.18.6 to 1.18.8 (#44) +- Bump tiles-maven-plugin from 2.13 to 2.14 (#43) +- Bump assertj-core from 3.12.1 to 3.12.2 (#42) +- Bump lombok from 1.18.4 to 1.18.6 (#41) +- Bump tiles-maven-plugin from 2.12 to 2.13 (#40) +- Bump hamcrest-core from 1.3 to 2.1 (#37) +- Clean up changelog and readme, and remove external build dependencies (#38) * [0.7.0] - 2017-02-18 diff --git a/pom.xml b/pom.xml index bbfbf69..a1cb290 100644 --- a/pom.xml +++ b/pom.xml @@ -18,8 +18,9 @@ 1.8 2.16 - 1.3.1 - 4.0.1 + 2.4.1 + 0.9 + 5.4.0 1.18.12 3.15.0 2.1.0 diff --git a/src/main/java/net/kemitix/node/HeadTail.java b/src/main/java/net/kemitix/node/HeadTail.java new file mode 100644 index 0000000..200454c --- /dev/null +++ b/src/main/java/net/kemitix/node/HeadTail.java @@ -0,0 +1,62 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2018 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 java.util.Collections; +import java.util.List; +import java.util.Optional; + +/** + * Provides a simple implementation of head() and tail() for {@link List}s. + */ +public interface HeadTail { + + /** + * Returns the first item in the list as an {@link Optional}. + * + * @param list the list + * @param the type of the lists contents + * @return an Optional containing the first item in the list, or empty if + * the list is empty. + */ + static Optional head(final List list) { + if (list.isEmpty()) { + return Optional.empty(); + } + return Optional.ofNullable(list.get(0)); + } + + /** + * Returns the list, minus the first item. + * + * @param list the list + * @param the type of the lists contents + * @return a view of the list starting with the second item, or an empty + * list if the original list has less than two items. + */ + static List tail(final List list) { + if (list.size() < 1) { + return Collections.emptyList(); + } + return list.subList(1, list.size()); + } +} diff --git a/src/main/java/net/kemitix/node/NodeItem.java b/src/main/java/net/kemitix/node/NodeItem.java index e03cde9..5fc9ffe 100644 --- a/src/main/java/net/kemitix/node/NodeItem.java +++ b/src/main/java/net/kemitix/node/NodeItem.java @@ -24,13 +24,13 @@ package net.kemitix.node; import lombok.NonNull; import lombok.val; -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; import java.util.stream.Stream; +import static net.kemitix.node.HeadTail.head; +import static net.kemitix.node.HeadTail.tail; + /** * Represents a tree of nodes. * @@ -230,9 +230,11 @@ class NodeItem implements Node { @Override public Optional> findChild(@NonNull final T child) { return children.stream() - .filter(node -> child.equals(node.findData() - .orElse(null))) - .findFirst(); + .filter(node -> + child.equals( + node.findData() + .orElse(null))) + .findFirst(); } @Override @@ -260,17 +262,19 @@ class NodeItem implements Node { * @return the child or null */ @Override - @SuppressWarnings("npathcomplexity") 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); + return head(path) + .flatMap(this::findChild) + .flatMap(findInChildsPath(tail(path))); + } + + private Function, Optional>> findInChildsPath(final List path) { + return child -> { + if (path.isEmpty()) { + return Optional.of(child); + } + return child.findInPath(path); + }; } @Override diff --git a/src/test/java/net/kemitix/node/HeadTailTest.java b/src/test/java/net/kemitix/node/HeadTailTest.java new file mode 100644 index 0000000..ab32ba0 --- /dev/null +++ b/src/test/java/net/kemitix/node/HeadTailTest.java @@ -0,0 +1,53 @@ +package net.kemitix.node; + +import org.junit.Test; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.UUID; + +import static net.kemitix.node.HeadTail.head; +import static net.kemitix.node.HeadTail.tail; +import static org.assertj.core.api.Assertions.assertThat; + +public class HeadTailTest { + + private String headValue = "1-" + UUID.randomUUID().toString(); + private String secondValue = "2-" + UUID.randomUUID().toString(); + private String thirdValue = "3-" + UUID.randomUUID().toString(); + private List emptyList = Collections.emptyList(); + private List singletonList = Collections.singletonList(headValue); + private List aList = Arrays.asList( + headValue, secondValue, thirdValue + ); + private List tailValue = Arrays.asList( + secondValue, thirdValue + ); + + @Test + public void headOfAnEmptyListIsEmpty() { + assertThat(head(emptyList)).isEmpty(); + } + @Test + public void headOfASingletonListIsTheItem() { + assertThat(head(singletonList)).contains(headValue); + } + @Test + public void headOfAListIsTheFirstItem() { + assertThat(head(aList)).contains(headValue); + } + + @Test + public void tailOfAnEmptyListIsEmpty() { + assertThat(tail(emptyList)).isEmpty(); + } + @Test + public void tailOfASingletonListIsEmpty() { + assertThat(tail(singletonList)).isEmpty(); + } + @Test + public void tailOfAListIsMinusTheHead() { + assertThat(tail(aList)).isEqualTo(tailValue); + } +} \ No newline at end of file diff --git a/src/test/java/net/kemitix/node/NodeItemTest.java b/src/test/java/net/kemitix/node/NodeItemTest.java index e9928b6..89d2d78 100644 --- a/src/test/java/net/kemitix/node/NodeItemTest.java +++ b/src/test/java/net/kemitix/node/NodeItemTest.java @@ -405,13 +405,17 @@ public class NodeItemTest { val subject = "subject"; node = Nodes.unnamedChild(subject, parentNode); //when - val result = grandParentNode.findInPath(Arrays.asList(parent, subject)); + val result = grandParentNode.findInPath( + Arrays.asList(parent, subject)); //then - assertThat(result.isPresent()).as("when we walk the tree to a node it is found") - .isTrue(); + assertThat(result.isPresent()) + .as("when we walk the tree to a node it is found") + .isTrue(); result.ifPresent( - stringNode -> assertThat(stringNode).as("when we walk the tree to a node the correct node is found") - .isSameAs(node)); + stringNode -> + assertThat(stringNode) + .as("when we walk the tree to a node we find the correct node") + .isSameAs(node)); } /** @@ -438,7 +442,7 @@ public class NodeItemTest { */ @Test @Category(NodeFindInPathTestsCategory.class) - public void shouldThrowNEWhenWalkTreeNull() { + public void shouldThrowNPEWhenWalkTreeNull() { //given node = Nodes.unnamedRoot("subject"); exception.expect(NullPointerException.class);