Project

General

Profile

Download (28.2 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.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
        List<TaxonNodeDto> dtos = new ArrayList<>(pageSize==null?25:pageSize);
122
        Long totalCount = Long.valueOf(allRecords.size());
123

    
124
        TaxonNameBase<?,?> parentName = null;
125

    
126
        for(CdmBase record : PagerUtils.pageList(allRecords, pageIndex, pageSize)) {
127
            if (record.isInstanceOf(TaxonNode.class)){
128
                dtos.add(new TaxonNodeDto(CdmBase.deproxy(record, TaxonNode.class)));
129
            }else if (record.isInstanceOf(Synonym.class)){
130
                Synonym synonym = CdmBase.deproxy(record, Synonym.class);
131
                parentName = parentName == null? parentNode.getTaxon().getName(): parentName;
132
                boolean isHomotypic = synonym.getName().isHomotypic(parentName);
133
                dtos.add(new TaxonNodeDto(synonym, isHomotypic));
134
            }
135
        }
136
        return new DefaultPagerImpl<TaxonNodeDto>(pageIndex, totalCount, pageSize , dtos);
137
    }
138

    
139
    @Override
140
    public TaxonNodeDto parentDto(UUID taxonNodeUuid) {
141
        TaxonNode taxonNode = dao.load(taxonNodeUuid);
142
        if(taxonNode.getParent() != null) {
143
            return new TaxonNodeDto(taxonNode.getParent());
144
        }
145
        return null;
146
    }
147

    
148
    @Override
149
    @Autowired
150
    protected void setDao(ITaxonNodeDao dao) {
151
        this.dao = dao;
152
    }
153

    
154
    @Override
155
    @Transactional(readOnly = false)
156
    public DeleteResult makeTaxonNodeASynonymOfAnotherTaxonNode(TaxonNode oldTaxonNode, TaxonNode newAcceptedTaxonNode, SynonymRelationshipType synonymRelationshipType, Reference citation, String citationMicroReference)  {
157

    
158

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

    
165
        if(oldTaxonNode.equals(newAcceptedTaxonNode)){
166
            throw new IllegalArgumentException("Taxon can not be made synonym of its own.");
167
        }
168

    
169

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

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

    
198
        //the synonyms of the homotypical group of the old taxon
199
        if (synonymRelationshipType.equals(SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF())){
200
        	synonymsInHomotypicalGroup = oldTaxon.getSynonymsInGroup(group);
201
        }
202

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

    
217
            }
218

    
219
            newAcceptedTaxon.addSynonym(synRelation.getSynonym(),
220
                    srt,
221
                    synRelation.getCitation(),
222
                    synRelation.getCitationMicroReference());
223

    
224
            /*if (synonymsInHomotypicalGroup.contains(synRelation.getSynonym()) && srt.equals(SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF())){
225
            	homotypicalGroupAcceptedTaxon.addTypifiedName(synRelation.getSynonym().getName());
226
            }*/
227

    
228
        }
229

    
230

    
231

    
232

    
233

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

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

    
254
            }else if(toTaxon == oldTaxon){
255
               fromTaxon.addTaxonRelation(newAcceptedTaxon, taxonRelationship.getType(),
256
                        taxonRelationship.getCitation(), taxonRelationship.getCitationMicroReference());
257
               taxonService.saveOrUpdate(fromTaxon);
258

    
259
            }else{
260
                logger.warn("Taxon is not part of its own Taxonrelationship");
261
            }
262
            // Remove old relationships
263

    
264
            fromTaxon.removeTaxonRelation(taxonRelationship);
265
            toTaxon.removeTaxonRelation(taxonRelationship);
266
            taxonRelationship.setToTaxon(null);
267
            taxonRelationship.setFromTaxon(null);
268
        }
269

    
270

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

    
282
        taxonService.update(newAcceptedTaxon);
283

    
284
        taxonService.update(oldTaxon);
285

    
286
        TaxonDeletionConfigurator conf = new TaxonDeletionConfigurator();
287
        conf.setDeleteSynonymsIfPossible(false);
288
        DeleteResult result = taxonService.isDeletable(oldTaxon, conf);
289
        conf.setDeleteNameIfPossible(false);
290

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

    
303
        //oldTaxonNode.delete();
304
        return result;
305
    }
306

    
307

    
308

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

    
320
        TaxonNode oldTaxonNode = dao.load(oldTaxonNodeUuid);
321
        TaxonNode oldTaxonParentNode = oldTaxonNode.getParent();
322
        TaxonNode newTaxonNode = dao.load(newAcceptedTaxonNodeUUID);
323

    
324
        UpdateResult result = makeTaxonNodeASynonymOfAnotherTaxonNode(oldTaxonNode,
325
                newTaxonNode,
326
                synonymRelationshipType,
327
                citation,
328
                citationMicroReference);
329
        result.addUpdatedCdmId(new CdmEntityIdentifier(oldTaxonParentNode.getId(), TaxonNode.class));
330
        result.addUpdatedCdmId(new CdmEntityIdentifier(newTaxonNode.getId(), TaxonNode.class));
331
        result.setCdmEntity(oldTaxonParentNode);
332
        return result;
333
    }
334

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

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

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

    
377
            		} else {
378
            			//move the children to the parent
379

    
380
            			for (TaxonNode child: childNodesList){
381
            				parent.addChildNode(child, child.getReference(), child.getMicroReference());
382
            			}
383

    
384
            		}
385
            	}
386

    
387
	            classification = taxonNode.getClassification();
388

    
389
	            if (classification.getRootNode().equals(taxonNode)){
390
	            	classification.removeRootNode();
391
	            	classification = null;
392
	            }else if (classification.getChildNodes().contains(taxonNode)){
393
            		Taxon taxon = taxonNode.getTaxon();
394
            		classification.deleteChildNode(taxonNode);
395

    
396
	            	//node is rootNode
397
	            	if (taxon != null){
398

    
399
	            		if (config.getTaxonNodeConfig().isDeleteTaxon()){
400
	            		    taxonService.saveOrUpdate(taxon);
401
	            		    saveOrUpdate(taxonNode);
402

    
403
			            	TaxonDeletionConfigurator configNew = new TaxonDeletionConfigurator();
404
			            	DeleteResult resultTaxon = taxonService.deleteTaxon(taxon.getUuid(), configNew, classification.getUuid());
405
			            	if (!resultTaxon.isOk()){
406
                                result.addExceptions(resultTaxon.getExceptions());
407
                                result.setStatus(resultTaxon.getStatus());
408
                            }
409

    
410
		            	}
411
	            	}
412
            		classification = null;
413

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

    
426
                            if (!resultTaxon.isOk()){
427
                                result.addExceptions(resultTaxon.getExceptions());
428
                                result.setStatus(resultTaxon.getStatus());
429
                            }
430
		            	}
431
	            	}
432

    
433
	            }
434

    
435
	            result.addUpdatedObject(parent);
436
	            if(result.getCdmEntity() == null){
437
	                result.setCdmEntity(taxonNode);
438
                }
439
	            UUID uuid = dao.delete(taxonNode);
440
	            logger.debug("Deleted node " +uuid.toString());
441

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

    
454
    }
455

    
456

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

    
467

    
468

    
469
    @Override
470
    @Transactional(readOnly = false)
471
    public DeleteResult deleteTaxonNode(UUID nodeUUID, TaxonDeletionConfigurator config) {
472

    
473
    	TaxonNode node = HibernateProxyHelper.deproxy(dao.load(nodeUUID), TaxonNode.class);
474
    	return deleteTaxonNode(node, config);
475
    }
476

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

    
493
        }
494
    	TaxonNode parent = HibernateProxyHelper.deproxy(node.getParent(), TaxonNode.class);
495
    	if (config == null){
496
    		config = new TaxonDeletionConfigurator();
497
    	}
498

    
499

    
500

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

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

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

    
550

    
551

    
552
    }
553

    
554

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

    
563
    @Override
564
    public int countAllNodesForClassification(Classification classification) {
565
        return dao.countTaxonOfAcceptedTaxaByClassification(classification);
566
    }
567

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

    
576
    @Override
577
    @Transactional
578
    public UpdateResult moveTaxonNode(TaxonNode taxonNode, TaxonNode newParent, int movingType){
579
        UpdateResult result = new UpdateResult();
580

    
581
        TaxonNode parentParent = HibernateProxyHelper.deproxy(newParent.getParent(), TaxonNode.class);
582

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

    
600
        newParent.addChildNode(taxonNode, sortIndex, taxonNode.getReference(),  taxonNode.getMicroReference());
601

    
602
        dao.saveOrUpdate(newParent);
603

    
604
        return result;
605
    }
606

    
607

    
608

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

    
621
    @Override
622
    public Pager<TaxonNodeAgentRelation> pageTaxonNodeAgentRelations(UUID taxonUuid, UUID classificationUuid,
623
            UUID agentUuid, UUID rankUuid, UUID relTypeUuid, Integer pageSize, Integer pageIndex, List<String> propertyPaths) {
624

    
625

    
626
        List<TaxonNodeAgentRelation> records = null;
627

    
628
        long count = dao.countTaxonNodeAgentRelations(taxonUuid, classificationUuid, agentUuid, rankUuid, relTypeUuid);
629
        if(PagerUtils.hasResultsInRange(count, pageIndex, pageSize)) {
630
            records = dao.listTaxonNodeAgentRelations(taxonUuid, classificationUuid,
631
                    agentUuid, rankUuid, relTypeUuid, PagerUtils.startFor(pageSize, pageIndex), PagerUtils.limitFor(pageSize), propertyPaths);
632
        }
633

    
634
        Pager<TaxonNodeAgentRelation> pager = new DefaultPagerImpl<TaxonNodeAgentRelation>(pageIndex, count, pageSize, records);
635
        return pager;
636
    }
637

    
638
    @Override
639
    @Transactional
640
    public UpdateResult createNewTaxonNode(UUID parentNodeUuid, Taxon newTaxon, Reference ref, String microref){
641
        UpdateResult result = new UpdateResult();
642

    
643
        UUID taxonUUID = taxonService.saveOrUpdate(newTaxon);
644
        newTaxon = (Taxon) taxonService.load(taxonUUID);
645

    
646
        TaxonNode parent = dao.load(parentNodeUuid);
647
        TaxonNode child = null;
648
        try{
649
            child = parent.addChildTaxon(newTaxon, parent.getReference(), parent.getMicroReference());
650
        }catch(Exception e){
651
            result.addException(e);
652
            result.setError();
653
            return result;
654
        }
655
//        child = dao.save(child);
656

    
657
        dao.saveOrUpdate(parent);
658
        result.addUpdatedObject(parent);
659
        if (child != null){
660
            result.setCdmEntity(child);
661
        }
662
        return result;
663

    
664
    }
665
    @Override
666
    @Transactional
667
    public UpdateResult createNewTaxonNode(UUID parentNodeUuid, UUID taxonUuid, Reference ref, String microref){
668
        UpdateResult result = new UpdateResult();
669
        TaxonNode parent = dao.load(parentNodeUuid);
670
        Taxon taxon = (Taxon) taxonService.load(taxonUuid);
671
        TaxonNode child = null;
672
        try{
673
            child = parent.addChildTaxon(taxon, parent.getReference(), parent.getMicroReference());
674
        }catch(Exception e){
675
            result.addException(e);
676
            result.setError();
677
            return result;
678
        }
679
//        child = dao.save(child);
680

    
681
        dao.saveOrUpdate(parent);
682
        result.addUpdatedObject(parent);
683
        if (child != null){
684
            result.setCdmEntity(child);
685
        }
686
        return result;
687

    
688
    }
689

    
690
    @Override
691
    @Transactional
692
    public UpdateResult addTaxonNodeAgentRelation(UUID taxonNodeUUID, UUID agentUUID, DefinedTerm relationshipType){
693
        UpdateResult result = new UpdateResult();
694
        TaxonNode node = dao.load(taxonNodeUUID);
695
        TeamOrPersonBase agent = (TeamOrPersonBase) agentService.load(agentUUID);
696
        node.addAgentRelation(relationshipType, agent);
697
        try{
698
            dao.merge(node, true);
699
        }catch (Exception e){
700
            result.setError();
701
            result.addException(e);
702
        }
703
        result.setCdmEntity(node);
704
        return result;
705
    }
706

    
707

    
708
}
(89-89/98)