All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.kemitix.node.Nodes Maven / Gradle / Ivy

The newest version!
/**
 * 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.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Utility class for {@link Node} items.
 *
 * @author Paul Campbell ([email protected])
 */
public final class Nodes {

    private Nodes() {
    }

    /**
     * Creates a new unnamed root node.
     *
     * @param data the data the node will contain
     * @param   the type of the data
     *
     * @return the new node
     */
    public static  Node unnamedRoot(final T data) {
        return new NodeItem<>(data, "", null, new HashSet<>());
    }

    /**
     * Creates a new named root node.
     *
     * @param data the data the node will contain
     * @param name the name of the node
     * @param   the type of the data
     *
     * @return the new node
     */
    public static  Node namedRoot(final T data, final String name) {
        return new NodeItem<>(data, name, null, new HashSet<>());
    }

    /**
     * Creates a new unnamed child node.
     *
     * @param data   the data the node will contain
     * @param parent the parent of the node
     * @param     the type of the data
     *
     * @return the new node
     */
    public static  Node unnamedChild(final T data, final Node parent) {
        return new NodeItem<>(data, "", parent, new HashSet<>());
    }

    /**
     * Creates a new named child node.
     *
     * @param data   the data the node will contain
     * @param name   the name of the node
     * @param parent the parent of the node
     * @param     the type of the data
     *
     * @return the new node
     */
    public static  Node namedChild(
            final T data, final String name, final Node parent
    ) {
        return new NodeItem<>(data, name, parent, new HashSet<>());
    }

    /**
     * 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.findParent()
                .isPresent()) {
            throw new IllegalArgumentException("source must be the root node");
        }
        final Set> children = getImmutableChildren(root);
        return ImmutableNodeItem.newRoot(root.findData()
                .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
    ) {
        return ImmutableNodeItem.newChild(source.findData()
                        .orElse(null), source.getName(), source.findParent()
                        .orElse(null),
                getImmutableChildren(source)
        );
    }

    /**
     * Draw a representation of the tree.
     *
     * @param node  the root node to draw
     * @param depth current depth for recursion
     * @param    the type of the node's content
     * @return a representation of the tree
     */
    public static  String drawTree(
            final Node node,
            final int depth
    ) {
        final StringBuilder sb = new StringBuilder();
        if (node.isNamed()) {
            sb.append(formatByDepth(node.getName(), depth));
        } else if (!node.getChildren().isEmpty()) {
            sb.append(formatByDepth("(unnamed)", depth));
        }
        node.getChildren().forEach(c -> sb.append(drawTree(c, depth + 1)));
        return sb.toString();
    }

    private static String formatByDepth(final String value, final int depth) {
        return String.format("[%1$" + (depth + value.length()) + "s]\n", value);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy