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 IMarkerService markerService;
112

    
113
    @SpringBeanByType
114
    private IEventBaseService eventService;
115

    
116
    @SpringBeanByType
117
    private IOccurrenceService occurenceService;
118

    
119
    private Synonym synonym;
120
    private Synonym synonym2;
121

    
122
    private Taxon taxWithSyn;
123
    private Taxon tax2WithSyn;
124
    private Taxon taxWithoutSyn;
125
    private UUID uuidSyn;
126
    private UUID uuidTaxWithoutSyn;
127
    private UUID uuidSyn2;
128
    private UUID uuidTaxWithSyn;
129

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

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

    
146
/****************** TESTS *****************************/
147

    
148

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

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

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

    
182

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

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

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

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

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

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

    
251

    
252
    @Test
253
    public final void testSwapSynonymAndAcceptedTaxon() throws FileNotFoundException{
254

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

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

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

    
275
    @Test
276
    public final void testSwapSynonymAndAcceptedTaxonNewUuid() throws FileNotFoundException{
277

    
278
        createTestDataSet();
279
        synonym.setSec(ReferenceFactory.newArticle());
280
        service.saveOrUpdate(synonym);
281
        UpdateResult result = service.swapSynonymAndAcceptedTaxon(synonym, taxWithSyn, true, true, SecReferenceHandlingSwapEnum.AlwaysDelete, null, null);
282

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

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

    
299
    @Test
300
    public final void testChangeSynonymToAcceptedTaxon() throws FileNotFoundException{
301

    
302
		createTestDataSet();
303

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

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

    
322
    @Test
323
    public final void testChangeSynonymToAcceptedTaxonWithSecHandlingAlwaysDelete(){
324
        Taxon genus = getTestTaxon();
325
        TaxonNode node = genus.getTaxonNodes().iterator().next();
326

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

    
344

    
345
    }
346

    
347

    
348

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

    
376
    }
377

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

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

    
410
    }
411

    
412

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

    
422

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

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

    
442
       // Assert.assertEquals("New taxon should have 1 synonym relationship (the old homotypic synonym)", 1, taxon.getSynonymRelations().size());
443
    }
444

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

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

    
463
        Synonym synonym = t1.getSynonyms().iterator().next();
464

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

    
473
        Assert.assertTrue("t1 should have no synonyms", t1.getSynonyms().isEmpty());
474

    
475
        Set<Synonym> synonyms = t2.getSynonyms();
476
        Assert.assertTrue("t2 should have exactly one synonym", synonyms.size() == 1);
477

    
478
        synonym = synonyms.iterator().next();
479

    
480
        Assert.assertEquals(t2, synonym.getAcceptedTaxon());
481
        Assert.assertEquals(heteroTypicSynonymType, synonym.getType());
482
        Assert.assertEquals(reference, synonym.getSec());
483
        Assert.assertEquals(referenceDetail, synonym.getSecMicroReference());
484
    }
485

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

    
491
//        printDataSet(System.err, new String[]{"AgentBase", "TaxonBase"});
492
//        printDataSet(System.err, new String[]{"TaxonNode"});
493

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

    
504

    
505
        boolean moveHomotypicGroup = true;
506
        SynonymType newSynonymType = null;
507
        boolean keepReference = true;
508
        Reference newReference = null;
509
        String newReferenceDetail = null;
510

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

    
518
        try {
519
            service.moveSynonymToAnotherTaxon(homotypicSynonym, newTaxon, moveHomotypicGroup, newSynonymType, null, newReferenceDetail, keepReference);
520
            Assert.fail("Homotypic synonym move to other taxon should throw an exception");
521
        } catch (HomotypicalGroupChangeException e) {
522
            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")){
523
                //OK
524
                commitAndStartNewTransaction(tableNames);
525
            }else{
526
                Assert.fail("Unexpected exception occurred: " + e.getMessage());
527
            }
528
        }
529
        //Asserts
530
        homotypicSynonym = (Synonym)service.load(uuidSyn1);
531
        Assert.assertNotNull("Synonym should still exist", homotypicSynonym);
532
        Assert.assertNotNull("Synonym should still have 1 relation", homotypicSynonym.getAcceptedTaxon());
533
        Assert.assertEquals("Accepted taxon of single relation should be the old taxon", oldTaxon, homotypicSynonym.getAcceptedTaxon());
534

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

    
544
        try {
545
            service.moveSynonymToAnotherTaxon(heterotypicSynonym, newTaxon, moveHomotypicGroup, newSynonymType, null, newReferenceDetail, keepReference);
546
            Assert.fail("Heterotypic synonym move to other taxon should throw an exception");
547
        } catch (HomotypicalGroupChangeException e) {
548
            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")){
549
                //OK
550
                commitAndStartNewTransaction(tableNames);
551
            }else{
552
                Assert.fail("Unexpected exception occurred: " + e.getMessage());
553
            }
554
        }
555
        //Asserts
556
        heterotypicSynonym = (Synonym)service.load(uuidSyn3);
557
        Assert.assertNotNull("Synonym should still exist", heterotypicSynonym);
558
        Assert.assertNotNull("Synonym should have accepted taxon", heterotypicSynonym.getAcceptedTaxon());
559
        Assert.assertEquals("Accepted taxon of single relation should still be the old taxon", oldTaxon, heterotypicSynonym.getAcceptedTaxon());
560

    
561

    
562
        //test heterotypic synonym with no other synonym in homotypic group
563
        //+ keep reference
564

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

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

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

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

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

    
606
        moveHomotypicGroup = true;
607
        keepReference = false;
608

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

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

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

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

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

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

    
682
        service.save(synonym1);
683
        service.save(synonym2);
684
        service.save(taxon1);
685

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

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

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

    
715
        service.save(synonym1);
716
        service.save(synonym2);
717
        service.save(taxon1);
718

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

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

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

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

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

    
747
        Synonym synonym1 = (Synonym)service.load(uuidSynonym1);
748
        SynonymDeletionConfigurator config = new SynonymDeletionConfigurator();
749
        config.setDeleteNameIfPossible(false);
750
        config.setNewHomotypicGroupIfNeeded(true);
751
        service.deleteSynonym(synonym1, config);
752

    
753
        this.commitAndStartNewTransaction(tableNames);
754

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

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

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

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

    
781
        this.commitAndStartNewTransaction(tableNames);
782

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

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

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

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

    
807
        Taxon taxon2 = (Taxon)service.load(uuidTaxon1);
808

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

    
815
        taxon2.removeSynonym(synonym1, false);
816
        service.saveOrUpdate(taxon2);
817

    
818
        commitAndStartNewTransaction(null);
819

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

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

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

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

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

    
872
        Taxon taxon2 = (Taxon)service.load(uuidTaxon2);
873
        Synonym synonym1 = (Synonym)service.load(uuidSynonym1);
874
        synonym1.setSec(ReferenceFactory.newArticle());
875

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

    
883
        this.commitAndStartNewTransaction(tableNames);
884

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

    
895
    @Test
896
    @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="TaxonServiceImplTest.testDeleteSynonym.xml")
897

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

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

    
907
        Taxon taxon2 = (Taxon)service.load(uuidTaxon2);
908
        Synonym synonym1 = (Synonym)service.load(uuidSynonym1);
909
        taxon2.addSynonym(synonym1, SynonymType.HETEROTYPIC_SYNONYM_OF());
910

    
911
        Annotation annotation = Annotation.NewDefaultLanguageInstance("test");
912
        synonym1.addAnnotation(annotation);
913
        service.saveOrUpdate(synonym1);
914

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

    
922
    @Test
923
    @DataSet("TaxonServiceImplTest.testDeleteSynonym.xml")
924

    
925
    public final void testDeleteSynonymSynonymTaxonBooleanWithRelatedName(){
926
        final String[]tableNames = {"TaxonBase","TaxonBase_AUD", "TaxonName","TaxonName_AUD",
927
                "HomotypicalGroup","HomotypicalGroup_AUD"};
928

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

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

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

    
943
        service.saveOrUpdate(synonym1);
944

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

    
950
        service.deleteSynonym(synonym1, config);
951

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

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

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

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

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

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

    
993
        service.saveOrUpdate(synonym1);
994

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

    
1003
        service.deleteSynonym(synonym1, config);
1004

    
1005
        this.commitAndStartNewTransaction(tableNames);
1006

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

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

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

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

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

    
1038
        service.saveOrUpdate(synonym1);
1039

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

    
1048
        DeleteResult result =service.deleteSynonym(synonym1, config);
1049
        if (!result.isOk()){
1050
        	Assert.fail();
1051
        }
1052

    
1053
        logger.debug(result);
1054
        this.commitAndStartNewTransaction(tableNames);
1055

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

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

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

    
1079
        //may change with better implementation of countAllRelationships (see #2653)
1080

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

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

    
1087
        Synonym synonym1 = (Synonym)service.load(uuidSynonym1);
1088
        TaxonName name2 = nameService.load(uuidSynonymName2);
1089
        synonym1.getName().addRelationshipFromName(name2, NameRelationshipType.LATER_HOMONYM(), null, null);
1090

    
1091
        service.deleteSynonym(synonym1, new SynonymDeletionConfigurator());
1092

    
1093
        this.rollback();
1094
//		printDataSet(System.out, tableNames);
1095
        this.startNewTransaction();
1096

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

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

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

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

    
1124
        Synonym synonym1 = (Synonym)service.load(uuidSynonym1);
1125
        TaxonName name2 = nameService.load(uuidSynonymName2);
1126
        synonym1.getName().addRelationshipFromName(name2, NameRelationshipType.LATER_HOMONYM(), null, null);
1127

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

    
1134
//        printDataSet(System.out, tableNames);
1135

    
1136
        //out of wrapping transaction
1137
        service.deleteSynonym(synonym1,  new SynonymDeletionConfigurator());
1138

    
1139
        this.startNewTransaction();
1140

    
1141
        nSynonyms = service.count(Synonym.class);
1142
        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);
1143
        nNames = nameService.count(TaxonName.class);
1144
        Assert.assertEquals("There should be 4 names left in the database", 4, nNames);
1145
        nRelations = service.countSynonyms(true);
1146
        Assert.assertEquals("There should be no taxon or synonym relationship in the database", 1, nRelations);
1147
        nRelations = nameService.listNameRelationships(null, 1000, 0, null, null).size();
1148
        Assert.assertEquals("There should be one name relationship in the database", 1, nRelations);
1149
    }
1150

    
1151
    @Test
1152
    @DataSet("TaxonServiceImplTest.testInferredSynonyms.xml")
1153
    public void testCreateInferredSynonymy(){
1154

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

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

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

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

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

    
1199
        commitAndStartNewTransaction(tableNames);
1200
        getTestTaxon();
1201
        commitAndStartNewTransaction(tableNames);
1202
        int nTaxa = service.count(Taxon.class);
1203

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

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

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

    
1226
        TaxonNode node = child1.getTaxonNodes().iterator().next();
1227
        child1.addSource(IdentifiableSource.NewInstance(OriginalSourceType.Import));
1228

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

    
1234
        TaxonNode parentNode = node.getParent();
1235
        parentNode =CdmBase.deproxy(parentNode, TaxonNode.class);
1236
        parentNode.deleteChildNode(node);
1237
        nodeService.save(parentNode);
1238
        //commitAndStartNewTransaction(tableNames);
1239

    
1240
       // try {
1241

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

    
1248
        //determinationEvent = (DeterminationEvent)eventService.load(eventUUID);
1249
        commitAndStartNewTransaction(tableNames);
1250
        identifiedUnit = occurenceService.load(identifiedUnitUUID);
1251

    
1252
        occurenceService.delete(identifiedUnit);
1253

    
1254
        commitAndStartNewTransaction(tableNames);
1255
        child1 = (Taxon)service.find(SPECIES1_UUID);
1256

    
1257
        assertEquals(0, child1.getTaxonNodes().size());
1258
       // try {
1259

    
1260
         result = service.deleteTaxon(child1.getUuid(), config, null);
1261

    
1262
         if (!result.isOk()){
1263
            Assert.fail("Delete should not throw an exception anymore");
1264
         }
1265

    
1266
        nTaxa = service.count(Taxon.class);
1267
        Assert.assertEquals("There should be 3 taxa in the database", 3, nTaxa);
1268

    
1269
        config.setDeleteTaxonNodes(true);
1270
        Taxon child2 =(Taxon) service.find(SPECIES2_UUID);
1271

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

    
1278
        //service.find(uuid);
1279

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

    
1288
    @Test
1289
    @DataSet(value="../../database/ClearDBDataSet.xml")
1290
    public final void testDeleteTaxon(){
1291

    
1292
        //create a small classification
1293
        Taxon testTaxon = getTestTaxon();
1294
        service.save(testTaxon).getUuid();
1295

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

    
1308
        TaxonDeletionConfigurator config = new TaxonDeletionConfigurator();
1309
        config.setDeleteNameIfPossible(false);
1310

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

    
1317
        taxonName = nameService.find(SPECIES1_NAME_UUID);
1318
        Taxon taxon = (Taxon)service.find(SPECIES1_UUID);
1319

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

    
1336
    @Test
1337
    @DataSet(value="../../database/ClearDBDataSet.xml")
1338
    public final void testDeleteTaxonWithAnnotations(){
1339

    
1340
        //create a small classification
1341
        Taxon testTaxon = getTestTaxon();
1342
        service.save(testTaxon).getUuid();
1343

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

    
1356
        TaxonDeletionConfigurator config = new TaxonDeletionConfigurator();
1357
        config.setDeleteNameIfPossible(false);
1358
        Annotation annotation = Annotation.NewDefaultLanguageInstance("test");
1359
        speciesTaxon.addAnnotation(annotation);
1360

    
1361

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

    
1368
        taxonName = nameService.find(SPECIES1_NAME_UUID);
1369
        Taxon taxon = (Taxon)service.find(SPECIES1_UUID);
1370

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

    
1387
    @Test
1388
    @DataSet(value="../../database/ClearDBDataSet.xml")
1389
    public final void testDeleteTaxonUsedInTaxonRelation(){
1390

    
1391
        //create a small classification
1392
        Taxon testTaxon = getTestTaxon();
1393
        service.save(testTaxon).getUuid();
1394

    
1395
        Taxon speciesTaxon = (Taxon)service.find(SPECIES1_UUID);
1396
        Taxon speciesTaxon2 = (Taxon)service.find(SPECIES2_UUID);
1397
        speciesTaxon.addTaxonRelation(speciesTaxon2, TaxonRelationshipType.MISAPPLIED_NAME_FOR(), null, null);
1398

    
1399
        IBotanicalName taxonName = nameService.find(SPECIES1_NAME_UUID);
1400
        assertNotNull(taxonName);
1401

    
1402
        TaxonDeletionConfigurator config = new TaxonDeletionConfigurator();
1403
        config.setDeleteNameIfPossible(false);
1404
        config.setDeleteTaxonRelationships(false);
1405

    
1406

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

    
1413
        taxonName = nameService.find(SPECIES1_NAME_UUID);
1414
        Taxon taxon = (Taxon)service.find(SPECIES1_UUID);
1415

    
1416
        assertNotNull(taxonName);
1417
        assertNotNull(taxon);
1418

    
1419
        config.setDeleteNameIfPossible(false);
1420
        config.setDeleteTaxonRelationships(true);
1421

    
1422

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

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

    
1439
    @Test
1440
    @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="../../database/ClearDBDataSet.xml")
1441
    public final void testDeleteTaxonDeleteSynonymRelations(){
1442

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

    
1454
        Synonym synonym = speciesTaxon.getSynonyms().iterator().next();
1455
        UUID synonymUuid = synonym.getUuid();
1456
        service.countSynonyms(true);
1457

    
1458
        TaxonDeletionConfigurator config = new TaxonDeletionConfigurator();
1459
        config.setDeleteSynonymsIfPossible(false);
1460

    
1461

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

    
1468
        Taxon taxon = (Taxon)service.find(SPECIES2_UUID);
1469
        assertNull("The deleted taxon should no longer exist", taxon);
1470

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

    
1476
    @Test
1477
    @DataSet(value="../../database/ClearDBDataSet.xml")
1478
    public final void testDeleteTaxonNameUsedInOtherContext(){
1479

    
1480
        //create a small classification
1481
        Taxon testTaxon = getTestTaxon();
1482
        service.save(testTaxon).getUuid();
1483
        Taxon speciesTaxon = (Taxon)service.find(SPECIES1_UUID);
1484

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

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

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

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

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

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

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

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

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

    
1567
        //commitAndStartNewTransaction(null);
1568
        Taxon tax = (Taxon)service.find(uuid);
1569
        assertNotNull(tax);
1570
        Taxon childTaxon = (Taxon)service.find(childUUID);
1571
        assertNotNull(tax);
1572
        //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
1573
        node = nodeService.find(childNodeUUID);
1574
        assertNotNull(node);
1575
    }
1576

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

    
1584
        Taxon topMost = Taxon.NewInstance(TaxonNameFactory.NewBotanicalInstance(Rank.FAMILY()), null);
1585

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

    
1592
        TaxonDeletionConfigurator config = new TaxonDeletionConfigurator() ;
1593
        config.getTaxonNodeConfig().setChildHandling(ChildHandling.MOVE_TO_PARENT);
1594

    
1595

    
1596
        DeleteResult result = service.deleteTaxon(testTaxon.getUuid(), config, classification.getUuid());
1597
        if(!result.isOk()){
1598
         	Assert.fail();
1599
       	}
1600

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

    
1612
        assertEquals(2, size);
1613
    }
1614

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

    
1622
        Taxon topMost = Taxon.NewInstance(TaxonNameFactory.NewBotanicalInstance(Rank.FAMILY()), null);
1623

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

    
1631
        TaxonDeletionConfigurator config = new TaxonDeletionConfigurator() ;
1632
        config.getTaxonNodeConfig().setChildHandling(ChildHandling.DELETE);
1633

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

    
1654

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

    
1662
        Taxon topMost = Taxon.NewInstance(TaxonNameFactory.NewBotanicalInstance(Rank.FAMILY()), null);
1663

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

    
1674
        DeleteResult result = service.deleteTaxon(testTaxon.getUuid(), config, node.getClassification().getUuid());
1675

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

    
1690
        assertEquals(0, size);
1691
    }
1692

    
1693

    
1694
    @Test
1695
    @DataSet(value="../../database/ClearDBDataSet.xml")
1696
    public final void testTaxonDeletionConfiguratorTaxonWithMisappliedName(){
1697

    
1698
        Taxon testTaxon = getTestTaxon();
1699
        UUID uuid = service.save(testTaxon).getUuid();
1700

    
1701
        Taxon misappliedName = Taxon.NewInstance(TaxonNameFactory.NewBotanicalInstance(Rank.GENUS()), null);
1702

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

    
1708
        TaxonDeletionConfigurator config = new TaxonDeletionConfigurator() ;
1709
        config.setDeleteMisappliedNames(true);
1710

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

    
1722
    }
1723
    @Test
1724
    @DataSet(value="../../database/ClearDBDataSet.xml")
1725
    public final void testTaxonDeletionConfiguratorTaxonWithMisappliedNameDoNotDelete(){
1726

    
1727
        Taxon testTaxon = getTestTaxon();
1728
        UUID uuid = service.save(testTaxon).getUuid();
1729

    
1730
        Taxon misappliedName = Taxon.NewInstance(TaxonNameFactory.NewBotanicalInstance(Rank.GENUS()), null);
1731

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

    
1737
        TaxonDeletionConfigurator config = new TaxonDeletionConfigurator() ;
1738
        config.setDeleteMisappliedNames(false);
1739

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

    
1752
    @Test
1753
    @DataSet(value="../../database/ClearDBDataSet.xml")
1754
    public final void testTaxonDeletionConfiguratorTaxonMisappliedName(){
1755

    
1756
        Taxon testTaxon = getTestTaxon();
1757
        UUID uuid = service.save(testTaxon).getUuid();
1758

    
1759
        Taxon misappliedNameTaxon = Taxon.NewInstance(TaxonNameFactory.NewBotanicalInstance(Rank.GENUS()), null);
1760

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

    
1768
        TaxonDeletionConfigurator config = new TaxonDeletionConfigurator() ;
1769

    
1770
        service.deleteTaxon(misappliedNameTaxon.getUuid(), config,null);
1771

    
1772
        commitAndStartNewTransaction(null);
1773
        Taxon tax = (Taxon)service.find(uuid);
1774
        assertNotNull(tax);
1775
        tax = (Taxon)service.find(misappliedNameUUID);
1776
        IBotanicalName name = nameService.find(misNameUUID);
1777

    
1778
        assertNull(tax);
1779
        assertNull(name);
1780
    }
1781

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

    
1788
    	//Data
1789
    	Classification cl1 = Classification.NewInstance("testClassification1");
1790
    	Classification cl2 = Classification.NewInstance("testClassification2");
1791
    	Classification cl3 = Classification.NewInstance("testClassification3");
1792

    
1793
    	classificationService.save(cl1);
1794
        classificationService.save(cl2);
1795
        classificationService.save(cl3);
1796

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

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

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

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

    
1837
    	TaxonRelationship rel = c1Species.addTaxonRelation(c2Species, TaxonRelationshipType.CONGRUENT_TO(), citation, microcitation);
1838
    	rel.setDoubtful(true);
1839
    	c1Species.addTaxonRelation(c4Species, TaxonRelationshipType.INCLUDES(), citation, microcitation);
1840
    	c2Species.addTaxonRelation(c1SubSpecies2, TaxonRelationshipType.INCLUDES(), citation, microcitation);
1841

    
1842
    	service.saveOrUpdate(c1Species);
1843
       	service.saveOrUpdate(c2Species);
1844
       	service.save(c4Species);
1845
       	commitAndStartNewTransaction();
1846

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

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

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

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

    
1888

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

    
1896
    	descriptionService.deleteDescription(description);
1897
    	service.saveOrUpdate(tax);
1898

    
1899
    	description = (TaxonDescription) descriptionService.find(uuidDescr);
1900
    	specimen = occurenceService.find(uuid);
1901
    	assertNull(description);
1902
    	DeleteResult result = occurenceService.delete(specimen);
1903
    	assertTrue(result.isOk());
1904

    
1905
    }
1906

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

    
1922

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

    
1929

    
1930
        tax.removeDescription(description, true);
1931
        service.saveOrUpdate(tax);
1932

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

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

    
1951
        taxWithSyn.addSynonym(synonym, SynonymType.HETEROTYPIC_SYNONYM_OF());
1952
        taxWithSyn.addSynonym(synonym2, SynonymType.HETEROTYPIC_SYNONYM_OF());
1953

    
1954
        uuidTaxWithoutSyn = service.save(taxWithoutSyn).getUuid();
1955
        uuidSyn = service.save(synonym).getUuid();
1956
        uuidSyn2 = service.save(synonym2).getUuid();
1957
        uuidTaxWithSyn =service.save(taxWithSyn).getUuid();
1958

    
1959
    }
1960

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

    
1964
    public Taxon getTestTaxon(){
1965
        int descrIndex = 6000;
1966
        Person deCandolle = Person.NewInstance();
1967
        deCandolle.setTitleCache("DC.", true);
1968

    
1969
        Reference sec = ReferenceFactory.newDatabase();
1970
        sec.setTitleCache("Flora lunaea", true);
1971
        Reference citationRef = ReferenceFactory.newBook();
1972
        citationRef.setTitleCache("Sp. lunarum", true);
1973

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

    
2019
        childTaxon.addSynonym(homoSynonym, SynonymType.HOMOTYPIC_SYNONYM_OF());
2020
        service.saveOrUpdate(childTaxon);
2021

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

    
2061
        return genusTaxon;
2062
    }
2063

    
2064
    public TaxonDescription getTestDescription(int index){
2065
        TaxonDescription taxonDescription = TaxonDescription.NewInstance();
2066
        Language language = Language.DEFAULT();
2067
        //taxonDescription.setId(index);
2068

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

    
2076
        //commonName
2077

    
2078
        String commonNameString = "Schönveilchen";
2079
        CommonTaxonName commonName = CommonTaxonName.NewInstance(commonNameString, language);
2080
        taxonDescription.addElement(commonName);
2081

    
2082
        return taxonDescription;
2083
    }
2084

    
2085
    public Classification getTestClassification(String name){
2086
        return Classification.NewInstance(name);
2087
    }
2088
}
(31-31/38)