From 48c5b157204498562615b0845ad1652d62a0099b Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Tue, 20 Sep 2016 22:59:50 +0100 Subject: [PATCH] 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"); }