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