080c7485997ae89f7bebe0d240754e620a2e8487
[cdmlib.git] / cdmlib-services / src / main / java / eu / etaxonomy / cdm / api / service / DistributionTree.java
1 package eu.etaxonomy.cdm.api.service;
2
3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.Iterator;
6 import java.util.List;
7 import java.util.Set;
8
9 import eu.etaxonomy.cdm.common.Tree;
10 import eu.etaxonomy.cdm.common.TreeNode;
11 import eu.etaxonomy.cdm.model.common.Language;
12 import eu.etaxonomy.cdm.model.description.Distribution;
13 import eu.etaxonomy.cdm.model.location.NamedArea;
14 import eu.etaxonomy.cdm.model.location.NamedAreaLevel;
15
16 public class DistributionTree extends Tree<Distribution>{
17
18 public DistributionTree(){
19 NamedArea area = new NamedArea();
20 Distribution data = Distribution.NewInstance();
21 data.setArea(area);
22 data.addModifyingText("test", Language.ENGLISH());
23 TreeNode<Distribution> rootElement = new TreeNode<Distribution>();
24 List<TreeNode<Distribution>> children = new ArrayList<TreeNode<Distribution>>();
25
26 rootElement.setData(data);
27 rootElement.setChildren(children);
28 setRootElement(rootElement);
29 }
30
31 public boolean containsChild(TreeNode<Distribution> root, TreeNode<Distribution> treeNode){
32 boolean result = false;
33 Iterator<TreeNode<Distribution>> it = root.getChildren().iterator();
34 while (it.hasNext() && !result) {
35 TreeNode<Distribution> node = (TreeNode<Distribution>) it.next();
36 if (node.getData().equalsForTree(treeNode.getData())) {
37 result = true;
38 }
39 }
40 /*
41 while (!result && it.hasNext()) {
42 if (it.next().data.equalsForTree(treeNode.data)){
43 result = true;
44 }
45 }
46 */
47 return result;
48 }
49
50 public TreeNode<Distribution> getChild(TreeNode<Distribution> root, TreeNode<Distribution> TreeNode) {
51 boolean found = false;
52 TreeNode<Distribution> result = null;
53 Iterator<TreeNode<Distribution>> it = root.children.iterator();
54 while (!found && it.hasNext()) {
55 result = (TreeNode<Distribution>) it.next();
56 if (result.data.equalsForTree(TreeNode.data)){
57 found = true;
58 }
59 }
60 if (!found){
61 try {
62 throw new Exception("The node was not found in among children and that is a precondition of getChild(node) method");
63 } catch (Exception e) {
64 e.printStackTrace();
65 }
66 }
67 return result;
68 }
69
70 public void merge(List<Distribution> distList, Set<NamedAreaLevel> omitLevels){
71 for (Distribution distribution : distList) {
72 List<NamedArea> levelList =
73 this.getAreaLevelPathList(distribution.getArea(), omitLevels);
74 mergeAux(distribution, distribution.getArea().getLevel(), levelList, this.getRootElement());
75 }
76 }
77
78 public void sortChildren(){
79 sortChildrenAux(this.getRootElement());
80 }
81
82 private void sortChildrenAux(TreeNode<Distribution> treeNode){
83 DistributionNodeComparator comp = new DistributionNodeComparator();
84 if (treeNode.children == null) {
85 //nothing => stop condition
86 return;
87 }else {
88 Collections.sort(treeNode.children, comp);
89 for (TreeNode<Distribution> child : treeNode.children) {
90 sortChildrenAux(child);
91 }
92 }
93 }
94
95 private void mergeAux(Distribution distribution,
96 NamedAreaLevel level,
97 List<NamedArea> areaHierarchieList,
98 TreeNode<Distribution> root){
99 TreeNode<Distribution> highestDistNode;
100 TreeNode<Distribution> child;// the new child to add or the child to follow through the tree
101 //if the list to merge is empty finish the execution
102 if (areaHierarchieList.isEmpty()) {
103 return;
104 }
105 //getting the highest area and inserting it into the tree
106 NamedArea highestArea = areaHierarchieList.get(0);
107 //NamedAreaLevel highestAreaLevel = (NamedAreaLevel) HibernateProxyHelper.deproxy(highestArea.getLevel());
108 //NamedAreaLevel currentLevel = (NamedAreaLevel) HibernateProxyHelper.deproxy(level);
109 //if (highestAreaLevel.compareTo(currentLevel) == 0){//if distribution.status is relevant
110
111 if (highestArea.getLevel().getLabel().compareTo(level.getLabel()) == 0){
112 highestDistNode = new TreeNode<Distribution>(distribution);//distribution.area comes from proxy!!!!
113 }else{ //if distribution.status is not relevant
114 Distribution data = Distribution.NewInstance(highestArea, null);
115 highestDistNode = new TreeNode<Distribution>(data);
116 }
117 if(highestDistNode.data.getModifyingText().isEmpty()){
118 highestDistNode.data.addModifyingText("test", Language.ENGLISH());
119 }
120
121 if (root.getChildren().isEmpty() || !containsChild(root, highestDistNode)) {
122 //if the highest level is not on the depth-1 of the tree we add it.
123 //child = highestDistNode;
124 child = new TreeNode<Distribution>(highestDistNode.data);
125 root.addChild(child);//child.getData().getArea().getUuid().toString().equals("8cfc1722-e1e8-49d3-95a7-9879de6de490");
126 }else {
127 //if the deepth-1 of the tree contains the highest area level
128 //get the subtree or create it in order to continuing merging
129 child = getChild(root,highestDistNode);
130 }
131 //continue merging with the next highest area of the list.
132 List<NamedArea> newList = areaHierarchieList.subList(1, areaHierarchieList.size());
133 mergeAux(distribution, level, newList, child);
134 }
135
136 private List<NamedArea> getAreaLevelPathList(NamedArea area, Set<NamedAreaLevel> omitLevels){
137 List<NamedArea> result = new ArrayList<NamedArea>();
138 if (omitLevels == null || !omitLevels.contains(area.getLevel())){
139 result.add(area);
140 }
141 while (area.getPartOf() != null) {
142 area = area.getPartOf();
143 if (omitLevels == null || !omitLevels.contains(area.getLevel())){
144 result.add(0, area);
145 }
146 }
147 return result;
148 }
149 }