1 |
01c21ead
|
n.hoffmann
|
/**
|
2 |
|
|
* Copyright (C) 2007 EDIT
|
3 |
1ae9f0ff
|
Andreas Kohlbecker
|
* European Distributed Institute of Taxonomy
|
4 |
01c21ead
|
n.hoffmann
|
* http://www.e-taxonomy.eu
|
5 |
1ae9f0ff
|
Andreas Kohlbecker
|
*
|
6 |
01c21ead
|
n.hoffmann
|
* The contents of this file are subject to the Mozilla Public License Version 1.1
|
7 |
|
|
* See LICENSE.TXT at the top of this package for the full license terms.
|
8 |
|
|
*/
|
9 |
|
|
|
10 |
|
|
package eu.etaxonomy.cdm.api.service;
|
11 |
|
|
|
12 |
|
|
import java.util.ArrayList;
|
13 |
b296585f
|
Andreas Müller
|
import java.util.Arrays;
|
14 |
01c21ead
|
n.hoffmann
|
import java.util.Collection;
|
15 |
|
|
import java.util.Collections;
|
16 |
|
|
import java.util.Comparator;
|
17 |
48dde342
|
Alexander Oppermann
|
import java.util.HashMap;
|
18 |
e3fc5af3
|
Andreas Müller
|
import java.util.HashSet;
|
19 |
01c21ead
|
n.hoffmann
|
import java.util.List;
|
20 |
|
|
import java.util.Map;
|
21 |
e3fc5af3
|
Andreas Müller
|
import java.util.Set;
|
22 |
01c21ead
|
n.hoffmann
|
import java.util.TreeMap;
|
23 |
|
|
import java.util.UUID;
|
24 |
562acef2
|
Andreas Kohlbecker
|
import java.util.stream.Collectors;
|
25 |
01c21ead
|
n.hoffmann
|
|
26 |
d8c4f8b9
|
Andreas Müller
|
import javax.persistence.EntityNotFoundException;
|
27 |
|
|
|
28 |
48dde342
|
Alexander Oppermann
|
import org.apache.commons.collections.CollectionUtils;
|
29 |
d8c4f8b9
|
Andreas Müller
|
import org.apache.commons.lang.StringUtils;
|
30 |
23de68fc
|
Andreas Müller
|
import org.apache.logging.log4j.LogManager;import org.apache.logging.log4j.Logger;
|
31 |
01c21ead
|
n.hoffmann
|
import org.springframework.beans.factory.annotation.Autowired;
|
32 |
|
|
import org.springframework.stereotype.Service;
|
33 |
|
|
import org.springframework.transaction.annotation.Transactional;
|
34 |
|
|
|
35 |
48dde342
|
Alexander Oppermann
|
import eu.etaxonomy.cdm.api.service.config.CreateHierarchyForClassificationConfigurator;
|
36 |
969dbe3e
|
Katja Luther
|
import eu.etaxonomy.cdm.api.service.config.NodeDeletionConfigurator.ChildHandling;
|
37 |
|
|
import eu.etaxonomy.cdm.api.service.config.TaxonDeletionConfigurator;
|
38 |
d17b9e90
|
Andreas Müller
|
import eu.etaxonomy.cdm.api.service.dto.EntityDTO;
|
39 |
63f513d9
|
Andreas Müller
|
import eu.etaxonomy.cdm.api.service.dto.GroupedTaxonDTO;
|
40 |
4f290ba6
|
Andreas Müller
|
import eu.etaxonomy.cdm.api.service.dto.MarkedEntityDTO;
|
41 |
d17b9e90
|
Andreas Müller
|
import eu.etaxonomy.cdm.api.service.dto.TaxonInContextDTO;
|
42 |
dba75be8
|
Andreas Kohlbecker
|
import eu.etaxonomy.cdm.api.service.pager.Pager;
|
43 |
|
|
import eu.etaxonomy.cdm.api.service.pager.PagerUtils;
|
44 |
7ff16b32
|
Andreas Kohlbecker
|
import eu.etaxonomy.cdm.api.service.pager.impl.AbstractPagerImpl;
|
45 |
dba75be8
|
Andreas Kohlbecker
|
import eu.etaxonomy.cdm.api.service.pager.impl.DefaultPagerImpl;
|
46 |
79c0eaa0
|
Andreas Müller
|
import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
|
47 |
eb1471a5
|
Andreas Müller
|
import eu.etaxonomy.cdm.compare.taxon.ITaxonNodeComparator;
|
48 |
65112c51
|
Andreas Müller
|
import eu.etaxonomy.cdm.compare.taxon.TaxonNodeSortMode;
|
49 |
1251ffed
|
Andreas Müller
|
import eu.etaxonomy.cdm.exception.FilterException;
|
50 |
cac97126
|
Andreas Müller
|
import eu.etaxonomy.cdm.exception.UnpublishedException;
|
51 |
6b5ba3cc
|
Andreas Kohlbecker
|
import eu.etaxonomy.cdm.model.common.CdmBase;
|
52 |
63f513d9
|
Andreas Müller
|
import eu.etaxonomy.cdm.model.common.ITreeNode;
|
53 |
4f290ba6
|
Andreas Müller
|
import eu.etaxonomy.cdm.model.common.MarkerType;
|
54 |
e3fc5af3
|
Andreas Müller
|
import eu.etaxonomy.cdm.model.common.TreeIndex;
|
55 |
01c21ead
|
n.hoffmann
|
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
|
56 |
|
|
import eu.etaxonomy.cdm.model.description.TaxonDescription;
|
57 |
|
|
import eu.etaxonomy.cdm.model.media.Media;
|
58 |
|
|
import eu.etaxonomy.cdm.model.media.MediaRepresentation;
|
59 |
892efc69
|
Andreas Kohlbecker
|
import eu.etaxonomy.cdm.model.media.MediaUtils;
|
60 |
a4c9dfc9
|
Andreas Müller
|
import eu.etaxonomy.cdm.model.name.INonViralName;
|
61 |
01c21ead
|
n.hoffmann
|
import eu.etaxonomy.cdm.model.name.Rank;
|
62 |
9dc896c9
|
Andreas Müller
|
import eu.etaxonomy.cdm.model.name.TaxonName;
|
63 |
22697c60
|
Andreas Müller
|
import eu.etaxonomy.cdm.model.taxon.Classification;
|
64 |
f6c2e10f
|
Andreas Müller
|
import eu.etaxonomy.cdm.model.taxon.ITaxonTreeNode;
|
65 |
d17b9e90
|
Andreas Müller
|
import eu.etaxonomy.cdm.model.taxon.Synonym;
|
66 |
01c21ead
|
n.hoffmann
|
import eu.etaxonomy.cdm.model.taxon.Taxon;
|
67 |
d17b9e90
|
Andreas Müller
|
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
|
68 |
01c21ead
|
n.hoffmann
|
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
|
69 |
1c39686b
|
Andreas Müller
|
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
|
70 |
b9cbcc7c
|
Andreas Kohlbecker
|
import eu.etaxonomy.cdm.persistence.dao.initializer.IBeanInitializer;
|
71 |
22697c60
|
Andreas Müller
|
import eu.etaxonomy.cdm.persistence.dao.taxon.IClassificationDao;
|
72 |
01c21ead
|
n.hoffmann
|
import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao;
|
73 |
|
|
import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonNodeDao;
|
74 |
76cfd0f6
|
Andreas Müller
|
import eu.etaxonomy.cdm.persistence.dao.term.IDefinedTermDao;
|
75 |
2b92f449
|
Andreas Kohlbecker
|
import eu.etaxonomy.cdm.persistence.dto.ClassificationLookupDTO;
|
76 |
d17b9e90
|
Andreas Müller
|
import eu.etaxonomy.cdm.persistence.dto.TaxonNodeDto;
|
77 |
d8c4f8b9
|
Andreas Müller
|
import eu.etaxonomy.cdm.persistence.dto.TaxonStatus;
|
78 |
d26d6619
|
Andreas M��ller
|
import eu.etaxonomy.cdm.persistence.dto.UuidAndTitleCache;
|
79 |
01c21ead
|
n.hoffmann
|
import eu.etaxonomy.cdm.persistence.query.OrderHint;
|
80 |
f197a589
|
Andreas Müller
|
import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy;
|
81 |
48dde342
|
Alexander Oppermann
|
import eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl;
|
82 |
01c21ead
|
n.hoffmann
|
|
83 |
|
|
/**
|
84 |
|
|
* @author n.hoffmann
|
85 |
a88578ce
|
Andreas Müller
|
* @since Sep 21, 2009
|
86 |
01c21ead
|
n.hoffmann
|
*/
|
87 |
|
|
@Service
|
88 |
77b4a247
|
Andreas Kohlbecker
|
@Transactional(readOnly = true)
|
89 |
4820d02b
|
Andreas Müller
|
public class ClassificationServiceImpl
|
90 |
|
|
extends IdentifiableServiceBase<Classification, IClassificationDao>
|
91 |
|
|
implements IClassificationService {
|
92 |
5f582094
|
Andreas Müller
|
|
93 |
23de68fc
|
Andreas Müller
|
private static final Logger logger = LogManager.getLogger(ClassificationServiceImpl.class);
|
94 |
1ae9f0ff
|
Andreas Kohlbecker
|
|
95 |
|
|
@Autowired
|
96 |
|
|
private ITaxonNodeDao taxonNodeDao;
|
97 |
f2889751
|
Andreas Kohlbecker
|
|
98 |
1ae9f0ff
|
Andreas Kohlbecker
|
@Autowired
|
99 |
|
|
private ITaxonDao taxonDao;
|
100 |
f2889751
|
Andreas Kohlbecker
|
|
101 |
d17b9e90
|
Andreas Müller
|
@Autowired
|
102 |
|
|
private ITaxonNodeService taxonNodeService;
|
103 |
|
|
|
104 |
4f290ba6
|
Andreas Müller
|
@Autowired
|
105 |
|
|
private IDefinedTermDao termDao;
|
106 |
|
|
|
107 |
1ae9f0ff
|
Andreas Kohlbecker
|
@Autowired
|
108 |
|
|
private IBeanInitializer defaultBeanInitializer;
|
109 |
f2889751
|
Andreas Kohlbecker
|
|
110 |
|
|
@Override
|
111 |
25461b19
|
Andreas Müller
|
@Autowired
|
112 |
|
|
protected void setDao(IClassificationDao dao) {
|
113 |
|
|
this.dao = dao;
|
114 |
|
|
}
|
115 |
f2889751
|
Andreas Kohlbecker
|
|
116 |
ddbbd267
|
Andreas Müller
|
private Comparator<TaxonNode> taxonNodeComparator;
|
117 |
f2889751
|
Andreas Kohlbecker
|
|
118 |
1ae9f0ff
|
Andreas Kohlbecker
|
@Autowired
|
119 |
ddbbd267
|
Andreas Müller
|
public void setTaxonNodeComparator(ITaxonNodeComparator<TaxonNode> taxonNodeComparator){
|
120 |
|
|
this.taxonNodeComparator = (Comparator<TaxonNode>) taxonNodeComparator;
|
121 |
1ae9f0ff
|
Andreas Kohlbecker
|
}
|
122 |
|
|
|
123 |
dba75be8
|
Andreas Kohlbecker
|
@Override
|
124 |
1ae9f0ff
|
Andreas Kohlbecker
|
public TaxonNode loadTaxonNodeByTaxon(Taxon taxon, UUID classificationUuid, List<String> propertyPaths){
|
125 |
|
|
Classification tree = dao.load(classificationUuid);
|
126 |
|
|
TaxonNode node = tree.getNode(taxon);
|
127 |
|
|
|
128 |
|
|
return loadTaxonNode(node.getUuid(), propertyPaths);
|
129 |
|
|
}
|
130 |
|
|
|
131 |
|
|
public TaxonNode loadTaxonNode(UUID taxonNodeUuid, List<String> propertyPaths){
|
132 |
|
|
return taxonNodeDao.load(taxonNodeUuid, propertyPaths);
|
133 |
|
|
}
|
134 |
|
|
|
135 |
dba75be8
|
Andreas Kohlbecker
|
@Override
|
136 |
185155f8
|
Andreas Müller
|
public List<TaxonNode> listRankSpecificRootNodes(Classification classification,
|
137 |
|
|
TaxonNode subtree, Rank rank,
|
138 |
62a08491
|
Andreas Müller
|
boolean includeUnpublished, Integer pageSize, Integer pageIndex, List<String> propertyPaths) {
|
139 |
185155f8
|
Andreas Müller
|
return pageRankSpecificRootNodes(classification, subtree, rank, includeUnpublished, pageSize, pageIndex, propertyPaths).getRecords();
|
140 |
dba75be8
|
Andreas Kohlbecker
|
}
|
141 |
|
|
|
142 |
562acef2
|
Andreas Kohlbecker
|
@Override
|
143 |
|
|
public List<TaxonNodeDto> listRankSpecificRootNodeDtos(Classification classification, TaxonNode subtree,
|
144 |
500073dd
|
Andreas Kohlbecker
|
Rank rank, boolean includeUnpublished, Integer pageSize, Integer pageIndex, TaxonNodeDtoSortMode sortMode,
|
145 |
562acef2
|
Andreas Kohlbecker
|
List<String> propertyPaths) {
|
146 |
|
|
List<TaxonNode> list = listRankSpecificRootNodes(classification, subtree, rank, includeUnpublished, pageSize, pageIndex, propertyPaths);
|
147 |
89ce56b3
|
Andreas Müller
|
return list.stream().filter(e -> e != null).map(e -> new TaxonNodeDto(e)).sorted(sortMode.comparator()).collect(Collectors.toList());
|
148 |
562acef2
|
Andreas Kohlbecker
|
}
|
149 |
|
|
|
150 |
dba75be8
|
Andreas Kohlbecker
|
@Override
|
151 |
62a08491
|
Andreas Müller
|
public Pager<TaxonNode> pageRankSpecificRootNodes(Classification classification, Rank rank,
|
152 |
|
|
boolean includeUnpublished, Integer pageSize, Integer pageIndex, List<String> propertyPaths) {
|
153 |
185155f8
|
Andreas Müller
|
return pageRankSpecificRootNodes(classification, null, rank, includeUnpublished, pageSize, pageIndex, propertyPaths);
|
154 |
|
|
}
|
155 |
|
|
|
156 |
|
|
@Override
|
157 |
|
|
public Pager<TaxonNode> pageRankSpecificRootNodes(Classification classification, TaxonNode subtree, Rank rank,
|
158 |
|
|
boolean includeUnpublished, Integer pageSize, Integer pageIndex, List<String> propertyPaths) {
|
159 |
|
|
long[] numberOfResults = dao.countRankSpecificRootNodes(classification, subtree, includeUnpublished, rank);
|
160 |
7ff16b32
|
Andreas Kohlbecker
|
long totalNumberOfResults = numberOfResults[0] + (numberOfResults.length > 1 ? numberOfResults[1] : 0);
|
161 |
dba75be8
|
Andreas Kohlbecker
|
|
162 |
62a08491
|
Andreas Müller
|
List<TaxonNode> results = new ArrayList<>();
|
163 |
dba75be8
|
Andreas Kohlbecker
|
|
164 |
7ff16b32
|
Andreas Kohlbecker
|
if (AbstractPagerImpl.hasResultsInRange(totalNumberOfResults, pageIndex, pageSize)) { // no point checking again
|
165 |
|
|
Integer limit = PagerUtils.limitFor(pageSize);
|
166 |
|
|
Integer start = PagerUtils.startFor(pageSize, pageIndex);
|
167 |
|
|
|
168 |
|
|
Integer remainingLimit = limit;
|
169 |
|
|
int[] queryIndexes = rank == null ? new int[]{0} : new int[]{0,1};
|
170 |
|
|
|
171 |
|
|
for(int queryIndex: queryIndexes) {
|
172 |
|
|
if(start != null && start > numberOfResults[queryIndex]) {
|
173 |
|
|
// start in next query with new start value
|
174 |
|
|
start = start - (int)numberOfResults[queryIndex];
|
175 |
|
|
continue;
|
176 |
|
|
}
|
177 |
|
|
|
178 |
62a08491
|
Andreas Müller
|
List<TaxonNode> perQueryResults = dao.listRankSpecificRootNodes(classification,
|
179 |
185155f8
|
Andreas Müller
|
subtree, rank, includeUnpublished, remainingLimit,
|
180 |
|
|
start, propertyPaths, queryIndex);
|
181 |
7ff16b32
|
Andreas Kohlbecker
|
results.addAll(perQueryResults);
|
182 |
|
|
if(remainingLimit != null ){
|
183 |
|
|
remainingLimit = remainingLimit - results.size();
|
184 |
|
|
if(remainingLimit <= 0) {
|
185 |
|
|
// no need to run further queries if first query returned enough items!
|
186 |
|
|
break;
|
187 |
|
|
}
|
188 |
|
|
// start at with fist item of next query to fetch the remaining items
|
189 |
|
|
start = 0;
|
190 |
|
|
}
|
191 |
|
|
}
|
192 |
dba75be8
|
Andreas Kohlbecker
|
}
|
193 |
f36a0784
|
Andreas Kohlbecker
|
// long start_t = System.currentTimeMillis();
|
194 |
256c8f84
|
Andreas Kohlbecker
|
Collections.sort(results, taxonNodeComparator); // TODO is ordering during the hibernate query in the dao possible?
|
195 |
f36a0784
|
Andreas Kohlbecker
|
// System.err.println("service.pageRankSpecificRootNodes() - Collections.sort(results, taxonNodeComparator) " + (System.currentTimeMillis() - start_t));
|
196 |
281a5d27
|
Andreas Müller
|
return new DefaultPagerImpl<>(pageIndex, totalNumberOfResults, pageSize, results);
|
197 |
dba75be8
|
Andreas Kohlbecker
|
|
198 |
|
|
}
|
199 |
|
|
|
200 |
d0df75bd
|
Andreas Müller
|
@Override
|
201 |
|
|
public List<TaxonNode> loadTreeBranch(TaxonNode taxonNode, Rank baseRank,
|
202 |
|
|
boolean includeUnpublished, List<String> propertyPaths) throws UnpublishedException{
|
203 |
|
|
return loadTreeBranch(taxonNode, null, baseRank, includeUnpublished, propertyPaths);
|
204 |
|
|
}
|
205 |
cac97126
|
Andreas Müller
|
|
206 |
dba75be8
|
Andreas Kohlbecker
|
@Override
|
207 |
d0df75bd
|
Andreas Müller
|
public List<TaxonNode> loadTreeBranch(TaxonNode taxonNode, TaxonNode subtree, Rank baseRank,
|
208 |
cac97126
|
Andreas Müller
|
boolean includeUnpublished, List<String> propertyPaths) throws UnpublishedException{
|
209 |
1ae9f0ff
|
Andreas Kohlbecker
|
|
210 |
|
|
TaxonNode thisNode = taxonNodeDao.load(taxonNode.getUuid(), propertyPaths);
|
211 |
c8363cf5
|
Andreas Kohlbecker
|
if(baseRank != null){
|
212 |
|
|
baseRank = (Rank) termDao.load(baseRank.getUuid());
|
213 |
|
|
}
|
214 |
df72b543
|
Andreas Müller
|
if (!includeUnpublished && thisNode.getTaxon() != null && !thisNode.getTaxon().isPublish()){
|
215 |
cac97126
|
Andreas Müller
|
throw new UnpublishedException("Final taxon in tree branch is unpublished.");
|
216 |
|
|
}
|
217 |
|
|
|
218 |
|
|
List<TaxonNode> pathToRoot = new ArrayList<>();
|
219 |
3f6e7646
|
Andreas Kohlbecker
|
pathToRoot.add(thisNode);
|
220 |
1ae9f0ff
|
Andreas Kohlbecker
|
|
221 |
1b880bc7
|
Andreas Kohlbecker
|
while(!thisNode.isTopmostNode()){
|
222 |
6b5ba3cc
|
Andreas Kohlbecker
|
//TODO why do we need to deproxy here?
|
223 |
d919773a
|
Andreas Kohlbecker
|
// without this thisNode.getParent() will return NULL in
|
224 |
|
|
// some cases (environment dependend?) even if the parent exits
|
225 |
cac97126
|
Andreas Müller
|
TaxonNode parentNode = CdmBase.deproxy(thisNode).getParent();
|
226 |
5b16dccb
|
Andreas Kohlbecker
|
|
227 |
|
|
if(parentNode == null){
|
228 |
cac97126
|
Andreas Müller
|
throw new NullPointerException("Taxon node " + thisNode + " must have a parent since it is not top most");
|
229 |
5b16dccb
|
Andreas Kohlbecker
|
}
|
230 |
|
|
if(parentNode.getTaxon() == null){
|
231 |
cac97126
|
Andreas Müller
|
throw new NullPointerException("The taxon associated with taxon node " + parentNode + " is NULL");
|
232 |
|
|
}
|
233 |
|
|
if(!includeUnpublished && !parentNode.getTaxon().isPublish()){
|
234 |
|
|
throw new UnpublishedException("Some taxon in tree branch is unpublished.");
|
235 |
5b16dccb
|
Andreas Kohlbecker
|
}
|
236 |
|
|
if(parentNode.getTaxon().getName() == null){
|
237 |
|
|
throw new NullPointerException("The name of the taxon associated with taxonNode " + parentNode + " is NULL");
|
238 |
|
|
}
|
239 |
|
|
|
240 |
cac97126
|
Andreas Müller
|
Rank parentNodeRank = (parentNode.getTaxon().getName() == null) ? null : parentNode.getTaxon().getName().getRank();
|
241 |
1ae9f0ff
|
Andreas Kohlbecker
|
// stop if the next parent is higher than the baseRank
|
242 |
29abeaf8
|
Andreas Müller
|
if(baseRank != null && parentNodeRank != null && baseRank.isLower(parentNodeRank)){
|
243 |
1ae9f0ff
|
Andreas Kohlbecker
|
break;
|
244 |
|
|
}
|
245 |
d0df75bd
|
Andreas Müller
|
if((subtree!= null && !subtree.isAncestor(parentNode) )){
|
246 |
|
|
break;
|
247 |
|
|
}
|
248 |
5b16dccb
|
Andreas Kohlbecker
|
|
249 |
|
|
pathToRoot.add(parentNode);
|
250 |
|
|
thisNode = parentNode;
|
251 |
1ae9f0ff
|
Andreas Kohlbecker
|
}
|
252 |
|
|
|
253 |
|
|
// initialize and invert order of nodes in list
|
254 |
|
|
defaultBeanInitializer.initializeAll(pathToRoot, propertyPaths);
|
255 |
|
|
Collections.reverse(pathToRoot);
|
256 |
|
|
|
257 |
|
|
return pathToRoot;
|
258 |
|
|
}
|
259 |
|
|
|
260 |
dba75be8
|
Andreas Kohlbecker
|
@Override
|
261 |
cac97126
|
Andreas Müller
|
public List<TaxonNode> loadTreeBranchToTaxon(Taxon taxon, Classification classification, Rank baseRank,
|
262 |
|
|
boolean includeUnpublished, List<String> propertyPaths) throws UnpublishedException{
|
263 |
d0df75bd
|
Andreas Müller
|
return loadTreeBranchToTaxon(taxon, classification, null, baseRank, includeUnpublished, propertyPaths);
|
264 |
|
|
}
|
265 |
|
|
|
266 |
562acef2
|
Andreas Kohlbecker
|
@Override
|
267 |
|
|
public List<TaxonNodeDto> loadTreeBranchDTOsToTaxon(Taxon taxon, Classification classification,
|
268 |
|
|
TaxonNode subtree, Rank baseRank,
|
269 |
|
|
boolean includeUnpublished, List<String> propertyPaths) throws UnpublishedException {
|
270 |
|
|
List<TaxonNode> list = loadTreeBranchToTaxon(taxon, classification, subtree, baseRank, includeUnpublished, propertyPaths);
|
271 |
|
|
return list.stream().map(e -> new TaxonNodeDto(e)).collect(Collectors.toList());
|
272 |
|
|
}
|
273 |
|
|
|
274 |
d0df75bd
|
Andreas Müller
|
@Override
|
275 |
619ccb21
|
Andreas Müller
|
public List<TaxonNode> loadTreeBranchToTaxon(Taxon taxon, Classification classification,
|
276 |
|
|
TaxonNode subtree, Rank baseRank,
|
277 |
d0df75bd
|
Andreas Müller
|
boolean includeUnpublished, List<String> propertyPaths) throws UnpublishedException{
|
278 |
cac97126
|
Andreas Müller
|
|
279 |
|
|
UUID nodeUuid = getTaxonNodeUuidByTaxonUuid(classification.getUuid(), taxon.getUuid());
|
280 |
|
|
TaxonNode node = taxonNodeService.find(nodeUuid);
|
281 |
1ae9f0ff
|
Andreas Kohlbecker
|
if(node == null){
|
282 |
|
|
logger.warn("The specified taxon is not found in the given tree.");
|
283 |
fd07b3aa
|
Andreas Kohlbecker
|
return new ArrayList<>(0);
|
284 |
619ccb21
|
Andreas Müller
|
}else if (subtree != null && !node.isDescendant(subtree)){
|
285 |
d0df75bd
|
Andreas Müller
|
//TODO handle as exception? E.g. FilterException, AccessDeniedException?
|
286 |
|
|
logger.warn("The specified taxon is not found for the given subtree.");
|
287 |
fd07b3aa
|
Andreas Kohlbecker
|
return new ArrayList<>(0);
|
288 |
1ae9f0ff
|
Andreas Kohlbecker
|
}
|
289 |
d0df75bd
|
Andreas Müller
|
|
290 |
|
|
return loadTreeBranch(node, subtree, baseRank, includeUnpublished, propertyPaths);
|
291 |
1ae9f0ff
|
Andreas Kohlbecker
|
}
|
292 |
|
|
|
293 |
|
|
|
294 |
dba75be8
|
Andreas Kohlbecker
|
@Override
|
295 |
1ae9f0ff
|
Andreas Kohlbecker
|
public List<TaxonNode> loadChildNodesOfTaxonNode(TaxonNode taxonNode,
|
296 |
|
|
List<String> propertyPaths) {
|
297 |
|
|
taxonNode = taxonNodeDao.load(taxonNode.getUuid());
|
298 |
|
|
List<TaxonNode> childNodes = new ArrayList<TaxonNode>(taxonNode.getChildNodes());
|
299 |
|
|
defaultBeanInitializer.initializeAll(childNodes, propertyPaths);
|
300 |
|
|
Collections.sort(childNodes, taxonNodeComparator);
|
301 |
|
|
return childNodes;
|
302 |
|
|
}
|
303 |
|
|
|
304 |
dba75be8
|
Andreas Kohlbecker
|
@Override
|
305 |
16fe90fd
|
Andreas Müller
|
public List<TaxonNode> listChildNodesOfTaxon(UUID taxonUuid, UUID classificationUuid,
|
306 |
|
|
boolean includeUnpublished, Integer pageSize, Integer pageIndex, List<String> propertyPaths){
|
307 |
1251ffed
|
Andreas Müller
|
try {
|
308 |
|
|
return listChildNodesOfTaxon(taxonUuid, classificationUuid, null, includeUnpublished, pageSize, pageIndex, propertyPaths);
|
309 |
|
|
} catch (FilterException e) {
|
310 |
|
|
throw new RuntimeException(e); //this should not happen as filter is null
|
311 |
|
|
}
|
312 |
d0df75bd
|
Andreas Müller
|
}
|
313 |
|
|
|
314 |
|
|
@Override
|
315 |
|
|
public List<TaxonNode> listChildNodesOfTaxon(UUID taxonUuid, UUID classificationUuid, UUID subtreeUuid,
|
316 |
1251ffed
|
Andreas Müller
|
boolean includeUnpublished, Integer pageSize, Integer pageIndex, List<String> propertyPaths) throws FilterException{
|
317 |
f989e265
|
Andreas Kohlbecker
|
|
318 |
ba84f3fd
|
Andreas Kohlbecker
|
Classification classification = dao.load(classificationUuid);
|
319 |
|
|
Taxon taxon = (Taxon) taxonDao.load(taxonUuid);
|
320 |
1251ffed
|
Andreas Müller
|
TaxonNode subtree = taxonNodeDao.load(subtreeUuid);
|
321 |
|
|
if (subtreeUuid != null && subtree == null){
|
322 |
|
|
throw new FilterException("Taxon node for subtree filter can not be found in database", true);
|
323 |
|
|
}
|
324 |
1ae9f0ff
|
Andreas Kohlbecker
|
|
325 |
16fe90fd
|
Andreas Müller
|
List<TaxonNode> results = dao.listChildrenOf(
|
326 |
1251ffed
|
Andreas Müller
|
taxon, classification, subtree, includeUnpublished, pageSize, pageIndex, propertyPaths);
|
327 |
911a8140
|
Alexander Oppermann
|
Collections.sort(results, taxonNodeComparator); // FIXME this is only a HACK, order during the hibernate query in the dao
|
328 |
|
|
return results;
|
329 |
1ae9f0ff
|
Andreas Kohlbecker
|
}
|
330 |
|
|
|
331 |
562acef2
|
Andreas Kohlbecker
|
@Override
|
332 |
|
|
public List<TaxonNodeDto> listChildNodeDtosOfTaxon(UUID taxonUuid, UUID classificationUuid, UUID subtreeUuid, boolean includeUnpublished,
|
333 |
500073dd
|
Andreas Kohlbecker
|
Integer pageSize, Integer pageIndex, TaxonNodeDtoSortMode sortMode, List<String> propertyPaths) throws FilterException{
|
334 |
562acef2
|
Andreas Kohlbecker
|
Classification classification = dao.load(classificationUuid);
|
335 |
|
|
Taxon taxon = (Taxon) taxonDao.load(taxonUuid);
|
336 |
|
|
TaxonNode subtree = taxonNodeDao.load(subtreeUuid);
|
337 |
|
|
if (subtreeUuid != null && subtree == null){
|
338 |
|
|
throw new FilterException("Taxon node for subtree filter can not be found in database", true);
|
339 |
|
|
}
|
340 |
|
|
|
341 |
|
|
List<TaxonNode> results = dao.listChildrenOf(
|
342 |
|
|
taxon, classification, subtree, includeUnpublished, pageSize, pageIndex, propertyPaths);
|
343 |
89ce56b3
|
Andreas Müller
|
Comparator<TaxonNodeDto> comparator = sortMode.comparator();
|
344 |
562acef2
|
Andreas Kohlbecker
|
// TODO order during the hibernate query in the dao?
|
345 |
|
|
List<TaxonNodeDto> dtos = results.stream().map(e -> new TaxonNodeDto(e)).sorted(comparator).collect(Collectors.toList());
|
346 |
|
|
return dtos;
|
347 |
|
|
}
|
348 |
|
|
|
349 |
183973c8
|
Andreas Kohlbecker
|
@Override
|
350 |
e073fc85
|
Andreas Müller
|
public Pager<TaxonNode> pageSiblingsOfTaxon(UUID taxonUuid, UUID classificationUuid, boolean includeUnpublished,
|
351 |
|
|
Integer pageSize, Integer pageIndex, List<String> propertyPaths){
|
352 |
183973c8
|
Andreas Kohlbecker
|
|
353 |
|
|
Classification classification = dao.load(classificationUuid);
|
354 |
|
|
Taxon taxon = (Taxon) taxonDao.load(taxonUuid);
|
355 |
|
|
|
356 |
e073fc85
|
Andreas Müller
|
long numberOfResults = dao.countSiblingsOf(taxon, classification, includeUnpublished);
|
357 |
183973c8
|
Andreas Kohlbecker
|
|
358 |
|
|
List<TaxonNode> results;
|
359 |
|
|
if(PagerUtils.hasResultsInRange(numberOfResults, pageIndex, pageSize)) {
|
360 |
e073fc85
|
Andreas Müller
|
results = dao.listSiblingsOf(taxon, classification, includeUnpublished, pageSize, pageIndex, propertyPaths);
|
361 |
183973c8
|
Andreas Kohlbecker
|
Collections.sort(results, taxonNodeComparator); // FIXME this is only a HACK, order during the hibernate query in the dao
|
362 |
|
|
} else {
|
363 |
|
|
results = new ArrayList<>();
|
364 |
|
|
}
|
365 |
|
|
|
366 |
281a5d27
|
Andreas Müller
|
return new DefaultPagerImpl<>(pageIndex, numberOfResults, pageSize, results);
|
367 |
183973c8
|
Andreas Kohlbecker
|
}
|
368 |
|
|
|
369 |
|
|
@Override
|
370 |
e073fc85
|
Andreas Müller
|
public List<TaxonNode> listSiblingsOfTaxon(UUID taxonUuid, UUID classificationUuid, boolean includeUnpublished,
|
371 |
|
|
Integer pageSize, Integer pageIndex, List<String> propertyPaths){
|
372 |
183973c8
|
Andreas Kohlbecker
|
|
373 |
e073fc85
|
Andreas Müller
|
Pager<TaxonNode> pager = pageSiblingsOfTaxon(taxonUuid, classificationUuid, includeUnpublished, pageSize, pageIndex, propertyPaths);
|
374 |
183973c8
|
Andreas Kohlbecker
|
return pager.getRecords();
|
375 |
|
|
}
|
376 |
|
|
|
377 |
dba75be8
|
Andreas Kohlbecker
|
@Override
|
378 |
f6c2e10f
|
Andreas Müller
|
public ITaxonTreeNode getTreeNodeByUuid(UUID uuid){
|
379 |
|
|
ITaxonTreeNode treeNode = taxonNodeDao.findByUuid(uuid);
|
380 |
1ae9f0ff
|
Andreas Kohlbecker
|
if(treeNode == null){
|
381 |
|
|
treeNode = dao.findByUuid(uuid);
|
382 |
|
|
}
|
383 |
|
|
|
384 |
|
|
return treeNode;
|
385 |
|
|
}
|
386 |
|
|
|
387 |
580b83e6
|
Patrick Plitzner
|
@Override
|
388 |
|
|
public TaxonNode getRootNode(UUID classificationUuid){
|
389 |
|
|
return dao.getRootNode(classificationUuid);
|
390 |
|
|
}
|
391 |
|
|
|
392 |
dba75be8
|
Andreas Kohlbecker
|
@Override
|
393 |
1ae9f0ff
|
Andreas Kohlbecker
|
public List<Classification> listClassifications(Integer limit, Integer start, List<OrderHint> orderHints, List<String> propertyPaths) {
|
394 |
|
|
return dao.list(limit, start, orderHints, propertyPaths);
|
395 |
|
|
}
|
396 |
|
|
|
397 |
dba75be8
|
Andreas Kohlbecker
|
@Override
|
398 |
f6c2e10f
|
Andreas Müller
|
public UUID removeTreeNode(ITaxonTreeNode treeNode) {
|
399 |
1ae9f0ff
|
Andreas Kohlbecker
|
if(treeNode instanceof Classification){
|
400 |
|
|
return dao.delete((Classification) treeNode);
|
401 |
|
|
}else if(treeNode instanceof TaxonNode){
|
402 |
|
|
return taxonNodeDao.delete((TaxonNode)treeNode);
|
403 |
|
|
}
|
404 |
|
|
return null;
|
405 |
|
|
}
|
406 |
|
|
|
407 |
dba75be8
|
Andreas Kohlbecker
|
@Override
|
408 |
1ae9f0ff
|
Andreas Kohlbecker
|
public Map<UUID, TaxonNode> saveTaxonNodeAll(
|
409 |
|
|
Collection<TaxonNode> taxonNodeCollection) {
|
410 |
|
|
return taxonNodeDao.saveAll(taxonNodeCollection);
|
411 |
|
|
}
|
412 |
|
|
|
413 |
08a698af
|
Katja Luther
|
@Override
|
414 |
|
|
public UUID saveClassification(Classification classification) {
|
415 |
|
|
|
416 |
|
|
taxonNodeDao.saveOrUpdateAll(classification.getAllNodes());
|
417 |
|
|
UUID result =dao.saveOrUpdate(classification);
|
418 |
|
|
return result;
|
419 |
|
|
}
|
420 |
|
|
|
421 |
dba75be8
|
Andreas Kohlbecker
|
@Override
|
422 |
f6c2e10f
|
Andreas Müller
|
public UUID saveTreeNode(ITaxonTreeNode treeNode) {
|
423 |
1ae9f0ff
|
Andreas Kohlbecker
|
if(treeNode instanceof Classification){
|
424 |
26b857a9
|
Cherian Mathew
|
return dao.save((Classification) treeNode).getUuid();
|
425 |
1ae9f0ff
|
Andreas Kohlbecker
|
}else if(treeNode instanceof TaxonNode){
|
426 |
26b857a9
|
Cherian Mathew
|
return taxonNodeDao.save((TaxonNode)treeNode).getUuid();
|
427 |
1ae9f0ff
|
Andreas Kohlbecker
|
}
|
428 |
|
|
return null;
|
429 |
|
|
}
|
430 |
|
|
|
431 |
dba75be8
|
Andreas Kohlbecker
|
@Override
|
432 |
1ae9f0ff
|
Andreas Kohlbecker
|
public List<TaxonNode> getAllNodes(){
|
433 |
|
|
return taxonNodeDao.list(null,null);
|
434 |
|
|
}
|
435 |
|
|
|
436 |
001595b1
|
Katja Luther
|
@Override
|
437 |
1364ddca
|
Katja Luther
|
public List<UuidAndTitleCache<TaxonNode>> getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByClassification(UUID classificationUuid, Integer limit, String pattern, boolean searchForClassifications, boolean includeDoubtful) {
|
438 |
|
|
return taxonNodeDao.getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByClassification(dao.load(classificationUuid), limit, pattern, searchForClassifications, includeDoubtful);
|
439 |
001595b1
|
Katja Luther
|
}
|
440 |
|
|
|
441 |
|
|
@Override
|
442 |
8e9115f6
|
Katja Luther
|
public List<UuidAndTitleCache<TaxonNode>> getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByClassification(Classification classification, Integer limit, String pattern, boolean searchForClassifications) {
|
443 |
|
|
return taxonNodeDao.getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByClassification(classification, limit, pattern, searchForClassifications);
|
444 |
001595b1
|
Katja Luther
|
}
|
445 |
|
|
|
446 |
818208b8
|
Cherian Mathew
|
@Override
|
447 |
8e9115f6
|
Katja Luther
|
public List<UuidAndTitleCache<TaxonNode>> getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByClassification(UUID classificationUuid, boolean searchForClassifications ) {
|
448 |
|
|
return taxonNodeDao.getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByClassification(dao.load(classificationUuid), null, null, searchForClassifications);
|
449 |
818208b8
|
Cherian Mathew
|
}
|
450 |
|
|
|
451 |
dba75be8
|
Andreas Kohlbecker
|
@Override
|
452 |
8e9115f6
|
Katja Luther
|
public List<UuidAndTitleCache<TaxonNode>> getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByClassification(Classification classification, boolean searchForClassifications ) {
|
453 |
|
|
return taxonNodeDao.getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByClassification(classification, null, null, searchForClassifications);
|
454 |
1ae9f0ff
|
Andreas Kohlbecker
|
}
|
455 |
|
|
|
456 |
|
|
@Override
|
457 |
001595b1
|
Katja Luther
|
public List<UuidAndTitleCache<Classification>> getUuidAndTitleCache(Integer limit, String pattern) {
|
458 |
|
|
return dao.getUuidAndTitleCache(limit, pattern);
|
459 |
1ae9f0ff
|
Andreas Kohlbecker
|
}
|
460 |
|
|
|
461 |
dba75be8
|
Andreas Kohlbecker
|
@Override
|
462 |
1ae9f0ff
|
Andreas Kohlbecker
|
public Map<UUID, List<MediaRepresentation>> getAllMediaForChildNodes(
|
463 |
|
|
TaxonNode taxonNode, List<String> propertyPaths, int size,
|
464 |
|
|
int height, int widthOrDuration, String[] mimeTypes) {
|
465 |
|
|
|
466 |
8c6a7c50
|
Andreas Müller
|
TreeMap<UUID, List<MediaRepresentation>> result = new TreeMap<>();
|
467 |
|
|
List<MediaRepresentation> mediaRepresentations = new ArrayList<>();
|
468 |
1ae9f0ff
|
Andreas Kohlbecker
|
|
469 |
|
|
//add all media of the children to the result map
|
470 |
|
|
if (taxonNode != null){
|
471 |
|
|
|
472 |
8c6a7c50
|
Andreas Müller
|
List<TaxonNode> nodes = new ArrayList<>();
|
473 |
1ae9f0ff
|
Andreas Kohlbecker
|
|
474 |
8c6a7c50
|
Andreas Müller
|
nodes.add(loadTaxonNode(taxonNode.getUuid(), propertyPaths));
|
475 |
1ae9f0ff
|
Andreas Kohlbecker
|
nodes.addAll(loadChildNodesOfTaxonNode(taxonNode, propertyPaths));
|
476 |
|
|
|
477 |
8c6a7c50
|
Andreas Müller
|
for(TaxonNode node : nodes){
|
478 |
|
|
Taxon taxon = node.getTaxon();
|
479 |
|
|
for (TaxonDescription taxonDescription: taxon.getDescriptions()){
|
480 |
|
|
for (DescriptionElementBase descriptionElement: taxonDescription.getElements()){
|
481 |
|
|
for(Media media : descriptionElement.getMedia()){
|
482 |
|
|
//find the best matching representation
|
483 |
eaeba65c
|
Andreas Kohlbecker
|
mediaRepresentations.add(MediaUtils.findBestMatchingRepresentation(media,null, size, height, widthOrDuration, mimeTypes, MediaUtils.MissingValueStrategy.MAX));
|
484 |
1ae9f0ff
|
Andreas Kohlbecker
|
}
|
485 |
|
|
}
|
486 |
|
|
}
|
487 |
8c6a7c50
|
Andreas Müller
|
result.put(taxon.getUuid(), mediaRepresentations);
|
488 |
1ae9f0ff
|
Andreas Kohlbecker
|
}
|
489 |
|
|
}
|
490 |
|
|
|
491 |
|
|
return result;
|
492 |
|
|
}
|
493 |
|
|
|
494 |
|
|
@Override
|
495 |
|
|
@Transactional(readOnly = false)
|
496 |
112ab4f7
|
Katja Luther
|
public UpdateResult updateCaches(Class<? extends Classification> clazz, Integer stepSize, IIdentifiableEntityCacheStrategy<Classification> cacheStrategy, IProgressMonitor monitor) {
|
497 |
1ae9f0ff
|
Andreas Kohlbecker
|
if (clazz == null){
|
498 |
|
|
clazz = Classification.class;
|
499 |
|
|
}
|
500 |
112ab4f7
|
Katja Luther
|
return super.updateCachesImpl(clazz, stepSize, cacheStrategy, monitor);
|
501 |
1ae9f0ff
|
Andreas Kohlbecker
|
}
|
502 |
f197a589
|
Andreas Müller
|
|
503 |
48dde342
|
Alexander Oppermann
|
/**
|
504 |
dadec8d0
|
Alexander Oppermann
|
*
|
505 |
48dde342
|
Alexander Oppermann
|
* @param allNodesOfClassification
|
506 |
|
|
* @return null - if allNodesOfClassification is empty <br>
|
507 |
|
|
*/
|
508 |
dadec8d0
|
Alexander Oppermann
|
|
509 |
48dde342
|
Alexander Oppermann
|
private Map<String, List<TaxonNode>> getSortedGenusList(Collection<TaxonNode> allNodesOfClassification){
|
510 |
dadec8d0
|
Alexander Oppermann
|
|
511 |
48dde342
|
Alexander Oppermann
|
if(allNodesOfClassification == null || allNodesOfClassification.isEmpty()){
|
512 |
|
|
return null;
|
513 |
|
|
}
|
514 |
a4c9dfc9
|
Andreas Müller
|
Map<String, List<TaxonNode>> sortedGenusMap = new HashMap<>();
|
515 |
48dde342
|
Alexander Oppermann
|
for(TaxonNode node:allNodesOfClassification){
|
516 |
|
|
Taxon taxon = node.getTaxon();
|
517 |
3d58795e
|
Andreas Müller
|
INonViralName name = taxon.getName();
|
518 |
48dde342
|
Alexander Oppermann
|
String genusOrUninomial = name.getGenusOrUninomial();
|
519 |
|
|
//if rank unknown split string and take first word
|
520 |
|
|
if(genusOrUninomial == null){
|
521 |
|
|
String titleCache = taxon.getTitleCache();
|
522 |
|
|
String[] split = titleCache.split("\\s+");
|
523 |
|
|
for(String s:split){
|
524 |
|
|
genusOrUninomial = s;
|
525 |
|
|
break;
|
526 |
|
|
}
|
527 |
|
|
}
|
528 |
|
|
//if node has children
|
529 |
dadec8d0
|
Alexander Oppermann
|
|
530 |
48dde342
|
Alexander Oppermann
|
//retrieve list from map if not create List
|
531 |
|
|
if(sortedGenusMap.containsKey(genusOrUninomial)){
|
532 |
|
|
List<TaxonNode> list = sortedGenusMap.get(genusOrUninomial);
|
533 |
|
|
list.add(node);
|
534 |
|
|
sortedGenusMap.put(genusOrUninomial, list);
|
535 |
|
|
}else{
|
536 |
|
|
//create List for genus
|
537 |
8c6a7c50
|
Andreas Müller
|
List<TaxonNode> list = new ArrayList<>();
|
538 |
48dde342
|
Alexander Oppermann
|
list.add(node);
|
539 |
|
|
sortedGenusMap.put(genusOrUninomial, list);
|
540 |
|
|
}
|
541 |
|
|
}
|
542 |
|
|
return sortedGenusMap;
|
543 |
|
|
}
|
544 |
f197a589
|
Andreas Müller
|
|
545 |
48dde342
|
Alexander Oppermann
|
/**
|
546 |
dadec8d0
|
Alexander Oppermann
|
*
|
547 |
48dde342
|
Alexander Oppermann
|
* creates new Classification and parent TaxonNodes at genus level
|
548 |
dadec8d0
|
Alexander Oppermann
|
*
|
549 |
|
|
*
|
550 |
48dde342
|
Alexander Oppermann
|
* @param map GenusMap which holds a name (Genus) and all the same Taxa as a list
|
551 |
|
|
* @param classification you want to improve the hierarchy (will not be modified)
|
552 |
dadec8d0
|
Alexander Oppermann
|
* @param configurator to change certain settings, if null then standard settings will be taken
|
553 |
|
|
* @return new classification with parentNodes for each entry in the map
|
554 |
48dde342
|
Alexander Oppermann
|
*/
|
555 |
75f222cf
|
Andreas Müller
|
@SuppressWarnings({ "unchecked" })
|
556 |
48dde342
|
Alexander Oppermann
|
@Transactional(readOnly = false)
|
557 |
|
|
@Override
|
558 |
dadec8d0
|
Alexander Oppermann
|
public UpdateResult createHierarchyInClassification(Classification classification, CreateHierarchyForClassificationConfigurator configurator){
|
559 |
ddbbd267
|
Andreas Müller
|
|
560 |
dadec8d0
|
Alexander Oppermann
|
UpdateResult result = new UpdateResult();
|
561 |
fd734dc9
|
Andreas Müller
|
Set<TaxonNode> taxonNodesToSave = new HashSet<>();
|
562 |
|
|
|
563 |
48dde342
|
Alexander Oppermann
|
classification = dao.findByUuid(classification.getUuid());
|
564 |
|
|
Map<String, List<TaxonNode>> map = getSortedGenusList(classification.getAllNodes());
|
565 |
dadec8d0
|
Alexander Oppermann
|
|
566 |
48dde342
|
Alexander Oppermann
|
final String APPENDIX = "repaired";
|
567 |
75f222cf
|
Andreas Müller
|
String titleCache = StringUtils.isBlank(classification.getTitleCache()) ? " " : classification.getTitleCache() ;
|
568 |
48dde342
|
Alexander Oppermann
|
//TODO classification clone???
|
569 |
|
|
Classification newClassification = Classification.NewInstance(titleCache +" "+ APPENDIX);
|
570 |
|
|
newClassification.setReference(classification.getReference());
|
571 |
|
|
|
572 |
|
|
for(Map.Entry<String, List<TaxonNode>> entry:map.entrySet()){
|
573 |
|
|
String genus = entry.getKey();
|
574 |
|
|
List<TaxonNode> listOfTaxonNodes = entry.getValue();
|
575 |
|
|
TaxonNode parentNode = null;
|
576 |
dadec8d0
|
Alexander Oppermann
|
//Search for genus in list
|
577 |
48dde342
|
Alexander Oppermann
|
for(TaxonNode tNode:listOfTaxonNodes){
|
578 |
|
|
//take that taxonNode as parent and remove from list with all it possible children
|
579 |
|
|
//FIXME NPE for name
|
580 |
9dc896c9
|
Andreas Müller
|
TaxonName name = tNode.getTaxon().getName();
|
581 |
a4c9dfc9
|
Andreas Müller
|
if(name.getNameCache().equalsIgnoreCase(genus)){
|
582 |
e1397e51
|
Andreas Müller
|
TaxonNode clone = tNode.clone();
|
583 |
48dde342
|
Alexander Oppermann
|
if(!tNode.hasChildNodes()){
|
584 |
dadec8d0
|
Alexander Oppermann
|
//FIXME remove classification
|
585 |
48dde342
|
Alexander Oppermann
|
// parentNode = newClassification.addChildNode(clone, 0, classification.getCitation(), classification.getMicroReference());
|
586 |
|
|
parentNode = newClassification.addChildNode(clone, 0, clone.getReference(), clone.getMicroReference());
|
587 |
|
|
//remove taxonNode from list because just added to classification
|
588 |
dadec8d0
|
Alexander Oppermann
|
result.addUpdatedObject(tNode);
|
589 |
48dde342
|
Alexander Oppermann
|
listOfTaxonNodes.remove(tNode);
|
590 |
|
|
}else{
|
591 |
dadec8d0
|
Alexander Oppermann
|
//get all childNodes
|
592 |
48dde342
|
Alexander Oppermann
|
//save prior Hierarchy and remove them from the list
|
593 |
dadec8d0
|
Alexander Oppermann
|
List<TaxonNode> copyAllChildrenToTaxonNode = copyAllChildrenToTaxonNode(tNode, clone, result);
|
594 |
ddbbd267
|
Andreas Müller
|
// //FIXME remove classification
|
595 |
48dde342
|
Alexander Oppermann
|
parentNode = newClassification.addChildNode(clone, 0, clone.getReference(), clone.getMicroReference());
|
596 |
|
|
//remove taxonNode from list because just added to classification
|
597 |
dadec8d0
|
Alexander Oppermann
|
result.addUpdatedObject(tNode);
|
598 |
48dde342
|
Alexander Oppermann
|
listOfTaxonNodes.remove(tNode);
|
599 |
|
|
if(copyAllChildrenToTaxonNode != null){
|
600 |
|
|
listOfTaxonNodes = (List<TaxonNode>) CollectionUtils.removeAll(listOfTaxonNodes, copyAllChildrenToTaxonNode);
|
601 |
|
|
}
|
602 |
|
|
}
|
603 |
|
|
break;
|
604 |
|
|
}
|
605 |
|
|
}
|
606 |
|
|
if(parentNode == null){
|
607 |
|
|
//if no match found in list, create parentNode
|
608 |
|
|
NonViralNameParserImpl parser = NonViralNameParserImpl.NewInstance();
|
609 |
db183545
|
Andreas Müller
|
TaxonName TaxonName = (TaxonName)parser.parseFullName(genus);
|
610 |
48dde342
|
Alexander Oppermann
|
//TODO Sec via configurator
|
611 |
9dc896c9
|
Andreas Müller
|
Taxon taxon = Taxon.NewInstance(TaxonName, null);
|
612 |
48dde342
|
Alexander Oppermann
|
parentNode = newClassification.addChildTaxon(taxon, 0, null, null);
|
613 |
dadec8d0
|
Alexander Oppermann
|
result.addUpdatedObject(parentNode);
|
614 |
48dde342
|
Alexander Oppermann
|
}
|
615 |
fd734dc9
|
Andreas Müller
|
taxonNodesToSave.add(parentNode);
|
616 |
|
|
|
617 |
|
|
//iterate over the remaining list
|
618 |
48dde342
|
Alexander Oppermann
|
for(TaxonNode tn : listOfTaxonNodes){
|
619 |
dadec8d0
|
Alexander Oppermann
|
//if TaxonNode has a parent and this is not the classification then skip it
|
620 |
48dde342
|
Alexander Oppermann
|
//and add to new classification via the parentNode as children of it
|
621 |
|
|
//this should assures to keep the already existing hierarchy
|
622 |
|
|
//FIXME: Assert is not rootnode --> entrypoint is not classification in future but rather rootNode
|
623 |
dadec8d0
|
Alexander Oppermann
|
|
624 |
48dde342
|
Alexander Oppermann
|
if(!tn.isTopmostNode()){
|
625 |
|
|
continue; //skip to next taxonNode
|
626 |
|
|
}
|
627 |
dadec8d0
|
Alexander Oppermann
|
|
628 |
e1397e51
|
Andreas Müller
|
TaxonNode clone = tn.clone();
|
629 |
48dde342
|
Alexander Oppermann
|
//FIXME: citation from node
|
630 |
ddbbd267
|
Andreas Müller
|
//TODO: addChildNode without citation and references
|
631 |
48dde342
|
Alexander Oppermann
|
TaxonNode taxonNode = parentNode.addChildNode(clone, clone.getReference(), clone.getMicroReference());
|
632 |
fd734dc9
|
Andreas Müller
|
taxonNodesToSave.add(taxonNode);
|
633 |
|
|
|
634 |
550710d2
|
Alexander Oppermann
|
result.addUnChangedObject(clone);
|
635 |
48dde342
|
Alexander Oppermann
|
if(tn.hasChildNodes()){
|
636 |
|
|
//save hierarchy in new classification
|
637 |
dadec8d0
|
Alexander Oppermann
|
List<TaxonNode> copyAllChildrenToTaxonNode = copyAllChildrenToTaxonNode(tn, taxonNode, result);
|
638 |
48dde342
|
Alexander Oppermann
|
if(copyAllChildrenToTaxonNode != null){
|
639 |
|
|
listOfTaxonNodes = (List<TaxonNode>) CollectionUtils.removeAll(listOfTaxonNodes, copyAllChildrenToTaxonNode);
|
640 |
|
|
}
|
641 |
|
|
}
|
642 |
|
|
}
|
643 |
|
|
}
|
644 |
|
|
dao.saveOrUpdate(newClassification);
|
645 |
fd734dc9
|
Andreas Müller
|
taxonNodeDao.saveOrUpdateAll(taxonNodesToSave);
|
646 |
dadec8d0
|
Alexander Oppermann
|
result.setCdmEntity(newClassification);
|
647 |
|
|
return result;
|
648 |
48dde342
|
Alexander Oppermann
|
}
|
649 |
|
|
|
650 |
|
|
/**
|
651 |
dadec8d0
|
Alexander Oppermann
|
*
|
652 |
48dde342
|
Alexander Oppermann
|
* recursive method to get all childnodes of taxonNode in classification.
|
653 |
dadec8d0
|
Alexander Oppermann
|
*
|
654 |
48dde342
|
Alexander Oppermann
|
* @param classification just for References and Citation, can be null
|
655 |
|
|
* @param copyFromNode TaxonNode with Children
|
656 |
|
|
* @param copyToNode TaxonNode which will receive the children
|
657 |
dadec8d0
|
Alexander Oppermann
|
* @return List of ChildNode which has been added. If node has no children returns null
|
658 |
48dde342
|
Alexander Oppermann
|
*/
|
659 |
dadec8d0
|
Alexander Oppermann
|
private List<TaxonNode> copyAllChildrenToTaxonNode(TaxonNode copyFromNode, TaxonNode copyToNode, UpdateResult result) {
|
660 |
48dde342
|
Alexander Oppermann
|
List<TaxonNode> childNodes;
|
661 |
|
|
if(!copyFromNode.hasChildNodes()){
|
662 |
|
|
return null;
|
663 |
|
|
}else{
|
664 |
|
|
childNodes = copyFromNode.getChildNodes();
|
665 |
|
|
}
|
666 |
|
|
for(TaxonNode childNode:childNodes){
|
667 |
e1397e51
|
Andreas Müller
|
TaxonNode clone = childNode.clone();
|
668 |
dadec8d0
|
Alexander Oppermann
|
result.addUnChangedObject(clone);
|
669 |
48dde342
|
Alexander Oppermann
|
if(childNode.hasChildNodes()){
|
670 |
dadec8d0
|
Alexander Oppermann
|
copyAllChildrenToTaxonNode(childNode, clone, result);
|
671 |
48dde342
|
Alexander Oppermann
|
}
|
672 |
|
|
//FIXME: citation from node instead of classification
|
673 |
|
|
// copyToNode.addChildNode(clone,classification.getCitation(), classification.getMicroReference());
|
674 |
|
|
copyToNode.addChildNode(clone, clone.getReference(), clone.getMicroReference());
|
675 |
|
|
}
|
676 |
|
|
return childNodes;
|
677 |
|
|
}
|
678 |
dadec8d0
|
Alexander Oppermann
|
|
679 |
2b92f449
|
Andreas Kohlbecker
|
@Override
|
680 |
357386e4
|
Andreas Müller
|
public ClassificationLookupDTO classificationLookup(Classification classification) {
|
681 |
|
|
return dao.classificationLookup(classification);
|
682 |
|
|
}
|
683 |
2b92f449
|
Andreas Kohlbecker
|
|
684 |
357386e4
|
Andreas Müller
|
@Override
|
685 |
b3efd136
|
Katja Luther
|
@Transactional
|
686 |
969dbe3e
|
Katja Luther
|
public DeleteResult delete(UUID classificationUuid, TaxonDeletionConfigurator config){
|
687 |
|
|
DeleteResult result = new DeleteResult();
|
688 |
|
|
Classification classification = dao.findByUuid(classificationUuid);
|
689 |
|
|
if (classification == null){
|
690 |
|
|
result.addException(new IllegalArgumentException("The classification does not exist in database."));
|
691 |
|
|
result.setAbort();
|
692 |
|
|
return result;
|
693 |
|
|
}
|
694 |
|
|
if (!classification.hasChildNodes()){
|
695 |
|
|
dao.delete(classification);
|
696 |
815a9015
|
Katja Luther
|
result.addDeletedObject(classification);
|
697 |
b3efd136
|
Katja Luther
|
return result;
|
698 |
969dbe3e
|
Katja Luther
|
}
|
699 |
b3efd136
|
Katja Luther
|
if (config.getTaxonNodeConfig().getChildHandling().equals(ChildHandling.DELETE)){
|
700 |
d8866c51
|
Katja Luther
|
// TaxonNode root = classification.getRootNode();
|
701 |
|
|
// result.includeResult(taxonNodeService.deleteTaxonNode(HibernateProxyHelper.deproxy(root), config));
|
702 |
|
|
// result.addDeletedObject(classification);
|
703 |
969dbe3e
|
Katja Luther
|
dao.delete(classification);
|
704 |
815a9015
|
Katja Luther
|
result.addDeletedObject(classification);
|
705 |
d8866c51
|
Katja Luther
|
return result;
|
706 |
969dbe3e
|
Katja Luther
|
}
|
707 |
|
|
|
708 |
|
|
|
709 |
|
|
return result;
|
710 |
|
|
}
|
711 |
|
|
|
712 |
63f513d9
|
Andreas Müller
|
@Override
|
713 |
|
|
public List<GroupedTaxonDTO> groupTaxaByHigherTaxon(List<UUID> originalTaxonUuids, UUID classificationUuid, Rank minRank, Rank maxRank){
|
714 |
|
|
List<GroupedTaxonDTO> result = new ArrayList<>();
|
715 |
|
|
|
716 |
|
|
//get treeindex for each taxonUUID
|
717 |
e3fc5af3
|
Andreas Müller
|
Map<UUID, TreeIndex> taxonIdTreeIndexMap = dao.treeIndexForTaxonUuids(classificationUuid, originalTaxonUuids);
|
718 |
63f513d9
|
Andreas Müller
|
|
719 |
a8609cad
|
Andreas Müller
|
//build treeindex list (or tree)
|
720 |
e3fc5af3
|
Andreas Müller
|
//TODO make it work with TreeIndex or move there
|
721 |
|
|
List<String> treeIndexClosureStr = new ArrayList<>();
|
722 |
|
|
for (TreeIndex treeIndex : taxonIdTreeIndexMap.values()){
|
723 |
|
|
String[] splits = treeIndex.toString().substring(1).split(ITreeNode.separator);
|
724 |
63f513d9
|
Andreas Müller
|
String currentIndex = ITreeNode.separator;
|
725 |
|
|
for (String split : splits){
|
726 |
|
|
if (split.equals("")){
|
727 |
|
|
continue;
|
728 |
|
|
}
|
729 |
|
|
currentIndex += split + ITreeNode.separator;
|
730 |
e3fc5af3
|
Andreas Müller
|
if (!treeIndexClosureStr.contains(currentIndex) && !split.startsWith(ITreeNode.treePrefix)){
|
731 |
|
|
treeIndexClosureStr.add(currentIndex);
|
732 |
63f513d9
|
Andreas Müller
|
}
|
733 |
|
|
}
|
734 |
|
|
}
|
735 |
|
|
|
736 |
|
|
//get rank sortindex for all parent taxa with sortindex <= minRank and sortIndex >= maxRank (if available)
|
737 |
29a5f57c
|
Andreas Müller
|
Integer minRankOrderIndex = minRank == null ? null : minRank.getOrderIndex();
|
738 |
|
|
Integer maxRankOrderIndex = maxRank == null ? null : maxRank.getOrderIndex();
|
739 |
e3fc5af3
|
Andreas Müller
|
List<TreeIndex> treeIndexClosure = TreeIndex.NewListInstance(treeIndexClosureStr);
|
740 |
|
|
|
741 |
|
|
Map<TreeIndex, Integer> treeIndexSortIndexMapTmp = taxonNodeDao.rankOrderIndexForTreeIndex(treeIndexClosure, minRankOrderIndex, maxRankOrderIndex);
|
742 |
63f513d9
|
Andreas Müller
|
|
743 |
|
|
//remove all treeindex with "exists child in above map(and child.sortindex > xxx)
|
744 |
e3fc5af3
|
Andreas Müller
|
List<TreeIndex> treeIndexList = TreeIndex.sort(treeIndexSortIndexMapTmp.keySet());
|
745 |
|
|
|
746 |
|
|
Map<TreeIndex, Integer> treeIndexSortIndexMap = new HashMap<>();
|
747 |
|
|
TreeIndex lastTreeIndex = null;
|
748 |
|
|
for (TreeIndex treeIndex : treeIndexList){
|
749 |
|
|
if (lastTreeIndex != null && lastTreeIndex.hasChild(treeIndex)){
|
750 |
63f513d9
|
Andreas Müller
|
treeIndexSortIndexMap.remove(lastTreeIndex);
|
751 |
|
|
}
|
752 |
|
|
treeIndexSortIndexMap.put(treeIndex, treeIndexSortIndexMapTmp.get(treeIndex));
|
753 |
|
|
lastTreeIndex = treeIndex;
|
754 |
|
|
}
|
755 |
|
|
|
756 |
|
|
//get taxonID for treeIndexes
|
757 |
e3fc5af3
|
Andreas Müller
|
Map<TreeIndex, UuidAndTitleCache<?>> treeIndexTaxonIdMap = taxonNodeDao.taxonUuidsForTreeIndexes(treeIndexSortIndexMap.keySet());
|
758 |
63f513d9
|
Andreas Müller
|
|
759 |
|
|
//fill result list
|
760 |
|
|
for (UUID originalTaxonUuid : originalTaxonUuids){
|
761 |
|
|
GroupedTaxonDTO item = new GroupedTaxonDTO();
|
762 |
|
|
result.add(item);
|
763 |
|
|
item.setTaxonUuid(originalTaxonUuid);
|
764 |
e3fc5af3
|
Andreas Müller
|
TreeIndex groupTreeIndex = taxonIdTreeIndexMap.get(originalTaxonUuid);
|
765 |
|
|
String groupIndexX = TreeIndex.toString(groupTreeIndex);
|
766 |
|
|
while (groupTreeIndex != null){
|
767 |
|
|
if (treeIndexTaxonIdMap.get(groupTreeIndex) != null){
|
768 |
|
|
UuidAndTitleCache<?> uuidAndLabel = treeIndexTaxonIdMap.get(groupTreeIndex);
|
769 |
63f513d9
|
Andreas Müller
|
item.setGroupTaxonUuid(uuidAndLabel.getUuid());
|
770 |
|
|
item.setGroupTaxonName(uuidAndLabel.getTitleCache());
|
771 |
|
|
break;
|
772 |
|
|
}else{
|
773 |
e3fc5af3
|
Andreas Müller
|
groupTreeIndex = groupTreeIndex.parent();
|
774 |
|
|
// int index = groupIndex.substring(0, groupIndex.length()-1).lastIndexOf(ITreeNode.separator);
|
775 |
|
|
// groupIndex = index < 0 ? null : groupIndex.substring(0, index+1);
|
776 |
63f513d9
|
Andreas Müller
|
}
|
777 |
|
|
}
|
778 |
|
|
}
|
779 |
|
|
|
780 |
|
|
return result;
|
781 |
|
|
}
|
782 |
|
|
|
783 |
e3fc5af3
|
Andreas Müller
|
@Override
|
784 |
|
|
public List<GroupedTaxonDTO> groupTaxaByMarkedParents(List<UUID> originalTaxonUuids, UUID classificationUuid,
|
785 |
|
|
MarkerType markerType, Boolean flag) {
|
786 |
|
|
|
787 |
|
|
List<GroupedTaxonDTO> result = new ArrayList<>();
|
788 |
|
|
|
789 |
|
|
//get treeindex for each taxonUUID
|
790 |
|
|
Map<UUID, TreeIndex> taxonIdTreeIndexMap = dao.treeIndexForTaxonUuids(classificationUuid, originalTaxonUuids);
|
791 |
|
|
|
792 |
|
|
//get all marked tree indexes
|
793 |
|
|
Set<TreeIndex> markedTreeIndexes = dao.getMarkedTreeIndexes(markerType, flag);
|
794 |
|
|
|
795 |
|
|
Map<TreeIndex, TreeIndex> groupedMap = TreeIndex.group(markedTreeIndexes, taxonIdTreeIndexMap.values());
|
796 |
|
|
Set<TreeIndex> notNullGroups = new HashSet<>(groupedMap.values());
|
797 |
|
|
notNullGroups.remove(null);
|
798 |
|
|
|
799 |
|
|
//get taxonInfo for treeIndexes
|
800 |
|
|
Map<TreeIndex, UuidAndTitleCache<?>> treeIndexTaxonIdMap = taxonNodeDao.taxonUuidsForTreeIndexes(notNullGroups);
|
801 |
|
|
|
802 |
|
|
//fill result list
|
803 |
|
|
for (UUID originalTaxonUuid : originalTaxonUuids){
|
804 |
|
|
GroupedTaxonDTO item = new GroupedTaxonDTO();
|
805 |
|
|
result.add(item);
|
806 |
|
|
item.setTaxonUuid(originalTaxonUuid);
|
807 |
|
|
|
808 |
|
|
TreeIndex toBeGroupedTreeIndex = taxonIdTreeIndexMap.get(originalTaxonUuid);
|
809 |
|
|
TreeIndex groupTreeIndex = groupedMap.get(toBeGroupedTreeIndex);
|
810 |
|
|
UuidAndTitleCache<?> uuidAndLabel = treeIndexTaxonIdMap.get(groupTreeIndex);
|
811 |
|
|
if (uuidAndLabel != null){
|
812 |
|
|
item.setGroupTaxonUuid(uuidAndLabel.getUuid());
|
813 |
|
|
item.setGroupTaxonName(uuidAndLabel.getTitleCache());
|
814 |
|
|
}
|
815 |
|
|
}
|
816 |
|
|
|
817 |
|
|
return result;
|
818 |
|
|
}
|
819 |
|
|
|
820 |
b296585f
|
Andreas Müller
|
@Override
|
821 |
|
|
public UUID getTaxonNodeUuidByTaxonUuid(UUID classificationUuid, UUID taxonUuid) {
|
822 |
|
|
Map<UUID, UUID> map = dao.getTaxonNodeUuidByTaxonUuid(classificationUuid, Arrays.asList(taxonUuid));
|
823 |
|
|
UUID taxonNodeUuid = map.get(taxonUuid);
|
824 |
|
|
return taxonNodeUuid;
|
825 |
|
|
}
|
826 |
|
|
|
827 |
d17b9e90
|
Andreas Müller
|
@Override
|
828 |
d8c4f8b9
|
Andreas Müller
|
public TaxonInContextDTO getTaxonInContext(UUID classificationUuid, UUID taxonBaseUuid,
|
829 |
2edda1af
|
Andreas Müller
|
Boolean doChildren, Boolean doSynonyms, boolean includeUnpublished, List<UUID> ancestorMarkers,
|
830 |
500073dd
|
Andreas Kohlbecker
|
TaxonNodeSortMode sortMode) {
|
831 |
562acef2
|
Andreas Kohlbecker
|
|
832 |
d17b9e90
|
Andreas Müller
|
TaxonInContextDTO result = new TaxonInContextDTO();
|
833 |
d8c4f8b9
|
Andreas Müller
|
|
834 |
|
|
TaxonBase<?> taxonBase = taxonDao.load(taxonBaseUuid);
|
835 |
1d54cd17
|
Andreas Müller
|
if (taxonBase == null){
|
836 |
d8c4f8b9
|
Andreas Müller
|
throw new EntityNotFoundException("Taxon with uuid " + taxonBaseUuid + " not found in datasource");
|
837 |
|
|
}
|
838 |
|
|
boolean isSynonym = false;
|
839 |
|
|
Taxon acceptedTaxon;
|
840 |
|
|
if (taxonBase.isInstanceOf(Synonym.class)){
|
841 |
|
|
isSynonym = true;
|
842 |
|
|
Synonym synonym = CdmBase.deproxy(taxonBase, Synonym.class);
|
843 |
f476ff86
|
Andreas Müller
|
acceptedTaxon = synonym.getAcceptedTaxon();
|
844 |
d8c4f8b9
|
Andreas Müller
|
if (acceptedTaxon == null) {
|
845 |
|
|
throw new EntityNotFoundException("Accepted taxon not found for synonym" );
|
846 |
|
|
}
|
847 |
|
|
TaxonStatus taxonStatus = TaxonStatus.Synonym;
|
848 |
|
|
if (synonym.getName()!= null && acceptedTaxon.getName() != null
|
849 |
|
|
&& synonym.getName().getHomotypicalGroup().equals(acceptedTaxon.getName().getHomotypicalGroup())){
|
850 |
|
|
taxonStatus = TaxonStatus.SynonymObjective;
|
851 |
|
|
}
|
852 |
|
|
result.setTaxonStatus(taxonStatus);
|
853 |
|
|
|
854 |
|
|
}else{
|
855 |
|
|
acceptedTaxon = CdmBase.deproxy(taxonBase, Taxon.class);
|
856 |
|
|
result.setTaxonStatus(TaxonStatus.Accepted);
|
857 |
|
|
}
|
858 |
|
|
UUID acceptedTaxonUuid = acceptedTaxon.getUuid();
|
859 |
|
|
|
860 |
|
|
UUID taxonNodeUuid = getTaxonNodeUuidByTaxonUuid(classificationUuid, acceptedTaxonUuid);
|
861 |
|
|
if (taxonNodeUuid == null) {
|
862 |
|
|
throw new EntityNotFoundException("Taxon not found in classficiation with uuid " + classificationUuid + ". Either classification does not exist or does not contain taxon/synonym with uuid " + taxonBaseUuid );
|
863 |
|
|
}
|
864 |
|
|
result.setTaxonNodeUuid(taxonNodeUuid);
|
865 |
cbae39d4
|
Andreas Müller
|
|
866 |
|
|
//TODO make it a dao call
|
867 |
|
|
Taxon parentTaxon = getParentTaxon(classificationUuid, acceptedTaxon);
|
868 |
|
|
if (parentTaxon != null){
|
869 |
|
|
result.setParentTaxonUuid(parentTaxon.getUuid());
|
870 |
|
|
result.setParentTaxonLabel(parentTaxon.getTitleCache());
|
871 |
|
|
if (parentTaxon.getName() != null){
|
872 |
|
|
result.setParentNameLabel(parentTaxon.getName().getTitleCache());
|
873 |
|
|
}
|
874 |
|
|
}
|
875 |
|
|
|
876 |
d8c4f8b9
|
Andreas Müller
|
result.setTaxonUuid(taxonBaseUuid);
|
877 |
|
|
result.setClassificationUuid(classificationUuid);
|
878 |
|
|
if (taxonBase.getSec() != null){
|
879 |
|
|
result.setSecundumUuid(taxonBase.getSec().getUuid());
|
880 |
|
|
result.setSecundumLabel(taxonBase.getSec().getTitleCache());
|
881 |
1d54cd17
|
Andreas Müller
|
}
|
882 |
d8c4f8b9
|
Andreas Müller
|
result.setTaxonLabel(taxonBase.getTitleCache());
|
883 |
d17b9e90
|
Andreas Müller
|
|
884 |
db183545
|
Andreas Müller
|
TaxonName name = taxonBase.getName();
|
885 |
d17b9e90
|
Andreas Müller
|
result.setNameUuid(name.getUuid());
|
886 |
|
|
result.setNameLabel(name.getTitleCache());
|
887 |
a4c9dfc9
|
Andreas Müller
|
result.setNameWithoutAuthor(name.getNameCache());
|
888 |
|
|
result.setGenusOrUninomial(name.getGenusOrUninomial());
|
889 |
|
|
result.setInfraGenericEpithet(name.getInfraGenericEpithet());
|
890 |
|
|
result.setSpeciesEpithet(name.getSpecificEpithet());
|
891 |
|
|
result.setInfraSpecificEpithet(name.getInfraSpecificEpithet());
|
892 |
|
|
|
893 |
|
|
result.setAuthorship(name.getAuthorshipCache());
|
894 |
|
|
|
895 |
|
|
Rank rank = name.getRank();
|
896 |
|
|
if (rank != null){
|
897 |
|
|
result.setRankUuid(rank.getUuid());
|
898 |
|
|
String rankLabel = rank.getAbbreviation();
|
899 |
|
|
if (StringUtils.isBlank(rankLabel)){
|
900 |
|
|
rankLabel = rank.getLabel();
|
901 |
d17b9e90
|
Andreas Müller
|
}
|
902 |
a4c9dfc9
|
Andreas Müller
|
result.setRankLabel(rankLabel);
|
903 |
d17b9e90
|
Andreas Müller
|
}
|
904 |
|
|
|
905 |
|
|
boolean recursive = false;
|
906 |
4f290ba6
|
Andreas Müller
|
Integer pageSize = null;
|
907 |
|
|
Integer pageIndex = null;
|
908 |
2edda1af
|
Andreas Müller
|
Pager<TaxonNodeDto> children = taxonNodeService.pageChildNodesDTOs(taxonNodeUuid, recursive, includeUnpublished, doSynonyms,
|
909 |
|
|
sortMode, pageSize, pageIndex);
|
910 |
d17b9e90
|
Andreas Müller
|
|
911 |
|
|
//children
|
912 |
d8c4f8b9
|
Andreas Müller
|
if(! isSynonym) {
|
913 |
|
|
for (TaxonNodeDto childDto : children.getRecords()){
|
914 |
525e9e11
|
Andreas Kohlbecker
|
if (doChildren && childDto.getTaxonStatus().equals(TaxonStatus.Accepted)){
|
915 |
d8c4f8b9
|
Andreas Müller
|
EntityDTO<Taxon> child = new EntityDTO<Taxon>(childDto.getTaxonUuid(), childDto.getTitleCache());
|
916 |
|
|
result.addChild(child);
|
917 |
525e9e11
|
Andreas Kohlbecker
|
}else if (doSynonyms && childDto.getTaxonStatus().isSynonym()){
|
918 |
281a5d27
|
Andreas Müller
|
EntityDTO<Synonym> child = new EntityDTO<>(childDto.getTaxonUuid(), childDto.getTitleCache());
|
919 |
d8c4f8b9
|
Andreas Müller
|
result.addSynonym(child);
|
920 |
|
|
}
|
921 |
d17b9e90
|
Andreas Müller
|
}
|
922 |
d8c4f8b9
|
Andreas Müller
|
}else{
|
923 |
|
|
result.setAcceptedTaxonUuid(acceptedTaxonUuid);
|
924 |
|
|
String nameTitel = acceptedTaxon.getName() == null ? null : acceptedTaxon.getName().getTitleCache();
|
925 |
|
|
result.setAcceptedTaxonLabel(acceptedTaxon.getTitleCache());
|
926 |
|
|
result.setAcceptedNameLabel(nameTitel);
|
927 |
d17b9e90
|
Andreas Müller
|
}
|
928 |
|
|
|
929 |
|
|
//marked ancestors
|
930 |
1d54cd17
|
Andreas Müller
|
if (ancestorMarkers != null && !ancestorMarkers.isEmpty()){
|
931 |
281a5d27
|
Andreas Müller
|
@SuppressWarnings("rawtypes")
|
932 |
4f290ba6
|
Andreas Müller
|
List<DefinedTermBase> markerTypesTerms = termDao.list(ancestorMarkers, pageSize, null, null, null);
|
933 |
|
|
List<MarkerType> markerTypes = new ArrayList<>();
|
934 |
|
|
for (DefinedTermBase<?> term : markerTypesTerms){
|
935 |
|
|
if (term.isInstanceOf(MarkerType.class)){
|
936 |
|
|
markerTypes.add(CdmBase.deproxy(term, MarkerType.class));
|
937 |
|
|
}
|
938 |
|
|
}
|
939 |
|
|
if (! markerTypes.isEmpty()){
|
940 |
|
|
TaxonNode node = taxonNodeDao.findByUuid(taxonNodeUuid);
|
941 |
|
|
handleAncestorsForMarkersRecursive(result, markerTypes, node);
|
942 |
|
|
}
|
943 |
|
|
}
|
944 |
|
|
|
945 |
d17b9e90
|
Andreas Müller
|
return result;
|
946 |
|
|
}
|
947 |
|
|
|
948 |
cbae39d4
|
Andreas Müller
|
private Taxon getParentTaxon(UUID classificationUuid, Taxon acceptedTaxon) {
|
949 |
|
|
if (classificationUuid == null){
|
950 |
|
|
return null;
|
951 |
|
|
}
|
952 |
|
|
TaxonNode parent = null;
|
953 |
|
|
for (TaxonNode node : acceptedTaxon.getTaxonNodes()){
|
954 |
|
|
if (classificationUuid.equals(node.getClassification().getUuid())){
|
955 |
|
|
parent = node.getParent();
|
956 |
|
|
}
|
957 |
|
|
}
|
958 |
|
|
if (parent != null){
|
959 |
|
|
return parent.getTaxon();
|
960 |
|
|
}
|
961 |
|
|
return null;
|
962 |
|
|
}
|
963 |
|
|
|
964 |
4f290ba6
|
Andreas Müller
|
private void handleAncestorsForMarkersRecursive(TaxonInContextDTO result, List<MarkerType> markerTypes, TaxonNode node) {
|
965 |
|
|
for (MarkerType type : markerTypes){
|
966 |
|
|
Taxon taxon = node.getTaxon();
|
967 |
|
|
if (taxon != null && taxon.hasMarker(type, true)){
|
968 |
d8c4f8b9
|
Andreas Müller
|
String label = taxon.getName() == null? taxon.getTitleCache() : taxon.getName().getTitleCache();
|
969 |
|
|
MarkedEntityDTO<Taxon> dto = new MarkedEntityDTO<>(type, true, taxon.getUuid(), label);
|
970 |
4f290ba6
|
Andreas Müller
|
result.addMarkedAncestor(dto);
|
971 |
|
|
}
|
972 |
|
|
}
|
973 |
|
|
TaxonNode parentNode = node.getParent();
|
974 |
|
|
if (parentNode != null){
|
975 |
|
|
handleAncestorsForMarkersRecursive(result, markerTypes, parentNode);
|
976 |
|
|
}
|
977 |
|
|
}
|
978 |
|
|
|
979 |
8e9115f6
|
Katja Luther
|
@Override
|
980 |
|
|
public List<UuidAndTitleCache<TaxonNode>> getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByClassification(
|
981 |
|
|
Classification classification) {
|
982 |
|
|
return getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByClassification(classification, false);
|
983 |
|
|
}
|
984 |
|
|
|
985 |
|
|
@Override
|
986 |
|
|
public List<UuidAndTitleCache<TaxonNode>> getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByClassification(
|
987 |
|
|
UUID classificationUuid) {
|
988 |
|
|
return getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByClassification(classificationUuid, false);
|
989 |
|
|
}
|
990 |
|
|
|
991 |
|
|
@Override
|
992 |
|
|
public List<UuidAndTitleCache<TaxonNode>> getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByClassification(
|
993 |
|
|
UUID classificationUuid, Integer limit, String pattern) {
|
994 |
|
|
return getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByClassification(classificationUuid, limit, pattern, false);
|
995 |
|
|
}
|
996 |
|
|
|
997 |
|
|
@Override
|
998 |
|
|
public List<UuidAndTitleCache<TaxonNode>> getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByClassification(
|
999 |
|
|
Classification classification, Integer limit, String pattern) {
|
1000 |
|
|
return getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByClassification(classification, limit, pattern, false);
|
1001 |
|
|
}
|
1002 |
1364ddca
|
Katja Luther
|
|
1003 |
|
|
@Override
|
1004 |
|
|
public List<UuidAndTitleCache<TaxonNode>> getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByClassification(
|
1005 |
|
|
UUID classificationUuid, Integer limit, String pattern, boolean searchForClassifications) {
|
1006 |
|
|
return getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByClassification(
|
1007 |
|
|
classificationUuid, limit, pattern, searchForClassifications, false);
|
1008 |
|
|
}
|
1009 |
01c21ead
|
n.hoffmann
|
}
|