package com.eactive.testmaster.client.dto; import java.util.ArrayList; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; public class ApiLayoutItemTreeBuilder { public static ApiLayoutItemDTO createTree(List layoutItems) { layoutItems.sort(Comparator.comparing(ApiLayoutItemDTO::getLoutItemSerno)); Long rootId = layoutItems.get(0).getParent(); ApiLayoutItemDTO root = new ApiLayoutItemDTO(); root.setLevel(0); root.setId(rootId); Map nodeMap = new HashMap<>(); nodeMap.put(rootId, root); for (ApiLayoutItemDTO item : layoutItems) { if (item.getLoutItemType().equals("Grid") || item.getLoutItemType().equals("Group")) { if (item.getLoutItemOccRef() != null && item.getLoutItemOccCnt().equals("*")) { for (ApiLayoutItemDTO parent : layoutItems) { if (parent.getLoutItemName().equals(item.getLoutItemOccRef())) { item.setChildOccCnt(Integer.parseInt(parent.getValue())); break; } } } else if (item.getLoutItemOccCnt() != null) { item.setChildOccCnt(Integer.parseInt(item.getLoutItemOccCnt())); } } if (nodeMap.containsKey(item.getParent())) { nodeMap.get(item.getParent()).getChildren().add(item); } nodeMap.put(item.getId(), item); } return root; } public static void moveNode(ApiLayoutItemDTO root, ApiLayoutItemDTO node, boolean moveUp) { ApiLayoutItemDTO parent = getParentNode(root, node); if (parent == null) { // Node is the root node, cannot be moved return; } List siblings = parent.getChildren(); int currentIndex = siblings.indexOf(node); if (currentIndex == -1) { // Node not found in parent's children list return; } int newIndex = moveUp ? currentIndex - 1 : currentIndex + 1; if (newIndex >= 0 && newIndex < siblings.size()) { // Swap the positions of the current node and the node at the new index siblings.set(currentIndex, siblings.get(newIndex)); siblings.set(newIndex, node); } } private static ApiLayoutItemDTO getParentNode(ApiLayoutItemDTO root, ApiLayoutItemDTO node) { if (node.getParent() == null) { return null; // Node is the root node } return getNodeById(root, node.getParent()); } private static int getNodeIndex(ApiLayoutItemDTO parent, ApiLayoutItemDTO node) { return parent.getChildren().indexOf(node); } public static ApiLayoutItemDTO getNodeById(ApiLayoutItemDTO node, Long id) { if (node.getId().equals(id)) { return node; } for (ApiLayoutItemDTO child : node.getChildren()) { ApiLayoutItemDTO found = getNodeById(child, id); if (found != null) { return found; } } return null; } private static ApiLayoutItemDTO findParent(ApiLayoutItemDTO root, ApiLayoutItemDTO node) { if (root == null || node == null) { return null; // Invalid input } if (root.getChildren().contains(node)) { return root; // The root is the parent of the node } for (ApiLayoutItemDTO child : root.getChildren()) { ApiLayoutItemDTO parent = findParent(child, node); if (parent != null) { return parent; } } return null; // Node not found in the tree } // private static ApiLayoutItemDTO findParentAtLevel(ApiLayoutItemDTO node, int targetLevel, ApiLayoutItemDTO excludedNode) { // if (node.getLoutItemDepth() == targetLevel && !node.equals(excludedNode)) { // return node; // } // // if (node.getChildren() == null) { // return null; // } // for (ApiLayoutItemDTO child : node.getChildren()) { // if (!child.equals(excludedNode)) { // ApiLayoutItemDTO foundParent = findParentAtLevel(child, targetLevel, excludedNode); // if (foundParent != null) { // return foundParent; // } // } // } // // return null; // } public static void printTree(ApiLayoutItemDTO root) { System.out.println("===================================="); printNode(root, 0); System.out.println("===================================="); } private static void printNode(ApiLayoutItemDTO node, int level) { if (node == null) { return; } // Print indentation based on the level for (int i = 0; i < level; i++) { System.out.print(" "); } // Print the node information System.out.println(node.getId() + ": " + node.getLoutName() + "[" + node.getLoutItemType() + ", Level: " + node.getLoutItemDepth() + ", Serno: " + node.getLoutItemSerno() + "]"); // Recursively print the children if (node.getChildren() != null) { for (ApiLayoutItemDTO child : node.getChildren()) { printNode(child, level + 1); } } } public static void moveNodeDepth(ApiLayoutItemDTO root, ApiLayoutItemDTO node, int newDepth) { if (node == null || root == null || newDepth < 0) { // Invalid input return; } ApiLayoutItemDTO parent = getParentNode(root, node); if (parent == null) { // Node is the root node, cannot be moved to a different level return; } int currentDepth = node.getLoutItemDepth(); int nodeIndex = getNodeIndex(parent, node); ApiLayoutItemDTO nextSibling = findClosestSibling(parent.getChildren(), nodeIndex); parent.getChildren().remove(node); if (newDepth > currentDepth) { // Moving to a higher depth if (nextSibling != null) { nextSibling.getChildren().add(node); node.setParent(nextSibling.getId()); node.setLoutItemDepth(newDepth); adjustChildrenDepth(node, newDepth + 1); } else { // No next sibling found, add the node back to the original parent parent.getChildren().add(node); } } else { // Moving to a lower depth ApiLayoutItemDTO newParent = findParent(root, parent); if (newParent != null) { newParent.getChildren().add(node); node.setParent(newParent.getId()); node.setLoutItemDepth(newDepth); adjustChildrenDepth(node, newDepth + 1); } else { // No parent found at the desired level, add the node back to the original parent parent.getChildren().add(node); } } } private static void adjustChildrenDepth(ApiLayoutItemDTO node, int depth) { for (ApiLayoutItemDTO child : node.getChildren()) { child.setLoutItemDepth(depth); adjustChildrenDepth(child, depth + 1); } } private static ApiLayoutItemDTO findNextSibling(List siblings) { if (siblings == null || siblings.isEmpty()) { return null; } return siblings.get(0); } private static ApiLayoutItemDTO findClosestSibling(List siblings, int nodeIndex) { if (siblings == null || siblings.isEmpty()) { return null; } if (nodeIndex < 1 || nodeIndex >= siblings.size()) { return findNextSibling(siblings); } return siblings.get(nodeIndex - 1); } private static ApiLayoutItemDTO findClosestSibling(List siblings, ApiLayoutItemDTO node) { int currentIndex = siblings.indexOf(node); if (currentIndex == -1) { return null; // Node not found in the siblings list } int closestIndex = -1; int minDistance = Integer.MAX_VALUE; // Find the sibling with the minimum distance from the current node for (int i = 0; i < siblings.size(); i++) { if (i != currentIndex) { int distance = Math.abs(siblings.get(i).getLoutItemSerno() - node.getLoutItemSerno()); if (distance < minDistance) { minDistance = distance; closestIndex = i; } } } if (closestIndex == -1) { return null; // No other siblings found } return siblings.get(closestIndex); } public static void main(String[] args) { ApiLayoutItemDTO root = new ApiLayoutItemDTO(); root.setId(1L); root.setLoutName("ROOT"); root.setLoutItemDepth(0); root.setChildren(new ArrayList<>(List.of( new ApiLayoutItemDTO(2L, 1L, "Field", "Child 2", 1, 10, "TEST11"), new ApiLayoutItemDTO(3L, 1L, "Group", "Child 3", 1, 0, ""), new ApiLayoutItemDTO(4L, 1L, "Field", "Child 4", 1, 10, "TEST21"), new ApiLayoutItemDTO(5L, 1L, "Field", "Child 5", 1, 10, "TEST22"), // new ApiLayoutItemDTO(6L, 1L, "Group", "Child 6", 1, 0, ""), new ApiLayoutItemDTO(7L, 1L, "Field", "Child 7", 1, 10, "TEST31"), new ApiLayoutItemDTO(8L, 1L, "Field", "Child 8", 1, 10, "TEST33"), new ApiLayoutItemDTO(9L, 1L, "Group", "Child 9", 1, 0, ""), new ApiLayoutItemDTO(10L, 1L, "Field", "Child 10", 1, 10, "TEST31"), new ApiLayoutItemDTO(11L, 1L, "Field", "Child 11", 1, 10, "TEST33") ))); for (ApiLayoutItemDTO item : root.getChildren()) { item.setChildOccCnt(1); } System.out.println("Before moving:"); printTree(root); moveNodeDepth(root, getNodeById(root, 4L), getNodeById(root, 4L).getLoutItemDepth() + 1); printTree(root); moveNodeDepth(root, getNodeById(root, 5L), getNodeById(root, 5L).getLoutItemDepth() + 1); printTree(root); moveNodeDepth(root, getNodeById(root, 7L), getNodeById(root, 7L).getLoutItemDepth() + 1); printTree(root); moveNodeDepth(root, getNodeById(root, 8L), getNodeById(root, 8L).getLoutItemDepth() + 1); printTree(root); moveNodeDepth(root, getNodeById(root, 10L), getNodeById(root, 10L).getLoutItemDepth() + 1); printTree(root); moveNodeDepth(root, getNodeById(root, 11L), getNodeById(root, 11L).getLoutItemDepth() + 1); printTree(root); moveNodeDepth(root, getNodeById(root, 9L), getNodeById(root, 9L).getLoutItemDepth() + 1); printTree(root); // moveNodeDepth(root, getNodeById(root, 6L), getNodeById(root, 6L).getLoutItemDepth() + 1); // printTree(root); moveNodeDepth(root, getNodeById(root, 9L), getNodeById(root, 9L).getLoutItemDepth() - 1); printTree(root); moveNodeDepth(root, getNodeById(root, 9L), getNodeById(root, 9L).getLoutItemDepth() - 1); printTree(root); moveNode(root, getNodeById(root, 9L), true); moveNodeDepth(root, getNodeById(root, 3L), getNodeById(root, 3L).getLoutItemDepth() + 1); printTree(root); ApiLayoutDTO layout = new ApiLayoutDTO(); layout.setComputedLayoutItemRoot(root); System.out.println(layout.buildMessage()); } }