1. Project Clover database Mon Dec 22 2025 14:59:38 CST
  2. Package org.europa.together.application

File ListTree.java

 

Coverage histogram

../../../../img/srcFileCovDistChart10.png
0% of files have more coverage

Code metrics

80
173
20
1
377
337
69
0.4
8.65
20
3.45

Classes

Class Line # Actions
ListTree 19 173 0% 69 1
0.99633799.6%
 

Contributing tests

This file is covered by 40 tests. .

Source view

1    package org.europa.together.application;
2   
3    import java.util.ArrayList;
4    import java.util.List;
5    import org.europa.together.business.Logger;
6    import org.europa.together.business.TreeWalker;
7    import org.europa.together.domain.LogLevel;
8    import org.europa.together.domain.TreeNode;
9    import org.europa.together.exceptions.MisconfigurationException;
10    import org.europa.together.utils.StringUtils;
11    import org.springframework.stereotype.Repository;
12   
13    /**
14    * Implementation of a TreeWalker.
15    *
16    * @param <T> define the TreeType
17    */
18    @Repository
 
19    public class ListTree<T> implements TreeWalker<T> {
20   
21    private static final long serialVersionUID = 9L;
22    private static final Logger LOGGER = new LogbackLogger(ListTree.class);
23   
24    private List<TreeNode<T>> tree = new ArrayList<>();
25    private String rootUuid;
26   
27    /**
28    * Constructor.
29    */
 
30  14 toggle public ListTree() {
31  14 LOGGER.log("instance class", LogLevel.INFO);
32    }
33   
34    /**
35    * Constructor.
36    *
37    * @param root as TreeNode
38    */
 
39  4 toggle public ListTree(final TreeNode<T> root) {
40  4 addRoot(root);
41  4 LOGGER.log("instance class (" + root.getNodeName() + ")", LogLevel.INFO);
42    }
43   
 
44  47 toggle @Override
45    public final boolean addRoot(final TreeNode<T> root) {
46  47 boolean success = false;
47  47 if (StringUtils.isEmpty(rootUuid)) {
48  46 this.rootUuid = root.getUuid();
49  46 root.setParent("-1");
50  46 tree.add(root);
51  46 success = true;
52  46 LOGGER.log("ROOT: [" + this.rootUuid + "] added.", LogLevel.DEBUG);
53    } else {
54  1 LOGGER.log("Root node [" + this.rootUuid + "] for this tree already exist.",
55    LogLevel.WARN);
56    }
57  47 return success;
58    }
59   
 
60  2 toggle @Override
61    public boolean isElementOfTree(final TreeNode<T> node) {
62  2 boolean success = false;
63  2 if (!tree.isEmpty()) {
64  1 for (TreeNode<T> element : this.tree) {
65  12 if (node.equals(element)) {
66  1 success = true;
67    }
68    }
69    } else {
70  1 LOGGER.log("Operation not possible, because Tree is empty.", LogLevel.WARN);
71    }
72  2 return success;
73    }
74   
 
75  2 toggle @Override
76    public boolean isEmpty() {
77  2 return tree.isEmpty();
78    }
79   
 
80  27 toggle @Override
81    public boolean isLeaf(final TreeNode<T> leaf) {
82  27 boolean isLeaf = false;
83  27 if (!tree.isEmpty()) {
84  26 boolean hasParent = false;
85  26 for (TreeNode<T> check : this.tree) {
86  246 if (leaf.getUuid().equals(check.getParent())) {
87  13 hasParent = true;
88  13 break;
89    }
90    }
91  26 if (!hasParent) {
92  13 isLeaf = true;
93    }
94    } else {
95  1 LOGGER.log("Operation not possible, because Tree is empty.", LogLevel.WARN);
96    }
97  27 return isLeaf;
98    }
99   
 
100  4 toggle @Override
101    public boolean removeNode(final TreeNode<T> node) {
102  4 boolean success = false;
103  4 if (this.isLeaf(node)) {
104  2 this.tree.remove(node);
105  2 success = true;
106  2 LOGGER.log("Node " + node.getNodeName() + " removed.", LogLevel.DEBUG);
107    } else {
108  2 LOGGER.log("Node " + node.getNodeName()
109    + " can't removed. First you need to remove all childe node(s)",
110    LogLevel.WARN);
111    }
112  4 return success;
113    }
114   
 
115  15 toggle @Override
116    public int countNodes() {
117  15 return this.tree.size();
118    }
119   
 
120  4 toggle @Override
121    public int isNameUnique(final String nodeName) {
122  4 int count = 0;
123  4 if (!tree.isEmpty()) {
124  3 for (TreeNode<T> node : this.tree) {
125  37 if (node.getNodeName().equals(nodeName)) {
126  3 count++;
127    }
128    }
129    } else {
130  1 LOGGER.log("Operation not possible, because Tree is empty.", LogLevel.WARN);
131    }
132  4 return count;
133    }
134   
 
135  12 toggle @Override
136    public List<TreeNode<T>> getElementByName(final String nodeName) {
137  12 List<TreeNode<T>> elements = new ArrayList<>();
138  12 if (!tree.isEmpty()) {
139  11 for (TreeNode<T> node : this.tree) {
140  136 if (node.getNodeName().equals(nodeName)) {
141  13 elements.add(node);
142    }
143    }
144   
145  11 if (elements.isEmpty()) {
146  1 LOGGER.log("No Node(s) with the name " + nodeName + " found.", LogLevel.DEBUG);
147    }
148    } else {
149  1 LOGGER.log("Operation not possible, because Tree is empty.", LogLevel.WARN);
150    }
151  12 return elements;
152    }
153   
 
154  1 toggle @Override
155    public List<TreeNode<T>> getLeafs() {
156  1 List<TreeNode<T>> leafs = new ArrayList<>();
157  1 for (TreeNode<T> node : tree) {
158  12 if (isLeaf(node)) {
159  5 leafs.add(node);
160    }
161    }
162  1 LOGGER.log(leafs.size() + " Leaf Nodes in the tree detected.", LogLevel.DEBUG);
163  1 return leafs;
164    }
165   
 
166  15 toggle @Override
167    public List<TreeNode<T>> getTree() {
168  15 return List.copyOf(tree);
169    }
170   
 
171  3 toggle @Override
172    public TreeNode<T> getNodeByUuid(final String uuid) {
173  3 TreeNode<T> search = null;
174  3 if (!tree.isEmpty()) {
175  2 for (TreeNode<T> node : this.tree) {
176  18 if (node.getUuid().equals(uuid)) {
177  1 search = node;
178  1 break;
179    }
180    }
181    } else {
182  1 LOGGER.log("Operation not possible, because Tree is empty.", LogLevel.WARN);
183    }
184  3 return search;
185    }
186   
 
187  88 toggle @Override
188    public TreeNode<T> getRoot() {
189  88 TreeNode<T> root = null;
190  88 if (this.rootUuid != null) {
191  87 for (TreeNode<T> node : this.tree) {
192  243 if (node.getUuid().equals(this.rootUuid)) {
193  87 root = node;
194    }
195    }
196    }
197  88 return root;
198    }
199   
 
200  286 toggle @Override
201    public boolean addNode(final TreeNode<T> node) {
202  286 boolean add = true;
203  286 if (node != null) {
204  285 for (TreeNode<T> check : this.tree) {
205  1724 if (node.getUuid().equals(check.getUuid())) {
206  1 LOGGER.log("Node with this UUID already exist.", LogLevel.WARN);
207  1 add = false;
208  1 break;
209    }
210  1723 if (!StringUtils.isEmpty(node.getParent())
211    && node.getParent().equals(check.getParent())
212    && node.getNodeName().equals(check.getNodeName())) {
213  1 LOGGER.log("Node with same name AND parent already exist.",
214    LogLevel.WARN);
215  1 add = false;
216  1 break;
217    }
218    }
219  285 if (add) {
220  283 tree.add(node);
221  283 LOGGER.log("Node [" + node.getNodeName() + "] added.",
222    LogLevel.DEBUG);
223    }
224    } else {
225  1 add = false;
226    }
227  286 return add;
228    }
229   
 
230  43 toggle @Override
231    public void clear() {
232  43 this.tree.clear();
233  43 this.rootUuid = "";
234  43 LOGGER.log("Tree successful reseted.", LogLevel.TRACE);
235    }
236   
 
237  6 toggle @Override
238    public void prune(final TreeNode<T> cutNode) throws MisconfigurationException {
239  6 List<TreeNode<T>> stack = new ArrayList<>();
240  6 stack.addAll(tree);
241   
242  6 LOGGER.log("Cut Tree by Node "
243    + cutNode.getNodeName() + " ["
244    + cutNode.getUuid() + "]", LogLevel.DEBUG);
245   
246  5 if (stack.isEmpty()) {
247  1 throw new MisconfigurationException("prune: tree is empty nothing to do");
248  4 } else if (cutNode.equals(getRoot())) {
249  1 LOGGER.log("Node to prune is ROOT - delee Tree", LogLevel.DEBUG);
250  1 clear();
251  3 } else if (isLeaf(cutNode)) {
252  2 LOGGER.log("Node to prune is a LEAF - remove(leaf)", LogLevel.DEBUG);
253  2 removeNode(cutNode);
254    } else {
255  1 TreeNode<T> node = cutNode;
256  1 List<TreeNode<T>> helper = new ArrayList<>();
257  1 List<TreeNode<T>> cutted = new ArrayList<>();
258  1 cutted.add(node);
259  3 for (int i = 0; i < tree.size(); i++) {
260  3 for (TreeNode<T> compare : stack) {
261  15 if (i != 0) {
262  3 node = compare;
263    }
264  147 for (int j = 0; j < tree.size(); j++) {
265  136 if (node.getUuid().equals(compare.getUuid())) {
266  4 cutted.add(compare);
267  4 if (!isLeaf(compare)) {
268  2 helper.add(compare);
269    }
270  4 break;
271    }
272    }
273    }
274  3 if (!helper.isEmpty()) {
275  2 stack.clear();
276  2 for (TreeNode<T> compare : helper) {
277  2 for (TreeNode<T> element : this.tree) {
278  24 if (compare.getUuid().equals(element.getParent())) {
279  3 stack.add(element);
280    }
281    }
282    }
283  2 cutted.addAll(stack);
284  2 helper.clear();
285    } else {
286  1 break;
287    }
288    }
289  1 for (TreeNode<T> item : cutted) {
290  8 this.tree.remove(item);
291    }
292    }
293    }
294   
 
295  3 toggle @Override
296    public void merge(final String parentUuid, final TreeWalker<T> appendingTree) {
297  3 if (appendingTree != null && !appendingTree.isEmpty()) {
298  1 TreeNode<T> appendingRoot = appendingTree.getRoot();
299  1 appendingRoot.setParent(parentUuid);
300  1 List<TreeNode<T>> newTree = new ArrayList<>();
301  1 newTree.addAll(appendingTree.getTree());
302  1 this.tree.addAll(newTree);
303  1 LOGGER.log("Append " + newTree.size()
304    + " Nodes to the new Tree.", LogLevel.DEBUG);
305    } else {
306  2 LOGGER.log("Merging tree is empty - no merge applied.", LogLevel.DEBUG);
307    }
308    }
309   
 
310  8 toggle @Override
311    public boolean validateTree(final List<TreeNode<T>> collection)
312    throws MisconfigurationException {
313  8 boolean isTree = false;
314  8 int marker = 0;
315  8 int counter = 0;
316  8 int root = 0;
317  8 if (!collection.isEmpty()) {
318  7 marker = collection.size() - 1;
319  7 List<TreeNode<T>> comperator = new ArrayList<>();
320  7 comperator.addAll(collection);
321  7 for (TreeNode<T> node : collection) {
322  70 if (StringUtils.isEmpty(node.getParent())) {
323  3 counter++;
324  3 LOGGER.log("Element with empty parent: " + node.getNodeName(), LogLevel.DEBUG);
325    }
326  70 if (!StringUtils.isEmpty(node.getParent()) && node.getParent().equals("-1")) {
327  7 root++;
328  7 LOGGER.log("ROOT element: " + node.getNodeName(), LogLevel.DEBUG);
329    }
330  70 for (TreeNode<T> element : comperator) {
331  864 if (!StringUtils.isEmpty(node.getParent())
332    && !node.getParent().equals("-1")
333    && !element.equals(node)
334    && element.getUuid().equals(node.getParent())) {
335  59 marker--;
336  59 LOGGER.log("Parent of (" + node.getNodeName() + ") : " + node.getUuid()
337    + " : (" + element.getNodeName() + ") " + element.getParent(),
338    LogLevel.DEBUG);
339    }
340    }
341    }
342    }
343  8 if (root == 0) {
344  2 LOGGER.log("Tree has no ROOT element.", LogLevel.DEBUG);
345  6 } else if (root > 1) {
346  1 LOGGER.log("Tree has muliple ROOT elements.", LogLevel.DEBUG);
347    }
348  8 if (marker != 0) {
349  4 LOGGER.log("Tree has " + marker + " disconnected Elemets.", LogLevel.DEBUG);
350    }
351  8 if (counter == 0
352    && root == 1
353    && marker == 0) {
354  2 isTree = true;
355    }
356  8 return isTree;
357    }
358   
 
359  2 toggle @Override
360    public String toString() {
361  2 StringBuilder out = new StringBuilder();
362  2 out.append("TreeWalkerImpl{\n")
363    .append("\t Root: ")
364    .append(getRoot().getNodeName())
365    .append("\n")
366    .append("\t Nodes: ")
367    .append(tree.size())
368    .append("\n TREE >>>\n");
369  2 for (TreeNode<T> node : tree) {
370  24 out.append("\t")
371    .append(node.toString())
372    .append("\n");
373    }
374  2 out.append("}");
375  2 return out.toString();
376    }
377    }