Project

General

Profile

Download (26 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.HibernateProxyHelper;
36
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
37
import eu.etaxonomy.cdm.model.common.DefinedTerm;
38
import eu.etaxonomy.cdm.model.description.TaxonDescription;
39
import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
40
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
41
import eu.etaxonomy.cdm.model.reference.Reference;
42
import eu.etaxonomy.cdm.model.taxon.Classification;
43
import eu.etaxonomy.cdm.model.taxon.Synonym;
44
import eu.etaxonomy.cdm.model.taxon.SynonymRelationship;
45
import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;
46
import eu.etaxonomy.cdm.model.taxon.Taxon;
47
import eu.etaxonomy.cdm.model.taxon.TaxonNaturalComparator;
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.TaxonNodeByRankAndNameComparator;
52
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
53
import eu.etaxonomy.cdm.persistence.dao.common.IDefinedTermDao;
54
import eu.etaxonomy.cdm.persistence.dao.initializer.IBeanInitializer;
55
import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonNodeDao;
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
        taxonNode = dao.load(taxonNode.getUuid());
88
        List<TaxonNode> childNodes;
89
        if (recursive == true){
90
        	childNodes  = dao.listChildrenOf(taxonNode, null, null, null, recursive);
91
        }else{
92
        	childNodes = new ArrayList<TaxonNode>(taxonNode.getChildNodes());
93
        }
94
        if (sortMode != null){
95
            Comparator<TaxonNode> comparator = null;
96
            if (sortMode.equals(NodeSortMode.NaturalOrder)){
97
                comparator = new TaxonNaturalComparator();
98
            } else if (sortMode.equals(NodeSortMode.AlphabeticalOrder)){
99
            	comparator = new TaxonNodeByNameComparator();
100
            } else if (sortMode.equals(NodeSortMode.RankAndAlphabeticalOrder)){
101
            	comparator = new TaxonNodeByRankAndNameComparator();
102
            }
103
        	Collections.sort(childNodes, comparator);
104
        }
105
        defaultBeanInitializer.initializeAll(childNodes, propertyPaths);
106
        return childNodes;
107
    }
108

    
109
    @Override
110
    @Autowired
111
    protected void setDao(ITaxonNodeDao dao) {
112
        this.dao = dao;
113
    }
114

    
115
    @Override
116
    @Transactional(readOnly = false)
117
    public DeleteResult makeTaxonNodeASynonymOfAnotherTaxonNode(TaxonNode oldTaxonNode, TaxonNode newAcceptedTaxonNode, SynonymRelationshipType synonymRelationshipType, Reference citation, String citationMicroReference)  {
118

    
119

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

    
126
        if(oldTaxonNode.equals(newAcceptedTaxonNode)){
127
            throw new IllegalArgumentException("Taxon can not be made synonym of its own.");
128
        }
129

    
130

    
131
        Classification classification = oldTaxonNode.getClassification();
132
        Taxon oldTaxon = HibernateProxyHelper.deproxy(oldTaxonNode.getTaxon());
133
        Taxon newAcceptedTaxon = (Taxon)this.taxonService.load(newAcceptedTaxonNode.getTaxon().getUuid());
134
        // Move oldTaxon to newTaxon
135
        //TaxonNameBase<?,?> synonymName = oldTaxon.getName();
136
        TaxonNameBase<?,?> synonymName = HibernateProxyHelper.deproxy(oldTaxon.getName());
137
        HomotypicalGroup group = synonymName.getHomotypicalGroup();
138
        group = HibernateProxyHelper.deproxy(group, HomotypicalGroup.class);
139
        if (synonymRelationshipType == null){
140
            if (synonymName.isHomotypic(newAcceptedTaxon.getName())){
141
                synonymRelationshipType = SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF();
142
            }else{
143
                synonymRelationshipType = SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF();
144
            }
145
        }
146

    
147
        //set homotypic group
148
        HomotypicalGroup newAcceptedTaxonHomotypicalgroup = newAcceptedTaxon.getHomotypicGroup();
149
        newAcceptedTaxonHomotypicalgroup = HibernateProxyHelper.deproxy(newAcceptedTaxonHomotypicalgroup, HomotypicalGroup.class);
150
        TaxonNameBase newAcceptedTaxonName = HibernateProxyHelper.deproxy(newAcceptedTaxon.getName(), TaxonNameBase.class);
151
        // Move Synonym Relations to new Taxon
152
        SynonymRelationship synonmyRelationship = newAcceptedTaxon.addSynonymName(synonymName,
153
                synonymRelationshipType, citation, citationMicroReference);
154
         HomotypicalGroup homotypicalGroupAcceptedTaxon = synonmyRelationship.getSynonym().getHomotypicGroup();
155
        // Move Synonym Relations to new Taxon
156
        // From ticket 3163 we can move taxon with accepted name having homotypic synonyms
157
        List<Synonym> synonymsInHomotypicalGroup = null;
158

    
159
        //the synonyms of the homotypical group of the old taxon
160
        if (synonymRelationshipType.equals(SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF())){
161
        	synonymsInHomotypicalGroup = oldTaxon.getSynonymsInGroup(group);
162
        }
163

    
164
        for(SynonymRelationship synRelation : oldTaxon.getSynonymRelations()){
165
            SynonymRelationshipType srt;
166
            if(synRelation.getSynonym().getName().getHomotypicalGroup()!= null
167
                    && synRelation.getSynonym().getName().getHomotypicalGroup().equals(newAcceptedTaxonName.getHomotypicalGroup())) {
168
                srt = SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF();
169
            } else if(synRelation.getType() != null && synRelation.getType().equals(SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF())) {
170
            	if (synonymRelationshipType.equals(SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF())){
171
            		srt = SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF();
172
            	} else{
173
            		srt = SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF();
174
            	}
175
            } else {
176
                srt = synRelation.getType();
177

    
178
            }
179

    
180
            newAcceptedTaxon.addSynonym(synRelation.getSynonym(),
181
                    srt,
182
                    synRelation.getCitation(),
183
                    synRelation.getCitationMicroReference());
184

    
185
            /*if (synonymsInHomotypicalGroup.contains(synRelation.getSynonym()) && srt.equals(SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF())){
186
            	homotypicalGroupAcceptedTaxon.addTypifiedName(synRelation.getSynonym().getName());
187
            }*/
188

    
189
        }
190

    
191

    
192

    
193

    
194

    
195
        // CHILD NODES
196
        if(oldTaxonNode.getChildNodes() != null && oldTaxonNode.getChildNodes().size() != 0){
197
        	List<TaxonNode> childNodes = new ArrayList<TaxonNode>();
198
        	for (TaxonNode childNode : oldTaxonNode.getChildNodes()){
199
        		childNodes.add(childNode);
200
        	}
201
            for(TaxonNode childNode :childNodes){
202
                newAcceptedTaxonNode.addChildNode(childNode, childNode.getReference(), childNode.getMicroReference()); // childNode.getSynonymToBeUsed()
203
            }
204
        }
205

    
206
        //Move Taxon RelationShips to new Taxon
207
        Set<TaxonRelationship> obsoleteTaxonRelationships = new HashSet<TaxonRelationship>();
208
        for(TaxonRelationship taxonRelationship : oldTaxon.getTaxonRelations()){
209
            Taxon fromTaxon = HibernateProxyHelper.deproxy(taxonRelationship.getFromTaxon());
210
            Taxon toTaxon = HibernateProxyHelper.deproxy(taxonRelationship.getToTaxon());
211
            if (fromTaxon == oldTaxon){
212
                newAcceptedTaxon.addTaxonRelation(taxonRelationship.getToTaxon(), taxonRelationship.getType(),
213
                        taxonRelationship.getCitation(), taxonRelationship.getCitationMicroReference());
214

    
215
            }else if(toTaxon == oldTaxon){
216
               fromTaxon.addTaxonRelation(newAcceptedTaxon, taxonRelationship.getType(),
217
                        taxonRelationship.getCitation(), taxonRelationship.getCitationMicroReference());
218
               taxonService.saveOrUpdate(fromTaxon);
219

    
220
            }else{
221
                logger.warn("Taxon is not part of its own Taxonrelationship");
222
            }
223
            // Remove old relationships
224

    
225
            fromTaxon.removeTaxonRelation(taxonRelationship);
226
            toTaxon.removeTaxonRelation(taxonRelationship);
227
            taxonRelationship.setToTaxon(null);
228
            taxonRelationship.setFromTaxon(null);
229
        }
230

    
231

    
232
        //Move descriptions to new taxon
233
        List<TaxonDescription> descriptions = new ArrayList<TaxonDescription>( oldTaxon.getDescriptions()); //to avoid concurrent modification errors (newAcceptedTaxon.addDescription() modifies also oldtaxon.descritpions())
234
        for(TaxonDescription description : descriptions){
235
            String message = "Description copied from former accepted taxon: %s (Old title: %s)";
236
            message = String.format(message, oldTaxon.getTitleCache(), description.getTitleCache());
237
            description.setTitleCache(message, true);
238
            //oldTaxon.removeDescription(description, false);
239
            newAcceptedTaxon.addDescription(description);
240
        }
241
        oldTaxon.clearDescriptions();
242

    
243
        taxonService.update(newAcceptedTaxon);
244

    
245
        taxonService.update(oldTaxon);
246

    
247
        TaxonDeletionConfigurator conf = new TaxonDeletionConfigurator();
248
        conf.setDeleteSynonymsIfPossible(false);
249
        DeleteResult result = taxonService.isDeletable(oldTaxon, conf);
250
        conf.setDeleteNameIfPossible(false);
251

    
252
        if (result.isOk()){
253
        	 result = taxonService.deleteTaxon(oldTaxon.getUuid(), conf, classification.getUuid());
254
        }else{
255
        	result.setStatus(Status.OK);
256
        	TaxonNodeDeletionConfigurator config = new TaxonNodeDeletionConfigurator();
257
        	config.setDeleteElement(false);
258
        	conf.setTaxonNodeConfig(config);
259
        	result.includeResult(deleteTaxonNode(oldTaxonNode, conf));
260
        }
261
        result.addUpdatedObject(newAcceptedTaxon);
262
        result.addUpdatedObject(oldTaxon);
263

    
264
        //oldTaxonNode.delete();
265
        return result;
266
    }
267

    
268

    
269

    
270
    /* (non-Javadoc)
271
     * @see eu.etaxonomy.cdm.api.service.ITaxonNodeService#makeTaxonNodeASynonymOfAnotherTaxonNode(java.util.UUID, java.util.UUID, java.util.UUID, java.util.UUID, java.lang.String)
272
     */
273
    @Override
274
    @Transactional(readOnly = false)
275
    public UpdateResult makeTaxonNodeASynonymOfAnotherTaxonNode(UUID oldTaxonNodeUuid,
276
            UUID newAcceptedTaxonNodeUUID,
277
            SynonymRelationshipType synonymRelationshipType,
278
            Reference citation,
279
            String citationMicroReference) {
280

    
281
        TaxonNode oldTaxonNode = dao.load(oldTaxonNodeUuid);
282
        TaxonNode oldTaxonParentNode = oldTaxonNode.getParent();
283
        TaxonNode newTaxonNode = dao.load(newAcceptedTaxonNodeUUID);
284

    
285
        UpdateResult result = makeTaxonNodeASynonymOfAnotherTaxonNode(oldTaxonNode,
286
                newTaxonNode,
287
                synonymRelationshipType,
288
                citation,
289
                citationMicroReference);
290
        result.addUpdatedCdmId(new CdmEntityIdentifier(oldTaxonParentNode.getId(), TaxonNode.class));
291
        result.addUpdatedCdmId(new CdmEntityIdentifier(newTaxonNode.getId(), TaxonNode.class));
292
        result.setCdmEntity(oldTaxonParentNode);
293
        return result;
294
    }
295

    
296
    /* (non-Javadoc)
297
     * @see eu.etaxonomy.cdm.api.service.ITaxonNodeService#deleteTaxonNodes(java.util.List)
298
     */
299
    @Override
300
    @Transactional(readOnly = false)
301
    public DeleteResult deleteTaxonNodes(List<TaxonNode> list, TaxonDeletionConfigurator config) {
302

    
303
        if (config == null){
304
        	config = new TaxonDeletionConfigurator();
305
        }
306
        DeleteResult result = new DeleteResult();
307
        List<UUID> deletedUUIDs = new ArrayList<UUID>();
308
        Classification classification = null;
309
        List<TaxonNode> taxonNodes = new ArrayList<TaxonNode>(list);
310
        for (TaxonNode treeNode:taxonNodes){
311
        	if (treeNode != null){
312

    
313
        		TaxonNode taxonNode;
314
	            taxonNode = HibernateProxyHelper.deproxy(treeNode, TaxonNode.class);
315
	            TaxonNode parent = taxonNode.getParent();
316
	            	//check whether the node has children or the children are already deleted
317
	            if(taxonNode.hasChildNodes()) {
318
            		List<TaxonNode> children = new ArrayList<TaxonNode> ();
319
            		List<TaxonNode> childNodesList = taxonNode.getChildNodes();
320
        			children.addAll(childNodesList);
321
        			int compare = config.getTaxonNodeConfig().getChildHandling().compareTo(ChildHandling.DELETE);
322
        			boolean childHandling = (compare == 0)? true: false;
323
            		if (childHandling){
324
            			boolean changeDeleteTaxon = false;
325
            			if (!config.getTaxonNodeConfig().isDeleteTaxon()){
326
            				config.getTaxonNodeConfig().setDeleteTaxon(true);
327
            				changeDeleteTaxon = true;
328
            			}
329
            			DeleteResult resultNodes = deleteTaxonNodes(children, config);
330
            			if (!resultNodes.isOk()){
331
                            result.addExceptions(resultNodes.getExceptions());
332
                            result.setStatus(resultNodes.getStatus());
333
                        }
334
            			if (changeDeleteTaxon){
335
            				config.getTaxonNodeConfig().setDeleteTaxon(false);
336
            			}
337

    
338
            		} else {
339
            			//move the children to the parent
340

    
341
            			for (TaxonNode child: childNodesList){
342
            				parent.addChildNode(child, child.getReference(), child.getMicroReference());
343
            			}
344

    
345
            		}
346
            	}
347

    
348
	            classification = taxonNode.getClassification();
349

    
350
	            if (classification.getRootNode().equals(taxonNode)){
351
	            	classification.removeRootNode();
352
	            	classification = null;
353
	            }else if (classification.getChildNodes().contains(taxonNode)){
354
            		Taxon taxon = taxonNode.getTaxon();
355
            		classification.deleteChildNode(taxonNode);
356

    
357
	            	//node is rootNode
358
	            	if (taxon != null){
359

    
360
	            		if (config.getTaxonNodeConfig().isDeleteTaxon()){
361
	            		    taxonService.saveOrUpdate(taxon);
362
	            		    saveOrUpdate(taxonNode);
363

    
364
			            	TaxonDeletionConfigurator configNew = new TaxonDeletionConfigurator();
365
			            	DeleteResult resultTaxon = taxonService.deleteTaxon(taxon.getUuid(), configNew, classification.getUuid());
366
			            	if (!resultTaxon.isOk()){
367
                                result.addExceptions(resultTaxon.getExceptions());
368
                                result.setStatus(resultTaxon.getStatus());
369
                            }
370

    
371
		            	}
372
	            	}
373
            		classification = null;
374

    
375
	            } else {
376
	            	classification = null;
377
	            	Taxon taxon = taxonNode.getTaxon();
378
	            	taxon = HibernateProxyHelper.deproxy(taxon, Taxon.class);
379
	            	if (taxon != null){
380
	            		taxon.removeTaxonNode(taxonNode);
381
	            		if (config.getTaxonNodeConfig().isDeleteTaxon()){
382
			            	TaxonDeletionConfigurator configNew = new TaxonDeletionConfigurator();
383
			            	saveOrUpdate(taxonNode);
384
			            	taxonService.saveOrUpdate(taxon);
385
			            	DeleteResult resultTaxon = taxonService.deleteTaxon(taxon.getUuid(), configNew, null);
386

    
387
                            if (!resultTaxon.isOk()){
388
                                result.addExceptions(resultTaxon.getExceptions());
389
                                result.setStatus(resultTaxon.getStatus());
390
                            }
391
		            	}
392
	            	}
393

    
394
	            }
395

    
396
	            result.addUpdatedObject(parent);
397
	            if(result.getCdmEntity() == null){
398
	                result.setCdmEntity(taxonNode);
399
                }
400
	            UUID uuid = dao.delete(taxonNode);
401
	            logger.debug("Deleted node " +uuid.toString());
402

    
403
	        }
404
        }
405
        /*if (classification != null){
406
            result.addUpdatedObject(classification);
407
        	DeleteResult resultClassification = classService.delete(classification);
408
        	 if (!resultClassification.isOk()){
409
                 result.addExceptions(resultClassification.getExceptions());
410
                 result.setStatus(resultClassification.getStatus());
411
             }
412
        }*/
413
        return result;
414

    
415
    }
416

    
417

    
418
    @Override
419
    @Transactional(readOnly = false)
420
    public DeleteResult deleteTaxonNodes(Collection<UUID> nodeUuids, TaxonDeletionConfigurator config) {
421
        List<TaxonNode> nodes = new ArrayList<TaxonNode>();
422
        for(UUID nodeUuid : nodeUuids) {
423
            nodes.add(dao.load(nodeUuid));
424
        }
425
        return deleteTaxonNodes(nodes, config);
426
    }
427

    
428

    
429

    
430
    @Override
431
    @Transactional(readOnly = false)
432
    public DeleteResult deleteTaxonNode(UUID nodeUUID, TaxonDeletionConfigurator config) {
433

    
434
    	TaxonNode node = HibernateProxyHelper.deproxy(dao.load(nodeUUID), TaxonNode.class);
435
    	return deleteTaxonNode(node, config);
436
    }
437

    
438
    @Override
439
    @Transactional(readOnly = false)
440
    public DeleteResult deleteTaxonNode(TaxonNode node, TaxonDeletionConfigurator config) {
441
        DeleteResult result = new DeleteResult();
442
        if (node == null){
443
            result.setAbort();
444
            result.addException(new Exception("The TaxonNode was already deleted."));
445
            return result;
446
        }
447
        Taxon taxon = null;
448
        try{
449
            taxon = HibernateProxyHelper.deproxy(node.getTaxon());
450
        }catch(NullPointerException e){
451
            result.setAbort();
452
            result.addException(new Exception("The Taxon was already deleted."));
453

    
454
        }
455
    	TaxonNode parent = HibernateProxyHelper.deproxy(node.getParent(), TaxonNode.class);
456
    	if (config == null){
457
    		config = new TaxonDeletionConfigurator();
458
    	}
459

    
460

    
461

    
462
    	if (config.getTaxonNodeConfig().getChildHandling().equals(ChildHandling.MOVE_TO_PARENT)){
463
    	   Object[] children = node.getChildNodes().toArray();
464
    	   TaxonNode childNode;
465
    	   for (Object child: children){
466
    	       childNode = (TaxonNode) child;
467
    	       parent.addChildNode(childNode, childNode.getReference(), childNode.getMicroReference());
468
    	   }
469
    	}else{
470
    	    deleteTaxonNodes(node.getChildNodes(), config);
471
    	}
472

    
473
    	if (taxon != null){
474
        	if (config.getTaxonNodeConfig().isDeleteTaxon() && (config.isDeleteInAllClassifications() || taxon.getTaxonNodes().size() == 1)){
475
        		result = taxonService.deleteTaxon(taxon.getUuid(), config, node.getClassification().getUuid());
476
        		result.addUpdatedObject(parent);
477
        		if (result.isOk()){
478
        			return result;
479
        		}
480
        	} else {
481
        	    result.addUpdatedObject(taxon);
482
        	}
483
    	}
484
    	result.setCdmEntity(node);
485
    	boolean success = taxon.removeTaxonNode(node);
486
    	dao.save(parent);
487
    	taxonService.saveOrUpdate(taxon);
488
    	result.addUpdatedObject(parent);
489

    
490
    	if (success){
491
			result.setStatus(Status.OK);
492
			parent = HibernateProxyHelper.deproxy(parent, TaxonNode.class);
493
			int index = parent.getChildNodes().indexOf(node);
494
			if (index > -1){
495
			    parent.removeChild(index);
496
			}
497
    		if (!dao.delete(node, config.getTaxonNodeConfig().getChildHandling().equals(ChildHandling.DELETE)).equals(null)){
498
    			return result;
499
    		} else {
500
    			result.setError();
501
    			return result;
502
    		}
503
    	}else{
504
    	    if (dao.findByUuid(node.getUuid()) != null){
505
        		result.setError();
506
        		result.addException(new Exception("The node can not be removed from the taxon."));
507
    		}
508
    		return result;
509
    	}
510

    
511

    
512

    
513
    }
514

    
515

    
516
    /* (non-Javadoc)
517
     * @see eu.etaxonomy.cdm.api.service.ITaxonNodeService#listAllNodesForClassification(eu.etaxonomy.cdm.model.taxon.Classification, int, int)
518
     */
519
    @Override
520
    public List<TaxonNode> listAllNodesForClassification(Classification classification, Integer start, Integer end) {
521
        return dao.getTaxonOfAcceptedTaxaByClassification(classification, start, end);
522
    }
523

    
524
    @Override
525
    public int countAllNodesForClassification(Classification classification) {
526
        return dao.countTaxonOfAcceptedTaxaByClassification(classification);
527
    }
528

    
529
    @Override
530
    @Transactional
531
    public UpdateResult moveTaxonNode(UUID taxonNodeUuid, UUID targetNodeUuid, int movingType){
532
        TaxonNode taxonNode = HibernateProxyHelper.deproxy(dao.load(taxonNodeUuid), TaxonNode.class);
533
    	TaxonNode targetNode = HibernateProxyHelper.deproxy(dao.load(targetNodeUuid), TaxonNode.class);
534
    	return moveTaxonNode(taxonNode, targetNode, movingType);
535
    }
536

    
537
    @Override
538
    @Transactional
539
    public UpdateResult moveTaxonNode(TaxonNode taxonNode, TaxonNode newParent, int movingType){
540
        UpdateResult result = new UpdateResult();
541

    
542
        TaxonNode parentParent = HibernateProxyHelper.deproxy(newParent.getParent(), TaxonNode.class);
543

    
544
        Integer sortIndex = -1;
545
        if (movingType == 0){
546
            sortIndex = 0;
547
        }else if (movingType == 1){
548
            sortIndex = newParent.getSortIndex();
549
            newParent = parentParent;
550
        } else if (movingType == 2){
551
            sortIndex = newParent.getSortIndex() +1;
552
            newParent = parentParent;
553
        } else{
554
            result.setAbort();
555
            result.addException(new Exception("The moving type "+ movingType +" is not supported."));
556
        }
557
        result.addUpdatedObject(newParent);
558
        result.addUpdatedObject(taxonNode.getParent());
559
        result.setCdmEntity(taxonNode);
560

    
561
        newParent.addChildNode(taxonNode, sortIndex, taxonNode.getReference(),  taxonNode.getMicroReference());
562

    
563
        dao.saveOrUpdate(newParent);
564

    
565
        return result;
566
    }
567

    
568

    
569

    
570
    @Override
571
    @Transactional
572
    public UpdateResult moveTaxonNodes(Set<UUID> taxonNodeUuids, UUID newParentNodeUuid, int movingType){
573
        UpdateResult result = new UpdateResult();
574
        TaxonNode targetNode = dao.load(newParentNodeUuid);
575
        for (UUID taxonNodeUuid: taxonNodeUuids){
576
            TaxonNode taxonNode = dao.load(taxonNodeUuid);
577
            result.includeResult(moveTaxonNode(taxonNode,targetNode, movingType));
578
        }
579
        return result;
580
    }
581

    
582
    @Override
583
    public Pager<TaxonNodeAgentRelation> pageTaxonNodeAgentRelations(UUID taxonUuid, UUID classificationUuid,
584
            UUID agentUuid, UUID rankUuid, UUID relTypeUuid, Integer pageSize, Integer pageIndex, List<String> propertyPaths) {
585

    
586

    
587
        List<TaxonNodeAgentRelation> records = null;
588

    
589
        long count = dao.countTaxonNodeAgentRelations(taxonUuid, classificationUuid, agentUuid, rankUuid, relTypeUuid);
590
        if(PagerUtils.hasResultsInRange(count, pageIndex, pageSize)) {
591
            records = dao.listTaxonNodeAgentRelations(taxonUuid, classificationUuid,
592
                    agentUuid, rankUuid, relTypeUuid, PagerUtils.startFor(pageSize, pageIndex), PagerUtils.limitFor(pageSize), propertyPaths);
593
        }
594

    
595
        Pager<TaxonNodeAgentRelation> pager = new DefaultPagerImpl<TaxonNodeAgentRelation>(pageIndex, count, pageSize, records);
596
        return pager;
597
    }
598

    
599
    @Override
600
    @Transactional
601
    public UpdateResult createNewTaxonNode(UUID parentNodeUuid, Taxon newTaxon, Reference ref, String microref){
602
        UpdateResult result = new UpdateResult();
603
        TaxonNode parent = dao.load(parentNodeUuid);
604
        TaxonNode child = null;
605
        try{
606
            child = parent.addChildTaxon(newTaxon, parent.getReference(), parent.getMicroReference());
607
        }catch(Exception e){
608
            result.addException(e);
609
            result.setError();
610
            return result;
611
        }
612
//        child = dao.save(child);
613

    
614
        dao.saveOrUpdate(parent);
615
        result.addUpdatedObject(parent);
616
        if (child != null){
617
            result.setCdmEntity(child);
618
        }
619
        return result;
620

    
621
    }
622

    
623
    @Override
624
    @Transactional
625
    public UpdateResult addTaxonNodeAgentRelation(UUID taxonNodeUUID, UUID agentUUID, DefinedTerm relationshipType){
626
        UpdateResult result = new UpdateResult();
627
        TaxonNode node = dao.load(taxonNodeUUID);
628
        TeamOrPersonBase agent = (TeamOrPersonBase) agentService.load(agentUUID);
629
        node.addAgentRelation(relationshipType, agent);
630
        try{
631
            dao.merge(node, true);
632
        }catch (Exception e){
633
            result.setError();
634
            result.addException(e);
635
        }
636
        result.setCdmEntity(node);
637
        return result;
638
    }
639

    
640
}
(89-89/97)