Project

General

Profile

Download (25.5 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.TaxonNode;
48
import eu.etaxonomy.cdm.model.taxon.TaxonNodeAgentRelation;
49
import eu.etaxonomy.cdm.model.taxon.TaxonNodeByNameComparator;
50
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
51
import eu.etaxonomy.cdm.persistence.dao.common.IDefinedTermDao;
52
import eu.etaxonomy.cdm.persistence.dao.initializer.IBeanInitializer;
53
import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonNodeDao;
54

    
55
/**
56
 * @author n.hoffmann
57
 * @created Apr 9, 2010
58
 * @version 1.0
59
 */
60
@Service
61
@Transactional(readOnly = true)
62
public class TaxonNodeServiceImpl extends AnnotatableServiceBase<TaxonNode, ITaxonNodeDao> implements ITaxonNodeService{
63
    private static final Logger logger = Logger.getLogger(TaxonNodeServiceImpl.class);
64

    
65
    @Autowired
66
    private IBeanInitializer defaultBeanInitializer;
67

    
68
    private final Comparator<? super TaxonNode> taxonNodeComparator = new TaxonNodeByNameComparator();
69

    
70
    @Autowired
71
    private ITaxonService taxonService;
72

    
73
    @Autowired
74
    private IAgentService agentService;
75

    
76
    @Autowired
77
    private IClassificationService classService;
78

    
79
    @Autowired
80
    private IDefinedTermDao termDao;
81

    
82
    @Override
83
    public List<TaxonNode> loadChildNodesOfTaxonNode(TaxonNode taxonNode,
84
            List<String> propertyPaths, boolean recursive, NodeSortMode sortMode) {
85
        taxonNode = dao.load(taxonNode.getUuid());
86
        List<TaxonNode> childNodes;
87
        if (recursive == true){
88
        	childNodes  = dao.listChildrenOf(taxonNode, null, null, null, recursive);
89
        }else{
90
        	childNodes = new ArrayList<TaxonNode>(taxonNode.getChildNodes());
91
        }
92
        if (sortMode != null){
93
            Comparator<TaxonNode> comparator = sortMode.newComparator();
94
        	Collections.sort(childNodes, comparator);
95
        }
96
        defaultBeanInitializer.initializeAll(childNodes, propertyPaths);
97
        return childNodes;
98
    }
99

    
100
    @Override
101
    @Autowired
102
    protected void setDao(ITaxonNodeDao dao) {
103
        this.dao = dao;
104
    }
105

    
106
    @Override
107
    @Transactional(readOnly = false)
108
    public DeleteResult makeTaxonNodeASynonymOfAnotherTaxonNode(TaxonNode oldTaxonNode, TaxonNode newAcceptedTaxonNode, SynonymRelationshipType synonymRelationshipType, Reference citation, String citationMicroReference)  {
109

    
110

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

    
117
        if(oldTaxonNode.equals(newAcceptedTaxonNode)){
118
            throw new IllegalArgumentException("Taxon can not be made synonym of its own.");
119
        }
120

    
121

    
122
        Classification classification = oldTaxonNode.getClassification();
123
        Taxon oldTaxon = HibernateProxyHelper.deproxy(oldTaxonNode.getTaxon());
124
        Taxon newAcceptedTaxon = (Taxon)this.taxonService.load(newAcceptedTaxonNode.getTaxon().getUuid());
125
        // Move oldTaxon to newTaxon
126
        //TaxonNameBase<?,?> synonymName = oldTaxon.getName();
127
        TaxonNameBase<?,?> synonymName = HibernateProxyHelper.deproxy(oldTaxon.getName());
128
        HomotypicalGroup group = synonymName.getHomotypicalGroup();
129
        group = HibernateProxyHelper.deproxy(group, HomotypicalGroup.class);
130
        if (synonymRelationshipType == null){
131
            if (synonymName.isHomotypic(newAcceptedTaxon.getName())){
132
                synonymRelationshipType = SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF();
133
            }else{
134
                synonymRelationshipType = SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF();
135
            }
136
        }
137

    
138
        //set homotypic group
139
        HomotypicalGroup newAcceptedTaxonHomotypicalgroup = newAcceptedTaxon.getHomotypicGroup();
140
        newAcceptedTaxonHomotypicalgroup = HibernateProxyHelper.deproxy(newAcceptedTaxonHomotypicalgroup, HomotypicalGroup.class);
141
        TaxonNameBase newAcceptedTaxonName = HibernateProxyHelper.deproxy(newAcceptedTaxon.getName(), TaxonNameBase.class);
142
        // Move Synonym Relations to new Taxon
143
        SynonymRelationship synonmyRelationship = newAcceptedTaxon.addSynonymName(synonymName,
144
                synonymRelationshipType, citation, citationMicroReference);
145
         HomotypicalGroup homotypicalGroupAcceptedTaxon = synonmyRelationship.getSynonym().getHomotypicGroup();
146
        // Move Synonym Relations to new Taxon
147
        // From ticket 3163 we can move taxon with accepted name having homotypic synonyms
148
        List<Synonym> synonymsInHomotypicalGroup = null;
149

    
150
        //the synonyms of the homotypical group of the old taxon
151
        if (synonymRelationshipType.equals(SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF())){
152
        	synonymsInHomotypicalGroup = oldTaxon.getSynonymsInGroup(group);
153
        }
154

    
155
        for(SynonymRelationship synRelation : oldTaxon.getSynonymRelations()){
156
            SynonymRelationshipType srt;
157
            if(synRelation.getSynonym().getName().getHomotypicalGroup()!= null
158
                    && synRelation.getSynonym().getName().getHomotypicalGroup().equals(newAcceptedTaxonName.getHomotypicalGroup())) {
159
                srt = SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF();
160
            } else if(synRelation.getType() != null && synRelation.getType().equals(SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF())) {
161
            	if (synonymRelationshipType.equals(SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF())){
162
            		srt = SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF();
163
            	} else{
164
            		srt = SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF();
165
            	}
166
            } else {
167
                srt = synRelation.getType();
168

    
169
            }
170

    
171
            newAcceptedTaxon.addSynonym(synRelation.getSynonym(),
172
                    srt,
173
                    synRelation.getCitation(),
174
                    synRelation.getCitationMicroReference());
175

    
176
            /*if (synonymsInHomotypicalGroup.contains(synRelation.getSynonym()) && srt.equals(SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF())){
177
            	homotypicalGroupAcceptedTaxon.addTypifiedName(synRelation.getSynonym().getName());
178
            }*/
179

    
180
        }
181

    
182

    
183

    
184

    
185

    
186
        // CHILD NODES
187
        if(oldTaxonNode.getChildNodes() != null && oldTaxonNode.getChildNodes().size() != 0){
188
        	List<TaxonNode> childNodes = new ArrayList<TaxonNode>();
189
        	for (TaxonNode childNode : oldTaxonNode.getChildNodes()){
190
        		childNodes.add(childNode);
191
        	}
192
            for(TaxonNode childNode :childNodes){
193
                newAcceptedTaxonNode.addChildNode(childNode, childNode.getReference(), childNode.getMicroReference()); // childNode.getSynonymToBeUsed()
194
            }
195
        }
196

    
197
        //Move Taxon RelationShips to new Taxon
198
        Set<TaxonRelationship> obsoleteTaxonRelationships = new HashSet<TaxonRelationship>();
199
        for(TaxonRelationship taxonRelationship : oldTaxon.getTaxonRelations()){
200
            Taxon fromTaxon = HibernateProxyHelper.deproxy(taxonRelationship.getFromTaxon());
201
            Taxon toTaxon = HibernateProxyHelper.deproxy(taxonRelationship.getToTaxon());
202
            if (fromTaxon == oldTaxon){
203
                newAcceptedTaxon.addTaxonRelation(taxonRelationship.getToTaxon(), taxonRelationship.getType(),
204
                        taxonRelationship.getCitation(), taxonRelationship.getCitationMicroReference());
205

    
206
            }else if(toTaxon == oldTaxon){
207
               fromTaxon.addTaxonRelation(newAcceptedTaxon, taxonRelationship.getType(),
208
                        taxonRelationship.getCitation(), taxonRelationship.getCitationMicroReference());
209
               taxonService.saveOrUpdate(fromTaxon);
210

    
211
            }else{
212
                logger.warn("Taxon is not part of its own Taxonrelationship");
213
            }
214
            // Remove old relationships
215

    
216
            fromTaxon.removeTaxonRelation(taxonRelationship);
217
            toTaxon.removeTaxonRelation(taxonRelationship);
218
            taxonRelationship.setToTaxon(null);
219
            taxonRelationship.setFromTaxon(null);
220
        }
221

    
222

    
223
        //Move descriptions to new taxon
224
        List<TaxonDescription> descriptions = new ArrayList<TaxonDescription>( oldTaxon.getDescriptions()); //to avoid concurrent modification errors (newAcceptedTaxon.addDescription() modifies also oldtaxon.descritpions())
225
        for(TaxonDescription description : descriptions){
226
            String message = "Description copied from former accepted taxon: %s (Old title: %s)";
227
            message = String.format(message, oldTaxon.getTitleCache(), description.getTitleCache());
228
            description.setTitleCache(message, true);
229
            //oldTaxon.removeDescription(description, false);
230
            newAcceptedTaxon.addDescription(description);
231
        }
232
        oldTaxon.clearDescriptions();
233

    
234
        taxonService.update(newAcceptedTaxon);
235

    
236
        taxonService.update(oldTaxon);
237

    
238
        TaxonDeletionConfigurator conf = new TaxonDeletionConfigurator();
239
        conf.setDeleteSynonymsIfPossible(false);
240
        DeleteResult result = taxonService.isDeletable(oldTaxon, conf);
241
        conf.setDeleteNameIfPossible(false);
242

    
243
        if (result.isOk()){
244
        	 result = taxonService.deleteTaxon(oldTaxon.getUuid(), conf, classification.getUuid());
245
        }else{
246
        	result.setStatus(Status.OK);
247
        	TaxonNodeDeletionConfigurator config = new TaxonNodeDeletionConfigurator();
248
        	config.setDeleteElement(false);
249
        	conf.setTaxonNodeConfig(config);
250
        	result.includeResult(deleteTaxonNode(oldTaxonNode, conf));
251
        }
252
        result.addUpdatedObject(newAcceptedTaxon);
253
        result.addUpdatedObject(oldTaxon);
254

    
255
        //oldTaxonNode.delete();
256
        return result;
257
    }
258

    
259

    
260

    
261
    /* (non-Javadoc)
262
     * @see eu.etaxonomy.cdm.api.service.ITaxonNodeService#makeTaxonNodeASynonymOfAnotherTaxonNode(java.util.UUID, java.util.UUID, java.util.UUID, java.util.UUID, java.lang.String)
263
     */
264
    @Override
265
    @Transactional(readOnly = false)
266
    public UpdateResult makeTaxonNodeASynonymOfAnotherTaxonNode(UUID oldTaxonNodeUuid,
267
            UUID newAcceptedTaxonNodeUUID,
268
            SynonymRelationshipType synonymRelationshipType,
269
            Reference citation,
270
            String citationMicroReference) {
271

    
272
        TaxonNode oldTaxonNode = dao.load(oldTaxonNodeUuid);
273
        TaxonNode oldTaxonParentNode = oldTaxonNode.getParent();
274
        TaxonNode newTaxonNode = dao.load(newAcceptedTaxonNodeUUID);
275

    
276
        UpdateResult result = makeTaxonNodeASynonymOfAnotherTaxonNode(oldTaxonNode,
277
                newTaxonNode,
278
                synonymRelationshipType,
279
                citation,
280
                citationMicroReference);
281
        result.addUpdatedCdmId(new CdmEntityIdentifier(oldTaxonParentNode.getId(), TaxonNode.class));
282
        result.addUpdatedCdmId(new CdmEntityIdentifier(newTaxonNode.getId(), TaxonNode.class));
283
        result.setCdmEntity(oldTaxonParentNode);
284
        return result;
285
    }
286

    
287
    /* (non-Javadoc)
288
     * @see eu.etaxonomy.cdm.api.service.ITaxonNodeService#deleteTaxonNodes(java.util.List)
289
     */
290
    @Override
291
    @Transactional(readOnly = false)
292
    public DeleteResult deleteTaxonNodes(List<TaxonNode> list, TaxonDeletionConfigurator config) {
293

    
294
        if (config == null){
295
        	config = new TaxonDeletionConfigurator();
296
        }
297
        DeleteResult result = new DeleteResult();
298
        List<UUID> deletedUUIDs = new ArrayList<UUID>();
299
        Classification classification = null;
300
        List<TaxonNode> taxonNodes = new ArrayList<TaxonNode>(list);
301
        for (TaxonNode treeNode:taxonNodes){
302
        	if (treeNode != null){
303

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

    
329
            		} else {
330
            			//move the children to the parent
331

    
332
            			for (TaxonNode child: childNodesList){
333
            				parent.addChildNode(child, child.getReference(), child.getMicroReference());
334
            			}
335

    
336
            		}
337
            	}
338

    
339
	            classification = taxonNode.getClassification();
340

    
341
	            if (classification.getRootNode().equals(taxonNode)){
342
	            	classification.removeRootNode();
343
	            	classification = null;
344
	            }else if (classification.getChildNodes().contains(taxonNode)){
345
            		Taxon taxon = taxonNode.getTaxon();
346
            		classification.deleteChildNode(taxonNode);
347

    
348
	            	//node is rootNode
349
	            	if (taxon != null){
350

    
351
	            		if (config.getTaxonNodeConfig().isDeleteTaxon()){
352
	            		    taxonService.saveOrUpdate(taxon);
353
	            		    saveOrUpdate(taxonNode);
354

    
355
			            	TaxonDeletionConfigurator configNew = new TaxonDeletionConfigurator();
356
			            	DeleteResult resultTaxon = taxonService.deleteTaxon(taxon.getUuid(), configNew, classification.getUuid());
357
			            	if (!resultTaxon.isOk()){
358
                                result.addExceptions(resultTaxon.getExceptions());
359
                                result.setStatus(resultTaxon.getStatus());
360
                            }
361

    
362
		            	}
363
	            	}
364
            		classification = null;
365

    
366
	            } else {
367
	            	classification = null;
368
	            	Taxon taxon = taxonNode.getTaxon();
369
	            	taxon = HibernateProxyHelper.deproxy(taxon, Taxon.class);
370
	            	if (taxon != null){
371
	            		taxon.removeTaxonNode(taxonNode);
372
	            		if (config.getTaxonNodeConfig().isDeleteTaxon()){
373
			            	TaxonDeletionConfigurator configNew = new TaxonDeletionConfigurator();
374
			            	saveOrUpdate(taxonNode);
375
			            	taxonService.saveOrUpdate(taxon);
376
			            	DeleteResult resultTaxon = taxonService.deleteTaxon(taxon.getUuid(), configNew, null);
377

    
378
                            if (!resultTaxon.isOk()){
379
                                result.addExceptions(resultTaxon.getExceptions());
380
                                result.setStatus(resultTaxon.getStatus());
381
                            }
382
		            	}
383
	            	}
384

    
385
	            }
386

    
387
	            result.addUpdatedObject(parent);
388
	            if(result.getCdmEntity() == null){
389
	                result.setCdmEntity(taxonNode);
390
                }
391
	            UUID uuid = dao.delete(taxonNode);
392
	            logger.debug("Deleted node " +uuid.toString());
393

    
394
	        }
395
        }
396
        /*if (classification != null){
397
            result.addUpdatedObject(classification);
398
        	DeleteResult resultClassification = classService.delete(classification);
399
        	 if (!resultClassification.isOk()){
400
                 result.addExceptions(resultClassification.getExceptions());
401
                 result.setStatus(resultClassification.getStatus());
402
             }
403
        }*/
404
        return result;
405

    
406
    }
407

    
408

    
409
    @Override
410
    @Transactional(readOnly = false)
411
    public DeleteResult deleteTaxonNodes(Collection<UUID> nodeUuids, TaxonDeletionConfigurator config) {
412
        List<TaxonNode> nodes = new ArrayList<TaxonNode>();
413
        for(UUID nodeUuid : nodeUuids) {
414
            nodes.add(dao.load(nodeUuid));
415
        }
416
        return deleteTaxonNodes(nodes, config);
417
    }
418

    
419

    
420

    
421
    @Override
422
    @Transactional(readOnly = false)
423
    public DeleteResult deleteTaxonNode(UUID nodeUUID, TaxonDeletionConfigurator config) {
424

    
425
    	TaxonNode node = HibernateProxyHelper.deproxy(dao.load(nodeUUID), TaxonNode.class);
426
    	return deleteTaxonNode(node, config);
427
    }
428

    
429
    @Override
430
    @Transactional(readOnly = false)
431
    public DeleteResult deleteTaxonNode(TaxonNode node, TaxonDeletionConfigurator config) {
432
        DeleteResult result = new DeleteResult();
433
        if (node == null){
434
            result.setAbort();
435
            result.addException(new Exception("The TaxonNode was already deleted."));
436
            return result;
437
        }
438
        Taxon taxon = null;
439
        try{
440
            taxon = HibernateProxyHelper.deproxy(node.getTaxon());
441
        }catch(NullPointerException e){
442
            result.setAbort();
443
            result.addException(new Exception("The Taxon was already deleted."));
444

    
445
        }
446
    	TaxonNode parent = HibernateProxyHelper.deproxy(node.getParent(), TaxonNode.class);
447
    	if (config == null){
448
    		config = new TaxonDeletionConfigurator();
449
    	}
450

    
451

    
452

    
453
    	if (config.getTaxonNodeConfig().getChildHandling().equals(ChildHandling.MOVE_TO_PARENT)){
454
    	   Object[] children = node.getChildNodes().toArray();
455
    	   TaxonNode childNode;
456
    	   for (Object child: children){
457
    	       childNode = (TaxonNode) child;
458
    	       parent.addChildNode(childNode, childNode.getReference(), childNode.getMicroReference());
459
    	   }
460
    	}else{
461
    	    deleteTaxonNodes(node.getChildNodes(), config);
462
    	}
463

    
464
    	if (taxon != null){
465
        	if (config.getTaxonNodeConfig().isDeleteTaxon() && (config.isDeleteInAllClassifications() || taxon.getTaxonNodes().size() == 1)){
466
        		result = taxonService.deleteTaxon(taxon.getUuid(), config, node.getClassification().getUuid());
467
        		result.addUpdatedObject(parent);
468
        		if (result.isOk()){
469
        			return result;
470
        		}
471
        	} else {
472
        	    result.addUpdatedObject(taxon);
473
        	}
474
    	}
475
    	result.setCdmEntity(node);
476
    	boolean success = taxon.removeTaxonNode(node);
477
    	dao.save(parent);
478
    	taxonService.saveOrUpdate(taxon);
479
    	result.addUpdatedObject(parent);
480

    
481
    	if (success){
482
			result.setStatus(Status.OK);
483
			parent = HibernateProxyHelper.deproxy(parent, TaxonNode.class);
484
			int index = parent.getChildNodes().indexOf(node);
485
			if (index > -1){
486
			    parent.removeChild(index);
487
			}
488
    		if (!dao.delete(node, config.getTaxonNodeConfig().getChildHandling().equals(ChildHandling.DELETE)).equals(null)){
489
    			return result;
490
    		} else {
491
    			result.setError();
492
    			return result;
493
    		}
494
    	}else{
495
    	    if (dao.findByUuid(node.getUuid()) != null){
496
        		result.setError();
497
        		result.addException(new Exception("The node can not be removed from the taxon."));
498
    		}
499
    		return result;
500
    	}
501

    
502

    
503

    
504
    }
505

    
506

    
507
    /* (non-Javadoc)
508
     * @see eu.etaxonomy.cdm.api.service.ITaxonNodeService#listAllNodesForClassification(eu.etaxonomy.cdm.model.taxon.Classification, int, int)
509
     */
510
    @Override
511
    public List<TaxonNode> listAllNodesForClassification(Classification classification, Integer start, Integer end) {
512
        return dao.getTaxonOfAcceptedTaxaByClassification(classification, start, end);
513
    }
514

    
515
    @Override
516
    public int countAllNodesForClassification(Classification classification) {
517
        return dao.countTaxonOfAcceptedTaxaByClassification(classification);
518
    }
519

    
520
    @Override
521
    @Transactional
522
    public UpdateResult moveTaxonNode(UUID taxonNodeUuid, UUID targetNodeUuid, int movingType){
523
        TaxonNode taxonNode = HibernateProxyHelper.deproxy(dao.load(taxonNodeUuid), TaxonNode.class);
524
    	TaxonNode targetNode = HibernateProxyHelper.deproxy(dao.load(targetNodeUuid), TaxonNode.class);
525
    	return moveTaxonNode(taxonNode, targetNode, movingType);
526
    }
527

    
528
    @Override
529
    @Transactional
530
    public UpdateResult moveTaxonNode(TaxonNode taxonNode, TaxonNode newParent, int movingType){
531
        UpdateResult result = new UpdateResult();
532

    
533
        TaxonNode parentParent = HibernateProxyHelper.deproxy(newParent.getParent(), TaxonNode.class);
534

    
535
        Integer sortIndex = -1;
536
        if (movingType == 0){
537
            sortIndex = 0;
538
        }else if (movingType == 1){
539
            sortIndex = newParent.getSortIndex();
540
            newParent = parentParent;
541
        } else if (movingType == 2){
542
            sortIndex = newParent.getSortIndex() +1;
543
            newParent = parentParent;
544
        } else{
545
            result.setAbort();
546
            result.addException(new Exception("The moving type "+ movingType +" is not supported."));
547
        }
548
        result.addUpdatedObject(newParent);
549
        result.addUpdatedObject(taxonNode.getParent());
550
        result.setCdmEntity(taxonNode);
551

    
552
        newParent.addChildNode(taxonNode, sortIndex, taxonNode.getReference(),  taxonNode.getMicroReference());
553

    
554
        dao.saveOrUpdate(newParent);
555

    
556
        return result;
557
    }
558

    
559

    
560

    
561
    @Override
562
    @Transactional
563
    public UpdateResult moveTaxonNodes(Set<UUID> taxonNodeUuids, UUID newParentNodeUuid, int movingType){
564
        UpdateResult result = new UpdateResult();
565
        TaxonNode targetNode = dao.load(newParentNodeUuid);
566
        for (UUID taxonNodeUuid: taxonNodeUuids){
567
            TaxonNode taxonNode = dao.load(taxonNodeUuid);
568
            result.includeResult(moveTaxonNode(taxonNode,targetNode, movingType));
569
        }
570
        return result;
571
    }
572

    
573
    @Override
574
    public Pager<TaxonNodeAgentRelation> pageTaxonNodeAgentRelations(UUID taxonUuid, UUID classificationUuid,
575
            UUID agentUuid, UUID rankUuid, UUID relTypeUuid, Integer pageSize, Integer pageIndex, List<String> propertyPaths) {
576

    
577

    
578
        List<TaxonNodeAgentRelation> records = null;
579

    
580
        long count = dao.countTaxonNodeAgentRelations(taxonUuid, classificationUuid, agentUuid, rankUuid, relTypeUuid);
581
        if(PagerUtils.hasResultsInRange(count, pageIndex, pageSize)) {
582
            records = dao.listTaxonNodeAgentRelations(taxonUuid, classificationUuid,
583
                    agentUuid, rankUuid, relTypeUuid, PagerUtils.startFor(pageSize, pageIndex), PagerUtils.limitFor(pageSize), propertyPaths);
584
        }
585

    
586
        Pager<TaxonNodeAgentRelation> pager = new DefaultPagerImpl<TaxonNodeAgentRelation>(pageIndex, count, pageSize, records);
587
        return pager;
588
    }
589

    
590
    @Override
591
    @Transactional
592
    public UpdateResult createNewTaxonNode(UUID parentNodeUuid, Taxon newTaxon, Reference ref, String microref){
593
        UpdateResult result = new UpdateResult();
594
        TaxonNode parent = dao.load(parentNodeUuid);
595
        TaxonNode child = null;
596
        try{
597
            child = parent.addChildTaxon(newTaxon, parent.getReference(), parent.getMicroReference());
598
        }catch(Exception e){
599
            result.addException(e);
600
            result.setError();
601
            return result;
602
        }
603
//        child = dao.save(child);
604

    
605
        dao.saveOrUpdate(parent);
606
        result.addUpdatedObject(parent);
607
        if (child != null){
608
            result.setCdmEntity(child);
609
        }
610
        return result;
611

    
612
    }
613

    
614
    @Override
615
    @Transactional
616
    public UpdateResult addTaxonNodeAgentRelation(UUID taxonNodeUUID, UUID agentUUID, DefinedTerm relationshipType){
617
        UpdateResult result = new UpdateResult();
618
        TaxonNode node = dao.load(taxonNodeUUID);
619
        TeamOrPersonBase agent = (TeamOrPersonBase) agentService.load(agentUUID);
620
        node.addAgentRelation(relationshipType, agent);
621
        try{
622
            dao.merge(node, true);
623
        }catch (Exception e){
624
            result.setError();
625
            result.addException(e);
626
        }
627
        result.setCdmEntity(node);
628
        return result;
629
    }
630

    
631
}
(89-89/97)