Project

General

Profile

Download (102 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2009 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.api.service;
10

    
11
import static org.junit.Assert.assertEquals;
12
import static org.junit.Assert.assertNotNull;
13
import static org.junit.Assert.assertNull;
14
import static org.junit.Assert.assertTrue;
15

    
16
import java.io.FileNotFoundException;
17
import java.util.ArrayList;
18
import java.util.Iterator;
19
import java.util.List;
20
import java.util.Set;
21
import java.util.UUID;
22

    
23
import org.apache.log4j.Logger;
24
import org.junit.Assert;
25
import org.junit.Test;
26
import org.unitils.dbunit.annotation.DataSet;
27
import org.unitils.spring.annotation.SpringBeanByType;
28

    
29
import eu.etaxonomy.cdm.api.service.config.IdentifiableServiceConfiguratorImpl;
30
import eu.etaxonomy.cdm.api.service.config.IncludedTaxonConfiguration;
31
import eu.etaxonomy.cdm.api.service.config.MatchingTaxonConfigurator;
32
import eu.etaxonomy.cdm.api.service.config.NameDeletionConfigurator;
33
import eu.etaxonomy.cdm.api.service.config.NodeDeletionConfigurator.ChildHandling;
34
import eu.etaxonomy.cdm.api.service.config.SynonymDeletionConfigurator;
35
import eu.etaxonomy.cdm.api.service.config.TaxonDeletionConfigurator;
36
import eu.etaxonomy.cdm.api.service.dto.IncludedTaxaDTO;
37
import eu.etaxonomy.cdm.api.service.exception.HomotypicalGroupChangeException;
38
import eu.etaxonomy.cdm.api.service.pager.Pager;
39
import eu.etaxonomy.cdm.model.agent.Person;
40
import eu.etaxonomy.cdm.model.common.Annotation;
41
import eu.etaxonomy.cdm.model.common.CdmBase;
42
import eu.etaxonomy.cdm.model.common.IdentifiableSource;
43
import eu.etaxonomy.cdm.model.common.Language;
44
import eu.etaxonomy.cdm.model.common.LanguageString;
45
import eu.etaxonomy.cdm.model.common.Marker;
46
import eu.etaxonomy.cdm.model.common.MarkerType;
47
import eu.etaxonomy.cdm.model.description.CommonTaxonName;
48
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
49
import eu.etaxonomy.cdm.model.description.IndividualsAssociation;
50
import eu.etaxonomy.cdm.model.description.TaxonDescription;
51
import eu.etaxonomy.cdm.model.description.TextData;
52
import eu.etaxonomy.cdm.model.metadata.SecReferenceHandlingEnum;
53
import eu.etaxonomy.cdm.model.metadata.SecReferenceHandlingSwapEnum;
54
import eu.etaxonomy.cdm.model.name.IBotanicalName;
55
import eu.etaxonomy.cdm.model.name.INonViralName;
56
import eu.etaxonomy.cdm.model.name.NameRelationship;
57
import eu.etaxonomy.cdm.model.name.NameRelationshipType;
58
import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
59
import eu.etaxonomy.cdm.model.name.Rank;
60
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
61
import eu.etaxonomy.cdm.model.name.TaxonName;
62
import eu.etaxonomy.cdm.model.name.TaxonNameFactory;
63
import eu.etaxonomy.cdm.model.occurrence.DerivationEvent;
64
import eu.etaxonomy.cdm.model.occurrence.DerivationEventType;
65
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
66
import eu.etaxonomy.cdm.model.occurrence.DeterminationEvent;
67
import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
68
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
69
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationType;
70
import eu.etaxonomy.cdm.model.reference.OriginalSourceType;
71
import eu.etaxonomy.cdm.model.reference.Reference;
72
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
73
import eu.etaxonomy.cdm.model.taxon.Classification;
74
import eu.etaxonomy.cdm.model.taxon.Synonym;
75
import eu.etaxonomy.cdm.model.taxon.SynonymType;
76
import eu.etaxonomy.cdm.model.taxon.Taxon;
77
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
78
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
79
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
80
import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
81
import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy;
82
import eu.etaxonomy.cdm.test.integration.CdmTransactionalIntegrationTest;
83
import eu.etaxonomy.cdm.test.unitils.CleanSweepInsertLoadStrategy;
84

    
85
/**
86
 * @author a.mueller
87
 */
88
public class TaxonServiceImplTest extends CdmTransactionalIntegrationTest {
89

    
90
    private static final Logger logger = Logger.getLogger(TaxonServiceImplTest.class);
91

    
92
    @SpringBeanByType
93
    private ITaxonService service;
94

    
95
    @SpringBeanByType
96
    private INameService nameService;
97

    
98
    @SpringBeanByType
99
    private IReferenceService referenceService;
100

    
101
    @SpringBeanByType
102
    private IClassificationService classificationService;
103

    
104
    @SpringBeanByType
105
    private ITaxonNodeService nodeService;
106

    
107
    @SpringBeanByType
108
    private IDescriptionService descriptionService;
109

    
110
    @SpringBeanByType
111
    private IDescriptionElementService descriptionElementService;
112

    
113
    @SpringBeanByType
114
    private IMarkerService markerService;
115

    
116
    @SpringBeanByType
117
    private IEventBaseService eventService;
118

    
119
    @SpringBeanByType
120
    private IOccurrenceService occurenceService;
121

    
122
    private Synonym synonym;
123
    private Synonym synonym2;
124

    
125
    private Taxon taxWithSyn;
126
    private Taxon tax2WithSyn;
127
    private Taxon taxWithoutSyn;
128
    private UUID uuidSyn;
129
    private UUID uuidTaxWithoutSyn;
130
    private UUID uuidSyn2;
131
    private UUID uuidTaxWithSyn;
132

    
133
    private static String[] genera = {"Carex", "Abies", "Belladonna", "Dracula", "Maria", "Calendula", "Polygala", "Vincia"};
134
    private static String[] epitheta = {"vulgaris", "magdalena", "officinalis", "alba", "negra", "communa", "alpina", "rotundifolia", "greutheriana", "helventica", "allemania", "franca"};
135
    private static String[] ranks = {"subsp", "var", "f"};
136

    
137
    public static UUID GENUS_NAME_UUID = UUID.fromString("8d761fc4-b509-42f4-9568-244161934336");
138
    public static UUID GENUS_UUID = UUID.fromString("bf4298a8-1735-4353-a210-244442e1bd62");
139
    public static UUID BASIONYM_UUID = UUID.fromString("7911c51d-ccb7-4708-8992-639eae58a0e3");
140
    public static UUID SPECIES1_UUID = UUID.fromString("f0eb77d9-76e0-47f4-813f-9b5605b78685");
141
    public static UUID SPECIES1_NAME_UUID = UUID.fromString("efd78713-126f-42e1-9070-a1ff83f12abf");
142
    public static UUID SYNONYM_NAME_UUID = UUID.fromString("b9cbaa74-dbe0-4930-8050-b7754ce85dc0");
143
    public static UUID SPECIES2_NAME_UUID = UUID.fromString("0267ab67-483e-4da5-b654-11013b242c22");
144
    public static UUID SPECIES2_UUID = UUID.fromString("e20eb549-ced6-4e79-9d74-44f0792a4929");
145
    public static UUID SYNONYM2_NAME_UUID = UUID.fromString("7c17c811-4201-454b-8108-7be7c91c0938");
146
    public static UUID SYNONYM2_UUID = UUID.fromString("2520b103-bd89-4ac1-99e4-e3bfcedfd4eb");
147
    public static UUID SPECIES5_NAME_UUID = UUID.fromString("0c6ecaac-804d-49e5-a33f-1b7ee77439e3");
148

    
149
/****************** TESTS *****************************/
150

    
151

    
152
    /**
153
     * Test method for {@link eu.etaxonomy.cdm.api.service.TaxonServiceImpl#getTaxonByUuid(java.util.UUID)}.
154
     */
155
    @Test
156
    public final void testGetTaxonByUuid() {
157
        Taxon expectedTaxon = Taxon.NewInstance(null, null);
158
        UUID uuid = service.save(expectedTaxon).getUuid();
159
        TaxonBase<?> actualTaxon = service.find(uuid);
160
        assertEquals(expectedTaxon, actualTaxon);
161
    }
162

    
163
    /**
164
     * Test method for {@link eu.etaxonomy.cdm.api.service.TaxonServiceImpl#getTaxonByUuid(java.util.UUID)}.
165
     */
166
    @Test
167
    public final void testGetTaxonByTitle() {
168
        TaxonName name = TaxonName.NewInstance(NomenclaturalCode.ICNAFP, Rank.SPECIES(), "Abies", null, "alba", null, null, null, null, null);
169
        Taxon expectedTaxon = Taxon.NewInstance(name, null);
170
        expectedTaxon.setDoubtful(true);
171
        service.save(expectedTaxon);
172
        IdentifiableServiceConfiguratorImpl<TaxonBase> config = new IdentifiableServiceConfiguratorImpl<TaxonBase>();
173
        config.setTitleSearchString("Abies alba*");
174
        //doubtful taxa should be found
175
        Pager<TaxonBase> actualTaxa = service.findByTitle(config);
176
        assertEquals(expectedTaxon, actualTaxa.getRecords().get(0));
177

    
178
        //and other taxa as well
179
        expectedTaxon.setDoubtful(false);
180
        service.saveOrUpdate(expectedTaxon);
181
        actualTaxa = service.findByTitle(config);
182
        assertEquals(expectedTaxon, actualTaxa.getRecords().get(0));
183
    }
184

    
185

    
186
    /**
187
     * Test method for {@link eu.etaxonomy.cdm.api.service.TaxonServiceImpl#saveTaxon(eu.etaxonomy.cdm.model.taxon.TaxonBase)}.
188
     */
189
    @Test
190
    public final void testSaveTaxon() {
191
        Taxon expectedTaxon = Taxon.NewInstance(null, null);
192
        UUID uuid = service.save(expectedTaxon).getUuid();
193
        TaxonBase<?> actualTaxon = service.find(uuid);
194
        assertEquals(expectedTaxon, actualTaxon);
195
    }
196

    
197
    @Test
198
    public final void testSaveOrUpdateTaxon() {
199
        Taxon expectedTaxon = Taxon.NewInstance(null, null);
200
        UUID uuid = service.save(expectedTaxon).getUuid();
201
        TaxonBase<?> actualTaxon = service.find(uuid);
202
        assertEquals(expectedTaxon, actualTaxon);
203

    
204
        actualTaxon.setName(TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES()));
205
        try{
206
            service.saveOrUpdate(actualTaxon);
207
        }catch(Exception e){
208
            Assert.fail();
209
        }
210
    }
211

    
212
    @Test
213
    public final void testSaveOrUpdateTaxonWithMisappliedName() {
214
        Taxon expectedTaxon = Taxon.NewInstance(null, null);
215
        TaxonName misappliedNameName = TaxonName.NewInstance(NomenclaturalCode.ICNAFP, Rank.SPECIES(), "Abies", null, "alba", null, null, null, null, null);
216

    
217
        UUID misappliedNameNameUuid = nameService.save(misappliedNameName).getUuid();
218
        misappliedNameName = nameService.find(misappliedNameNameUuid);
219
        SpecimenTypeDesignation typedes = SpecimenTypeDesignation.NewInstance();
220
        DerivedUnit derivedUnit = DerivedUnit.NewPreservedSpecimenInstance();
221
        FieldUnit fieldUnit = FieldUnit.NewInstance();
222
        DerivationEvent derivationEvent = DerivationEvent.NewSimpleInstance(fieldUnit, derivedUnit, DerivationEventType.ACCESSIONING());
223
//        derivedUnit.addDerivationEvent(derivationEvent);
224
        typedes.setTypeSpecimen(derivedUnit);
225
        misappliedNameName.addTypeDesignation(typedes, false);
226
        Taxon misappliedName = Taxon.NewInstance(misappliedNameName, null);
227
        UUID misappliedNameUuid = service.save(misappliedName).getUuid();
228
        misappliedName = (Taxon) service.find(misappliedNameUuid);
229
        expectedTaxon.addMisappliedName(misappliedName, null, null);
230
        UUID uuid = service.save(expectedTaxon).getUuid();
231
        TaxonBase<?> actualTaxon = service.find(uuid);
232
        assertEquals(expectedTaxon, actualTaxon);
233
        misappliedName.setSec(ReferenceFactory.newArticle());
234

    
235
        try{
236
            service.saveOrUpdate(actualTaxon);
237
            misappliedName = (Taxon)service.find(misappliedNameUuid);
238
            Assert.assertNotNull(misappliedName.getSec());
239
        }catch(Exception e){
240
            Assert.fail();
241
        }
242
        commitAndStartNewTransaction(null);
243
        actualTaxon = service.find(uuid);
244
        ((Taxon)actualTaxon).getTaxonRelations(misappliedName).iterator().next().getFromTaxon().setSec(null);
245
        try{
246
            service.saveOrUpdate(actualTaxon);
247
            misappliedName = (Taxon)service.find(misappliedNameUuid);
248
            Assert.assertNull(misappliedName.getSec());
249
        }catch(Exception e){
250
            Assert.fail();
251
        }
252
    }
253

    
254

    
255
    @Test
256
    public final void testSwapSynonymAndAcceptedTaxon() throws FileNotFoundException{
257

    
258
        createTestDataSet();
259
        synonym.setSec(ReferenceFactory.newArticle());
260
        service.saveOrUpdate(synonym);
261
        UpdateResult result = service.swapSynonymAndAcceptedTaxon(synonym, taxWithSyn, true, false, SecReferenceHandlingSwapEnum.AlwaysDelete, null, null);
262

    
263
        // find forces flush
264
        Taxon tax = (Taxon)service.find(result.getCdmEntity().getUuid());
265
        MatchingTaxonConfigurator configurator = MatchingTaxonConfigurator.NewInstance();
266
        configurator.setTaxonNameTitle("Test3");
267
        List<TaxonBase> synList = service.findTaxaByName(configurator);
268

    
269
        if (synList.size() > 0){
270
            TaxonBase<?> syn = synList.get(0);
271
            assertTrue(tax.getSynonyms().contains(syn));
272
        }else{
273
            Assert.fail("There should be a synonym with name Test3");
274
        }
275
        assertTrue(tax.getName().getTitleCache().equals("Test2"));
276
    }
277

    
278
    @Test
279
    public final void testSwapSynonymAndAcceptedTaxonNewUuid() throws FileNotFoundException{
280

    
281
        createTestDataSet();
282
        synonym.setSec(ReferenceFactory.newArticle());
283
        service.saveOrUpdate(synonym);
284
        UpdateResult result = service.swapSynonymAndAcceptedTaxon(synonym, taxWithSyn, true, true, SecReferenceHandlingSwapEnum.AlwaysDelete, null, null);
285

    
286
        // find forces flush
287
        Taxon tax = (Taxon)service.find(result.getCdmEntity().getUuid());
288
        MatchingTaxonConfigurator configurator = MatchingTaxonConfigurator.NewInstance();
289
        configurator.setTaxonNameTitle("Test3");
290
        @SuppressWarnings("rawtypes")
291
        List<TaxonBase> synList = service.findTaxaByName(configurator);
292

    
293
        if (synList.size() > 0){
294
            TaxonBase<?> syn = synList.get(0);
295
            assertTrue(tax.getSynonyms().contains(syn));
296
        }else{
297
            Assert.fail("There should be a synonym with name Test3");
298
        }
299
        assertTrue(tax.getName().getTitleCache().equals("Test2"));
300
    }
301

    
302
    @Test
303
    public final void testChangeSynonymToAcceptedTaxon() throws FileNotFoundException{
304

    
305
		createTestDataSet();
306

    
307
        UpdateResult result = new UpdateResult();
308
        try {
309
            result = service.changeSynonymToAcceptedTaxon(synonym, taxWithSyn, null, null, null, true);
310
        } catch (HomotypicalGroupChangeException e) {
311
            Assert.fail("Invocation of change method should not throw an exception");
312
        }
313
        taxWithSyn = null;
314
        //test flush (resave deleted object)
315
        TaxonBase<?> syn = service.find(uuidSyn);
316
        taxWithSyn = (Taxon)service.find(uuidTaxWithSyn);
317
        Taxon taxNew = (Taxon)service.find(result.getCdmEntity().getUuid());
318
        assertNull(syn);
319
        assertNotNull(taxWithSyn);
320
        assertNotNull(taxNew);
321

    
322
        Assert.assertEquals("New taxon should have 1 synonym relationship (the old homotypic synonym)", 1, ((Taxon)result.getCdmEntity()).getSynonyms().size());
323
    }
324

    
325
    @Test
326
    public final void testChangeSynonymToAcceptedTaxonWithSecHandlingAlwaysDelete(){
327
        Taxon genus = getTestTaxon();
328
        TaxonNode node = genus.getTaxonNodes().iterator().next();
329

    
330
        UpdateResult result = new UpdateResult();
331
        try {
332
            result = service.changeSynonymToAcceptedTaxon(SYNONYM2_UUID, SPECIES2_UUID, node.getUuid(), null, null, SecReferenceHandlingEnum.AlwaysDelete, true);
333
        } catch (HomotypicalGroupChangeException e) {
334
            Assert.fail("Invocation of change method should not throw an exception");
335
        }
336
        taxWithSyn = null;
337
        //test flush (resave deleted object)
338
        TaxonBase<?> syn = service.find(SYNONYM2_UUID);
339
        taxWithSyn = (Taxon)service.find(SPECIES2_UUID);
340
        TaxonNode taxNodeNew = nodeService.find(result.getCdmEntity().getUuid());
341
        Taxon taxNew = taxNodeNew.getTaxon();
342
        assertNull(syn);
343
        assertNotNull(taxWithSyn);
344
        assertNotNull(taxNew);
345
        assertNull(taxNew.getSec());
346

    
347

    
348
    }
349

    
350

    
351

    
352
    @Test
353
    public final void testChangeSynonymToAcceptedTaxonWithSecHandlingUseNewParentSec(){
354
        Taxon genus = getTestTaxon();
355
        TaxonNode node = genus.getTaxonNodes().iterator().next();
356
        UpdateResult result = new UpdateResult();
357
        TaxonBase<?> syn = service.find(SYNONYM2_UUID);
358
        Reference sec = ReferenceFactory.newBook();
359
        sec.setTitleCache("Flora Cuba", true);
360
        syn.setSec(sec);
361
        service.saveOrUpdate(syn);
362
        try {
363
            result = service.changeSynonymToAcceptedTaxon(SYNONYM2_UUID, SPECIES2_UUID, node.getUuid(), null, null, SecReferenceHandlingEnum.UseNewParentSec, true);
364
        } catch (HomotypicalGroupChangeException e) {
365
            Assert.fail("Invocation of change method should not throw an exception");
366
        }
367
        taxWithSyn = null;
368
        //test flush (resave deleted object)
369
        syn = service.find(SYNONYM2_UUID);
370
        taxWithSyn = (Taxon)service.find(SPECIES2_UUID);
371
        TaxonNode taxNodeNew = nodeService.find(result.getCdmEntity().getUuid());
372
        Taxon taxNew = taxNodeNew.getTaxon();
373
        assertNull(syn);
374
        assertNotNull(taxWithSyn);
375
        assertNotNull(taxNew);
376
        assertNotNull(taxNew.getSec());
377
        assertEquals(taxWithSyn.getSec(), taxNew.getSec());
378

    
379
    }
380

    
381
    @Test
382
    @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="TaxonServiceImplTest.testMoveSynonymToAnotherTaxon.xml")
383
    public final void testChangeSynonymToAcceptedTaxonWithSecHandlingWarningSelect(){
384
        Taxon genus = getTestTaxon();
385
        TaxonNode node = genus.getTaxonNodes().iterator().next();
386

    
387
        UpdateResult result = new UpdateResult();
388
        TaxonBase<?> syn = service.find(SYNONYM2_UUID);
389
        Reference sec = ReferenceFactory.newBook();
390
        sec.setTitleCache("Flora Cuba", true);
391
        Reference newSec = ReferenceFactory.newBook();
392
        newSec.setTitleCache("Flora Hawaii", true);
393
        UUID newSecUuid = referenceService.saveOrUpdate(newSec);
394
        syn.setSec(sec);
395
        service.saveOrUpdate(syn);
396
        try {
397
            result = service.changeSynonymToAcceptedTaxon(SYNONYM2_UUID, SPECIES2_UUID, node.getUuid(), newSecUuid, "23", SecReferenceHandlingEnum.KeepOrSelect, true);
398
        } catch (HomotypicalGroupChangeException e) {
399
            Assert.fail("Invocation of change method should not throw an exception");
400
        }
401
        taxWithSyn = null;
402
        //test flush (resave deleted object)
403
        syn = service.find(SYNONYM2_UUID);
404
        taxWithSyn = (Taxon)service.find(SPECIES2_UUID);
405
        TaxonNode taxNodeNew = nodeService.find(result.getCdmEntity().getUuid());
406
        Taxon taxNew = taxNodeNew.getTaxon();
407
        assertNull(syn);
408
        assertNotNull(taxWithSyn);
409
        assertNotNull(taxNew);
410
        assertNotNull(taxNew.getSec());
411
        assertEquals(newSec, taxNew.getSec());
412

    
413
    }
414

    
415

    
416
    @Test
417
    public final void testChangeSynonymToAcceptedTaxonSynonymForTwoTaxa(){
418
        try {
419
			createTestDataSet();
420
		} catch (FileNotFoundException e1) {
421
			// TODO Auto-generated catch block
422
			e1.printStackTrace();
423
		}
424

    
425

    
426
        Taxon taxon = null;
427
        UpdateResult result = new UpdateResult();
428
        try {
429
            result = service.changeSynonymToAcceptedTaxon(synonym, taxWithSyn, null, null, null, true);
430
            service.save(taxon);
431
        } catch (HomotypicalGroupChangeException e) {
432
            Assert.fail("Invocation of change method should not throw an exception");
433
        }
434
        taxWithSyn = null;
435
        tax2WithSyn = null;
436

    
437
        //test flush (resave deleted object)
438
        TaxonBase<?> syn = service.find(uuidSyn);
439
        taxWithSyn = (Taxon)service.find(uuidTaxWithSyn);
440
        Taxon taxNew = (Taxon)service.find(((Taxon)result.getCdmEntity()).getUuid());
441
        assertNull(syn);
442
        assertNotNull(taxWithSyn);
443
        assertNotNull(taxNew);
444

    
445
       // Assert.assertEquals("New taxon should have 1 synonym relationship (the old homotypic synonym)", 1, taxon.getSynonymRelations().size());
446
    }
447

    
448
    /**
449
     * Old implementation taken from {@link TaxonServiceImplBusinessTest} for old version of method.
450
     */
451
    @Test
452
    public final void testMoveSynonymToAnotherTaxon_OLD() {
453
        SynonymType heteroTypicSynonymType = SynonymType.HETEROTYPIC_SYNONYM_OF();
454
        Reference reference = ReferenceFactory.newGeneric();
455
        String referenceDetail = "test";
456

    
457
        INonViralName t1n = TaxonNameFactory.NewNonViralInstance(null);
458
        Taxon t1 = Taxon.NewInstance(t1n, reference);
459
        INonViralName t2n = TaxonNameFactory.NewNonViralInstance(null);
460
        Taxon t2 = Taxon.NewInstance(t2n, reference);
461
        INonViralName s1n = TaxonNameFactory.NewNonViralInstance(null);
462
        Synonym s1 = Synonym.NewInstance(s1n, reference);
463
        t1.addSynonym(s1, heteroTypicSynonymType);
464
        service.saveOrUpdate(t1);
465

    
466
        Synonym synonym = t1.getSynonyms().iterator().next();
467

    
468
        boolean keepReference = false;
469
        boolean moveHomotypicGroup = false;
470
        try {
471
            service.moveSynonymToAnotherTaxon(synonym, t2, moveHomotypicGroup, heteroTypicSynonymType, reference.getUuid(), referenceDetail, keepReference);
472
        } catch (HomotypicalGroupChangeException e) {
473
            Assert.fail("Method call should not throw exception");
474
        }
475

    
476
        Assert.assertTrue("t1 should have no synonyms", t1.getSynonyms().isEmpty());
477

    
478
        Set<Synonym> synonyms = t2.getSynonyms();
479
        Assert.assertTrue("t2 should have exactly one synonym", synonyms.size() == 1);
480

    
481
        synonym = synonyms.iterator().next();
482

    
483
        Assert.assertEquals(t2, synonym.getAcceptedTaxon());
484
        Assert.assertEquals(heteroTypicSynonymType, synonym.getType());
485
        Assert.assertEquals(reference, synonym.getSec());
486
        Assert.assertEquals(referenceDetail, synonym.getSecMicroReference());
487
    }
488

    
489
    @Test
490
    @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="TaxonServiceImplTest.testMoveSynonymToAnotherTaxon.xml")
491
    public final void testMoveSynonymToAnotherTaxon() throws Exception {
492
        final String[] tableNames = new String[]{};
493

    
494
//        printDataSet(System.err, new String[]{"AgentBase", "TaxonBase"});
495
//        printDataSet(System.err, new String[]{"TaxonNode"});
496

    
497
        UUID uuidNewTaxon = UUID.fromString("2d9a642d-5a82-442d-8fec-95efa978e8f8");
498
        UUID uuidOldTaxon = UUID.fromString("c47fdb72-f32c-452e-8305-4b44f01179d0");
499
        UUID uuidSyn1 = UUID.fromString("7da85381-ad9d-4886-9d4d-0eeef40e3d88");
500
        UUID uuidSyn3 = UUID.fromString("3fba2b22-22ae-4291-af67-faab748a5232");
501
        UUID uuidSyn4 = UUID.fromString("f9b589c7-50cf-4df2-a52e-1b85eb7e4805");
502
        UUID uuidSyn5 = UUID.fromString("fcc0bcf8-8bac-43bd-9508-1e97821587dd");
503
        UUID uuidSyn6 = UUID.fromString("0ccd4e7c-6fbd-4b7c-bd47-29e45b92f34b");
504
        UUID uuidRef1 = UUID.fromString("336f9b38-698c-45d7-be7b-993ed3355bdc");
505
        UUID uuidRef2 = UUID.fromString("c8f49d1a-69e1-48a3-98bb-45d61f3da3e7");
506

    
507

    
508
        boolean moveHomotypicGroup = true;
509
        SynonymType newSynonymType = null;
510
        boolean keepReference = true;
511
        Reference newReference = null;
512
        String newReferenceDetail = null;
513

    
514
        Taxon newTaxon = (Taxon)service.load(uuidNewTaxon);
515
        Synonym homotypicSynonym = (Synonym)service.load(uuidSyn1);
516
        Assert.assertNotNull("Synonym should exist", homotypicSynonym);
517
        Assert.assertNotNull("Synonym should have 1 relation", homotypicSynonym.getAcceptedTaxon());
518
        Assert.assertEquals("Accepted taxon of single relation should be the old taxon", uuidOldTaxon, homotypicSynonym.getAcceptedTaxon().getUuid());
519
        Taxon oldTaxon = homotypicSynonym.getAcceptedTaxon();
520

    
521
        try {
522
            service.moveSynonymToAnotherTaxon(homotypicSynonym, newTaxon, moveHomotypicGroup, newSynonymType, null, newReferenceDetail, keepReference);
523
            Assert.fail("Homotypic synonym move to other taxon should throw an exception");
524
        } catch (HomotypicalGroupChangeException e) {
525
            if (e.getMessage().contains("Synonym is in homotypic group with accepted taxon and other synonym(s). First remove synonym from homotypic group of accepted taxon before moving to other taxon")){
526
                //OK
527
                commitAndStartNewTransaction(tableNames);
528
            }else{
529
                Assert.fail("Unexpected exception occurred: " + e.getMessage());
530
            }
531
        }
532
        //Asserts
533
        homotypicSynonym = (Synonym)service.load(uuidSyn1);
534
        Assert.assertNotNull("Synonym should still exist", homotypicSynonym);
535
        Assert.assertNotNull("Synonym should still have 1 relation", homotypicSynonym.getAcceptedTaxon());
536
        Assert.assertEquals("Accepted taxon of single relation should be the old taxon", oldTaxon, homotypicSynonym.getAcceptedTaxon());
537

    
538
        //test heterotypic synonym with other synonym in homotypic group
539
        newTaxon = (Taxon)service.load(uuidNewTaxon);
540
        Synonym heterotypicSynonym = (Synonym)service.load(uuidSyn3);
541
        Assert.assertNotNull("Synonym should exist", heterotypicSynonym);
542
        Assert.assertNotNull("Synonym should have 1 relation", heterotypicSynonym.getAcceptedTaxon());
543
        Assert.assertEquals("Accepted taxon of single relation should be the old taxon", uuidOldTaxon, heterotypicSynonym.getAcceptedTaxon().getUuid());
544
        oldTaxon = heterotypicSynonym.getAcceptedTaxon();
545
        moveHomotypicGroup = false;
546

    
547
        try {
548
            service.moveSynonymToAnotherTaxon(heterotypicSynonym, newTaxon, moveHomotypicGroup, newSynonymType, null, newReferenceDetail, keepReference);
549
            Assert.fail("Heterotypic synonym move to other taxon should throw an exception");
550
        } catch (HomotypicalGroupChangeException e) {
551
            if (e.getMessage().contains("Synonym is in homotypic group with other synonym(s). Either move complete homotypic group or remove synonym from homotypic group prior to moving to other taxon")){
552
                //OK
553
                commitAndStartNewTransaction(tableNames);
554
            }else{
555
                Assert.fail("Unexpected exception occurred: " + e.getMessage());
556
            }
557
        }
558
        //Asserts
559
        heterotypicSynonym = (Synonym)service.load(uuidSyn3);
560
        Assert.assertNotNull("Synonym should still exist", heterotypicSynonym);
561
        Assert.assertNotNull("Synonym should have accepted taxon", heterotypicSynonym.getAcceptedTaxon());
562
        Assert.assertEquals("Accepted taxon of single relation should still be the old taxon", oldTaxon, heterotypicSynonym.getAcceptedTaxon());
563

    
564

    
565
        //test heterotypic synonym with no other synonym in homotypic group
566
        //+ keep reference
567

    
568
        newTaxon = (Taxon)service.load(uuidNewTaxon);
569
        heterotypicSynonym = (Synonym)service.load(uuidSyn5);
570
        Assert.assertNotNull("Synonym should exist", heterotypicSynonym);
571
        Assert.assertNotNull("Synonym should have accepted taxon", heterotypicSynonym.getAcceptedTaxon());
572
        Assert.assertEquals("Accepted taxon of single relation should be the old taxon", uuidOldTaxon, heterotypicSynonym.getAcceptedTaxon().getUuid());
573
        oldTaxon = heterotypicSynonym.getAcceptedTaxon();
574
        moveHomotypicGroup = false;
575

    
576
        try {
577
            service.moveSynonymToAnotherTaxon(heterotypicSynonym, newTaxon, moveHomotypicGroup, newSynonymType, null, newReferenceDetail, keepReference);
578
        } catch (HomotypicalGroupChangeException e) {
579
            Assert.fail("Move of single heterotypic synonym should not throw exception: " + e.getMessage());
580
        }
581
        //Asserts
582
        commitAndStartNewTransaction(tableNames);
583

    
584
        heterotypicSynonym = (Synonym)service.load(uuidSyn5);
585
        Assert.assertNotNull("Synonym should still exist", heterotypicSynonym);
586
        Assert.assertNotNull("Synonym should have accepted taxon", heterotypicSynonym.getAcceptedTaxon());
587
        Assert.assertEquals("Accepted taxon of single relation should be new taxon", newTaxon, heterotypicSynonym.getAcceptedTaxon());
588
        Assert.assertEquals("Old detail should be kept", "rel5", heterotypicSynonym.getSecMicroReference());
589

    
590
        //test heterotypic synonym with other synonym in homotypic group and moveHomotypicGroup="true"
591
        //+ new detail
592
        newTaxon = (Taxon)service.load(uuidNewTaxon);
593
        heterotypicSynonym = (Synonym)service.load(uuidSyn3);
594
        Reference ref1 = referenceService.load(uuidRef1);
595
        Assert.assertNotNull("Synonym should exist", heterotypicSynonym);
596
        Assert.assertNotNull("Synonym should have 1 relation", heterotypicSynonym.getAcceptedTaxon());
597
        Assert.assertEquals("Accepted taxon of single relation should be the old taxon", uuidOldTaxon, heterotypicSynonym.getAcceptedTaxon().getUuid());
598
        oldTaxon = heterotypicSynonym.getAcceptedTaxon();
599
        Assert.assertEquals("Detail should be ref1", ref1, heterotypicSynonym.getSec());
600
        Assert.assertEquals("Detail should be 'rel3'", "rel3", heterotypicSynonym.getSecMicroReference());
601
        TaxonName oldSynName3 = heterotypicSynonym.getName();
602

    
603
        Synonym heterotypicSynonym4 = (Synonym)service.load(uuidSyn4);
604
        Assert.assertNotNull("Synonym should exist", heterotypicSynonym4);
605
        Assert.assertNotNull("Synonym should have accepted taxon", heterotypicSynonym4.getAcceptedTaxon());
606
        Assert.assertEquals("Accepted taxon of other synonym in group should be the old taxon", uuidOldTaxon, heterotypicSynonym4.getAcceptedTaxon().getUuid());
607
        Assert.assertSame("Homotypic group of both synonyms should be same", oldSynName3.getHomotypicalGroup() , heterotypicSynonym4.getName().getHomotypicalGroup() );
608

    
609
        moveHomotypicGroup = true;
610
        keepReference = false;
611

    
612
        try {
613
            service.moveSynonymToAnotherTaxon(heterotypicSynonym4, newTaxon, moveHomotypicGroup, newSynonymType, null, newReferenceDetail, keepReference);
614
        } catch (HomotypicalGroupChangeException e) {
615
            Assert.fail("Move with 'moveHomotypicGroup = true' should not throw exception: " + e.getMessage());
616
        }
617
        //Asserts
618
        commitAndStartNewTransaction(tableNames);
619
        heterotypicSynonym = (Synonym)service.load(uuidSyn3);
620
        Assert.assertNotNull("Synonym should still exist", heterotypicSynonym);
621
        Assert.assertNotNull("Synonym should still have accepted taxon", heterotypicSynonym.getAcceptedTaxon());
622
        Assert.assertEquals("Accepted taxon of relation should be new taxon now", newTaxon, heterotypicSynonym.getAcceptedTaxon());
623
        TaxonName synName3 = heterotypicSynonym.getName();
624

    
625
        heterotypicSynonym = (Synonym)service.load(uuidSyn4);
626
        Assert.assertNotNull("Synonym should still exist", heterotypicSynonym);
627
        Assert.assertNotNull("Synonym should still have accepted taxon", heterotypicSynonym.getAcceptedTaxon());
628
        Assert.assertEquals("Accepted taxon of relation should be new taxon now", newTaxon, heterotypicSynonym.getAcceptedTaxon());
629
        Assert.assertNull("Old citation should be removed", heterotypicSynonym.getSec());
630
        Assert.assertNull("Old detail should be removed", heterotypicSynonym.getSecMicroReference());
631
        TaxonName synName4 = heterotypicSynonym.getName();
632
        Assert.assertEquals("Homotypic group of both synonyms should be equal", synName3.getHomotypicalGroup() , synName4.getHomotypicalGroup() );
633
        Assert.assertSame("Homotypic group of both synonyms should be same", synName3.getHomotypicalGroup() , synName4.getHomotypicalGroup() );
634
        Assert.assertEquals("Homotypic group of both synonyms should be equal to old homotypic group", oldSynName3.getHomotypicalGroup() , synName3.getHomotypicalGroup() );
635

    
636
        //test single heterotypic synonym to homotypic synonym of new taxon
637
        //+ new reference
638
        newTaxon = (Taxon)service.load(uuidNewTaxon);
639
        Reference ref2 = referenceService.load(uuidRef2);
640
        heterotypicSynonym = (Synonym)service.load(uuidSyn6);
641
        Assert.assertNotNull("Synonym should exist", heterotypicSynonym);
642
        Assert.assertNotNull("Synonym should have accepted taxon", heterotypicSynonym.getAcceptedTaxon());
643
        Assert.assertEquals("Accepted taxon of single relation should be the old taxon", uuidOldTaxon, heterotypicSynonym.getAcceptedTaxon().getUuid());
644
        oldTaxon = heterotypicSynonym.getAcceptedTaxon();
645
        moveHomotypicGroup = false;
646
        keepReference = false;
647
        newReference = ref2;
648
        newReferenceDetail = "newRefDetail";
649
        newSynonymType = SynonymType.HOMOTYPIC_SYNONYM_OF();
650

    
651
        try {
652
            service.moveSynonymToAnotherTaxon(heterotypicSynonym, newTaxon, moveHomotypicGroup, newSynonymType, newReference.getUuid(), newReferenceDetail, keepReference);
653
        } catch (HomotypicalGroupChangeException e) {
654
            Assert.fail("Move of single heterotypic synonym should not throw exception: " + e.getMessage());
655
        }
656
        //Asserts
657
        commitAndStartNewTransaction(tableNames);
658
        heterotypicSynonym = (Synonym)service.load(uuidSyn6);
659
        Assert.assertNotNull("Synonym should still exist", heterotypicSynonym);
660
        Assert.assertNotNull("Synonym should still have accepted taxon", heterotypicSynonym.getAcceptedTaxon());
661
        Assert.assertEquals("Relationship type should be 'homotypic synonym'", newSynonymType, heterotypicSynonym.getType());
662
        Assert.assertEquals("Accepted taxon of single relation should be new taxon", newTaxon, heterotypicSynonym.getAcceptedTaxon());
663
        Assert.assertEquals("New citation should be ref2", ref2 ,heterotypicSynonym.getSec());
664
        Assert.assertEquals("New detail should be kept", "newRefDetail", heterotypicSynonym.getSecMicroReference());
665

    
666
        Assert.assertEquals("New taxon and new synonym should have equal homotypical group", heterotypicSynonym.getHomotypicGroup(), heterotypicSynonym.getAcceptedTaxon().getHomotypicGroup());
667
        Assert.assertSame("New taxon and new synonym should have same homotypical group", heterotypicSynonym.getHomotypicGroup(), heterotypicSynonym.getAcceptedTaxon().getHomotypicGroup());
668
    }
669

    
670
    @Test
671
    public final void testGetHeterotypicSynonymyGroups(){
672
        Rank rank = Rank.SPECIES();
673
        Reference ref1 = ReferenceFactory.newGeneric();
674
        //HomotypicalGroup group = HomotypicalGroup.NewInstance();
675
        Taxon taxon1 = Taxon.NewInstance(TaxonNameFactory.NewBotanicalInstance(rank, "Test3", null, null, null, null, null, null, null), null);
676
        Synonym synonym0 = Synonym.NewInstance(TaxonNameFactory.NewBotanicalInstance(rank, "Test2", null, null, null, null, null, null, null), null);
677
        Synonym synonym1 = Synonym.NewInstance(TaxonNameFactory.NewBotanicalInstance(rank, "Test2", null, null, null, null, null, null, null), null);
678
        Synonym synonym2 = Synonym.NewInstance(TaxonNameFactory.NewBotanicalInstance(rank, "Test4", null, null, null, null, null, null, null), null);
679
        synonym0.getName().setHomotypicalGroup(taxon1.getHomotypicGroup());
680
        synonym2.getName().setHomotypicalGroup(synonym1.getHomotypicGroup());
681
        //tax2.addHeterotypicSynonymName(synonym.getName());
682
        taxon1.addSynonym(synonym1, SynonymType.HETEROTYPIC_SYNONYM_OF());
683
        taxon1.addSynonym(synonym2, SynonymType.HETEROTYPIC_SYNONYM_OF());
684

    
685
        service.save(synonym1);
686
        service.save(synonym2);
687
        service.save(taxon1);
688

    
689
        List<List<Synonym>> heteroSyns = service.getHeterotypicSynonymyGroups(taxon1, null);
690
        Assert.assertEquals("There should be 1 heterotypic group", 1, heteroSyns.size());
691
        List<Synonym> synList = heteroSyns.get(0);
692
        Assert.assertEquals("There should be 2 heterotypic syns in group 1", 2, synList.size());
693

    
694
        //test sec
695
        synonym2.setSec(ref1);
696
        heteroSyns = service.getHeterotypicSynonymyGroups(taxon1, null);
697
        Assert.assertEquals("There should be 1 heterotypic group", 1, heteroSyns.size());
698
        synList = heteroSyns.get(0);
699
        Assert.assertEquals("getHeterotypicSynonymyGroups should be independent of sec reference", 2, synList.size());
700
    }
701

    
702
    @Test
703
    public final void testGetHomotypicSynonymsByHomotypicGroup(){
704
        Rank rank = Rank.SPECIES();
705
        Reference ref1 = ReferenceFactory.newGeneric();
706
        //HomotypicalGroup group = HomotypicalGroup.NewInstance();
707
        Taxon taxon1 = Taxon.NewInstance(TaxonNameFactory.NewBotanicalInstance(rank, "Test3", null, null, null, null, null, null, null), null);
708
        Synonym synonym0 = Synonym.NewInstance(TaxonNameFactory.NewBotanicalInstance(rank, "Test2", null, null, null, null, null, null, null), null);
709
        Synonym synonym1 = Synonym.NewInstance(TaxonNameFactory.NewBotanicalInstance(rank, "Test2", null, null, null, null, null, null, null), null);
710
        Synonym synonym2 = Synonym.NewInstance(TaxonNameFactory.NewBotanicalInstance(rank, "Test4", null, null, null, null, null, null, null), null);
711
        synonym0.getName().setHomotypicalGroup(taxon1.getHomotypicGroup());
712
        synonym2.getName().setHomotypicalGroup(synonym1.getHomotypicGroup());
713
        //tax2.addHeterotypicSynonymName(synonym.getName());
714
        taxon1.addSynonym(synonym0, SynonymType.HOMOTYPIC_SYNONYM_OF());
715
        taxon1.addSynonym(synonym1, SynonymType.HETEROTYPIC_SYNONYM_OF());
716
        taxon1.addSynonym(synonym2, SynonymType.HETEROTYPIC_SYNONYM_OF());
717

    
718
        service.save(synonym1);
719
        service.save(synonym2);
720
        service.save(taxon1);
721

    
722
        List<Synonym> homoSyns = service.getHomotypicSynonymsByHomotypicGroup(taxon1, null);
723
        Assert.assertEquals("There should be 1 heterotypic group", 1, homoSyns.size());
724
        Assert.assertSame("The homotypic synonym should be synonym0", synonym0, homoSyns.get(0));
725

    
726
        //test sec
727
        synonym0.setSec(ref1);
728
        homoSyns = service.getHomotypicSynonymsByHomotypicGroup(taxon1, null);
729
        Assert.assertEquals("getHeterotypicSynonymyGroups should be independent of sec reference", 1, homoSyns.size());
730
    }
731

    
732
    @Test
733
    @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="TaxonServiceImplTest.testDeleteSynonym.xml")
734
    //test delete synonym, but the name will not be deleted
735
    public final void testDeleteSynonymSynonymTaxonDontDeleteName(){
736
        final String[]tableNames = {
737
//                "TaxonBase","TaxonBase_AUD", "TaxonName","TaxonName_AUD",
738
//                "HomotypicalGroup","HomotypicalGroup_AUD"
739
        };
740

    
741
        int nSynonyms = service.count(Synonym.class);
742
        Assert.assertEquals("There should be 2 synonyms in the database", 2, nSynonyms);
743
        int nNames = nameService.count(TaxonName.class);
744
        Assert.assertEquals("There should  be 4 names in the database", 4, nNames);
745
        long nRelations = service.countSynonyms(true);
746
        Assert.assertEquals("There should be two relationship left in the database", 2, nRelations);
747

    
748
        UUID uuidSynonym1=UUID.fromString("7da85381-ad9d-4886-9d4d-0eeef40e3d88");
749

    
750
        Synonym synonym1 = (Synonym)service.load(uuidSynonym1);
751
        SynonymDeletionConfigurator config = new SynonymDeletionConfigurator();
752
        config.setDeleteNameIfPossible(false);
753
        config.setNewHomotypicGroupIfNeeded(true);
754
        service.deleteSynonym(synonym1, config);
755

    
756
        this.commitAndStartNewTransaction(tableNames);
757

    
758
        nSynonyms = service.count(Synonym.class);
759
        Assert.assertEquals("There should be 1 synonym left in the database", 1, nSynonyms);
760
        nNames = nameService.count(TaxonName.class);
761
        Assert.assertEquals("There should be 4 names left in the database", 4, nNames);
762
        nRelations = service.countSynonyms(true);
763
        Assert.assertEquals("There should be no relationship left in the database", 1, nRelations);
764
    }
765

    
766
    @Test
767
    @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="TaxonServiceImplTest.testDeleteSynonym.xml")
768
    //test delete synonym and his name
769
    public final void testDeleteSynonymSynonymTaxonDeleteName(){
770
        final String[]tableNames = {"TaxonBase","TaxonBase_AUD", "TaxonName","TaxonName_AUD",
771
                "HomotypicalGroup","HomotypicalGroup_AUD"};
772

    
773
        int nSynonyms = service.count(Synonym.class);
774
        Assert.assertEquals("There should be 2 synonyms in the database", 2, nSynonyms);
775
        int nNames = nameService.count(TaxonName.class);
776
        Assert.assertEquals("There should  be 4 names in the database", 4, nNames);
777
        long nRelations = service.countSynonyms(true);
778
        Assert.assertEquals("There should be 2 relationship left in the database", 2, nRelations);
779

    
780
        UUID uuidSynonym1=UUID.fromString("7da85381-ad9d-4886-9d4d-0eeef40e3d88");
781
        Synonym synonym1 = (Synonym)service.load(uuidSynonym1);
782
        service.deleteSynonym(synonym1, new SynonymDeletionConfigurator());
783

    
784
        this.commitAndStartNewTransaction(tableNames);
785

    
786
        nSynonyms = service.count(Synonym.class);
787
        Assert.assertEquals("There should be 1 synonym left in the database", 1, nSynonyms);
788
        nNames = nameService.count(TaxonName.class);
789
        Assert.assertEquals("There should be 3 names left in the database", 3, nNames);
790
        nRelations = service.countSynonyms(true);
791
        Assert.assertEquals("There should be 1 relationship left in the database", 1, nRelations);
792
    }
793

    
794
    @Test
795
    @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="TaxonServiceImplTest.testDeleteSynonym.xml")
796
    //test remove synonym from taxon -> synonym and name still in the db and the synonymrelationship to the other taxon
797
    //test delete synonym -> all relationships are deleted, the name is deleted and the synonym itself
798
    public final void testDeleteSynonymSynonymTaxonBooleanRelToOneTaxon(){
799
        final String[]tableNames = {"TaxonBase","TaxonBase_AUD", "TaxonName","TaxonName_AUD",
800
                "HomotypicalGroup","HomotypicalGroup_AUD"};
801

    
802
        int nSynonyms = service.count(Synonym.class);
803
        Assert.assertEquals("There should be 2 synonyms in the database", 2, nSynonyms);
804
        int nNames = nameService.count(TaxonName.class);
805
        Assert.assertEquals("There should  be 4 names in the database", 4, nNames);
806

    
807
        UUID uuidTaxon1=UUID.fromString("c47fdb72-f32c-452e-8305-4b44f01179d0");
808
        UUID uuidSynonym1=UUID.fromString("7da85381-ad9d-4886-9d4d-0eeef40e3d88");
809

    
810
        Taxon taxon2 = (Taxon)service.load(uuidTaxon1);
811

    
812
        List<String> initStrat = new ArrayList<>();
813
        initStrat.add("markers");
814
        Synonym synonym1 = (Synonym)service.load(uuidSynonym1, initStrat);
815
        long nRelations = service.countSynonyms(true);
816
        Assert.assertEquals("There should be 2 relationship left in the database", 2, nRelations);
817

    
818
        taxon2.removeSynonym(synonym1, false);
819
        service.saveOrUpdate(taxon2);
820

    
821
        commitAndStartNewTransaction(null);
822

    
823
        nSynonyms = service.count(Synonym.class);
824
        Assert.assertEquals("There should be 2 synonyms in the database", 2, nSynonyms);
825
        nNames = nameService.count(TaxonName.class);
826
        Assert.assertEquals("There should  be 4 names in the database", 4, nNames);
827
        nRelations = service.countSynonyms(true);
828
        Assert.assertEquals("There should be 1 relationship left in the database", 1, nRelations);
829
        Marker marker1 = Marker.NewInstance(MarkerType.IMPORTED(), true);
830
        Marker marker2 = Marker.NewInstance(MarkerType.COMPUTED(), true);
831
        synonym1.addMarker(marker1);
832
        synonym1.addMarker(marker2);
833
        service.update(synonym1);
834
        synonym1 =(Synonym) service.load(uuidSynonym1);
835

    
836
        Set<Marker> markers = synonym1.getMarkers();
837
        Marker marker = markers.iterator().next();
838
        UUID markerUUID = marker.getUuid();
839
       // taxon2 = (Taxon)service.load(uuidTaxon2);
840
        synonym1 = (Synonym)service.load(uuidSynonym1);
841
        //the marker should not prevent the deletion
842
        DeleteResult result = service.deleteSynonym(synonym1, new SynonymDeletionConfigurator());
843
        if (!result.isOk()){
844
        	Assert.fail();
845
        }
846

    
847
        commitAndStartNewTransaction(tableNames);
848
        nSynonyms = service.count(Synonym.class);
849
        Assert.assertEquals("There should be 1 synonym left in the database", 1, nSynonyms);
850
        nNames = nameService.count(TaxonName.class);
851
        Assert.assertEquals("There should be 3 names left in the database", 3, nNames);
852
        nRelations = service.countSynonyms(true);
853
        Assert.assertEquals("There should be no relationship left in the database", 1, nRelations);
854
        marker = markerService.load(markerUUID);
855
        assertNull(marker);
856
    }
857

    
858
    @Test
859
    @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="TaxonServiceImplTest.testDeleteSynonym.xml")
860
    //this test is more or less obsolete since we have no synonym relationships anymore
861
    //test delete synonym, only for a special taxon, but because of other relationships it will not be deleted at all
862
    public final void testDeleteSynonymSynonymTaxonBooleanDeleteOneTaxon(){
863
        final String[]tableNames = {
864
//                "TaxonBase","TaxonBase_AUD", "TaxonName","TaxonName_AUD",
865
//                "HomotypicalGroup","HomotypicalGroup_AUD"
866
        };
867
        int nSynonyms = service.count(Synonym.class);
868
        Assert.assertEquals("There should be 2 synonyms in the database", 2, nSynonyms);
869
        int nNames = nameService.count(TaxonName.class);
870
        Assert.assertEquals("There should  be 4 names in the database", 4, nNames);
871

    
872
        UUID uuidTaxon2=UUID.fromString("2d9a642d-5a82-442d-8fec-95efa978e8f8");
873
        UUID uuidSynonym1=UUID.fromString("7da85381-ad9d-4886-9d4d-0eeef40e3d88");
874

    
875
        Taxon taxon2 = (Taxon)service.load(uuidTaxon2);
876
        Synonym synonym1 = (Synonym)service.load(uuidSynonym1);
877
        synonym1.setSec(ReferenceFactory.newArticle());
878

    
879
        taxon2.addSynonym(synonym1, SynonymType.HETEROTYPIC_SYNONYM_OF());
880
        service.saveOrUpdate(synonym1);
881
        long nRelations = service.countSynonyms(true);
882
        //this was "3" when we still had synonym relationships
883
        Assert.assertEquals("There should be 2 relationship left in the database", 2, nRelations);
884
        service.deleteSynonym(synonym1, new SynonymDeletionConfigurator());
885

    
886
        this.commitAndStartNewTransaction(tableNames);
887

    
888
        nSynonyms = service.count(Synonym.class);
889
        //this was "2" when we still had synonym relationships
890
        Assert.assertEquals("There should still be 1 synonym left in the database", 1, nSynonyms);
891
        nNames = nameService.count(TaxonName.class);
892
        //was 3
893
        Assert.assertEquals("There should be 3 names left in the database", 3, nNames);
894
        nRelations = service.countSynonyms(true);
895
        Assert.assertEquals("There should be 1 related synonym left in the database", 1, nRelations);
896
    }
897

    
898
    @Test
899
    @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="TaxonServiceImplTest.testDeleteSynonym.xml")
900

    
901
    public final void testDeleteSynonymWithAnnotations(){
902
        final String[]tableNames = {
903
//                "TaxonBase","TaxonBase_AUD", "TaxonName","TaxonName_AUD",
904
//                "HomotypicalGroup","HomotypicalGroup_AUD"
905
        };
906

    
907
        UUID uuidTaxon2=UUID.fromString("2d9a642d-5a82-442d-8fec-95efa978e8f8");
908
        UUID uuidSynonym1=UUID.fromString("7da85381-ad9d-4886-9d4d-0eeef40e3d88");
909

    
910
        Taxon taxon2 = (Taxon)service.load(uuidTaxon2);
911
        Synonym synonym1 = (Synonym)service.load(uuidSynonym1);
912
        taxon2.addSynonym(synonym1, SynonymType.HETEROTYPIC_SYNONYM_OF());
913

    
914
        Annotation annotation = Annotation.NewDefaultLanguageInstance("test");
915
        synonym1.addAnnotation(annotation);
916
        service.saveOrUpdate(synonym1);
917

    
918
        DeleteResult result = service.deleteSynonym(synonym1, new SynonymDeletionConfigurator());
919
        if (result.isError()){
920
            Assert.fail();
921
        }
922
        this.commitAndStartNewTransaction(tableNames);
923
    }
924

    
925
    @Test
926
    @DataSet("TaxonServiceImplTest.testDeleteSynonym.xml")
927

    
928
    public final void testDeleteSynonymSynonymTaxonBooleanWithRelatedName(){
929
        final String[]tableNames = {"TaxonBase","TaxonBase_AUD", "TaxonName","TaxonName_AUD",
930
                "HomotypicalGroup","HomotypicalGroup_AUD"};
931

    
932
        int nSynonyms = service.count(Synonym.class);
933
        Assert.assertEquals("There should be 2 synonyms in the database", 2, nSynonyms);
934
        int nNames = nameService.count(TaxonName.class);
935
        Assert.assertEquals("There should  be 4 names in the database", 4, nNames);
936

    
937
        UUID uuidSynonym1=UUID.fromString("7da85381-ad9d-4886-9d4d-0eeef40e3d88");
938
        UUID uuidSynonymName2=UUID.fromString("613f3c93-013e-4ffc-aadc-1c98d71c335e");
939

    
940
        Synonym synonym1 = (Synonym)service.load(uuidSynonym1);
941
        TaxonName name2 = nameService.load(uuidSynonymName2);
942
        UUID name3Uuid = synonym1.getName().getUuid();
943
        TaxonName name3 = nameService.load(name3Uuid);
944
        name3.addRelationshipFromName(name2, NameRelationshipType.LATER_HOMONYM(), null, null);
945

    
946
        service.saveOrUpdate(synonym1);
947

    
948
        long nRelations = nameService.listNameRelationships(null, 1000, 0, null, null).size();
949
        logger.info("number of name relations: " + nRelations);
950
        Assert.assertEquals("There should be 1 name relationship left in the database", 1, nRelations);
951
        SynonymDeletionConfigurator config = new SynonymDeletionConfigurator();
952

    
953
        service.deleteSynonym(synonym1, config);
954

    
955
        this.commitAndStartNewTransaction(tableNames);
956
        //synonym is deleted, but the name can not be deleted because of a name relationship
957
        nSynonyms = service.count(Synonym.class);
958
        Assert.assertEquals("There should still be 1 synonyms left in the database", 1, nSynonyms);
959
        nNames = nameService.count(TaxonName.class);
960
        Assert.assertEquals("There should be 4 names left in the database (name is related to synonymName2)", 4, nNames);
961
        nRelations = service.countSynonyms(true);
962
        //may change with better implementation of countAllRelationships (see #2653)
963
        nRelations = nameService.listNameRelationships(null, 1000, 0, null, null).size();
964
        logger.info("number of name relations: " + nRelations);
965
        Assert.assertEquals("There should be 1 name relationship left in the database", 1, nRelations);
966

    
967
        //clean up database
968
        name2 = nameService.load(uuidSynonymName2);
969
        NameRelationship rel = CdmBase.deproxy(name2.getNameRelations().iterator().next(), NameRelationship.class);
970
        name2.removeNameRelationship(rel);
971
        nameService.save(name2);
972
        this.setComplete();
973
        this.endTransaction();
974
    }
975

    
976
    @Test
977
    @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="TaxonServiceImplTest.testDeleteSynonym.xml")
978
    public final void testDeleteSynonymSynonymTaxonBooleanWithRelatedNameDeleteAllNameRelations(){
979
        final String[]tableNames = {"TaxonBase","TaxonBase_AUD", "TaxonName","TaxonName_AUD",
980
                "HomotypicalGroup","HomotypicalGroup_AUD"};
981

    
982
        int nSynonyms = service.count(Synonym.class);
983
        Assert.assertEquals("There should be 2 synonyms in the database", 2, nSynonyms);
984
        int nNames = nameService.count(TaxonName.class);
985
        Assert.assertEquals("There should  be 4 names in the database", 4, nNames);
986

    
987
        UUID uuidSynonym1=UUID.fromString("7da85381-ad9d-4886-9d4d-0eeef40e3d88");
988
        UUID uuidSynonymName2=UUID.fromString("613f3c93-013e-4ffc-aadc-1c98d71c335e");
989

    
990
        Synonym synonym1 = (Synonym)service.load(uuidSynonym1);
991
        TaxonName name2 = nameService.load(uuidSynonymName2);
992
        UUID name3Uuid = synonym1.getName().getUuid();
993
        TaxonName name3 = nameService.load(name3Uuid);
994
        name3.addRelationshipFromName(name2, NameRelationshipType.LATER_HOMONYM(), null, null);
995

    
996
        service.saveOrUpdate(synonym1);
997

    
998
        long nRelations = nameService.listNameRelationships(null, 1000, 0, null, null).size();
999
        logger.info("number of name relations: " + nRelations);
1000
        Assert.assertEquals("There should be 1 name relationship left in the database", 1, nRelations);
1001
        SynonymDeletionConfigurator config = new SynonymDeletionConfigurator();
1002
        NameDeletionConfigurator nameDeletionConfig = new NameDeletionConfigurator();
1003
        nameDeletionConfig.setRemoveAllNameRelationships(true);
1004
        config.setNameDeletionConfig(nameDeletionConfig);
1005

    
1006
        service.deleteSynonym(synonym1, config);
1007

    
1008
        this.commitAndStartNewTransaction(tableNames);
1009

    
1010
        nSynonyms = service.count(Synonym.class);
1011
        Assert.assertEquals("There should still be 1 synonyms left in the database", 1, nSynonyms);
1012
        nNames = nameService.count(TaxonName.class);
1013
        Assert.assertEquals("There should be 3 names left in the database ", 3, nNames);
1014
        nRelations = service.countSynonyms(true);
1015
        //may change with better implementation of countAllRelationships (see #2653)
1016
        nRelations = nameService.listNameRelationships(null, 1000, 0, null, null).size();
1017
        logger.info("number of name relations: " + nRelations);
1018
        Assert.assertEquals("There should be no name relationship left in the database", 0, nRelations);
1019
    }
1020

    
1021
    @Test
1022
    @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="TaxonServiceImplTest.testDeleteSynonym.xml")
1023
    public final void testDeleteSynonymSynonymTaxonBooleanWithRelatedNameIgnoreIsBasionym(){
1024
        final String[]tableNames = {"TaxonBase","TaxonBase_AUD", "TaxonName","TaxonName_AUD",
1025
                "HomotypicalGroup","HomotypicalGroup_AUD"};
1026

    
1027
        int nSynonyms = service.count(Synonym.class);
1028
        Assert.assertEquals("There should be 2 synonyms in the database", 2, nSynonyms);
1029
        int nNames = nameService.count(TaxonName.class);
1030
        Assert.assertEquals("There should  be 4 names in the database", 4, nNames);
1031

    
1032
        UUID uuidSynonym1=UUID.fromString("7da85381-ad9d-4886-9d4d-0eeef40e3d88");
1033
        UUID uuidSynonymName2=UUID.fromString("613f3c93-013e-4ffc-aadc-1c98d71c335e");
1034

    
1035
        Synonym synonym1 = (Synonym)service.load(uuidSynonym1);
1036
        TaxonName synName2 = nameService.load(uuidSynonymName2);
1037
        UUID name3Uuid = synonym1.getName().getUuid();
1038
        TaxonName synName1 = nameService.load(name3Uuid);
1039
        synName1.addRelationshipFromName(synName2, NameRelationshipType.BASIONYM(), null, null);
1040

    
1041
        service.saveOrUpdate(synonym1);
1042

    
1043
        long nRelations = nameService.listNameRelationships(null, 1000, 0, null, null).size();
1044
        logger.info("number of name relations: " + nRelations);
1045
        Assert.assertEquals("There should be 1 name relationship left in the database", 1, nRelations);
1046
        SynonymDeletionConfigurator config = new SynonymDeletionConfigurator();
1047
        NameDeletionConfigurator nameDeletionConfig = new NameDeletionConfigurator();
1048
        nameDeletionConfig.setIgnoreIsBasionymFor(true);
1049
        config.setNameDeletionConfig(nameDeletionConfig);
1050

    
1051
        DeleteResult result =service.deleteSynonym(synonym1, config);
1052
        if (!result.isOk()){
1053
        	Assert.fail();
1054
        }
1055

    
1056
        logger.debug(result);
1057
        this.commitAndStartNewTransaction(tableNames);
1058

    
1059
        nSynonyms = service.count(Synonym.class);
1060
        Assert.assertEquals("There should still be 1 synonyms left in the database", 1, nSynonyms);
1061
        nNames = nameService.count(TaxonName.class);
1062
        Assert.assertEquals("There should be 3 names left in the database ", 3, nNames);
1063
        nRelations = service.countSynonyms(true);
1064
        //may change with better implementation of countAllRelationships (see #2653)
1065
        nRelations = nameService.listNameRelationships(null, 1000, 0, null, null).size();
1066
        logger.info("number of name relations: " + nRelations);
1067
        Assert.assertEquals("There should be no name relationship left in the database", 0, nRelations);
1068
    }
1069

    
1070
    @Test
1071
    @DataSet("TaxonServiceImplTest.testDeleteSynonym.xml")
1072
    public final void testDeleteSynonymSynonymTaxonBooleanWithRollback(){
1073
//        final String[]tableNames = {"TaxonBase","TaxonBase_AUD", "TaxonName","TaxonName_AUD",
1074
//                "HomotypicalGroup","HomotypicalGroup_AUD"};
1075

    
1076
        int nSynonyms = service.count(Synonym.class);
1077
        Assert.assertEquals("There should be 2 synonyms in the database", 2, nSynonyms);
1078
        int nNames = nameService.count(TaxonName.class);
1079
        Assert.assertEquals("There should  be 4 names in the database", 4, nNames);
1080
        long nRelations = service.countSynonyms(true);
1081

    
1082
        //may change with better implementation of countAllRelationships (see #2653)
1083

    
1084
        logger.debug("");
1085
        Assert.assertEquals("There should be 2 relationships in the database (the 2 synonym relationship) but no name relationship", 2, nRelations);
1086

    
1087
        UUID uuidSynonym1=UUID.fromString("7da85381-ad9d-4886-9d4d-0eeef40e3d88");
1088
        UUID uuidSynonymName2=UUID.fromString("613f3c93-013e-4ffc-aadc-1c98d71c335e");
1089

    
1090
        Synonym synonym1 = (Synonym)service.load(uuidSynonym1);
1091
        TaxonName name2 = nameService.load(uuidSynonymName2);
1092
        synonym1.getName().addRelationshipFromName(name2, NameRelationshipType.LATER_HOMONYM(), null, null);
1093

    
1094
        service.deleteSynonym(synonym1, new SynonymDeletionConfigurator());
1095

    
1096
        this.rollback();
1097
//		printDataSet(System.out, tableNames);
1098
        this.startNewTransaction();
1099

    
1100
        nSynonyms = service.count(Synonym.class);
1101
        Assert.assertEquals("There should still be 2 synonyms left in the database", 2, nSynonyms);
1102
        nNames = nameService.count(TaxonName.class);
1103
        Assert.assertEquals("There should be 4 names left in the database", 4, nNames);
1104
        nRelations = service.countSynonyms(true);
1105
        //may change with better implementation of countAllRelationships (see #2653)
1106
        Assert.assertEquals("There should be 2 relationship in the database (the 2 synonym relationship) but no name relationship", 2, nRelations);
1107
    }
1108

    
1109
    @Test
1110
    @DataSet("TaxonServiceImplTest.testDeleteSynonym.xml")
1111
    public final void testDeleteSynonymSynonymTaxonBooleanWithoutTransaction(){
1112
        @SuppressWarnings("unused")
1113
        final String[]tableNames = {"TaxonBase","TaxonBase_AUD", "TaxonName","TaxonName_AUD",
1114
                "HomotypicalGroup","HomotypicalGroup_AUD"};
1115

    
1116
        int nSynonyms = service.count(Synonym.class);
1117
        Assert.assertEquals("There should be 2 synonyms in the database", 2, nSynonyms);
1118
        int nNames = nameService.count(TaxonName.class);
1119
        Assert.assertEquals("There should  be 4 names in the database", 4, nNames);
1120
        long nRelations = service.countSynonyms(true);
1121
        //may change with better implementation of countAllRelationships (see #2653)
1122
        Assert.assertEquals("There should be 2 relationship in the database (the 2 synonym relationships) but no name relationship", 2, nRelations);
1123

    
1124
        UUID uuidSynonym1=UUID.fromString("7da85381-ad9d-4886-9d4d-0eeef40e3d88");
1125
        UUID uuidSynonymName2=UUID.fromString("613f3c93-013e-4ffc-aadc-1c98d71c335e");
1126

    
1127
        Synonym synonym1 = (Synonym)service.load(uuidSynonym1);
1128
        TaxonName name2 = nameService.load(uuidSynonymName2);
1129
        synonym1.getName().addRelationshipFromName(name2, NameRelationshipType.LATER_HOMONYM(), null, null);
1130

    
1131
        service.saveOrUpdate(synonym1);
1132
        nRelations = service.countSynonyms(true);
1133
        Assert.assertEquals("There should be two relationships in the database", 2, nRelations);
1134
        this.setComplete();
1135
        this.endTransaction();
1136

    
1137
//        printDataSet(System.out, tableNames);
1138

    
1139
        //out of wrapping transaction
1140
        service.deleteSynonym(synonym1,  new SynonymDeletionConfigurator());
1141

    
1142
        this.startNewTransaction();
1143

    
1144
        nSynonyms = service.count(Synonym.class);
1145
        Assert.assertEquals("There should still be 1 synonyms left in the database. The rollback on name delete should not lead to rollback in synonym delete.", 1, nSynonyms);
1146
        nNames = nameService.count(TaxonName.class);
1147
        Assert.assertEquals("There should be 4 names left in the database", 4, nNames);
1148
        nRelations = service.countSynonyms(true);
1149
        Assert.assertEquals("There should be no taxon or synonym relationship in the database", 1, nRelations);
1150
        nRelations = nameService.listNameRelationships(null, 1000, 0, null, null).size();
1151
        Assert.assertEquals("There should be one name relationship in the database", 1, nRelations);
1152
    }
1153

    
1154
    @Test
1155
    @DataSet("TaxonServiceImplTest.testInferredSynonyms.xml")
1156
    public void testCreateInferredSynonymy(){
1157

    
1158
        UUID classificationUuid = UUID.fromString("aeee7448-5298-4991-b724-8d5b75a0a7a9");
1159
        Classification tree = classificationService.find(classificationUuid);
1160
        UUID taxonUuid = UUID.fromString("bc09aca6-06fd-4905-b1e7-cbf7cc65d783");
1161
        TaxonBase<?> taxonBase =  service.find(taxonUuid);
1162
        List <Synonym> synonyms = service.list(Synonym.class, null, null, null, null);
1163
        assertEquals("Number of synonyms should be 2",2,synonyms.size());
1164
        Taxon taxon = (Taxon)taxonBase;
1165

    
1166
        //synonyms = taxonDao.getAllSynonyms(null, null);
1167
        //assertEquals("Number of synonyms should be 2",2,synonyms.size());
1168
        List<Synonym> inferredSynonyms = service.createInferredSynonyms(taxon, tree, SynonymType.INFERRED_EPITHET_OF(), true);
1169
        assertNotNull("there should be a new synonym ", inferredSynonyms);
1170
        assertEquals ("the name of inferred epithet should be SynGenus lachesis", "SynGenus lachesis syn. sec. Sp. Pl.", inferredSynonyms.get(0).getTitleCache());
1171

    
1172
        inferredSynonyms = service.createInferredSynonyms(taxon, tree, SynonymType.INFERRED_GENUS_OF(), true);
1173
        assertNotNull("there should be a new synonym ", inferredSynonyms);
1174
        assertEquals ("the name of inferred epithet should be SynGenus lachesis", "Acherontia ciprosus syn. sec. Sp. Pl.", inferredSynonyms.get(0).getTitleCache());
1175

    
1176
        inferredSynonyms = service.createInferredSynonyms(taxon, tree, SynonymType.POTENTIAL_COMBINATION_OF(), true);
1177
        assertNotNull("there should be a new synonym ", inferredSynonyms);
1178
        assertEquals ("the name of inferred epithet should be SynGenus lachesis", "SynGenus ciprosus syn. sec. Sp. Pl.", inferredSynonyms.get(0).getTitleCache());
1179
        //assertTrue("set of synonyms should contain an inferred Synonym ", synonyms.contains(arg0))
1180
    }
1181

    
1182
    @Test
1183
    @DataSet("../../database/ClearDBDataSet.xml")
1184
    public final void testTaxonDeletionConfig(){
1185
        final String[]tableNames = {}
1186
//                "Classification", "Classification_AUD",
1187
//                "TaxonBase","TaxonBase_AUD",
1188
//                "TaxonNode","TaxonNode_AUD",
1189
//                "TaxonName","TaxonName_AUD",
1190
//                "TaxonRelationship", "TaxonRelationship_AUD",
1191
//                "TaxonDescription", "TaxonDescription_AUD",
1192
//                "HomotypicalGroup","HomotypicalGroup_AUD",
1193
//                "PolytomousKey","PolytomousKey_AUD",
1194
//                "PolytomousKeyNode","PolytomousKeyNode_AUD",
1195
//                "Media","Media_AUD",
1196
//                "DescriptiveDataSet","DescriptiveDataSet_AUD",
1197
//                "DescriptionElementBase","DescriptionElementBase_AUD",
1198
//        		"DeterminationEvent","DeterminationEvent_AUD",
1199
//        		"SpecimenOrObservationBase","SpecimenOrObservationBase_AUD"}
1200
        ;
1201

    
1202
        commitAndStartNewTransaction(tableNames);
1203
        getTestTaxon();
1204
        commitAndStartNewTransaction(tableNames);
1205
        int nTaxa = service.count(Taxon.class);
1206

    
1207
        Assert.assertEquals("There should be 4 taxa in the database", 4, nTaxa);
1208
        Taxon parent = (Taxon)service.find(GENUS_UUID);
1209
        Assert.assertNotNull("Parent taxon should exist", parent);
1210
        Taxon child1 = (Taxon)service.find(SPECIES1_UUID);
1211
        Assert.assertNotNull("Child taxon should exist", child1);
1212
        TaxonDeletionConfigurator config = new TaxonDeletionConfigurator();
1213
        config.setDeleteTaxonNodes(false);
1214
        config.setDeleteMisappliedNames(false);
1215
        //try {
1216
            //commitAndStartNewTransaction(tableNames);
1217

    
1218
        DeleteResult result = service.deleteTaxon(child1.getUuid(), config, null);
1219
        if (result.isOk()){
1220
            Assert.fail("Delete should throw an error as long as name is used in classification.");
1221
        }
1222

    
1223
        nTaxa = service.count(Taxon.class);
1224
        Assert.assertEquals("There should be 4 taxa in the database", 4, nTaxa);
1225
        child1 = (Taxon)service.find(SPECIES1_UUID);
1226
        Assert.assertNotNull("Child taxon should exist", child1);
1227
        Assert.assertEquals("Child should belong to 1 node", 1, child1.getTaxonNodes().size());
1228

    
1229
        TaxonNode node = child1.getTaxonNodes().iterator().next();
1230
        child1.addSource(IdentifiableSource.NewInstance(OriginalSourceType.Import));
1231

    
1232
        SpecimenOrObservationBase<?> identifiedUnit = DerivedUnit.NewInstance(SpecimenOrObservationType.DerivedUnit);
1233
        DeterminationEvent.NewInstance(child1, identifiedUnit);
1234
        //UUID eventUUID = eventService.save(determinationEvent);
1235
        UUID identifiedUnitUUID = occurenceService.save(identifiedUnit).getUuid();
1236

    
1237
        TaxonNode parentNode = node.getParent();
1238
        parentNode =CdmBase.deproxy(parentNode, TaxonNode.class);
1239
        parentNode.deleteChildNode(node);
1240
        nodeService.save(parentNode);
1241
        //commitAndStartNewTransaction(tableNames);
1242

    
1243
       // try {
1244

    
1245
       result = service.deleteTaxon(child1
1246
    		   .getUuid(), config, null);
1247
       if (result.isOk()){
1248
           	Assert.fail("Delete should throw an exception because of the determination event");
1249
       }
1250

    
1251
        //determinationEvent = (DeterminationEvent)eventService.load(eventUUID);
1252
        commitAndStartNewTransaction(tableNames);
1253
        identifiedUnit = occurenceService.load(identifiedUnitUUID);
1254

    
1255
        occurenceService.delete(identifiedUnit);
1256

    
1257
        commitAndStartNewTransaction(tableNames);
1258
        child1 = (Taxon)service.find(SPECIES1_UUID);
1259

    
1260
        assertEquals(0, child1.getTaxonNodes().size());
1261
       // try {
1262

    
1263
         result = service.deleteTaxon(child1.getUuid(), config, null);
1264

    
1265
         if (!result.isOk()){
1266
            Assert.fail("Delete should not throw an exception anymore");
1267
         }
1268

    
1269
        nTaxa = service.count(Taxon.class);
1270
        Assert.assertEquals("There should be 3 taxa in the database", 3, nTaxa);
1271

    
1272
        config.setDeleteTaxonNodes(true);
1273
        Taxon child2 =(Taxon) service.find(SPECIES2_UUID);
1274

    
1275
       // try {
1276
        result = service.deleteTaxon(child2.getUuid(), config, child2.getTaxonNodes().iterator().next().getClassification().getUuid());
1277
        if (!result.isOk()){
1278
            Assert.fail("Delete should not throw an exception");
1279
        }
1280

    
1281
        //service.find(uuid);
1282

    
1283
        nTaxa = service.count(Taxon.class);
1284
        Assert.assertEquals("There should be 2 taxa in the database",2, nTaxa);
1285
//		nNames = nameService.count(TaxonName.class);
1286
//		Assert.assertEquals("There should be 3 names left in the database", 3, nNames);
1287
//		int nRelations = service.countAllRelationships();
1288
//		Assert.assertEquals("There should be no relationship left in the database", 0, nRelations);
1289
    }
1290

    
1291
    @Test
1292
    @DataSet(value="../../database/ClearDBDataSet.xml")
1293
    public final void testDeleteTaxon(){
1294

    
1295
        //create a small classification
1296
        Taxon testTaxon = getTestTaxon();
1297
        service.save(testTaxon).getUuid();
1298

    
1299
        Taxon speciesTaxon = (Taxon)service.find(SPECIES1_UUID);
1300
        Iterator<TaxonDescription> descriptionIterator = speciesTaxon.getDescriptions().iterator();
1301
        UUID descrUUID = null;
1302
        UUID descrElementUUID = null;
1303
        if (descriptionIterator.hasNext()){
1304
            TaxonDescription descr = descriptionIterator.next();
1305
            descrUUID = descr.getUuid();
1306
            descrElementUUID = descr.getElements().iterator().next().getUuid();
1307
        }
1308
        IBotanicalName taxonName = nameService.find(SPECIES1_NAME_UUID);
1309
        assertNotNull(taxonName);
1310

    
1311
        TaxonDeletionConfigurator config = new TaxonDeletionConfigurator();
1312
        config.setDeleteNameIfPossible(false);
1313

    
1314
        DeleteResult result = service.deleteTaxon(speciesTaxon.getUuid(), config, speciesTaxon.getTaxonNodes().iterator().next().getClassification().getUuid());
1315
        if (!result.isOk()){
1316
        	Assert.fail();
1317
        }
1318
        commitAndStartNewTransaction(null);
1319

    
1320
        taxonName = nameService.find(SPECIES1_NAME_UUID);
1321
        Taxon taxon = (Taxon)service.find(SPECIES1_UUID);
1322

    
1323
        //descriptionService.find(descrUUID);
1324
        assertNull(descriptionService.find(descrUUID));
1325
        assertNull(descriptionElementService.find(descrElementUUID));
1326
        //assertNull(synName);
1327
        assertNotNull(taxonName);
1328
        assertNull(taxon);
1329
        config.setDeleteNameIfPossible(true);
1330
        Taxon newTaxon = Taxon.NewInstance(TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES()), null);
1331
        service.save(newTaxon);
1332
        result = service.deleteTaxon(newTaxon.getUuid()
1333
        		, config, null);
1334
        if (!result.isOk()){
1335
        	Assert.fail();
1336
        }
1337
    }
1338

    
1339
    @Test
1340
    @DataSet(value="../../database/ClearDBDataSet.xml")
1341
    public final void testDeleteTaxonWithAnnotations(){
1342

    
1343
        //create a small classification
1344
        Taxon testTaxon = getTestTaxon();
1345
        service.save(testTaxon).getUuid();
1346

    
1347
        Taxon speciesTaxon = (Taxon)service.find(SPECIES1_UUID);
1348
        Iterator<TaxonDescription> descriptionIterator = speciesTaxon.getDescriptions().iterator();
1349
        UUID descrUUID = null;
1350
        UUID descrElementUUID = null;
1351
        if (descriptionIterator.hasNext()){
1352
            TaxonDescription descr = descriptionIterator.next();
1353
            descrUUID = descr.getUuid();
1354
            descrElementUUID = descr.getElements().iterator().next().getUuid();
1355
        }
1356
        IBotanicalName taxonName = nameService.find(SPECIES1_NAME_UUID);
1357
        assertNotNull(taxonName);
1358

    
1359
        TaxonDeletionConfigurator config = new TaxonDeletionConfigurator();
1360
        config.setDeleteNameIfPossible(false);
1361
        Annotation annotation = Annotation.NewDefaultLanguageInstance("test");
1362
        speciesTaxon.addAnnotation(annotation);
1363

    
1364

    
1365
        DeleteResult result = service.deleteTaxon(speciesTaxon.getUuid(), config, speciesTaxon.getTaxonNodes().iterator().next().getClassification().getUuid());
1366
        if (!result.isOk()){
1367
            Assert.fail();
1368
        }
1369
        commitAndStartNewTransaction(null);
1370

    
1371
        taxonName = nameService.find(SPECIES1_NAME_UUID);
1372
        Taxon taxon = (Taxon)service.find(SPECIES1_UUID);
1373

    
1374
        //descriptionService.find(descrUUID);
1375
        assertNull(descriptionService.find(descrUUID));
1376
        assertNull(descriptionElementService.find(descrElementUUID));
1377
        //assertNull(synName);
1378
        assertNotNull(taxonName);
1379
        assertNull(taxon);
1380
        config.setDeleteNameIfPossible(true);
1381
        Taxon newTaxon = Taxon.NewInstance(TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES()), null);
1382
        service.save(newTaxon);
1383
        result = service.deleteTaxon(newTaxon.getUuid()
1384
                , config, null);
1385
        if (!result.isOk()){
1386
            Assert.fail();
1387
        }
1388
    }
1389

    
1390
    @Test
1391
    @DataSet(value="../../database/ClearDBDataSet.xml")
1392
    public final void testDeleteTaxonUsedInTaxonRelation(){
1393

    
1394
        //create a small classification
1395
        Taxon testTaxon = getTestTaxon();
1396
        service.save(testTaxon).getUuid();
1397

    
1398
        Taxon speciesTaxon = (Taxon)service.find(SPECIES1_UUID);
1399
        Taxon speciesTaxon2 = (Taxon)service.find(SPECIES2_UUID);
1400
        speciesTaxon.addTaxonRelation(speciesTaxon2, TaxonRelationshipType.MISAPPLIED_NAME_FOR(), null, null);
1401

    
1402
        IBotanicalName taxonName = nameService.find(SPECIES1_NAME_UUID);
1403
        assertNotNull(taxonName);
1404

    
1405
        TaxonDeletionConfigurator config = new TaxonDeletionConfigurator();
1406
        config.setDeleteNameIfPossible(false);
1407
        config.setDeleteTaxonRelationships(false);
1408

    
1409

    
1410
        DeleteResult result = service.deleteTaxon(speciesTaxon.getUuid(), config, speciesTaxon.getTaxonNodes().iterator().next().getClassification().getUuid());
1411
        if (result.isOk()){
1412
            Assert.fail();
1413
        }
1414
        commitAndStartNewTransaction(null);
1415

    
1416
        taxonName = nameService.find(SPECIES1_NAME_UUID);
1417
        Taxon taxon = (Taxon)service.find(SPECIES1_UUID);
1418

    
1419
        assertNotNull(taxonName);
1420
        assertNotNull(taxon);
1421

    
1422
        config.setDeleteNameIfPossible(false);
1423
        config.setDeleteTaxonRelationships(true);
1424

    
1425

    
1426
        result = service.deleteTaxon(speciesTaxon.getUuid(), config, speciesTaxon.getTaxonNodes().iterator().next().getClassification().getUuid());
1427
        if (!result.isOk()){
1428
            Assert.fail();
1429
        }
1430
        commitAndStartNewTransaction(null);
1431

    
1432
        config.setDeleteNameIfPossible(true);
1433
        Taxon newTaxon = Taxon.NewInstance(TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES()), null);
1434
        service.save(newTaxon);
1435
        result = service.deleteTaxon(newTaxon.getUuid()
1436
                , config, null);
1437
        if (!result.isOk()){
1438
            Assert.fail();
1439
        }
1440
    }
1441

    
1442
    @Test
1443
    @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="../../database/ClearDBDataSet.xml")
1444
    public final void testDeleteTaxonDeleteSynonymRelations(){
1445

    
1446
    	 final String[]tableNames = {
1447
                 "Classification", "Classification_AUD",
1448
                 "TaxonBase","TaxonBase_AUD",
1449
                 "TaxonNode","TaxonNode_AUD",
1450
                 "TaxonName","TaxonName_AUD"};
1451
    	 commitAndStartNewTransaction(tableNames);
1452
        //create a small classification
1453
        Taxon testTaxon = getTestTaxon();
1454
        service.save(testTaxon).getUuid();
1455
        Taxon speciesTaxon = (Taxon)service.find(SPECIES2_UUID);
1456

    
1457
        Synonym synonym = speciesTaxon.getSynonyms().iterator().next();
1458
        UUID synonymUuid = synonym.getUuid();
1459
        service.countSynonyms(true);
1460

    
1461
        TaxonDeletionConfigurator config = new TaxonDeletionConfigurator();
1462
        config.setDeleteSynonymsIfPossible(false);
1463

    
1464

    
1465
        DeleteResult result = service.deleteTaxon(speciesTaxon.getUuid(), config, speciesTaxon.getTaxonNodes().iterator().next().getClassification().getUuid());
1466
        if (!result.isOk()){
1467
        	Assert.fail();
1468
        }
1469
        commitAndStartNewTransaction(null);
1470

    
1471
        Taxon taxon = (Taxon)service.find(SPECIES2_UUID);
1472
        assertNull("The deleted taxon should no longer exist", taxon);
1473

    
1474
        Synonym syn = (Synonym)service.find(synonymUuid);
1475
        assertNotNull("The synonym should still exist since DeleteSynonymsIfPossible was false", service.find(synonymUuid));
1476
        assertNull("The synonym should not be attached to an accepted taxon anymore", syn.getAcceptedTaxon());
1477
    }
1478

    
1479
    @Test
1480
    @DataSet(value="../../database/ClearDBDataSet.xml")
1481
    public final void testDeleteTaxonNameUsedInOtherContext(){
1482

    
1483
        //create a small classification
1484
        Taxon testTaxon = getTestTaxon();
1485
        service.save(testTaxon).getUuid();
1486
        Taxon speciesTaxon = (Taxon)service.find(SPECIES1_UUID);
1487

    
1488
        IBotanicalName taxonName = nameService.find(SPECIES1_NAME_UUID);
1489
        assertNotNull(taxonName);
1490
        TaxonName fromName = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
1491
        taxonName.addRelationshipFromName(fromName, NameRelationshipType.VALIDATED_BY_NAME(), null, null);
1492
        nameService.save(fromName);
1493

    
1494
        TaxonDeletionConfigurator config = new TaxonDeletionConfigurator();
1495
        config.setDeleteNameIfPossible(true);
1496
        DeleteResult result = service.deleteTaxon(speciesTaxon.getUuid(), config, speciesTaxon.getTaxonNodes().iterator().next().getClassification().getUuid());
1497
        if (!result.isOk()){
1498
        	Assert.fail();
1499
        }
1500
        commitAndStartNewTransaction(null);
1501

    
1502
        taxonName = nameService.find(SPECIES1_NAME_UUID);
1503
        Taxon taxon = (Taxon)service.find(SPECIES1_UUID);
1504
        //because of the namerelationship the name cannot be deleted
1505
        assertNotNull(taxonName);
1506
        assertNull(taxon);
1507
    }
1508

    
1509
    @Test
1510
    @DataSet(value="../../database/ClearDBDataSet.xml")
1511
    public final void testDeleteTaxonNameUsedInTwoClassificationsDeleteAllNodes(){
1512
        commitAndStartNewTransaction(null);
1513
        TaxonDeletionConfigurator config = new TaxonDeletionConfigurator();
1514
        //create a small classification
1515
        Taxon testTaxon = getTestTaxon();
1516

    
1517
        UUID uuid = service.save(testTaxon).getUuid();
1518
        //BotanicalName name = nameService.find(uuid);
1519
        Set<TaxonNode> nodes = testTaxon.getTaxonNodes();
1520
        TaxonNode node = nodes.iterator().next();
1521
        List<TaxonNode> childNodes = node.getChildNodes();
1522
        TaxonNode childNode = childNodes.iterator().next();
1523
        UUID childUUID = childNode.getTaxon().getUuid();
1524
        Classification secondClassification = getTestClassification("secondClassification");
1525

    
1526
        secondClassification.addChildTaxon(testTaxon, null, null);
1527
        //delete the taxon in all classifications
1528
        config.setDeleteInAllClassifications(true);
1529
       DeleteResult result = service.deleteTaxon(testTaxon.getUuid(), config, null);
1530
       if (!result.isOk()){
1531
        	Assert.fail();
1532
        }
1533
        commitAndStartNewTransaction(null);
1534
        Taxon tax = (Taxon)service.find(uuid);
1535
        assertNull(tax);
1536
        Taxon childTaxon = (Taxon)service.find(childUUID);
1537
        assertNull(tax);
1538
        commitAndStartNewTransaction(null);
1539
    }
1540

    
1541
    @Test
1542
    @DataSet(value="../../database/ClearDBDataSet.xml")
1543
    public final void testDeleteTaxonNameUsedInTwoClassificationsDoNotDeleteAllNodes(){
1544
        // delete the taxon only in second classification, this should delete only the nodes, not the taxa
1545
        Taxon testTaxon = getTestTaxon();
1546
        UUID uuid = service.save(testTaxon).getUuid();
1547
        Classification secondClassification = getTestClassification("secondClassification");
1548
        Set<TaxonNode> nodes = testTaxon.getTaxonNodes();
1549
        TaxonNode node = nodes.iterator().next();
1550
        List<TaxonNode> childNodes = node.getChildNodes();
1551
        TaxonNode childNode = childNodes.iterator().next();
1552
        UUID childUUID = childNode.getTaxon().getUuid();
1553
        childNode = secondClassification.addChildTaxon(testTaxon, null, null);
1554
        UUID childNodeUUID = childNode.getUuid();
1555

    
1556
        TaxonDeletionConfigurator config = new TaxonDeletionConfigurator() ;
1557
        config.setDeleteInAllClassifications(false);
1558
       //     try {
1559
       DeleteResult result = service.deleteTaxon(testTaxon.getUuid(), config, secondClassification.getUuid());
1560
/*                Assert.fail("The taxon should not be deletable because it is used in a second classification and the configuration is set to deleteInAllClassifications = false");
1561
            } catch (DataChangeNoRollbackException e) {
1562
                logger.debug(e.getMessage());
1563
            }
1564
  */
1565

    
1566
       if (result.isOk()){
1567
           	Assert.fail("The taxon should not be deletable because it is used in a second classification and the configuration is set to deleteInAllClassifications = false");
1568
        }
1569

    
1570
        //commitAndStartNewTransaction(null);
1571
        Taxon tax = (Taxon)service.find(uuid);
1572
        assertNotNull(tax);
1573
        Taxon childTaxon = (Taxon)service.find(childUUID);
1574
        assertNotNull(tax);
1575
        //when calling delete taxon and the taxon can not be deleted the children should not be deleted as well. If children should be deleted call delete taxonnode
1576
        node = nodeService.find(childNodeUUID);
1577
        assertNotNull(node);
1578
    }
1579

    
1580
    @Test
1581
    @DataSet(value="../../database/ClearDBDataSet.xml")
1582
    public final void testTaxonNodeDeletionConfiguratorMoveToParent(){
1583
        //test childHandling MOVE_TO_PARENT:
1584
        Taxon testTaxon = getTestTaxon();
1585
        UUID uuid = service.save(testTaxon).getUuid();
1586

    
1587
        Taxon topMost = Taxon.NewInstance(TaxonNameFactory.NewBotanicalInstance(Rank.FAMILY()), null);
1588

    
1589
        Iterator<TaxonNode> nodes = testTaxon.getTaxonNodes().iterator();
1590
        TaxonNode node =nodes.next();
1591
        Classification classification = node.getClassification();
1592
        classification.addParentChild(topMost, testTaxon, null, null);
1593
        UUID topMostUUID = service.save(topMost).getUuid();
1594

    
1595
        TaxonDeletionConfigurator config = new TaxonDeletionConfigurator() ;
1596
        config.getTaxonNodeConfig().setChildHandling(ChildHandling.MOVE_TO_PARENT);
1597

    
1598

    
1599
        DeleteResult result = service.deleteTaxon(testTaxon.getUuid(), config, classification.getUuid());
1600
        if(!result.isOk()){
1601
         	Assert.fail();
1602
       	}
1603

    
1604
        commitAndStartNewTransaction(null);
1605
        Taxon tax = (Taxon)service.find(uuid);
1606
        assertNull(tax);
1607
        tax = (Taxon)service.find(topMostUUID);
1608
        Set<TaxonNode> topMostNodes = tax.getTaxonNodes();
1609
        assertNotNull(topMostNodes);
1610
        assertEquals("there should be one taxon node", 1, topMostNodes.size());
1611
        nodes = topMostNodes.iterator();
1612
        TaxonNode topMostNode = nodes.next();
1613
        int size = topMostNode.getChildNodes().size();
1614

    
1615
        assertEquals(2, size);
1616
    }
1617

    
1618
    @Test
1619
    @DataSet(value="../../database/ClearDBDataSet.xml")
1620
    public final void testTaxonNodeDeletionConfiguratorDeleteChildren(){
1621
        //test childHandling DELETE:
1622
        Taxon testTaxon = getTestTaxon();
1623
        UUID uuid = service.save(testTaxon).getUuid();
1624

    
1625
        Taxon topMost = Taxon.NewInstance(TaxonNameFactory.NewBotanicalInstance(Rank.FAMILY()), null);
1626

    
1627
        Iterator<TaxonNode> nodes = testTaxon.getTaxonNodes().iterator();
1628
        TaxonNode node =nodes.next();
1629
        UUID taxonNodeUUID = node.getUuid();
1630
        Classification classification = node.getClassification();
1631
        classification.addParentChild(topMost, testTaxon, null, null);
1632
        UUID topMostUUID = service.save(topMost).getUuid();
1633

    
1634
        TaxonDeletionConfigurator config = new TaxonDeletionConfigurator() ;
1635
        config.getTaxonNodeConfig().setChildHandling(ChildHandling.DELETE);
1636

    
1637
       // try {
1638
        DeleteResult result = service.deleteTaxon(testTaxon.getUuid(), config, testTaxon.getTaxonNodes().iterator().next().getClassification().getUuid());
1639
        if(!result.isOk()){
1640
         	Assert.fail();
1641
       	}
1642
        commitAndStartNewTransaction(null);
1643
        Taxon tax = (Taxon)service.find(uuid);
1644
        assertNull(tax);
1645
        tax = (Taxon)service.find(topMostUUID);
1646
        Set<TaxonNode> topMostNodes = tax.getTaxonNodes();
1647
        assertNotNull(topMostNodes);
1648
        assertEquals("there should be one taxon node", 1, topMostNodes.size());
1649
        nodes = topMostNodes.iterator();
1650
        TaxonNode topMostNode = nodes.next();
1651
        int size = topMostNode.getChildNodes().size();
1652
        node = nodeService.find(taxonNodeUUID);
1653
        assertNull(node);
1654
        assertEquals(0, size);
1655
    }
1656

    
1657

    
1658
    @Test
1659
    @DataSet(value="../../database/ClearDBDataSet.xml")
1660
    public final void testTaxonDeletionConfiguratorDeleteMarker(){
1661
        //test childHandling DELETE:
1662
        Taxon testTaxon = getTestTaxon();
1663
        UUID uuid = service.save(testTaxon).getUuid();
1664

    
1665
        Taxon topMost = Taxon.NewInstance(TaxonNameFactory.NewBotanicalInstance(Rank.FAMILY()), null);
1666

    
1667
        Iterator<TaxonNode> nodes = testTaxon.getTaxonNodes().iterator();
1668
        TaxonNode node =nodes.next();
1669
        Classification classification = node.getClassification();
1670
        classification.addParentChild(topMost, testTaxon, null, null);
1671
        UUID topMostUUID = service.save(topMost).getUuid();
1672
        Marker marker = Marker.NewInstance(testTaxon, true, MarkerType.IS_DOUBTFUL());
1673
        testTaxon.addMarker(marker);
1674
        TaxonDeletionConfigurator config = new TaxonDeletionConfigurator() ;
1675
        config.getTaxonNodeConfig().setChildHandling(ChildHandling.DELETE);
1676

    
1677
        DeleteResult result = service.deleteTaxon(testTaxon.getUuid(), config, node.getClassification().getUuid());
1678

    
1679
        if(!result.isOk()){
1680
         	Assert.fail();
1681
       	}
1682
        commitAndStartNewTransaction(null);
1683
        Taxon tax = (Taxon)service.find(uuid);
1684
        assertNull(tax);
1685
        tax = (Taxon)service.find(topMostUUID);
1686
        Set<TaxonNode> topMostNodes = tax.getTaxonNodes();
1687
        assertNotNull(topMostNodes);
1688
        assertEquals("there should be one taxon node", 1, topMostNodes.size());
1689
        nodes = topMostNodes.iterator();
1690
        TaxonNode topMostNode = nodes.next();
1691
        int size = topMostNode.getChildNodes().size();
1692

    
1693
        assertEquals(0, size);
1694
    }
1695

    
1696

    
1697
    @Test
1698
    @DataSet(value="../../database/ClearDBDataSet.xml")
1699
    public final void testTaxonDeletionConfiguratorTaxonWithMisappliedName(){
1700

    
1701
        Taxon testTaxon = getTestTaxon();
1702
        UUID uuid = service.save(testTaxon).getUuid();
1703

    
1704
        Taxon misappliedName = Taxon.NewInstance(TaxonNameFactory.NewBotanicalInstance(Rank.GENUS()), null);
1705

    
1706
        Iterator<TaxonNode> nodes = testTaxon.getTaxonNodes().iterator();
1707
        TaxonNode node =nodes.next();
1708
        testTaxon.addMisappliedName(misappliedName, null, null);
1709
        UUID misappliedNameUUID = service.save(misappliedName).getUuid();
1710

    
1711
        TaxonDeletionConfigurator config = new TaxonDeletionConfigurator() ;
1712
        config.setDeleteMisappliedNames(true);
1713

    
1714
        DeleteResult result  = service.deleteTaxon(testTaxon.getUuid(), config, node.getClassification().getUuid());
1715
        if(!result.isOk()){
1716
         	Assert.fail();
1717
       	}
1718
        commitAndStartNewTransaction(null);
1719
        Taxon tax = (Taxon)service.find(uuid);
1720
        assertNull(tax);
1721
        tax = (Taxon)service.find(misappliedNameUUID);
1722
        //TODO: is that correct or should it be deleted because there is no relation to anything
1723
        assertNull(tax);
1724

    
1725
    }
1726
    @Test
1727
    @DataSet(value="../../database/ClearDBDataSet.xml")
1728
    public final void testTaxonDeletionConfiguratorTaxonWithMisappliedNameDoNotDelete(){
1729

    
1730
        Taxon testTaxon = getTestTaxon();
1731
        UUID uuid = service.save(testTaxon).getUuid();
1732

    
1733
        Taxon misappliedName = Taxon.NewInstance(TaxonNameFactory.NewBotanicalInstance(Rank.GENUS()), null);
1734

    
1735
        Iterator<TaxonNode> nodes = testTaxon.getTaxonNodes().iterator();
1736
        TaxonNode node =nodes.next();
1737
        testTaxon.addMisappliedName(misappliedName, null, null);
1738
        UUID misappliedNameUUID = service.save(misappliedName).getUuid();
1739

    
1740
        TaxonDeletionConfigurator config = new TaxonDeletionConfigurator() ;
1741
        config.setDeleteMisappliedNames(false);
1742

    
1743
        DeleteResult result = service.deleteTaxon(testTaxon.getUuid(), config, node.getClassification().getUuid());
1744
        if(!result.isOk()){
1745
         	Assert.fail();
1746
       	}
1747
        commitAndStartNewTransaction(null);
1748
        Taxon tax = (Taxon)service.find(uuid);
1749
        assertNull(tax);
1750
        tax = (Taxon)service.find(misappliedNameUUID);
1751
        //TODO: is that correct or should it be deleted because there is no relation to anything
1752
        assertNotNull(tax);
1753
    }
1754

    
1755
    @Test
1756
    @DataSet(value="../../database/ClearDBDataSet.xml")
1757
    public final void testTaxonDeletionConfiguratorTaxonMisappliedName(){
1758

    
1759
        Taxon testTaxon = getTestTaxon();
1760
        UUID uuid = service.save(testTaxon).getUuid();
1761

    
1762
        Taxon misappliedNameTaxon = Taxon.NewInstance(TaxonNameFactory.NewBotanicalInstance(Rank.GENUS()), null);
1763

    
1764
        Iterator<TaxonNode> nodes = testTaxon.getTaxonNodes().iterator();
1765
        TaxonNode node =nodes.next();
1766
        testTaxon.addMisappliedName(misappliedNameTaxon, null, null);
1767
        UUID misappliedNameUUID = service.save(misappliedNameTaxon).getUuid();
1768
        misappliedNameTaxon = (Taxon)service.find(misappliedNameUUID);
1769
        UUID misNameUUID = misappliedNameTaxon.getName().getUuid();
1770

    
1771
        TaxonDeletionConfigurator config = new TaxonDeletionConfigurator() ;
1772

    
1773
        service.deleteTaxon(misappliedNameTaxon.getUuid(), config,null);
1774

    
1775
        commitAndStartNewTransaction(null);
1776
        Taxon tax = (Taxon)service.find(uuid);
1777
        assertNotNull(tax);
1778
        tax = (Taxon)service.find(misappliedNameUUID);
1779
        IBotanicalName name = nameService.find(misNameUUID);
1780

    
1781
        assertNull(tax);
1782
        assertNull(name);
1783
    }
1784

    
1785
    @Test
1786
    @DataSet(value="../../database/ClearDBDataSet.xml")
1787
    public final void testListIncludedTaxa(){
1788
    	Reference citation = null;
1789
    	String microcitation = null;
1790

    
1791
    	//Data
1792
    	Classification cl1 = Classification.NewInstance("testClassification1");
1793
    	Classification cl2 = Classification.NewInstance("testClassification2");
1794
    	Classification cl3 = Classification.NewInstance("testClassification3");
1795

    
1796
    	classificationService.save(cl1);
1797
        classificationService.save(cl2);
1798
        classificationService.save(cl3);
1799

    
1800
    	Taxon c1Genus = Taxon.NewInstance(null, null);c1Genus.setUuid(UUID.fromString("daa24f6f-7e38-4668-b385-10c789212e4e"));
1801
    	Taxon c1Species = Taxon.NewInstance(null, null);c1Species.setUuid(UUID.fromString("1c1d0566-67d0-4806-bf23-ecf55f4b9118"));
1802
    	Taxon c1SubSpecies1 = Taxon.NewInstance(null, null);c1SubSpecies1.setUuid(UUID.fromString("96ae2fad-76df-429f-b179-42e00838fea4"));
1803
    	Taxon c1SubSpecies2 = Taxon.NewInstance(null, null);c1SubSpecies2.setUuid(UUID.fromString("5d3f6147-ca72-40e0-be8a-6c835a09a579"));
1804
    	TaxonNode c1childNodeSpecies1 = cl1.addParentChild(c1Genus, c1Species, null, null);
1805
    	nodeService.saveOrUpdate(c1childNodeSpecies1.getParent());
1806
    	nodeService.saveOrUpdate(c1childNodeSpecies1);
1807
    	TaxonNode c1childNodeSubSpecies1 =cl1.addParentChild(c1Species, c1SubSpecies1, null, null);
1808
    	nodeService.saveOrUpdate(c1childNodeSubSpecies1);
1809
    	TaxonNode c1childNodeSubSpecies2 =cl1.addParentChild(c1Species, c1SubSpecies2, null, null);
1810
    	nodeService.saveOrUpdate(c1childNodeSubSpecies2);
1811

    
1812
    	Taxon c2Genus = Taxon.NewInstance(null, null);c2Genus.setUuid(UUID.fromString("ed0ec006-3ac8-4a12-ae13-fdf2a13dedbe"));
1813
    	Taxon c2Species = Taxon.NewInstance(null, null);c2Species.setUuid(UUID.fromString("1027eb18-1c26-450e-a299-981b775ebc3c"));
1814
    	Taxon c2SubSpecies1 = Taxon.NewInstance(null, null);c2SubSpecies1.setUuid(UUID.fromString("61f039c8-01f3-4f5d-8e16-1602139774e7"));
1815
    	Taxon c2SubSpecies2 = Taxon.NewInstance(null, null);c2SubSpecies2.setUuid(UUID.fromString("2ed6b6f8-05f9-459a-a075-2bca57e3013e"));
1816
    	TaxonNode c2childNodeSpecies1 = cl2.addParentChild(c2Genus, c2Species, null, null);
1817
    	nodeService.saveOrUpdate(c2childNodeSpecies1.getParent());
1818
        nodeService.saveOrUpdate(c2childNodeSpecies1);
1819
    	TaxonNode c2childNodeSubSpecies1 = cl2.addParentChild(c2Species, c2SubSpecies1, null, null);
1820
    	nodeService.saveOrUpdate(c2childNodeSubSpecies1);
1821
    	TaxonNode c2childNodeSubSpecies2 = cl2.addParentChild(c2Species, c2SubSpecies2, null, null);
1822
    	nodeService.saveOrUpdate(c2childNodeSubSpecies2);
1823

    
1824
    	Taxon c3Genus = Taxon.NewInstance(null, null);c3Genus.setUuid(UUID.fromString("407dfc8d-7a4f-4370-ada4-76c1a8279d1f"));
1825
    	Taxon c3Species = Taxon.NewInstance(null, null);c3Species.setUuid(UUID.fromString("b6d34fc7-4aa7-41e5-b633-86f474edbbd5"));
1826
    	Taxon c3SubSpecies1 = Taxon.NewInstance(null, null);c3SubSpecies1.setUuid(UUID.fromString("01c07585-a422-40cd-9339-a74c56901d9f"));
1827
    	Taxon c3SubSpecies2 = Taxon.NewInstance(null, null);c3SubSpecies2.setUuid(UUID.fromString("390c8e23-e05f-4f89-b417-50cf080f4c91"));
1828
    	TaxonNode c3childNodeSpecies1 = cl3.addParentChild(c3Genus, c3Species, null, null);
1829
    	nodeService.saveOrUpdate(c3childNodeSpecies1.getParent());
1830
        nodeService.saveOrUpdate(c3childNodeSpecies1);
1831
    	TaxonNode c3childNodeSubSpecies1 = cl3.addParentChild(c3Species, c3SubSpecies1, null, null);
1832
    	nodeService.saveOrUpdate(c3childNodeSubSpecies1);
1833
    	TaxonNode c3childNodeSubSpecies2 = cl3.addParentChild(c3Species, c3SubSpecies2, null, null);
1834
    	nodeService.saveOrUpdate(c3childNodeSubSpecies2);
1835

    
1836
      	Taxon c4Genus = Taxon.NewInstance(null, null);c4Genus.setUuid(UUID.fromString("bfd6bbdd-0116-4ab2-a781-9316224aad78"));
1837
    	Taxon c4Species = Taxon.NewInstance(null, null);c4Species.setUuid(UUID.fromString("9347a3d9-5ece-4d64-9035-e8aaf5d3ee02"));
1838
    	Taxon c4SubSpecies = Taxon.NewInstance(null, null);c4SubSpecies.setUuid(UUID.fromString("777aabbe-4c3a-449c-ab99-a91f2fec9f07"));
1839

    
1840
    	TaxonRelationship rel = c1Species.addTaxonRelation(c2Species, TaxonRelationshipType.CONGRUENT_TO(), citation, microcitation);
1841
    	rel.setDoubtful(true);
1842
    	c1Species.addTaxonRelation(c4Species, TaxonRelationshipType.INCLUDES(), citation, microcitation);
1843
    	c2Species.addTaxonRelation(c1SubSpecies2, TaxonRelationshipType.INCLUDES(), citation, microcitation);
1844

    
1845
    	service.saveOrUpdate(c1Species);
1846
       	service.saveOrUpdate(c2Species);
1847
       	service.save(c4Species);
1848
       	commitAndStartNewTransaction();
1849

    
1850
    	//Tests
1851
       	//default starting at species 1
1852
       	IncludedTaxaDTO dto = service.listIncludedTaxa(c1Species.getUuid(), new IncludedTaxonConfiguration(null, true, false));
1853
    	Assert.assertNotNull("IncludedTaxaDTO", dto);
1854
    	Assert.assertEquals("Result should contain 7 taxa: c1Species", 7, dto.getIncludedTaxa().size());
1855
    	Assert.assertNotNull("date should not be null", dto.getDate());
1856
//    	Assert.assertTrue(dto.contains(taxonUuid));
1857
        //same without doubtful
1858
    	dto = service.listIncludedTaxa(c1Species.getUuid(), new IncludedTaxonConfiguration(null, false, false));
1859
    	Assert.assertEquals(4, dto.getIncludedTaxa().size());
1860

    
1861
    	//other example starting at Genus2
1862
    	dto = service.listIncludedTaxa(c2Genus.getUuid(), new IncludedTaxonConfiguration(null, true, false));
1863
    	Assert.assertEquals(8, dto.getIncludedTaxa().size());
1864
    	//same without doubtful
1865
    	dto = service.listIncludedTaxa(c2Genus.getUuid(), new IncludedTaxonConfiguration(null, false, false));
1866
    	Assert.assertEquals(5, dto.getIncludedTaxa().size());
1867

    
1868
    	//only congruent
1869
    	dto = service.listIncludedTaxa(c1Species.getUuid(), new IncludedTaxonConfiguration(null, true, true));
1870
    	Assert.assertEquals(2, dto.getIncludedTaxa().size());
1871
    	//same without doubtful
1872
    	dto = service.listIncludedTaxa(c1Species.getUuid(), new IncludedTaxonConfiguration(null, false, true));
1873
    	Assert.assertEquals(1, dto.getIncludedTaxa().size());
1874
    }
1875

    
1876
    @Test
1877
    public void testDeleteDescriptions(){
1878
    	try {
1879
			createTestDataSet();
1880
		} catch (FileNotFoundException e) {
1881
			// TODO Auto-generated catch block
1882
			e.printStackTrace();
1883
		}
1884
    	TaxonDescription description = TaxonDescription.NewInstance(taxWithoutSyn);
1885
    	SpecimenOrObservationBase<IIdentifiableEntityCacheStrategy<FieldUnit>> specimen = FieldUnit.NewInstance();
1886
    	UUID uuid = occurenceService.saveOrUpdate(specimen);
1887
    	DescriptionElementBase element = IndividualsAssociation.NewInstance(specimen);
1888
    	description.addElement(element);
1889
    	service.saveOrUpdate(taxWithoutSyn);
1890

    
1891

    
1892
    	Taxon tax = (Taxon)service.find(uuidTaxWithoutSyn);
1893
    	Set<TaxonDescription> descr =  tax.getDescriptions();
1894
    	assertEquals(1, descr.size());
1895
    	description = descr.iterator().next();
1896
    	UUID uuidDescr = description.getUuid();
1897
    	UUID uuidDescEl = description.getElements().iterator().next().getUuid();
1898

    
1899
    	descriptionService.deleteDescription(description);
1900
    	service.saveOrUpdate(tax);
1901

    
1902
    	description = (TaxonDescription) descriptionService.find(uuidDescr);
1903
    	specimen = occurenceService.find(uuid);
1904
    	assertNull(description);
1905
    	DeleteResult result = occurenceService.delete(specimen);
1906
    	assertTrue(result.isOk());
1907

    
1908
    }
1909

    
1910
    @Test
1911
    public void testRemoveDescriptionsFromTaxa(){
1912
        try {
1913
            createTestDataSet();
1914
        } catch (FileNotFoundException e) {
1915
            // TODO Auto-generated catch block
1916
            e.printStackTrace();
1917
        }
1918
        TaxonDescription description = TaxonDescription.NewInstance(taxWithoutSyn);
1919
        SpecimenOrObservationBase<IIdentifiableEntityCacheStrategy<FieldUnit>> specimen = FieldUnit.NewInstance();
1920
        UUID uuid = occurenceService.saveOrUpdate(specimen);
1921
        DescriptionElementBase element = IndividualsAssociation.NewInstance(specimen);
1922
        description.addElement(element);
1923
        service.saveOrUpdate(taxWithoutSyn);
1924

    
1925

    
1926
        Taxon tax = (Taxon)service.find(uuidTaxWithoutSyn);
1927
        Set<TaxonDescription> descr =  tax.getDescriptions();
1928
        assertEquals(1, descr.size());
1929
        description = descr.iterator().next();
1930
        UUID uuidDescr = description.getUuid();
1931

    
1932

    
1933
        tax.removeDescription(description, true);
1934
        service.saveOrUpdate(tax);
1935

    
1936
        description = (TaxonDescription) descriptionService.find(uuidDescr);
1937
        specimen = occurenceService.find(uuid);
1938
        assertNotNull(description);
1939
        DeleteResult result = occurenceService.delete(specimen);
1940
        assertTrue(result.isOk());
1941
    }
1942

    
1943
    @Override
1944
    @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="ClearDBDataSet.xml")
1945
    public void createTestDataSet() throws FileNotFoundException {
1946
    	Rank rank = Rank.SPECIES();
1947
        taxWithoutSyn = Taxon.NewInstance(TaxonNameFactory.NewBotanicalInstance(rank, "Test1", null, null, null, null, null, null, null), null);
1948
        taxWithSyn = Taxon.NewInstance(TaxonNameFactory.NewBotanicalInstance(rank, "Test3", null, null, null, null, null, null, null), null);
1949
        tax2WithSyn = Taxon.NewInstance(TaxonNameFactory.NewBotanicalInstance(rank, "Test5", null, null, null, null, null, null, null), null);
1950
        synonym = Synonym.NewInstance(TaxonNameFactory.NewBotanicalInstance(rank, "Test2", null, null, null, null, null, null, null), null);
1951
        synonym2 = Synonym.NewInstance(TaxonNameFactory.NewBotanicalInstance(rank, "Test4", null, null, null, null, null, null, null), null);
1952
        synonym2.getName().setHomotypicalGroup(synonym.getHomotypicGroup());
1953

    
1954
        taxWithSyn.addSynonym(synonym, SynonymType.HETEROTYPIC_SYNONYM_OF());
1955
        taxWithSyn.addSynonym(synonym2, SynonymType.HETEROTYPIC_SYNONYM_OF());
1956

    
1957
        uuidTaxWithoutSyn = service.save(taxWithoutSyn).getUuid();
1958
        uuidSyn = service.save(synonym).getUuid();
1959
        uuidSyn2 = service.save(synonym2).getUuid();
1960
        uuidTaxWithSyn =service.save(taxWithSyn).getUuid();
1961

    
1962
    }
1963

    
1964
        //public static UUID DESCRIPTION1_UUID = UUID.fromString("f3e061f6-c5df-465c-a253-1e18ab4c7e50");
1965
        //public static UUID DESCRIPTION2_UUID = UUID.fromString("1b009a40-ebff-4f7e-9f7f-75a850ba995d");
1966

    
1967
    public Taxon getTestTaxon(){
1968
        int descrIndex = 6000;
1969
        Person deCandolle = Person.NewInstance();
1970
        deCandolle.setTitleCache("DC.", true);
1971

    
1972
        Reference sec = ReferenceFactory.newDatabase();
1973
        sec.setTitleCache("Flora lunaea", true);
1974
        Reference citationRef = ReferenceFactory.newBook();
1975
        citationRef.setTitleCache("Sp. lunarum", true);
1976

    
1977
        //genus taxon with Name, combinationAuthor,
1978
        IBotanicalName botName = TaxonNameFactory.NewBotanicalInstance(Rank.GENUS());
1979
        botName.setTitleCache("Hieracium L.", true);
1980
        botName.setGenusOrUninomial("Hieracium");
1981
        botName.setCombinationAuthorship(Person.NewInstance());
1982
        botName.getCombinationAuthorship().setNomenclaturalTitleCache("L.", true);
1983
        botName.setUuid(GENUS_NAME_UUID);
1984
        Taxon genusTaxon = Taxon.NewInstance(botName, sec);
1985
        genusTaxon.setUuid(GENUS_UUID);
1986
        service.save(genusTaxon);
1987
        //a name that is the basionym of genusTaxon's name
1988
        TaxonName basionym = TaxonNameFactory.NewBotanicalInstance(Rank.GENUS());
1989
        basionym.setTitleCache("Hieracilla DC.", true);
1990
        basionym.setGenusOrUninomial("Hieracilla");
1991
        basionym.setCombinationAuthorship(deCandolle);
1992
        basionym.setUuid(BASIONYM_UUID);
1993
        botName.addBasionym(basionym, null, null,"216", null);
1994
        nameService.saveOrUpdate(basionym);
1995
        //species taxon that is the child of genus taxon
1996
        IBotanicalName botSpecies = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
1997
        botSpecies.setTitleCache("Hieracium asturianum Pau", true);
1998
        botSpecies.setGenusOrUninomial("Hieracium");
1999
        botSpecies.setSpecificEpithet("asturianum");
2000
        botSpecies.setCombinationAuthorship(Person.NewInstance());
2001
        botSpecies.getCombinationAuthorship().setNomenclaturalTitleCache("Pau", true);
2002
        botSpecies.setUuid(SPECIES1_NAME_UUID);
2003
        Taxon childTaxon = Taxon.NewInstance(botSpecies, sec);
2004
        childTaxon.setUuid(SPECIES1_UUID);
2005
        TaxonDescription taxDesc = getTestDescription(descrIndex++);
2006
        //taxDesc.setUuid(DESCRIPTION1_UUID);
2007
        childTaxon.addDescription(taxDesc);
2008
        service.saveOrUpdate(childTaxon);
2009
        Classification classification = getTestClassification("TestClassification");
2010
        classification.addParentChild(genusTaxon, childTaxon, citationRef, "456");
2011
//            childTaxon.setTaxonomicParent(genusTaxon, citationRef, "456");
2012
        classificationService.save(classification);
2013
        //homotypic synonym of childTaxon1
2014
        IBotanicalName botSpecies4= TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
2015
        botSpecies4.setTitleCache("Hieracium gueri DC.", true);
2016
        botSpecies4.setGenusOrUninomial("Hieracium");
2017
        botSpecies4.setSpecificEpithet("gueri");
2018
        botSpecies4.setCombinationAuthorship(deCandolle);
2019
        botSpecies4.setUuid(SYNONYM_NAME_UUID);
2020
        Synonym homoSynonym = Synonym.NewInstance(botSpecies4, sec);
2021

    
2022
        childTaxon.addSynonym(homoSynonym, SynonymType.HOMOTYPIC_SYNONYM_OF());
2023
        service.saveOrUpdate(childTaxon);
2024

    
2025
        //2nd child species taxon that is the child of genus taxon
2026
        IBotanicalName botSpecies2= TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
2027
        botSpecies2.setTitleCache("Hieracium wolffii Zahn", true);
2028
        botSpecies2.setGenusOrUninomial("Hieracium");
2029
        botSpecies2.setSpecificEpithet("wolffii");
2030
        botSpecies2.setCombinationAuthorship(Person.NewInstance());
2031
        botSpecies2.getCombinationAuthorship().setNomenclaturalTitleCache("Zahn", true);
2032
        botSpecies2.setUuid(SPECIES2_NAME_UUID);
2033
        Taxon childTaxon2 = Taxon.NewInstance(botSpecies2, sec);
2034
        childTaxon2.setUuid(SPECIES2_UUID);
2035
        classification.addParentChild(genusTaxon, childTaxon2, citationRef, "499");
2036
        //childTaxon2.setTaxonomicParent(genusTaxon, citationRef, "499");
2037
        service.saveOrUpdate(childTaxon2);
2038
        //heterotypic synonym of childTaxon2
2039
        IBotanicalName botSpecies3= TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
2040
        botSpecies3.setTitleCache("Hieracium lupium DC.", true);
2041
        botSpecies3.setGenusOrUninomial("Hieracium");
2042
        botSpecies3.setSpecificEpithet("lupium");
2043
        botSpecies3.setCombinationAuthorship(deCandolle);
2044
        botSpecies3.setUuid(SYNONYM2_NAME_UUID);
2045
        Synonym heteroSynonym = Synonym.NewInstance(botSpecies3, sec);
2046
        heteroSynonym.setUuid(SYNONYM2_UUID);
2047
        childTaxon2.addSynonym(heteroSynonym, SynonymType.HETEROTYPIC_SYNONYM_OF());
2048
        service.saveOrUpdate(childTaxon2);
2049
        //missaplied Name for childTaxon2
2050
        IBotanicalName missName= TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
2051
        missName.setTitleCache("Hieracium lupium DC.", true);
2052
        missName.setGenusOrUninomial("Hieracium");
2053
        missName.setSpecificEpithet("lupium");
2054
        missName.setCombinationAuthorship(deCandolle);
2055
        missName.setUuid(SPECIES5_NAME_UUID);
2056
        Taxon misappliedNameTaxon = Taxon.NewInstance(missName, sec);
2057
        childTaxon2.addMisappliedName(misappliedNameTaxon, citationRef, "125");
2058
        taxDesc = getTestDescription(descrIndex++);
2059
       // taxDesc.setUuid(DESCRIPTION2_UUID);
2060
        genusTaxon.addDescription(taxDesc);
2061
        service.saveOrUpdate(genusTaxon);
2062
        service.save(misappliedNameTaxon);
2063

    
2064
        return genusTaxon;
2065
    }
2066

    
2067
    public TaxonDescription getTestDescription(int index){
2068
        TaxonDescription taxonDescription = TaxonDescription.NewInstance();
2069
        Language language = Language.DEFAULT();
2070
        //taxonDescription.setId(index);
2071

    
2072
        //textData
2073
        TextData textData = TextData.NewInstance();
2074
        String descriptionText = "this is a desciption for a taxon";
2075
        LanguageString languageString = LanguageString.NewInstance(descriptionText, language);
2076
        textData.putText(languageString);
2077
        taxonDescription.addElement(textData);
2078

    
2079
        //commonName
2080

    
2081
        String commonNameString = "Schönveilchen";
2082
        CommonTaxonName commonName = CommonTaxonName.NewInstance(commonNameString, language);
2083
        taxonDescription.addElement(commonName);
2084

    
2085
        return taxonDescription;
2086
    }
2087

    
2088
    public Classification getTestClassification(String name){
2089
        return Classification.NewInstance(name);
2090
    }
2091
}
(30-30/37)