cleanup
[cdmlib.git] / cdmlib-services / src / main / java / eu / etaxonomy / cdm / api / service / TaxonNodeServiceImpl.java
1 // $Id$
2 /**
3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10
11 package eu.etaxonomy.cdm.api.service;
12
13 import java.util.ArrayList;
14 import java.util.Collection;
15 import java.util.Collections;
16 import java.util.Comparator;
17 import java.util.HashSet;
18 import java.util.List;
19 import java.util.Set;
20 import java.util.UUID;
21
22 import org.apache.log4j.Logger;
23 import org.springframework.beans.factory.annotation.Autowired;
24 import org.springframework.stereotype.Service;
25 import org.springframework.transaction.annotation.Transactional;
26
27 import eu.etaxonomy.cdm.api.service.UpdateResult.Status;
28 import eu.etaxonomy.cdm.api.service.config.NodeDeletionConfigurator.ChildHandling;
29 import eu.etaxonomy.cdm.api.service.config.TaxonDeletionConfigurator;
30 import eu.etaxonomy.cdm.api.service.config.TaxonNodeDeletionConfigurator;
31 import eu.etaxonomy.cdm.api.service.dto.CdmEntityIdentifier;
32 import eu.etaxonomy.cdm.api.service.pager.Pager;
33 import eu.etaxonomy.cdm.api.service.pager.PagerUtils;
34 import eu.etaxonomy.cdm.api.service.pager.impl.DefaultPagerImpl;
35 import eu.etaxonomy.cdm.hibernate.HHH_9751_Util;
36 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
37 import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
38 import eu.etaxonomy.cdm.model.common.CdmBase;
39 import eu.etaxonomy.cdm.model.common.DefinedTerm;
40 import eu.etaxonomy.cdm.model.description.TaxonDescription;
41 import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
42 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
43 import eu.etaxonomy.cdm.model.reference.Reference;
44 import eu.etaxonomy.cdm.model.taxon.Classification;
45 import eu.etaxonomy.cdm.model.taxon.HomotypicGroupTaxonComparator;
46 import eu.etaxonomy.cdm.model.taxon.Synonym;
47 import eu.etaxonomy.cdm.model.taxon.SynonymRelationship;
48 import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;
49 import eu.etaxonomy.cdm.model.taxon.Taxon;
50 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
51 import eu.etaxonomy.cdm.model.taxon.TaxonNodeAgentRelation;
52 import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
53 import eu.etaxonomy.cdm.persistence.dao.initializer.IBeanInitializer;
54 import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonNodeDao;
55 import eu.etaxonomy.cdm.persistence.dto.TaxonNodeDto;
56
57 /**
58 * @author n.hoffmann
59 * @created Apr 9, 2010
60 * @version 1.0
61 */
62 @Service
63 @Transactional(readOnly = true)
64 public class TaxonNodeServiceImpl extends AnnotatableServiceBase<TaxonNode, ITaxonNodeDao> implements ITaxonNodeService{
65 private static final Logger logger = Logger.getLogger(TaxonNodeServiceImpl.class);
66
67 @Autowired
68 private IBeanInitializer defaultBeanInitializer;
69
70 @Autowired
71 private ITaxonService taxonService;
72
73 @Autowired
74 private IAgentService agentService;
75
76 @Override
77 public List<TaxonNode> loadChildNodesOfTaxonNode(TaxonNode taxonNode,
78 List<String> propertyPaths, boolean recursive, NodeSortMode sortMode) {
79
80 getSession().refresh(taxonNode);
81 List<TaxonNode> childNodes;
82 if (recursive == true){
83 childNodes = dao.listChildrenOf(taxonNode, null, null, null, recursive);
84 }else{
85 childNodes = new ArrayList<TaxonNode>(taxonNode.getChildNodes());
86 }
87
88 HHH_9751_Util.removeAllNull(childNodes);
89
90 if (sortMode != null){
91 Comparator<TaxonNode> comparator = sortMode.newComparator();
92 Collections.sort(childNodes, comparator);
93 }
94 defaultBeanInitializer.initializeAll(childNodes, propertyPaths);
95 return childNodes;
96 }
97
98 /**
99 * {@inheritDoc}
100 */
101 @Override
102 public Pager<TaxonNodeDto> pageChildNodesDTOs(UUID taxonNodeUuid, boolean recursive,
103 boolean doSynonyms, NodeSortMode sortMode,
104 Integer pageSize, Integer pageIndex) {
105
106 TaxonNode parentNode = dao.load(taxonNodeUuid);
107
108 List<CdmBase> allRecords = new ArrayList<>();
109
110 //acceptedTaxa
111 List<TaxonNode> childNodes = loadChildNodesOfTaxonNode(parentNode, null, recursive, sortMode);
112 allRecords.addAll(childNodes);
113
114 //add synonyms if pager is not yet full synonyms
115 List<Synonym> synList = new ArrayList<>(parentNode.getTaxon().getSynonyms());
116 Collections.sort(synList, new HomotypicGroupTaxonComparator(null));
117 //TODO: test sorting
118
119 allRecords.addAll(synList);
120
121
122 List<TaxonNodeDto> dtos = new ArrayList<>(pageSize);
123 int start = PagerUtils.startFor(pageSize, pageIndex);
124 int limit = PagerUtils.limitFor(pageSize);
125 Long totalCount = Long.valueOf(allRecords.size());
126
127 if(PagerUtils.hasResultsInRange(totalCount, pageIndex, pageSize)) {
128 TaxonNameBase<?,?> parentName = null;
129
130 for(int i = start; i < Math.min(totalCount, start + limit); i++) {
131 CdmBase record = allRecords.get(i);
132
133 if (record.isInstanceOf(TaxonNode.class)){
134 dtos.add(new TaxonNodeDto(CdmBase.deproxy(record, TaxonNode.class)));
135 }else if (record.isInstanceOf(Synonym.class)){
136 Synonym synonym = CdmBase.deproxy(record, Synonym.class);
137 parentName = parentName == null? parentNode.getTaxon().getName(): parentName;
138 boolean isHomotypic = synonym.getName().isHomotypic(parentName);
139 dtos.add(new TaxonNodeDto(synonym, isHomotypic));
140 }
141 }
142 }
143
144 return new DefaultPagerImpl<TaxonNodeDto>(pageIndex, totalCount, pageSize , dtos);
145 }
146
147 @Override
148 public TaxonNodeDto parentDto(UUID taxonNodeUuid) {
149 TaxonNode taxonNode = dao.load(taxonNodeUuid);
150 if(taxonNode.getParent() != null) {
151 return new TaxonNodeDto(taxonNode.getParent());
152 }
153 return null;
154 }
155
156 @Override
157 @Autowired
158 protected void setDao(ITaxonNodeDao dao) {
159 this.dao = dao;
160 }
161
162 @Override
163 @Transactional(readOnly = false)
164 public DeleteResult makeTaxonNodeASynonymOfAnotherTaxonNode(TaxonNode oldTaxonNode, TaxonNode newAcceptedTaxonNode, SynonymRelationshipType synonymRelationshipType, Reference citation, String citationMicroReference) {
165
166
167 // TODO at the moment this method only moves synonym-, concept relations and descriptions to the new accepted taxon
168 // in a future version we also want to move cdm data like annotations, marker, so., but we will need a policy for that
169 if (oldTaxonNode == null || newAcceptedTaxonNode == null || oldTaxonNode.getTaxon().getName() == null){
170 throw new IllegalArgumentException("A mandatory parameter was null.");
171 }
172
173 if(oldTaxonNode.equals(newAcceptedTaxonNode)){
174 throw new IllegalArgumentException("Taxon can not be made synonym of its own.");
175 }
176
177
178 Classification classification = oldTaxonNode.getClassification();
179 Taxon oldTaxon = HibernateProxyHelper.deproxy(oldTaxonNode.getTaxon());
180 Taxon newAcceptedTaxon = (Taxon)this.taxonService.load(newAcceptedTaxonNode.getTaxon().getUuid());
181 // Move oldTaxon to newTaxon
182 //TaxonNameBase<?,?> synonymName = oldTaxon.getName();
183 TaxonNameBase<?,?> synonymName = HibernateProxyHelper.deproxy(oldTaxon.getName());
184 HomotypicalGroup group = synonymName.getHomotypicalGroup();
185 group = HibernateProxyHelper.deproxy(group, HomotypicalGroup.class);
186 if (synonymRelationshipType == null){
187 if (synonymName.isHomotypic(newAcceptedTaxon.getName())){
188 synonymRelationshipType = SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF();
189 }else{
190 synonymRelationshipType = SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF();
191 }
192 }
193
194 //set homotypic group
195 HomotypicalGroup newAcceptedTaxonHomotypicalgroup = newAcceptedTaxon.getHomotypicGroup();
196 newAcceptedTaxonHomotypicalgroup = HibernateProxyHelper.deproxy(newAcceptedTaxonHomotypicalgroup, HomotypicalGroup.class);
197 TaxonNameBase newAcceptedTaxonName = HibernateProxyHelper.deproxy(newAcceptedTaxon.getName(), TaxonNameBase.class);
198 // Move Synonym Relations to new Taxon
199 SynonymRelationship synonmyRelationship = newAcceptedTaxon.addSynonymName(synonymName,
200 synonymRelationshipType, citation, citationMicroReference);
201 HomotypicalGroup homotypicalGroupAcceptedTaxon = synonmyRelationship.getSynonym().getHomotypicGroup();
202 // Move Synonym Relations to new Taxon
203 // From ticket 3163 we can move taxon with accepted name having homotypic synonyms
204 List<Synonym> synonymsInHomotypicalGroup = null;
205
206 //the synonyms of the homotypical group of the old taxon
207 if (synonymRelationshipType.equals(SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF())){
208 synonymsInHomotypicalGroup = oldTaxon.getSynonymsInGroup(group);
209 }
210
211 for(SynonymRelationship synRelation : oldTaxon.getSynonymRelations()){
212 SynonymRelationshipType srt;
213 if(synRelation.getSynonym().getName().getHomotypicalGroup()!= null
214 && synRelation.getSynonym().getName().getHomotypicalGroup().equals(newAcceptedTaxonName.getHomotypicalGroup())) {
215 srt = SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF();
216 } else if(synRelation.getType() != null && synRelation.getType().equals(SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF())) {
217 if (synonymRelationshipType.equals(SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF())){
218 srt = SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF();
219 } else{
220 srt = SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF();
221 }
222 } else {
223 srt = synRelation.getType();
224
225 }
226
227 newAcceptedTaxon.addSynonym(synRelation.getSynonym(),
228 srt,
229 synRelation.getCitation(),
230 synRelation.getCitationMicroReference());
231
232 /*if (synonymsInHomotypicalGroup.contains(synRelation.getSynonym()) && srt.equals(SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF())){
233 homotypicalGroupAcceptedTaxon.addTypifiedName(synRelation.getSynonym().getName());
234 }*/
235
236 }
237
238
239
240
241
242 // CHILD NODES
243 if(oldTaxonNode.getChildNodes() != null && oldTaxonNode.getChildNodes().size() != 0){
244 List<TaxonNode> childNodes = new ArrayList<TaxonNode>();
245 for (TaxonNode childNode : oldTaxonNode.getChildNodes()){
246 childNodes.add(childNode);
247 }
248 for(TaxonNode childNode :childNodes){
249 newAcceptedTaxonNode.addChildNode(childNode, childNode.getReference(), childNode.getMicroReference()); // childNode.getSynonymToBeUsed()
250 }
251 }
252
253 //Move Taxon RelationShips to new Taxon
254 Set<TaxonRelationship> obsoleteTaxonRelationships = new HashSet<TaxonRelationship>();
255 for(TaxonRelationship taxonRelationship : oldTaxon.getTaxonRelations()){
256 Taxon fromTaxon = HibernateProxyHelper.deproxy(taxonRelationship.getFromTaxon());
257 Taxon toTaxon = HibernateProxyHelper.deproxy(taxonRelationship.getToTaxon());
258 if (fromTaxon == oldTaxon){
259 newAcceptedTaxon.addTaxonRelation(taxonRelationship.getToTaxon(), taxonRelationship.getType(),
260 taxonRelationship.getCitation(), taxonRelationship.getCitationMicroReference());
261
262 }else if(toTaxon == oldTaxon){
263 fromTaxon.addTaxonRelation(newAcceptedTaxon, taxonRelationship.getType(),
264 taxonRelationship.getCitation(), taxonRelationship.getCitationMicroReference());
265 taxonService.saveOrUpdate(fromTaxon);
266
267 }else{
268 logger.warn("Taxon is not part of its own Taxonrelationship");
269 }
270 // Remove old relationships
271
272 fromTaxon.removeTaxonRelation(taxonRelationship);
273 toTaxon.removeTaxonRelation(taxonRelationship);
274 taxonRelationship.setToTaxon(null);
275 taxonRelationship.setFromTaxon(null);
276 }
277
278
279 //Move descriptions to new taxon
280 List<TaxonDescription> descriptions = new ArrayList<TaxonDescription>( oldTaxon.getDescriptions()); //to avoid concurrent modification errors (newAcceptedTaxon.addDescription() modifies also oldtaxon.descritpions())
281 for(TaxonDescription description : descriptions){
282 String message = "Description copied from former accepted taxon: %s (Old title: %s)";
283 message = String.format(message, oldTaxon.getTitleCache(), description.getTitleCache());
284 description.setTitleCache(message, true);
285 //oldTaxon.removeDescription(description, false);
286 newAcceptedTaxon.addDescription(description);
287 }
288 oldTaxon.clearDescriptions();
289
290 taxonService.update(newAcceptedTaxon);
291
292 taxonService.update(oldTaxon);
293
294 TaxonDeletionConfigurator conf = new TaxonDeletionConfigurator();
295 conf.setDeleteSynonymsIfPossible(false);
296 DeleteResult result = taxonService.isDeletable(oldTaxon, conf);
297 conf.setDeleteNameIfPossible(false);
298
299 if (result.isOk()){
300 result = taxonService.deleteTaxon(oldTaxon.getUuid(), conf, classification.getUuid());
301 }else{
302 result.setStatus(Status.OK);
303 TaxonNodeDeletionConfigurator config = new TaxonNodeDeletionConfigurator();
304 config.setDeleteElement(false);
305 conf.setTaxonNodeConfig(config);
306 result.includeResult(deleteTaxonNode(oldTaxonNode, conf));
307 }
308 result.addUpdatedObject(newAcceptedTaxon);
309 result.addUpdatedObject(oldTaxon);
310
311 //oldTaxonNode.delete();
312 return result;
313 }
314
315
316
317 /* (non-Javadoc)
318 * @see eu.etaxonomy.cdm.api.service.ITaxonNodeService#makeTaxonNodeASynonymOfAnotherTaxonNode(java.util.UUID, java.util.UUID, java.util.UUID, java.util.UUID, java.lang.String)
319 */
320 @Override
321 @Transactional(readOnly = false)
322 public UpdateResult makeTaxonNodeASynonymOfAnotherTaxonNode(UUID oldTaxonNodeUuid,
323 UUID newAcceptedTaxonNodeUUID,
324 SynonymRelationshipType synonymRelationshipType,
325 Reference citation,
326 String citationMicroReference) {
327
328 TaxonNode oldTaxonNode = dao.load(oldTaxonNodeUuid);
329 TaxonNode oldTaxonParentNode = oldTaxonNode.getParent();
330 TaxonNode newTaxonNode = dao.load(newAcceptedTaxonNodeUUID);
331
332 UpdateResult result = makeTaxonNodeASynonymOfAnotherTaxonNode(oldTaxonNode,
333 newTaxonNode,
334 synonymRelationshipType,
335 citation,
336 citationMicroReference);
337 result.addUpdatedCdmId(new CdmEntityIdentifier(oldTaxonParentNode.getId(), TaxonNode.class));
338 result.addUpdatedCdmId(new CdmEntityIdentifier(newTaxonNode.getId(), TaxonNode.class));
339 result.setCdmEntity(oldTaxonParentNode);
340 return result;
341 }
342
343 /* (non-Javadoc)
344 * @see eu.etaxonomy.cdm.api.service.ITaxonNodeService#deleteTaxonNodes(java.util.List)
345 */
346 @Override
347 @Transactional(readOnly = false)
348 public DeleteResult deleteTaxonNodes(List<TaxonNode> list, TaxonDeletionConfigurator config) {
349
350 if (config == null){
351 config = new TaxonDeletionConfigurator();
352 }
353 DeleteResult result = new DeleteResult();
354 List<UUID> deletedUUIDs = new ArrayList<UUID>();
355 Classification classification = null;
356 List<TaxonNode> taxonNodes = new ArrayList<TaxonNode>(list);
357 for (TaxonNode treeNode:taxonNodes){
358 if (treeNode != null){
359
360 TaxonNode taxonNode;
361 taxonNode = HibernateProxyHelper.deproxy(treeNode, TaxonNode.class);
362 TaxonNode parent = taxonNode.getParent();
363 //check whether the node has children or the children are already deleted
364 if(taxonNode.hasChildNodes()) {
365 List<TaxonNode> children = new ArrayList<TaxonNode> ();
366 List<TaxonNode> childNodesList = taxonNode.getChildNodes();
367 children.addAll(childNodesList);
368 int compare = config.getTaxonNodeConfig().getChildHandling().compareTo(ChildHandling.DELETE);
369 boolean childHandling = (compare == 0)? true: false;
370 if (childHandling){
371 boolean changeDeleteTaxon = false;
372 if (!config.getTaxonNodeConfig().isDeleteTaxon()){
373 config.getTaxonNodeConfig().setDeleteTaxon(true);
374 changeDeleteTaxon = true;
375 }
376 DeleteResult resultNodes = deleteTaxonNodes(children, config);
377 if (!resultNodes.isOk()){
378 result.addExceptions(resultNodes.getExceptions());
379 result.setStatus(resultNodes.getStatus());
380 }
381 if (changeDeleteTaxon){
382 config.getTaxonNodeConfig().setDeleteTaxon(false);
383 }
384
385 } else {
386 //move the children to the parent
387
388 for (TaxonNode child: childNodesList){
389 parent.addChildNode(child, child.getReference(), child.getMicroReference());
390 }
391
392 }
393 }
394
395 classification = taxonNode.getClassification();
396
397 if (classification.getRootNode().equals(taxonNode)){
398 classification.removeRootNode();
399 classification = null;
400 }else if (classification.getChildNodes().contains(taxonNode)){
401 Taxon taxon = taxonNode.getTaxon();
402 classification.deleteChildNode(taxonNode);
403
404 //node is rootNode
405 if (taxon != null){
406
407 if (config.getTaxonNodeConfig().isDeleteTaxon()){
408 taxonService.saveOrUpdate(taxon);
409 saveOrUpdate(taxonNode);
410
411 TaxonDeletionConfigurator configNew = new TaxonDeletionConfigurator();
412 DeleteResult resultTaxon = taxonService.deleteTaxon(taxon.getUuid(), configNew, classification.getUuid());
413 if (!resultTaxon.isOk()){
414 result.addExceptions(resultTaxon.getExceptions());
415 result.setStatus(resultTaxon.getStatus());
416 }
417
418 }
419 }
420 classification = null;
421
422 } else {
423 classification = null;
424 Taxon taxon = taxonNode.getTaxon();
425 taxon = HibernateProxyHelper.deproxy(taxon, Taxon.class);
426 if (taxon != null){
427 taxon.removeTaxonNode(taxonNode);
428 if (config.getTaxonNodeConfig().isDeleteTaxon()){
429 TaxonDeletionConfigurator configNew = new TaxonDeletionConfigurator();
430 saveOrUpdate(taxonNode);
431 taxonService.saveOrUpdate(taxon);
432 DeleteResult resultTaxon = taxonService.deleteTaxon(taxon.getUuid(), configNew, null);
433
434 if (!resultTaxon.isOk()){
435 result.addExceptions(resultTaxon.getExceptions());
436 result.setStatus(resultTaxon.getStatus());
437 }
438 }
439 }
440
441 }
442
443 result.addUpdatedObject(parent);
444 if(result.getCdmEntity() == null){
445 result.setCdmEntity(taxonNode);
446 }
447 UUID uuid = dao.delete(taxonNode);
448 logger.debug("Deleted node " +uuid.toString());
449
450 }
451 }
452 /*if (classification != null){
453 result.addUpdatedObject(classification);
454 DeleteResult resultClassification = classService.delete(classification);
455 if (!resultClassification.isOk()){
456 result.addExceptions(resultClassification.getExceptions());
457 result.setStatus(resultClassification.getStatus());
458 }
459 }*/
460 return result;
461
462 }
463
464
465 @Override
466 @Transactional(readOnly = false)
467 public DeleteResult deleteTaxonNodes(Collection<UUID> nodeUuids, TaxonDeletionConfigurator config) {
468 List<TaxonNode> nodes = new ArrayList<TaxonNode>();
469 for(UUID nodeUuid : nodeUuids) {
470 nodes.add(dao.load(nodeUuid));
471 }
472 return deleteTaxonNodes(nodes, config);
473 }
474
475
476
477 @Override
478 @Transactional(readOnly = false)
479 public DeleteResult deleteTaxonNode(UUID nodeUUID, TaxonDeletionConfigurator config) {
480
481 TaxonNode node = HibernateProxyHelper.deproxy(dao.load(nodeUUID), TaxonNode.class);
482 return deleteTaxonNode(node, config);
483 }
484
485 @Override
486 @Transactional(readOnly = false)
487 public DeleteResult deleteTaxonNode(TaxonNode node, TaxonDeletionConfigurator config) {
488 DeleteResult result = new DeleteResult();
489 if (node == null){
490 result.setAbort();
491 result.addException(new Exception("The TaxonNode was already deleted."));
492 return result;
493 }
494 Taxon taxon = null;
495 try{
496 taxon = HibernateProxyHelper.deproxy(node.getTaxon());
497 }catch(NullPointerException e){
498 result.setAbort();
499 result.addException(new Exception("The Taxon was already deleted."));
500
501 }
502 TaxonNode parent = HibernateProxyHelper.deproxy(node.getParent(), TaxonNode.class);
503 if (config == null){
504 config = new TaxonDeletionConfigurator();
505 }
506
507
508
509 if (config.getTaxonNodeConfig().getChildHandling().equals(ChildHandling.MOVE_TO_PARENT)){
510 Object[] children = node.getChildNodes().toArray();
511 TaxonNode childNode;
512 for (Object child: children){
513 childNode = (TaxonNode) child;
514 parent.addChildNode(childNode, childNode.getReference(), childNode.getMicroReference());
515 }
516 }else{
517 deleteTaxonNodes(node.getChildNodes(), config);
518 }
519
520 if (taxon != null){
521 if (config.getTaxonNodeConfig().isDeleteTaxon() && (config.isDeleteInAllClassifications() || taxon.getTaxonNodes().size() == 1)){
522 result = taxonService.deleteTaxon(taxon.getUuid(), config, node.getClassification().getUuid());
523 result.addUpdatedObject(parent);
524 if (result.isOk()){
525 return result;
526 }
527 } else {
528 result.addUpdatedObject(taxon);
529 }
530 }
531 result.setCdmEntity(node);
532 boolean success = taxon.removeTaxonNode(node);
533 dao.save(parent);
534 taxonService.saveOrUpdate(taxon);
535 result.addUpdatedObject(parent);
536
537 if (success){
538 result.setStatus(Status.OK);
539 parent = HibernateProxyHelper.deproxy(parent, TaxonNode.class);
540 int index = parent.getChildNodes().indexOf(node);
541 if (index > -1){
542 parent.removeChild(index);
543 }
544 if (!dao.delete(node, config.getTaxonNodeConfig().getChildHandling().equals(ChildHandling.DELETE)).equals(null)){
545 return result;
546 } else {
547 result.setError();
548 return result;
549 }
550 }else{
551 if (dao.findByUuid(node.getUuid()) != null){
552 result.setError();
553 result.addException(new Exception("The node can not be removed from the taxon."));
554 }
555 return result;
556 }
557
558
559
560 }
561
562
563 /* (non-Javadoc)
564 * @see eu.etaxonomy.cdm.api.service.ITaxonNodeService#listAllNodesForClassification(eu.etaxonomy.cdm.model.taxon.Classification, int, int)
565 */
566 @Override
567 public List<TaxonNode> listAllNodesForClassification(Classification classification, Integer start, Integer end) {
568 return dao.getTaxonOfAcceptedTaxaByClassification(classification, start, end);
569 }
570
571 @Override
572 public int countAllNodesForClassification(Classification classification) {
573 return dao.countTaxonOfAcceptedTaxaByClassification(classification);
574 }
575
576 @Override
577 @Transactional
578 public UpdateResult moveTaxonNode(UUID taxonNodeUuid, UUID targetNodeUuid, int movingType){
579 TaxonNode taxonNode = HibernateProxyHelper.deproxy(dao.load(taxonNodeUuid), TaxonNode.class);
580 TaxonNode targetNode = HibernateProxyHelper.deproxy(dao.load(targetNodeUuid), TaxonNode.class);
581 return moveTaxonNode(taxonNode, targetNode, movingType);
582 }
583
584 @Override
585 @Transactional
586 public UpdateResult moveTaxonNode(TaxonNode taxonNode, TaxonNode newParent, int movingType){
587 UpdateResult result = new UpdateResult();
588
589 TaxonNode parentParent = HibernateProxyHelper.deproxy(newParent.getParent(), TaxonNode.class);
590
591 Integer sortIndex = -1;
592 if (movingType == 0){
593 sortIndex = 0;
594 }else if (movingType == 1){
595 sortIndex = newParent.getSortIndex();
596 newParent = parentParent;
597 } else if (movingType == 2){
598 sortIndex = newParent.getSortIndex() +1;
599 newParent = parentParent;
600 } else{
601 result.setAbort();
602 result.addException(new Exception("The moving type "+ movingType +" is not supported."));
603 }
604 result.addUpdatedObject(newParent);
605 result.addUpdatedObject(taxonNode.getParent());
606 result.setCdmEntity(taxonNode);
607
608 newParent.addChildNode(taxonNode, sortIndex, taxonNode.getReference(), taxonNode.getMicroReference());
609
610 dao.saveOrUpdate(newParent);
611
612 return result;
613 }
614
615
616
617 @Override
618 @Transactional
619 public UpdateResult moveTaxonNodes(Set<UUID> taxonNodeUuids, UUID newParentNodeUuid, int movingType){
620 UpdateResult result = new UpdateResult();
621 TaxonNode targetNode = dao.load(newParentNodeUuid);
622 for (UUID taxonNodeUuid: taxonNodeUuids){
623 TaxonNode taxonNode = dao.load(taxonNodeUuid);
624 result.includeResult(moveTaxonNode(taxonNode,targetNode, movingType));
625 }
626 return result;
627 }
628
629 @Override
630 public Pager<TaxonNodeAgentRelation> pageTaxonNodeAgentRelations(UUID taxonUuid, UUID classificationUuid,
631 UUID agentUuid, UUID rankUuid, UUID relTypeUuid, Integer pageSize, Integer pageIndex, List<String> propertyPaths) {
632
633
634 List<TaxonNodeAgentRelation> records = null;
635
636 long count = dao.countTaxonNodeAgentRelations(taxonUuid, classificationUuid, agentUuid, rankUuid, relTypeUuid);
637 if(PagerUtils.hasResultsInRange(count, pageIndex, pageSize)) {
638 records = dao.listTaxonNodeAgentRelations(taxonUuid, classificationUuid,
639 agentUuid, rankUuid, relTypeUuid, PagerUtils.startFor(pageSize, pageIndex), PagerUtils.limitFor(pageSize), propertyPaths);
640 }
641
642 Pager<TaxonNodeAgentRelation> pager = new DefaultPagerImpl<TaxonNodeAgentRelation>(pageIndex, count, pageSize, records);
643 return pager;
644 }
645
646 @Override
647 @Transactional
648 public UpdateResult createNewTaxonNode(UUID parentNodeUuid, Taxon newTaxon, Reference ref, String microref){
649 UpdateResult result = new UpdateResult();
650
651 UUID taxonUUID = taxonService.saveOrUpdate(newTaxon);
652 newTaxon = (Taxon) taxonService.load(taxonUUID);
653
654 TaxonNode parent = dao.load(parentNodeUuid);
655 TaxonNode child = null;
656 try{
657 child = parent.addChildTaxon(newTaxon, parent.getReference(), parent.getMicroReference());
658 }catch(Exception e){
659 result.addException(e);
660 result.setError();
661 return result;
662 }
663 // child = dao.save(child);
664
665 dao.saveOrUpdate(parent);
666 result.addUpdatedObject(parent);
667 if (child != null){
668 result.setCdmEntity(child);
669 }
670 return result;
671
672 }
673 @Override
674 @Transactional
675 public UpdateResult createNewTaxonNode(UUID parentNodeUuid, UUID taxonUuid, Reference ref, String microref){
676 UpdateResult result = new UpdateResult();
677 TaxonNode parent = dao.load(parentNodeUuid);
678 Taxon taxon = (Taxon) taxonService.load(taxonUuid);
679 TaxonNode child = null;
680 try{
681 child = parent.addChildTaxon(taxon, parent.getReference(), parent.getMicroReference());
682 }catch(Exception e){
683 result.addException(e);
684 result.setError();
685 return result;
686 }
687 // child = dao.save(child);
688
689 dao.saveOrUpdate(parent);
690 result.addUpdatedObject(parent);
691 if (child != null){
692 result.setCdmEntity(child);
693 }
694 return result;
695
696 }
697
698 @Override
699 @Transactional
700 public UpdateResult addTaxonNodeAgentRelation(UUID taxonNodeUUID, UUID agentUUID, DefinedTerm relationshipType){
701 UpdateResult result = new UpdateResult();
702 TaxonNode node = dao.load(taxonNodeUUID);
703 TeamOrPersonBase agent = (TeamOrPersonBase) agentService.load(agentUUID);
704 node.addAgentRelation(relationshipType, agent);
705 try{
706 dao.merge(node, true);
707 }catch (Exception e){
708 result.setError();
709 result.addException(e);
710 }
711 result.setCdmEntity(node);
712 return result;
713 }
714
715
716 }