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

io.github.astrapi69.gen.tree.convert.BaseTreeNodeTransformer Maven / Gradle / Ivy

There is a newer version: 10.1
Show newest version
/**
 * The MIT License
 *
 * Copyright (C) 2015 Asterios Raptis
 *
 * 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 io.github.astrapi69.gen.tree.convert;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import io.github.astrapi69.gen.tree.BaseTreeNode;
import io.github.astrapi69.gen.tree.TreeIdNode;
import lombok.NonNull;

/**
 * The class {@link BaseTreeNodeTransformer} provides algorithms for converting between the
 * {@link BaseTreeNode} objects and {@link TreeIdNode} objects. This is useful if you want to save
 * {@link BaseTreeNode} objects in a store, you have first to transform the {@link BaseTreeNode}
 * objects (you want to store) to {@link TreeIdNode} objects and save them. Note: The
 * {@link BaseTreeNode} object can not be stored
 */
public final class BaseTreeNodeTransformer
{
	private BaseTreeNodeTransformer()
	{
	}

	/**
	 * Transforms the given {@link BaseTreeNode} object to a {@link Map} object with the key and the
	 * corresponding {@link TreeIdNode} objects
	 *
	 * @param 
	 *            the generic type of the value
	 * @param 
	 *            the generic type of the id of the node
	 * @param root
	 *            the {@link BaseTreeNode} object to transform
	 * @return a {@link Map} object with the corresponding {@link TreeIdNode} objects
	 */
	public static  Map> toKeyMap(final @NonNull BaseTreeNode root)
	{
		return root.traverse().stream().collect(Collectors.toMap(BaseTreeNode::getId, // keyMapper
			BaseTreeNodeTransformer::toTreeIdNode, // valueMapper
			(first, second) -> first, // mergeFunction
			LinkedHashMap::new // mapFactory
		));
	}

	/**
	 * Transforms the given {@link BaseTreeNode} object to a {@link TreeIdNode} object
	 *
	 * @param 
	 *            the generic type of the value
	 * @param 
	 *            the generic type of the id of the node
	 * @param baseTreeNode
	 *            the {@link BaseTreeNode} object to convert
	 * @return the new created {@link TreeIdNode} object
	 */
	public static  TreeIdNode toTreeIdNode(
		final @NonNull BaseTreeNode baseTreeNode)
	{
		return TreeIdNode. builder().id(baseTreeNode.getId())
			.parentId(baseTreeNode.hasParent() ? baseTreeNode.getParent().getId() : null)
			.value(baseTreeNode.getValue()).displayValue(baseTreeNode.getDisplayValue())
			.leaf(baseTreeNode.isLeaf()).childrenIds(baseTreeNode.getChildren().stream()
				.map(BaseTreeNode::getId).collect(Collectors.toSet()))
			.build();
	}

	/**
	 * Transforms the given {@link BaseTreeNode} object to a {@link Map} object with the key and the
	 * corresponding {@link BaseTreeNode} objects
	 *
	 * @param 
	 *            the generic type of the value
	 * @param 
	 *            the generic type of the id of the node
	 * @param root
	 *            the {@link BaseTreeNode} object to transform
	 * @return a {@link Map} object with the corresponding {@link BaseTreeNode} objects
	 */
	public static  Map> toKeyBaseTreeNodeMap(
		final @NonNull BaseTreeNode root)
	{
		return root.traverse().stream().collect(Collectors.toMap(BaseTreeNode::getId, // keyMapper
			element -> element, // valueMapper
			(first, second) -> first, // mergeFunction
			LinkedHashMap::new // mapFactory
		));
	}

	/**
	 * Transforms the given {@link Map} object that contains {@link TreeIdNode} objects as values
	 * and the id as key
	 *
	 * @param 
	 *            the generic type of the value
	 * @param 
	 *            the generic type of the id of the node
	 * @param treeIdNodeMap
	 *            the {@link Map} object with the {@link TreeIdNode} objects to transform
	 * @return a {@link Map} object with the corresponding {@link BaseTreeNode} objects
	 */
	public static  Map> transform(
		final @NonNull Map> treeIdNodeMap)
	{
		final Map> baseTreeNodeMap = treeIdNodeMap.entrySet().stream()
			.collect(Collectors.toMap(Map.Entry::getKey, // keyMapper
				entry -> BaseTreeNode. builder().id(entry.getValue().getId())
					.value(entry.getValue().getValue())
					.displayValue(entry.getValue().getDisplayValue())
					.leaf(entry.getValue().isLeaf()).build(), // valueMapper
				(first, second) -> first, // mergeFunction
				LinkedHashMap::new // mapFactory
			));
		for (Map.Entry> entry : treeIdNodeMap.entrySet())
		{
			K key = entry.getKey();
			TreeIdNode treeIdNode = entry.getValue();
			BaseTreeNode baseTreeNode = baseTreeNodeMap.get(key);
			BaseTreeNode parent = treeIdNode.getParentId() != null
				? baseTreeNodeMap.get(treeIdNode.getParentId())
				: null;
			baseTreeNode.setParent(parent);
			Set> children = treeIdNode.getChildrenIds().stream()
				.map(baseTreeNodeMap::get).collect(Collectors.toSet());
			baseTreeNode.setChildren(children);
		}
		return baseTreeNodeMap;
	}

	/**
	 * Retrieves the root {@link BaseTreeNode} object from the given @link Map} object that contains
	 * {@link TreeIdNode} objects as values and the id as key
	 *
	 * @param 
	 *            the generic type of the value
	 * @param 
	 *            the generic type of the id of the node
	 * @param treeIdNodeMap
	 *            the {@link Map} object with the {@link TreeIdNode} objects to transform
	 * @return the root {@link BaseTreeNode} object or null if not found
	 */
	public static  BaseTreeNode getRoot(
		final @NonNull Map> treeIdNodeMap)
	{
		AtomicReference> root = new AtomicReference<>();
		if (treeIdNodeMap.isEmpty())
		{
			return root.get();
		}
		transform(treeIdNodeMap).entrySet().stream().findAny().ifPresent(entry -> {
			BaseTreeNode any = entry.getValue();
			BaseTreeNode treeNode = any.getRoot();
			root.set(treeNode);
		});
		return root.get();
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy