Project

General

Profile

Download (26.9 KB) Statistics
| Branch: | Tag: | Revision:
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.DefinedTerm;
39
import eu.etaxonomy.cdm.model.description.TaxonDescription;
40
import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
41
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
42
import eu.etaxonomy.cdm.model.reference.Reference;
43
import eu.etaxonomy.cdm.model.taxon.Classification;
44
import eu.etaxonomy.cdm.model.taxon.Synonym;
45
import eu.etaxonomy.cdm.model.taxon.SynonymRelationship;
46
import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;
47
import eu.etaxonomy.cdm.model.taxon.Taxon;
48
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
49
import eu.etaxonomy.cdm.model.taxon.TaxonNodeAgentRelation;
50
import eu.etaxonomy.cdm.model.taxon.TaxonNodeByNameComparator;
51
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
52
import eu.etaxonomy.cdm.persistence.dao.common.IDefinedTermDao;
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
    private final Comparator<? super TaxonNode> taxonNodeComparator = new TaxonNodeByNameComparator();
71

    
72
    @Autowired
73
    private ITaxonService taxonService;
74

    
75
    @Autowired
76
    private IAgentService agentService;
77

    
78
    @Autowired
79
    private IClassificationService classService;
80

    
81
    @Autowired
82
    private IDefinedTermDao termDao;
83

    
84
    @Override
85
    public List<TaxonNode> loadChildNodesOfTaxonNode(TaxonNode taxonNode,
86
            List<String> propertyPaths, boolean recursive, NodeSortMode sortMode) {
87

    
88
        getSession().refresh(taxonNode);
89
        List<TaxonNode> childNodes;
90
        if (recursive == true){
91
        	childNodes  = dao.listChildrenOf(taxonNode, null, null, null, recursive);
92
        }else{
93
        	childNodes = new ArrayList<TaxonNode>(taxonNode.getChildNodes());
94
        }
95

    
96
        HHH_9751_Util.removeAllNull(childNodes);
97

    
98
        if (sortMode != null){
99
            Comparator<TaxonNode> comparator = sortMode.newComparator();
100
        	Collections.sort(childNodes, comparator);
101
        }
102
        defaultBeanInitializer.initializeAll(childNodes, propertyPaths);
103
        return childNodes;
104
    }
105

    
106
    /**
107
     * {@inheritDoc}
108
     */
109
    @Override
110
    public Pager<TaxonNodeDto> pageChildNodesDTOs(UUID taxonNodeUuid, boolean recursive, NodeSortMode sortMode,
111
            Integer pageSize, Integer pageIndex) {
112

    
113

    
114
        List<TaxonNode> childNodes = loadChildNodesOfTaxonNode(dao.load(taxonNodeUuid), null, recursive, sortMode);
115

    
116
        if (sortMode != null){
117
            Comparator<TaxonNode> comparator = sortMode.newComparator();
118
            Collections.sort(childNodes, comparator);
119
        }
120

    
121
        List<TaxonNodeDto> dtos = new ArrayList<>(pageSize);
122
        int start = PagerUtils.startFor(pageSize, pageIndex);
123
        int limit = PagerUtils.limitFor(pageSize);
124
        Long totalCount = Long.valueOf(childNodes.size());
125
        if(PagerUtils.hasResultsInRange(totalCount, pageIndex, pageSize)) {
126
            for(int i = start; i < start + limit; i++) {
127
                dtos.add(new TaxonNodeDto(childNodes.get(i)));
128
            }
129
        }
130

    
131

    
132
        return new DefaultPagerImpl<TaxonNodeDto>(pageIndex, totalCount, pageSize , dtos);
133
    }
134

    
135
    @Override
136
    public TaxonNodeDto parentDto(UUID taxonNodeUuid) {
137
        TaxonNode taxonNode = dao.load(taxonNodeUuid);
138
        if(taxonNode.getParent() != null) {
139
            return new TaxonNodeDto(taxonNode.getParent());
140
        }
141
        return null;
142
    }
143

    
144
    @Override
145
    @Autowired
146
    protected void setDao(ITaxonNodeDao dao) {
147
        this.dao = dao;
148
    }
149

    
150
    @Override
151
    @Transactional(readOnly = false)
152
    public DeleteResult makeTaxonNodeASynonymOfAnotherTaxonNode(TaxonNode oldTaxonNode, TaxonNode newAcceptedTaxonNode, SynonymRelationshipType synonymRelationshipType, Reference citation, String citationMicroReference)  {
153

    
154

    
155
        // TODO at the moment this method only moves synonym-, concept relations and descriptions to the new accepted taxon
156
        // in a future version we also want to move cdm data like annotations, marker, so., but we will need a policy for that
157
        if (oldTaxonNode == null || newAcceptedTaxonNode == null || oldTaxonNode.getTaxon().getName() == null){
158
            throw new IllegalArgumentException("A mandatory parameter was null.");
159
        }
160

    
161
        if(oldTaxonNode.equals(newAcceptedTaxonNode)){
162
            throw new IllegalArgumentException("Taxon can not be made synonym of its own.");
163
        }
164

    
165

    
166
        Classification classification = oldTaxonNode.getClassification();
167
        Taxon oldTaxon = HibernateProxyHelper.deproxy(oldTaxonNode.getTaxon());
168
        Taxon newAcceptedTaxon = (Taxon)this.taxonService.load(newAcceptedTaxonNode.getTaxon().getUuid());
169
        // Move oldTaxon to newTaxon
170
        //TaxonNameBase<?,?> synonymName = oldTaxon.getName();
171
        TaxonNameBase<?,?> synonymName = HibernateProxyHelper.deproxy(oldTaxon.getName());
172
        HomotypicalGroup group = synonymName.getHomotypicalGroup();
173
        group = HibernateProxyHelper.deproxy(group, HomotypicalGroup.class);
174
        if (synonymRelationshipType == null){
175
            if (synonymName.isHomotypic(newAcceptedTaxon.getName())){
176
                synonymRelationshipType = SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF();
177
            }else{
178
                synonymRelationshipType = SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF();
179
            }
180
        }
181

    
182
        //set homotypic group
183
        HomotypicalGroup newAcceptedTaxonHomotypicalgroup = newAcceptedTaxon.getHomotypicGroup();
184
        newAcceptedTaxonHomotypicalgroup = HibernateProxyHelper.deproxy(newAcceptedTaxonHomotypicalgroup, HomotypicalGroup.class);
185
        TaxonNameBase newAcceptedTaxonName = HibernateProxyHelper.deproxy(newAcceptedTaxon.getName(), TaxonNameBase.class);
186
        // Move Synonym Relations to new Taxon
187
        SynonymRelationship synonmyRelationship = newAcceptedTaxon.addSynonymName(synonymName,
188
                synonymRelationshipType, citation, citationMicroReference);
189
         HomotypicalGroup homotypicalGroupAcceptedTaxon = synonmyRelationship.getSynonym().getHomotypicGroup();
190
        // Move Synonym Relations to new Taxon
191
        // From ticket 3163 we can move taxon with accepted name having homotypic synonyms
192
        List<Synonym> synonymsInHomotypicalGroup = null;
193

    
194
        //the synonyms of the homotypical group of the old taxon
195
        if (synonymRelationshipType.equals(SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF())){
196
        	synonymsInHomotypicalGroup = oldTaxon.getSynonymsInGroup(group);
197
        }
198

    
199
        for(SynonymRelationship synRelation : oldTaxon.getSynonymRelations()){
200
            SynonymRelationshipType srt;
201
            if(synRelation.getSynonym().getName().getHomotypicalGroup()!= null
202
                    && synRelation.getSynonym().getName().getHomotypicalGroup().equals(newAcceptedTaxonName.getHomotypicalGroup())) {
203
                srt = SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF();
204
            } else if(synRelation.getType() != null && synRelation.getType().equals(SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF())) {
205
            	if (synonymRelationshipType.equals(SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF())){
206
            		srt = SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF();
207
            	} else{
208
            		srt = SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF();
209
            	}
210
            } else {
211
                srt = synRelation.getType();
212

    
213
            }
214

    
215
            newAcceptedTaxon.addSynonym(synRelation.getSynonym(),
216
                    srt,
217
                    synRelation.getCitation(),
218
                    synRelation.getCitationMicroReference());
219

    
220
            /*if (synonymsInHomotypicalGroup.contains(synRelation.getSynonym()) && srt.equals(SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF())){
221
            	homotypicalGroupAcceptedTaxon.addTypifiedName(synRelation.getSynonym().getName());
222
            }*/
223

    
224
        }
225

    
226

    
227

    
228

    
229

    
230
        // CHILD NODES
231
        if(oldTaxonNode.getChildNodes() != null && oldTaxonNode.getChildNodes().size() != 0){
232
        	List<TaxonNode> childNodes = new ArrayList<TaxonNode>();
233
        	for (TaxonNode childNode : oldTaxonNode.getChildNodes()){
234
        		childNodes.add(childNode);
235
        	}
236
            for(TaxonNode childNode :childNodes){
237
                newAcceptedTaxonNode.addChildNode(childNode, childNode.getReference(), childNode.getMicroReference()); // childNode.getSynonymToBeUsed()
238
            }
239
        }
240

    
241
        //Move Taxon RelationShips to new Taxon
242
        Set<TaxonRelationship> obsoleteTaxonRelationships = new HashSet<TaxonRelationship>();
243
        for(TaxonRelationship taxonRelationship : oldTaxon.getTaxonRelations()){
244
            Taxon fromTaxon = HibernateProxyHelper.deproxy(taxonRelationship.getFromTaxon());
245
            Taxon toTaxon = HibernateProxyHelper.deproxy(taxonRelationship.getToTaxon());
246
            if (fromTaxon == oldTaxon){
247
                newAcceptedTaxon.addTaxonRelation(taxonRelationship.getToTaxon(), taxonRelationship.getType(),
248
                        taxonRelationship.getCitation(), taxonRelationship.getCitationMicroReference());
249

    
250
            }else if(toTaxon == oldTaxon){
251
               fromTaxon.addTaxonRelation(newAcceptedTaxon, taxonRelationship.getType(),
252
                        taxonRelationship.getCitation(), taxonRelationship.getCitationMicroReference());
253
               taxonService.saveOrUpdate(fromTaxon);
254

    
255
            }else{
256
                logger.warn("Taxon is not part of its own Taxonrelationship");
257
            }
258
            // Remove old relationships
259

    
260
            fromTaxon.removeTaxonRelation(taxonRelationship);
261
            toTaxon.removeTaxonRelation(taxonRelationship);
262
            taxonRelationship.setToTaxon(null);
263
            taxonRelationship.setFromTaxon(null);
264
        }
265

    
266

    
267
        //Move descriptions to new taxon
268
        List<TaxonDescription> descriptions = new ArrayList<TaxonDescription>( oldTaxon.getDescriptions()); //to avoid concurrent modification errors (newAcceptedTaxon.addDescription() modifies also oldtaxon.descritpions())
269
        for(TaxonDescription description : descriptions){
270
            String message = "Description copied from former accepted taxon: %s (Old title: %s)";
271
            message = String.format(message, oldTaxon.getTitleCache(), description.getTitleCache());
272
            description.setTitleCache(message, true);
273
            //oldTaxon.removeDescription(description, false);
274
            newAcceptedTaxon.addDescription(description);
275
        }
276
        oldTaxon.clearDescriptions();
277

    
278
        taxonService.update(newAcceptedTaxon);
279

    
280
        taxonService.update(oldTaxon);
281

    
282
        TaxonDeletionConfigurator conf = new TaxonDeletionConfigurator();
283
        conf.setDeleteSynonymsIfPossible(false);
284
        DeleteResult result = taxonService.isDeletable(oldTaxon, conf);
285
        conf.setDeleteNameIfPossible(false);
286

    
287
        if (result.isOk()){
288
        	 result = taxonService.deleteTaxon(oldTaxon.getUuid(), conf, classification.getUuid());
289
        }else{
290
        	result.setStatus(Status.OK);
291
        	TaxonNodeDeletionConfigurator config = new TaxonNodeDeletionConfigurator();
292
        	config.setDeleteElement(false);
293
        	conf.setTaxonNodeConfig(config);
294
        	result.includeResult(deleteTaxonNode(oldTaxonNode, conf));
295
        }
296
        result.addUpdatedObject(newAcceptedTaxon);
297
        result.addUpdatedObject(oldTaxon);
298

    
299
        //oldTaxonNode.delete();
300
        return result;
301
    }
302

    
303

    
304

    
305
    /* (non-Javadoc)
306
     * @see eu.etaxonomy.cdm.api.service.ITaxonNodeService#makeTaxonNodeASynonymOfAnotherTaxonNode(java.util.UUID, java.util.UUID, java.util.UUID, java.util.UUID, java.lang.String)
307
     */
308
    @Override
309
    @Transactional(readOnly = false)
310
    public UpdateResult makeTaxonNodeASynonymOfAnotherTaxonNode(UUID oldTaxonNodeUuid,
311
            UUID newAcceptedTaxonNodeUUID,
312
            SynonymRelationshipType synonymRelationshipType,
313
            Reference citation,
314
            String citationMicroReference) {
315

    
316
        TaxonNode oldTaxonNode = dao.load(oldTaxonNodeUuid);
317
        TaxonNode oldTaxonParentNode = oldTaxonNode.getParent();
318
        TaxonNode newTaxonNode = dao.load(newAcceptedTaxonNodeUUID);
319

    
320
        UpdateResult result = makeTaxonNodeASynonymOfAnotherTaxonNode(oldTaxonNode,
321
                newTaxonNode,
322
                synonymRelationshipType,
323
                citation,
324
                citationMicroReference);
325
        result.addUpdatedCdmId(new CdmEntityIdentifier(oldTaxonParentNode.getId(), TaxonNode.class));
326
        result.addUpdatedCdmId(new CdmEntityIdentifier(newTaxonNode.getId(), TaxonNode.class));
327
        result.setCdmEntity(oldTaxonParentNode);
328
        return result;
329
    }
330

    
331
    /* (non-Javadoc)
332
     * @see eu.etaxonomy.cdm.api.service.ITaxonNodeService#deleteTaxonNodes(java.util.List)
333
     */
334
    @Override
335
    @Transactional(readOnly = false)
336
    public DeleteResult deleteTaxonNodes(List<TaxonNode> list, TaxonDeletionConfigurator config) {
337

    
338
        if (config == null){
339
        	config = new TaxonDeletionConfigurator();
340
        }
341
        DeleteResult result = new DeleteResult();
342
        List<UUID> deletedUUIDs = new ArrayList<UUID>();
343
        Classification classification = null;
344
        List<TaxonNode> taxonNodes = new ArrayList<TaxonNode>(list);
345
        for (TaxonNode treeNode:taxonNodes){
346
        	if (treeNode != null){
347

    
348
        		TaxonNode taxonNode;
349
	            taxonNode = HibernateProxyHelper.deproxy(treeNode, TaxonNode.class);
350
	            TaxonNode parent = taxonNode.getParent();
351
	            	//check whether the node has children or the children are already deleted
352
	            if(taxonNode.hasChildNodes()) {
353
            		List<TaxonNode> children = new ArrayList<TaxonNode> ();
354
            		List<TaxonNode> childNodesList = taxonNode.getChildNodes();
355
        			children.addAll(childNodesList);
356
        			int compare = config.getTaxonNodeConfig().getChildHandling().compareTo(ChildHandling.DELETE);
357
        			boolean childHandling = (compare == 0)? true: false;
358
            		if (childHandling){
359
            			boolean changeDeleteTaxon = false;
360
            			if (!config.getTaxonNodeConfig().isDeleteTaxon()){
361
            				config.getTaxonNodeConfig().setDeleteTaxon(true);
362
            				changeDeleteTaxon = true;
363
            			}
364
            			DeleteResult resultNodes = deleteTaxonNodes(children, config);
365
            			if (!resultNodes.isOk()){
366
                            result.addExceptions(resultNodes.getExceptions());
367
                            result.setStatus(resultNodes.getStatus());
368
                        }
369
            			if (changeDeleteTaxon){
370
            				config.getTaxonNodeConfig().setDeleteTaxon(false);
371
            			}
372

    
373
            		} else {
374
            			//move the children to the parent
375

    
376
            			for (TaxonNode child: childNodesList){
377
            				parent.addChildNode(child, child.getReference(), child.getMicroReference());
378
            			}
379

    
380
            		}
381
            	}
382

    
383
	            classification = taxonNode.getClassification();
384

    
385
	            if (classification.getRootNode().equals(taxonNode)){
386
	            	classification.removeRootNode();
387
	            	classification = null;
388
	            }else if (classification.getChildNodes().contains(taxonNode)){
389
            		Taxon taxon = taxonNode.getTaxon();
390
            		classification.deleteChildNode(taxonNode);
391

    
392
	            	//node is rootNode
393
	            	if (taxon != null){
394

    
395
	            		if (config.getTaxonNodeConfig().isDeleteTaxon()){
396
	            		    taxonService.saveOrUpdate(taxon);
397
	            		    saveOrUpdate(taxonNode);
398

    
399
			            	TaxonDeletionConfigurator configNew = new TaxonDeletionConfigurator();
400
			            	DeleteResult resultTaxon = taxonService.deleteTaxon(taxon.getUuid(), configNew, classification.getUuid());
401
			            	if (!resultTaxon.isOk()){
402
                                result.addExceptions(resultTaxon.getExceptions());
403
                                result.setStatus(resultTaxon.getStatus());
404
                            }
405

    
406
		            	}
407
	            	}
408
            		classification = null;
409

    
410
	            } else {
411
	            	classification = null;
412
	            	Taxon taxon = taxonNode.getTaxon();
413
	            	taxon = HibernateProxyHelper.deproxy(taxon, Taxon.class);
414
	            	if (taxon != null){
415
	            		taxon.removeTaxonNode(taxonNode);
416
	            		if (config.getTaxonNodeConfig().isDeleteTaxon()){
417
			            	TaxonDeletionConfigurator configNew = new TaxonDeletionConfigurator();
418
			            	saveOrUpdate(taxonNode);
419
			            	taxonService.saveOrUpdate(taxon);
420
			            	DeleteResult resultTaxon = taxonService.deleteTaxon(taxon.getUuid(), configNew, null);
421

    
422
                            if (!resultTaxon.isOk()){
423
                                result.addExceptions(resultTaxon.getExceptions());
424
                                result.setStatus(resultTaxon.getStatus());
425
                            }
426
		            	}
427
	            	}
428

    
429
	            }
430

    
431
	            result.addUpdatedObject(parent);
432
	            if(result.getCdmEntity() == null){
433
	                result.setCdmEntity(taxonNode);
434
                }
435
	            UUID uuid = dao.delete(taxonNode);
436
	            logger.debug("Deleted node " +uuid.toString());
437

    
438
	        }
439
        }
440
        /*if (classification != null){
441
            result.addUpdatedObject(classification);
442
        	DeleteResult resultClassification = classService.delete(classification);
443
        	 if (!resultClassification.isOk()){
444
                 result.addExceptions(resultClassification.getExceptions());
445
                 result.setStatus(resultClassification.getStatus());
446
             }
447
        }*/
448
        return result;
449

    
450
    }
451

    
452

    
453
    @Override
454
    @Transactional(readOnly = false)
455
    public DeleteResult deleteTaxonNodes(Collection<UUID> nodeUuids, TaxonDeletionConfigurator config) {
456
        List<TaxonNode> nodes = new ArrayList<TaxonNode>();
457
        for(UUID nodeUuid : nodeUuids) {
458
            nodes.add(dao.load(nodeUuid));
459
        }
460
        return deleteTaxonNodes(nodes, config);
461
    }
462

    
463

    
464

    
465
    @Override
466
    @Transactional(readOnly = false)
467
    public DeleteResult deleteTaxonNode(UUID nodeUUID, TaxonDeletionConfigurator config) {
468

    
469
    	TaxonNode node = HibernateProxyHelper.deproxy(dao.load(nodeUUID), TaxonNode.class);
470
    	return deleteTaxonNode(node, config);
471
    }
472

    
473
    @Override
474
    @Transactional(readOnly = false)
475
    public DeleteResult deleteTaxonNode(TaxonNode node, TaxonDeletionConfigurator config) {
476
        DeleteResult result = new DeleteResult();
477
        if (node == null){
478
            result.setAbort();
479
            result.addException(new Exception("The TaxonNode was already deleted."));
480
            return result;
481
        }
482
        Taxon taxon = null;
483
        try{
484
            taxon = HibernateProxyHelper.deproxy(node.getTaxon());
485
        }catch(NullPointerException e){
486
            result.setAbort();
487
            result.addException(new Exception("The Taxon was already deleted."));
488

    
489
        }
490
    	TaxonNode parent = HibernateProxyHelper.deproxy(node.getParent(), TaxonNode.class);
491
    	if (config == null){
492
    		config = new TaxonDeletionConfigurator();
493
    	}
494

    
495

    
496

    
497
    	if (config.getTaxonNodeConfig().getChildHandling().equals(ChildHandling.MOVE_TO_PARENT)){
498
    	   Object[] children = node.getChildNodes().toArray();
499
    	   TaxonNode childNode;
500
    	   for (Object child: children){
501
    	       childNode = (TaxonNode) child;
502
    	       parent.addChildNode(childNode, childNode.getReference(), childNode.getMicroReference());
503
    	   }
504
    	}else{
505
    	    deleteTaxonNodes(node.getChildNodes(), config);
506
    	}
507

    
508
    	if (taxon != null){
509
        	if (config.getTaxonNodeConfig().isDeleteTaxon() && (config.isDeleteInAllClassifications() || taxon.getTaxonNodes().size() == 1)){
510
        		result = taxonService.deleteTaxon(taxon.getUuid(), config, node.getClassification().getUuid());
511
        		result.addUpdatedObject(parent);
512
        		if (result.isOk()){
513
        			return result;
514
        		}
515
        	} else {
516
        	    result.addUpdatedObject(taxon);
517
        	}
518
    	}
519
    	result.setCdmEntity(node);
520
    	boolean success = taxon.removeTaxonNode(node);
521
    	dao.save(parent);
522
    	taxonService.saveOrUpdate(taxon);
523
    	result.addUpdatedObject(parent);
524

    
525
    	if (success){
526
			result.setStatus(Status.OK);
527
			parent = HibernateProxyHelper.deproxy(parent, TaxonNode.class);
528
			int index = parent.getChildNodes().indexOf(node);
529
			if (index > -1){
530
			    parent.removeChild(index);
531
			}
532
    		if (!dao.delete(node, config.getTaxonNodeConfig().getChildHandling().equals(ChildHandling.DELETE)).equals(null)){
533
    			return result;
534
    		} else {
535
    			result.setError();
536
    			return result;
537
    		}
538
    	}else{
539
    	    if (dao.findByUuid(node.getUuid()) != null){
540
        		result.setError();
541
        		result.addException(new Exception("The node can not be removed from the taxon."));
542
    		}
543
    		return result;
544
    	}
545

    
546

    
547

    
548
    }
549

    
550

    
551
    /* (non-Javadoc)
552
     * @see eu.etaxonomy.cdm.api.service.ITaxonNodeService#listAllNodesForClassification(eu.etaxonomy.cdm.model.taxon.Classification, int, int)
553
     */
554
    @Override
555
    public List<TaxonNode> listAllNodesForClassification(Classification classification, Integer start, Integer end) {
556
        return dao.getTaxonOfAcceptedTaxaByClassification(classification, start, end);
557
    }
558

    
559
    @Override
560
    public int countAllNodesForClassification(Classification classification) {
561
        return dao.countTaxonOfAcceptedTaxaByClassification(classification);
562
    }
563

    
564
    @Override
565
    @Transactional
566
    public UpdateResult moveTaxonNode(UUID taxonNodeUuid, UUID targetNodeUuid, int movingType){
567
        TaxonNode taxonNode = HibernateProxyHelper.deproxy(dao.load(taxonNodeUuid), TaxonNode.class);
568
    	TaxonNode targetNode = HibernateProxyHelper.deproxy(dao.load(targetNodeUuid), TaxonNode.class);
569
    	return moveTaxonNode(taxonNode, targetNode, movingType);
570
    }
571

    
572
    @Override
573
    @Transactional
574
    public UpdateResult moveTaxonNode(TaxonNode taxonNode, TaxonNode newParent, int movingType){
575
        UpdateResult result = new UpdateResult();
576

    
577
        TaxonNode parentParent = HibernateProxyHelper.deproxy(newParent.getParent(), TaxonNode.class);
578

    
579
        Integer sortIndex = -1;
580
        if (movingType == 0){
581
            sortIndex = 0;
582
        }else if (movingType == 1){
583
            sortIndex = newParent.getSortIndex();
584
            newParent = parentParent;
585
        } else if (movingType == 2){
586
            sortIndex = newParent.getSortIndex() +1;
587
            newParent = parentParent;
588
        } else{
589
            result.setAbort();
590
            result.addException(new Exception("The moving type "+ movingType +" is not supported."));
591
        }
592
        result.addUpdatedObject(newParent);
593
        result.addUpdatedObject(taxonNode.getParent());
594
        result.setCdmEntity(taxonNode);
595

    
596
        newParent.addChildNode(taxonNode, sortIndex, taxonNode.getReference(),  taxonNode.getMicroReference());
597

    
598
        dao.saveOrUpdate(newParent);
599

    
600
        return result;
601
    }
602

    
603

    
604

    
605
    @Override
606
    @Transactional
607
    public UpdateResult moveTaxonNodes(Set<UUID> taxonNodeUuids, UUID newParentNodeUuid, int movingType){
608
        UpdateResult result = new UpdateResult();
609
        TaxonNode targetNode = dao.load(newParentNodeUuid);
610
        for (UUID taxonNodeUuid: taxonNodeUuids){
611
            TaxonNode taxonNode = dao.load(taxonNodeUuid);
612
            result.includeResult(moveTaxonNode(taxonNode,targetNode, movingType));
613
        }
614
        return result;
615
    }
616

    
617
    @Override
618
    public Pager<TaxonNodeAgentRelation> pageTaxonNodeAgentRelations(UUID taxonUuid, UUID classificationUuid,
619
            UUID agentUuid, UUID rankUuid, UUID relTypeUuid, Integer pageSize, Integer pageIndex, List<String> propertyPaths) {
620

    
621

    
622
        List<TaxonNodeAgentRelation> records = null;
623

    
624
        long count = dao.countTaxonNodeAgentRelations(taxonUuid, classificationUuid, agentUuid, rankUuid, relTypeUuid);
625
        if(PagerUtils.hasResultsInRange(count, pageIndex, pageSize)) {
626
            records = dao.listTaxonNodeAgentRelations(taxonUuid, classificationUuid,
627
                    agentUuid, rankUuid, relTypeUuid, PagerUtils.startFor(pageSize, pageIndex), PagerUtils.limitFor(pageSize), propertyPaths);
628
        }
629

    
630
        Pager<TaxonNodeAgentRelation> pager = new DefaultPagerImpl<TaxonNodeAgentRelation>(pageIndex, count, pageSize, records);
631
        return pager;
632
    }
633

    
634
    @Override
635
    @Transactional
636
    public UpdateResult createNewTaxonNode(UUID parentNodeUuid, Taxon newTaxon, Reference ref, String microref){
637
        UpdateResult result = new UpdateResult();
638
        TaxonNode parent = dao.load(parentNodeUuid);
639
        TaxonNode child = null;
640
        try{
641
            child = parent.addChildTaxon(newTaxon, parent.getReference(), parent.getMicroReference());
642
        }catch(Exception e){
643
            result.addException(e);
644
            result.setError();
645
            return result;
646
        }
647
//        child = dao.save(child);
648

    
649
        dao.saveOrUpdate(parent);
650
        result.addUpdatedObject(parent);
651
        if (child != null){
652
            result.setCdmEntity(child);
653
        }
654
        return result;
655

    
656
    }
657

    
658
    @Override
659
    @Transactional
660
    public UpdateResult addTaxonNodeAgentRelation(UUID taxonNodeUUID, UUID agentUUID, DefinedTerm relationshipType){
661
        UpdateResult result = new UpdateResult();
662
        TaxonNode node = dao.load(taxonNodeUUID);
663
        TeamOrPersonBase agent = (TeamOrPersonBase) agentService.load(agentUUID);
664
        node.addAgentRelation(relationshipType, agent);
665
        try{
666
            dao.merge(node, true);
667
        }catch (Exception e){
668
            result.setError();
669
            result.addException(e);
670
        }
671
        result.setCdmEntity(node);
672
        return result;
673
    }
674

    
675

    
676
}
(89-89/97)