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