Project

General

Profile

Download (44.1 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2013 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.description;
10

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

    
17
import java.io.FileNotFoundException;
18
import java.util.ArrayList;
19
import java.util.Arrays;
20
import java.util.Collection;
21
import java.util.EnumSet;
22
import java.util.HashSet;
23
import java.util.Iterator;
24
import java.util.List;
25
import java.util.Set;
26
import java.util.UUID;
27

    
28
import org.apache.log4j.Logger;
29
import org.junit.Assert;
30
import org.junit.Before;
31
import org.junit.Test;
32
import org.unitils.dbunit.annotation.DataSet;
33
import org.unitils.dbunit.annotation.DataSets;
34
import org.unitils.spring.annotation.SpringBeanByType;
35

    
36
import eu.etaxonomy.cdm.api.application.ICdmRepository;
37
import eu.etaxonomy.cdm.api.service.DeleteResult;
38
import eu.etaxonomy.cdm.api.service.IClassificationService;
39
import eu.etaxonomy.cdm.api.service.IDescriptionElementService;
40
import eu.etaxonomy.cdm.api.service.IDescriptionService;
41
import eu.etaxonomy.cdm.api.service.IReferenceService;
42
import eu.etaxonomy.cdm.api.service.ITaxonService;
43
import eu.etaxonomy.cdm.api.service.ITermService;
44
import eu.etaxonomy.cdm.common.CdmUtils;
45
import eu.etaxonomy.cdm.common.JvmLimitsException;
46
import eu.etaxonomy.cdm.common.monitor.DefaultProgressMonitor;
47
import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
48
import eu.etaxonomy.cdm.filter.TaxonNodeFilter;
49
import eu.etaxonomy.cdm.model.common.CdmBase;
50
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
51
import eu.etaxonomy.cdm.model.description.DescriptionElementSource;
52
import eu.etaxonomy.cdm.model.description.DescriptionType;
53
import eu.etaxonomy.cdm.model.description.Distribution;
54
import eu.etaxonomy.cdm.model.description.PresenceAbsenceTerm;
55
import eu.etaxonomy.cdm.model.description.TaxonDescription;
56
import eu.etaxonomy.cdm.model.location.NamedArea;
57
import eu.etaxonomy.cdm.model.name.IBotanicalName;
58
import eu.etaxonomy.cdm.model.name.Rank;
59
import eu.etaxonomy.cdm.model.name.TaxonNameFactory;
60
import eu.etaxonomy.cdm.model.reference.ICdmTarget;
61
import eu.etaxonomy.cdm.model.reference.OriginalSourceType;
62
import eu.etaxonomy.cdm.model.reference.Reference;
63
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
64
import eu.etaxonomy.cdm.model.taxon.Classification;
65
import eu.etaxonomy.cdm.model.taxon.Taxon;
66
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
67
import eu.etaxonomy.cdm.model.term.OrderedTermVocabulary;
68
import eu.etaxonomy.cdm.model.term.TermTree;
69
import eu.etaxonomy.cdm.model.term.TermType;
70
import eu.etaxonomy.cdm.test.integration.CdmTransactionalIntegrationTest;
71
import eu.etaxonomy.cdm.test.unitils.CleanSweepInsertLoadStrategy;
72

    
73
/**
74
 * @author a.kohlbecker
75
 * @author a.mueller
76
 * @since Feb 26, 2013
77
 */
78
public class DistributionAggregationTest extends CdmTransactionalIntegrationTest {
79

    
80
    private static Logger logger = Logger.getLogger(DistributionAggregationTest.class);
81

    
82
    private static final UUID T_LAPSANA_UUID = UUID.fromString("f65d47bd-4f49-4ab1-bc4a-bc4551eaa1a8");
83

    
84
    private static final UUID T_LAPSANA_COMMUNIS_UUID = UUID.fromString("2a5ceebb-4830-4524-b330-78461bf8cb6b");
85

    
86
    private static final UUID T_LAPSANA_COMMUNIS_COMMUNIS_UUID = UUID.fromString("441a3c40-0c84-11de-8c30-0800200c9a66");
87

    
88
    private static final UUID T_LAPSANA_COMMUNIS_ADENOPHORA_UUID = UUID.fromString("e4acf200-63b6-11dd-ad8b-0800200c9a66");
89

    
90
    private static final UUID T_LAPSANA_COMMUNIS_ALPINA_UUID = UUID.fromString("596b1325-be50-4b0a-9aa2-3ecd610215f2");
91

    
92
    private static final UUID CLASSIFICATION_UUID = UUID.fromString("4b266053-a841-4980-b548-3f21d8d7d712");
93

    
94
    @SpringBeanByType
95
    private ICdmRepository repository;
96

    
97
    @SpringBeanByType
98
    private ITermService termService;
99

    
100
    @SpringBeanByType
101
    private IDescriptionService descriptionService;
102

    
103
    @SpringBeanByType
104
    private IDescriptionElementService descriptionElementService;
105

    
106
    @SpringBeanByType
107
    private ITaxonService taxonService;
108

    
109
    @SpringBeanByType
110
    private IClassificationService classificationService;
111

    
112
    @SpringBeanByType
113
    private IReferenceService referenceService;
114

    
115
    private DistributionAggregation engine;
116

    
117
    // --- Distributions --- //
118
    // tdwg3 level YUG :  Yugoslavia
119
    // contains tdwg4 level areas :
120
    //   YUG-BH	Bosnia-Herzegovina
121
    //   YUG-CR	Croatia
122
    //   YUG-KO	Kosovo
123
    //   YUG-MA	Macedonia
124
    //   YUG-MN	Montenegro
125
    private NamedArea yug = null;
126
    private NamedArea yug_bh = null;
127
    private NamedArea yug_cr = null;
128
    private NamedArea yug_ko = null;
129
    private NamedArea yug_ma = null;
130
    private NamedArea yug_mn = null;
131

    
132
    List<UUID> superAreas = null;
133
    Rank upperRank = null;
134
    Rank lowerRank = null;
135

    
136

    
137
    private Reference book_a = null;
138
    private Reference book_b = null;
139

    
140
    private TermTree<PresenceAbsenceTerm> statusOrder;
141

    
142
    private IProgressMonitor monitor;
143

    
144
    @Before
145
    public void setUp() {
146

    
147
        superAreas = Arrays.asList(new UUID[]{
148
        		termService.getAreaByTdwgAbbreviation("YUG").getUuid()
149
        });
150
        lowerRank = Rank.SUBSPECIES();
151
        upperRank = Rank.GENUS();
152

    
153
        yug = termService.getAreaByTdwgAbbreviation("YUG");
154
        yug_bh = termService.getAreaByTdwgAbbreviation("YUG-BH");
155
        yug_cr = termService.getAreaByTdwgAbbreviation("YUG-CR");
156
        yug_ko = termService.getAreaByTdwgAbbreviation("YUG-KO");
157
        yug_ma = termService.getAreaByTdwgAbbreviation("YUG-MA");
158
        yug_mn = termService.getAreaByTdwgAbbreviation("YUG-MN");
159

    
160
        book_a = ReferenceFactory.newBook();
161
        book_a.setTitle("book_a");
162
        book_b = ReferenceFactory.newBook();
163
        book_b.setTitle("book_a");
164

    
165
        engine = new DistributionAggregation();
166
        engine.setBatchMinFreeHeap(35 * 1024 * 1024);
167
        makeStatusOrder();
168

    
169
        monitor = DefaultProgressMonitor.NewInstance();
170
    }
171

    
172
    private void makeStatusOrder() {
173
        if (statusOrder == null){
174
            statusOrder = TermTree.NewInstance(TermType.PresenceAbsenceTerm);
175

    
176
            @SuppressWarnings("unchecked")
177
            OrderedTermVocabulary<PresenceAbsenceTerm> voc = CdmBase.deproxy(termService.find(PresenceAbsenceTerm.uuidNative).getVocabulary(), OrderedTermVocabulary.class);
178
            for (PresenceAbsenceTerm term : voc.getTerms()){
179
                statusOrder.getRoot().addChild(term);
180
            }
181
        }
182
    }
183

    
184
    @Test
185
    @DataSets({
186
        @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="/eu/etaxonomy/cdm/database/ClearDB_with_Terms_DataSet.xml"),
187
        @DataSet(value="/eu/etaxonomy/cdm/database/TermsDataSet-with_auditing_info.xml"),
188
        @DataSet(value="DistributionAggregationTest.xml"),
189
    })
190
    public void test_ignore(){
191
        PresenceAbsenceTerm endemic = PresenceAbsenceTerm.ENDEMIC_FOR_THE_RELEVANT_AREA();
192
        addDistributions(
193
                T_LAPSANA_COMMUNIS_ALPINA_UUID,
194
                Arrays.asList(new Distribution[] {
195
                        // should succeed during area aggregation be ignored by rank aggregation
196
                        // => yug will get status ENDEMIC_FOR_THE_RELEVANT_AREA
197
                        //    but only for LAPSANA_COMMUNIS_ALPINA
198
                        Distribution.NewInstance(yug_mn, PresenceAbsenceTerm.ENDEMIC_FOR_THE_RELEVANT_AREA()),
199
                        // should be ignored by area aggregation
200
                        // => LAPSANA_COMMUNIS will wave distribution with yug_ko and INTRODUCED_FORMERLY_INTRODUCED
201
                        Distribution.NewInstance(yug_ko, PresenceAbsenceTerm.INTRODUCED_DOUBTFULLY_INTRODUCED()),
202
               })
203
            );
204

    
205
        TaxonNodeFilter filter = TaxonNodeFilter.NewInstance(null, null, null, null, null, lowerRank.getUuid(), upperRank.getUuid());
206

    
207
        DistributionAggregationConfiguration config = DistributionAggregationConfiguration.NewInstance(
208
                AggregationMode.byWithinTaxonAndToParent(), superAreas, filter, monitor);
209
        commitAndStartNewTransaction();
210
        DeleteResult result = engine.invoke(config, repository);
211
        testStatusOk(result);
212
        commitAndStartNewTransaction();
213

    
214
        Taxon lapsana_communis_alpina  = (Taxon) taxonService.load(T_LAPSANA_COMMUNIS_ALPINA_UUID);
215
        assertEquals(2, lapsana_communis_alpina.getDescriptions().size());
216
        assertEquals("LCA must have 1 computed description", 1, lapsana_communis_alpina.getDescriptions().stream()
217
            .filter(td->td.isAggregatedDistribution()).count());
218
        assertEquals("Endemic in yug is missing", 1, lapsana_communis_alpina.getDescriptions().stream()
219
                .filter(td->td.isAggregatedDistribution())
220
                .flatMap(td->td.getElements().stream())
221
                .filter(deb->deb.isInstanceOf(Distribution.class))
222
                .map(deb->((Distribution)deb))
223
                .filter(db->db.getStatus().equals(endemic)&&db.getArea().equals(yug)).count());
224

    
225
        //TODO decide if absent status should aggregate along rank, originally they were not ignored
226
//        Taxon lapsana_communis  = (Taxon) taxonService.load(T_LAPSANA_COMMUNIS_UUID);
227
//        assertEquals(1, lapsana_communis.getDescriptions().size());
228
//        TaxonDescription description = lapsana_communis.getDescriptions().iterator().next();
229
//        assertEquals(1, description.getElements().size());
230
//        int numExpectedFound = 0;
231
//        for (DescriptionElementBase element : description.getElements()){
232
//            Distribution distribution = (Distribution)element;
233
//            if(distribution.getArea().equals(yug_ko)){
234
//                numExpectedFound++;
235
//                assertEquals("aggregated status of area YUG-KO wrong", PresenceAbsenceTerm.INTRODUCED_FORMERLY_INTRODUCED(), distribution.getStatus());
236
//            }
237
//        }
238
//        assertEquals("YUG-KO should have been found before", numExpectedFound, 1);
239
    }
240

    
241
    @Test
242
    @DataSets({
243
        @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="/eu/etaxonomy/cdm/database/ClearDB_with_Terms_DataSet.xml"),
244
        @DataSet(value="/eu/etaxonomy/cdm/database/TermsDataSet-with_auditing_info.xml"),
245
        @DataSet(value="DistributionAggregationTest.xml"),
246
    })
247
    public void testArea_area() {
248

    
249
        Set<Distribution> distributions_LCA = new HashSet<>();
250

    
251
        distributions_LCA.add(newDistribution(book_a, yug_mn, PresenceAbsenceTerm.CULTIVATED(), "1"));
252
        distributions_LCA.add(newDistribution(book_a, yug_ko, PresenceAbsenceTerm.NATIVE(), "2")); // NATIVE should succeed
253
        distributions_LCA.add(newDistribution(book_a, yug_bh, PresenceAbsenceTerm.INTRODUCED(), "3"));
254
        distributions_LCA.add(newDistribution(book_a, yug_ma, PresenceAbsenceTerm.NATIVE(), "4")); // NATIVE should succeed
255
        addDistributions(T_LAPSANA_COMMUNIS_ALPINA_UUID, distributions_LCA);
256

    
257
        Taxon lapsana_communis_alpina  = (Taxon) taxonService.load(T_LAPSANA_COMMUNIS_ALPINA_UUID);
258
        assertEquals(1, lapsana_communis_alpina.getDescriptions().size());
259

    
260
        Set<UUID> classificationUuids = new HashSet<>();
261
        classificationUuids.add(CLASSIFICATION_UUID);
262
        TaxonNodeFilter filter = TaxonNodeFilter.NewInstance(classificationUuids, null, null, null, null, lowerRank.getUuid(), upperRank.getUuid());
263
        DistributionAggregationConfiguration config = DistributionAggregationConfiguration.NewInstance(
264
                AggregationMode.byWithinTaxon(), superAreas, filter, statusOrder, monitor);
265
        commitAndStartNewTransaction();
266
        DeleteResult result = engine.invoke(config, repository);
267
        testStatusOk(result);
268
        commitAndStartNewTransaction();
269

    
270
        lapsana_communis_alpina  = (Taxon) taxonService.load(T_LAPSANA_COMMUNIS_ALPINA_UUID);
271
        assertEquals(2, lapsana_communis_alpina.getDescriptions().size());
272

    
273
        Distribution accumulatedDistribution = null;
274
        for (TaxonDescription description : lapsana_communis_alpina.getDescriptions()) {
275
            if(description.isAggregatedDistribution()) {
276
                assertNull("only one computed Distribution should exists", accumulatedDistribution);
277
                assertEquals("the computed Decsription should have only one element", 1, description.getElements().size());
278
                accumulatedDistribution = (Distribution) description.getElements().iterator().next();
279
                assertEquals("Expecting area to be YUG", yug, accumulatedDistribution.getArea());
280
                assertEquals("Expecting status to be NATIVE", PresenceAbsenceTerm.NATIVE(), accumulatedDistribution.getStatus());
281
            }
282
        }
283
        assertNotNull("The area YUG should have been found", accumulatedDistribution);
284
        assertEquals("Expecting two source references", 2, accumulatedDistribution.getSources().size());
285
        Iterator<DescriptionElementSource> sourceIt = accumulatedDistribution.getSources().iterator();
286
        // should contain source_LCA_yug_ma and source_LCA_yug_ko, testing the microreference which is unique in the tests
287
        assertTrue(" 2  4 ".contains(" " + sourceIt.next().getCitationMicroReference() + " "));
288
        assertTrue(" 2  4 ".contains(" " + sourceIt.next().getCitationMicroReference() + " "));
289
    }
290

    
291
    @Test
292
    @DataSets({
293
        @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="/eu/etaxonomy/cdm/database/ClearDB_with_Terms_DataSet.xml"),
294
        @DataSet(value="/eu/etaxonomy/cdm/database/TermsDataSet-with_auditing_info.xml"),
295
        @DataSet(value="DistributionAggregationTest.xml"),
296
    })
297
    public void testArea_rank_and_area_1() {
298

    
299
        //Lapsana communis alpina
300
        List<Distribution> distributions_LCA = new ArrayList<>();
301
        distributions_LCA.add(newDistribution(book_a, yug_mn, PresenceAbsenceTerm.CULTIVATED(), "1"));
302
        distributions_LCA.add(newDistribution(book_a, yug_ko, PresenceAbsenceTerm.NATIVE(), "2")); // NATIVE should succeed
303
        addDistributions(T_LAPSANA_COMMUNIS_ALPINA_UUID, distributions_LCA);
304

    
305
        //Lapsana communis
306
        List<Distribution> distributions_LC = new ArrayList<>();
307
        distributions_LC.add(newDistribution(book_a, yug_mn, PresenceAbsenceTerm.CULTIVATED(), "3"));
308
        distributions_LC.add(newDistribution(book_a, yug_ko, PresenceAbsenceTerm.NATIVE(), "4")); // NATIVE should succeed
309
        addDistributions(T_LAPSANA_COMMUNIS_UUID, distributions_LC);
310

    
311
        //aggregation
312
        TaxonNodeFilter filter = TaxonNodeFilter.NewInstance(null, null, null, null, null, lowerRank.getUuid(), upperRank.getUuid());
313
        DistributionAggregationConfiguration config = DistributionAggregationConfiguration.NewInstance(
314
                AggregationMode.byWithinTaxonAndToParent(), superAreas, filter, monitor);
315
        config.setToParentSourceMode(AggregationSourceMode.ALL_SAMEVALUE);
316

    
317
        commitAndStartNewTransaction();
318
        DeleteResult result = engine.invoke(config, repository);
319
        testStatusOk(result);
320
        commitAndStartNewTransaction();
321

    
322
        //test
323
        Taxon lapsana_communis  = (Taxon) taxonService.load(T_LAPSANA_COMMUNIS_UUID);
324
        assertEquals("Lapsana communis alpina must have 2 Descriptions, 1 with original data, 1 with aggregated data",
325
                2, lapsana_communis.getDescriptions().size());
326

    
327
        Taxon lapsana = (Taxon) taxonService.load(T_LAPSANA_UUID);
328
        assertEquals("Lapsana must have 1 Description with only aggregated data (original data does not exist)",
329
                1, lapsana.getDescriptions().size());
330
        TaxonDescription lapsanaAggregatedDescription = lapsana.getDescriptions().iterator().next();
331
        assertTrue(lapsanaAggregatedDescription.isAggregatedDistribution());
332
        assertEquals(3, lapsanaAggregatedDescription.getElements().size());
333

    
334
        int numExpectedFound = 0; //to test that each "if" part is entered below
335
        UUID lapsanaDescriptionUuid = lapsanaAggregatedDescription.getUuid();
336
        UUID yugDistributionUuid = null;
337
        UUID yug_mn_DistributionUuid = null;
338

    
339
        for (DescriptionElementBase element : lapsanaAggregatedDescription.getElements()){
340
            Distribution lapsanaDistribution = (Distribution)element;
341
            if(lapsanaDistribution.getArea().equals(yug)){
342
                numExpectedFound++;
343
                assertEquals("Aggregated status of area YUG is wrong", PresenceAbsenceTerm.NATIVE(), lapsanaDistribution.getStatus());
344
                assertEquals(2, lapsanaDistribution.getSources().size());
345
                // should contain source_LCA_yug_ma and source_LCA_yug_ko, testing the microreference which is unique in the tests
346
                assertTrue(sourceExists(lapsanaDistribution.getSources(), book_a, "2"));
347
                assertTrue(sourceExists(lapsanaDistribution.getSources(), book_a, "4"));
348
                yugDistributionUuid = lapsanaDistribution.getUuid(); //for later
349
            }
350
            if(lapsanaDistribution.getArea().equals(yug_mn)){
351
                numExpectedFound++;
352
                assertEquals("Aggregated status of area YUG-MN is wrong", PresenceAbsenceTerm.CULTIVATED(), lapsanaDistribution.getStatus());
353
                assertEquals(2, lapsanaDistribution.getSources().size());
354
                // should contain source_LCA_yug_ma and source_LCA_yug_ko, testing the microreference which is unique in the tests
355
                assertTrue(sourceExists(lapsanaDistribution.getSources(), book_a, "1"));
356
                assertTrue(sourceExists(lapsanaDistribution.getSources(), book_a, "3"));
357
                yug_mn_DistributionUuid = lapsanaDistribution.getUuid();  //for reaggregation test
358
            }
359
            if(lapsanaDistribution.getArea().equals(yug_ko)){
360
                numExpectedFound++;
361
                assertEquals("aggregated status of area YUG-KO wrong", PresenceAbsenceTerm.NATIVE(), lapsanaDistribution.getStatus());
362
                assertEquals(2, lapsanaDistribution.getSources().size());
363
                // should contain source_LCA_yug_ma and source_LCA_yug_ko, testing the microreference which is unique in the tests
364
                assertTrue(sourceExists(lapsanaDistribution.getSources(), book_a, "2"));
365
                assertTrue(sourceExists(lapsanaDistribution.getSources(), book_a, "4"));
366
            }
367
        }
368
        assertEquals("All three expected areas should have been found before", numExpectedFound, 3);
369

    
370
        //RERUN aggregation, result should be same except for the little changes,
371
        //      descriptions, distributions and sources should be reused where possible
372
        //      (equal instances existed in previous aggregation)
373

    
374
        //add higher status to L. communis alpina/yug_mn
375
        Set<Distribution> mn_distr = new HashSet<>();
376
        Distribution distrNative = newDistribution(null, yug_mn, PresenceAbsenceTerm.INTRODUCED(), "5");
377
        mn_distr.add(distrNative);
378
        addDistributions(T_LAPSANA_COMMUNIS_ALPINA_UUID, mn_distr);
379

    
380
        Set<DescriptionElementSource> lca_yug_ko_sources = descriptionElementService.load(distributions_LCA.get(1).getUuid(), null).getSources();
381
        Assert.assertEquals(1, lca_yug_ko_sources.size());
382
        DescriptionElementSource lca_yug_ko_source = lca_yug_ko_sources.iterator().next();
383
        lca_yug_ko_source.setCitationMicroReference("2a");
384

    
385
        //remove L communis/yug_ko ;
386
        Distribution lc_yug_ko_distr = distributions_LC.get(1);
387
        removeDistributions(T_LAPSANA_COMMUNIS_UUID, lc_yug_ko_distr);
388

    
389
        config.setMonitor(DefaultProgressMonitor.NewInstance());
390
        commitAndStartNewTransaction();
391
        result = engine.invoke(config, repository);
392
        testStatusOk(result);
393
        commitAndStartNewTransaction();
394

    
395
        //test
396
        lapsana_communis  = (Taxon) taxonService.load(T_LAPSANA_COMMUNIS_UUID);
397
        assertEquals("Lapsana communis alpina must still have 2 Descriptions", 2, lapsana_communis.getDescriptions().size());
398

    
399
        lapsana = (Taxon) taxonService.load(T_LAPSANA_UUID);
400
        assertEquals("Lapsana must only have 1 Description", 1, lapsana.getDescriptions().size());
401
        lapsanaAggregatedDescription = lapsana.getDescriptions().iterator().next();
402
        assertEquals(lapsanaDescriptionUuid, lapsanaAggregatedDescription.getUuid());
403
        assertTrue(lapsanaAggregatedDescription.isAggregatedDistribution());
404
        assertEquals("After reaggregation there should still be only 3 distributions", 3, lapsanaAggregatedDescription.getElements().size());
405
        numExpectedFound = 0;
406
        for (DescriptionElementBase element : lapsanaAggregatedDescription.getElements()){
407
            Distribution lapsanaDistr = (Distribution)element;
408
            if(lapsanaDistr.getArea().equals(yug)){
409
                numExpectedFound++;
410
                assertEquals(yugDistributionUuid, lapsanaDistr.getUuid());
411
                assertEquals("aggregated status of area YUG is wrong", PresenceAbsenceTerm.NATIVE(), lapsanaDistr.getStatus());
412
                assertEquals(1, lapsanaDistr.getSources().size());
413
                assertFalse(sourceExists(lapsanaDistr.getSources(), book_a, "2"));
414
                assertFalse(sourceExists(lapsanaDistr.getSources(), book_a, "4"));
415
                assertTrue(sourceExists(lapsanaDistr.getSources(), book_a, "2a"));
416
            }
417
            if(lapsanaDistr.getArea().equals(yug_mn)){
418
                //new status and source after reaggregation
419
                numExpectedFound++;
420
                //this may change in future
421
                Assert.assertEquals("Distribution should be reused even if status changes", yug_mn_DistributionUuid, lapsanaDistr.getUuid());
422
                assertEquals("aggregated status of area YUG-MN is wrong", PresenceAbsenceTerm.INTRODUCED(), lapsanaDistr.getStatus());
423
                assertEquals("on higher status there should only 1 source left",1, lapsanaDistr.getSources().size());
424
                assertTrue(sourceExists(lapsanaDistr.getSources(), null, "5"));
425
            }
426
            if(lapsanaDistr.getArea().equals(yug_ko)){
427
                numExpectedFound++;
428
                assertEquals("aggregated status of area YUG-KO wrong", PresenceAbsenceTerm.NATIVE(), lapsanaDistr.getStatus());
429
                assertEquals(1, lapsanaDistr.getSources().size());
430
                assertTrue(sourceExists(lapsanaDistr.getSources(), book_a, "2a"));
431
            }
432
        }
433
        assertEquals("All three expected areas should have been found before", numExpectedFound, 3);
434
    }
435

    
436
    private boolean sourceExists(Set<DescriptionElementSource> sources, Reference ref, String microCitation) {
437
        for (DescriptionElementSource source:sources){
438
            if (CdmUtils.nullSafeEqual(source.getCitation(), ref) &&
439
                    CdmUtils.nullSafeEqual(source.getCitationMicroReference(), microCitation)){
440
                return true;
441
            }
442
        }
443
        return false;
444
    }
445

    
446
    private boolean sourceExists(Set<DescriptionElementSource> sources, ICdmTarget target) {
447
        for (DescriptionElementSource source:sources){
448
            if (CdmUtils.nullSafeEqual(source.getCdmSource(), target) &&
449
                    CdmUtils.nullSafeEqual(source.getType(), OriginalSourceType.Aggregation)){
450
                return true;
451
            }
452
        }
453
        return false;
454
    }
455

    
456
    /**
457
     * Variant of {@link #testArea_rank_and_area_1()} with alternate source references to check the
458
     * suppression of duplicates.
459
     *
460
     * This test relies on {@link #testArea_rank_and_area_1()}
461
     * an makes assertions only on the alternative source references
462
     * @throws JvmLimitsException
463
     */
464
    @Test
465
    @DataSets({
466
        @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="/eu/etaxonomy/cdm/database/ClearDB_with_Terms_DataSet.xml"),
467
        @DataSet(value="/eu/etaxonomy/cdm/database/TermsDataSet-with_auditing_info.xml"),
468
        @DataSet(value="DistributionAggregationTest.xml"),
469
    })
470
    public void testArea_rank_and_area_2() throws JvmLimitsException {
471

    
472
        Set<Distribution> distributions_LCA = new HashSet<Distribution>();
473
        distributions_LCA.add(newDistribution(book_a, yug_ko, PresenceAbsenceTerm.NATIVE(), "1"));
474
        distributions_LCA.add(newDistribution(book_b, yug_ko, PresenceAbsenceTerm.NATIVE(), "2"));
475

    
476
        addDistributions(T_LAPSANA_COMMUNIS_ALPINA_UUID, distributions_LCA);
477

    
478
        TaxonNodeFilter filter = TaxonNodeFilter.NewInstance(null, null, null, null, null, lowerRank.getUuid(), upperRank.getUuid());
479
        DistributionAggregationConfiguration config = DistributionAggregationConfiguration.NewInstance(
480
                AggregationMode.byWithinTaxonAndToParent(), superAreas, filter, monitor);
481
        config.setToParentSourceMode(AggregationSourceMode.ALL_SAMEVALUE);
482
        commitAndStartNewTransaction();
483
        DeleteResult result = engine.invoke(config, repository);
484
        testStatusOk(result);
485
        commitAndStartNewTransaction();
486

    
487
        Taxon lapsana_communis = (Taxon) taxonService.load(T_LAPSANA_COMMUNIS_UUID);
488
        int computedDescriptionsCnt = 0;
489
        for(TaxonDescription description : lapsana_communis.getDescriptions()) {
490
            if(description.isAggregatedDistribution()) {
491
                computedDescriptionsCnt++;
492
                assertEquals(2, description.getElements().size()); // yug, yug_ko
493
                for(DescriptionElementBase distribution : description.getElements()) {
494
                    logger.debug(((Distribution)distribution).getArea() + " " + sourcesToString(distribution));
495
                    if(((Distribution)distribution).getArea().equals(yug_ko)){
496
                        assertEquals(2, distribution.getSources().size());
497
                    }
498
                    if(((Distribution)distribution).getArea().equals(yug)){
499
                        assertEquals(2, distribution.getSources().size());
500
                    }
501
                }
502
            }
503
        }
504
        assertEquals(1, computedDescriptionsCnt);
505
    }
506

    
507

    
508
    /**
509
     * Variant of {@link #testArea_rank_and_area_1()} with alternate source references to check the
510
     * suppression of duplicates.
511
     *
512
     * This test relies on {@link #testArea_rank_and_area_1()}
513
     * an makes assertions only on the alternative source references
514
     */
515
    @Test
516
    @DataSets({
517
        @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="/eu/etaxonomy/cdm/database/ClearDB_with_Terms_DataSet.xml"),
518
        @DataSet(value="/eu/etaxonomy/cdm/database/TermsDataSet-with_auditing_info.xml"),
519
        @DataSet(value="DistributionAggregationTest.xml"),
520
    })
521
    public void testArea_rank_and_area_3() {
522

    
523
        Set<Distribution> distributions_LCA = new HashSet<>();
524
        distributions_LCA.add(newDistribution(book_a, yug_ko, PresenceAbsenceTerm.NATIVE(), "1"));
525
        distributions_LCA.add(newDistribution(book_a, yug_ko, PresenceAbsenceTerm.NATIVE(), "3"));
526

    
527
        addDistributions(T_LAPSANA_COMMUNIS_ALPINA_UUID, distributions_LCA);
528

    
529
        Set<Distribution> distributions_LC = new HashSet<>();
530
        distributions_LC.add(newDistribution(book_a, yug_ko, PresenceAbsenceTerm.NATIVE(), "1"));
531
        distributions_LC.add(newDistribution(book_b, yug_ko, PresenceAbsenceTerm.NATIVE(), "2"));
532

    
533
        addDistributions(T_LAPSANA_COMMUNIS_UUID, distributions_LC);
534

    
535
        TaxonNodeFilter filter = TaxonNodeFilter.NewInstance(null, null, null, null, null, lowerRank.getUuid(), upperRank.getUuid());
536
        DistributionAggregationConfiguration config = DistributionAggregationConfiguration.NewInstance(
537
                AggregationMode.byWithinTaxonAndToParent(), superAreas, filter, monitor);
538
        config.setToParentSourceMode(AggregationSourceMode.ALL_SAMEVALUE);
539
        commitAndStartNewTransaction();
540
        DeleteResult result = engine.invoke(config, repository);
541
        testStatusOk(result);
542
        commitAndStartNewTransaction();
543

    
544
        Taxon lapsana_communis = (Taxon) taxonService.load(T_LAPSANA_COMMUNIS_UUID);
545
        int computedDescriptionsCnt = 0;
546
        for(TaxonDescription description : lapsana_communis.getDescriptions()) {
547
            if(description.isAggregatedDistribution()) {
548
                computedDescriptionsCnt++;
549
                assertEquals(2, description.getElements().size());
550
                for(DescriptionElementBase distribution : description.getElements()) {
551
                    logger.debug(((Distribution)distribution).getArea() + " " + sourcesToString(distribution));
552
                    if(((Distribution)distribution).getArea().equals(yug_ko)){
553
                        assertEquals(2, distribution.getSources().size());
554
                    }
555
                    if(((Distribution)distribution).getArea().equals(yug)){
556
                        assertEquals(3, distribution.getSources().size());
557
                    }
558
                }
559
            }
560
        }
561
        assertEquals(1, computedDescriptionsCnt);
562
    }
563

    
564
    /**
565
     * Variant of {@link #testArea_rank_and_area_1()} with alternate source references to
566
     * check the handling of the case where the target taxon already has the distribution which is the
567
     * result of the aggregation (see https://dev.e-taxonomy.eu/redmine/issues/4366#comment:12)
568
     *
569
     * This test relies on {@link #testArea_rank_and_area_1()}
570
     * and makes assertions only on the alternative source references
571
     */
572
    @Test
573
    @DataSets({
574
        @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="/eu/etaxonomy/cdm/database/ClearDB_with_Terms_DataSet.xml"),
575
        @DataSet(value="/eu/etaxonomy/cdm/database/TermsDataSet-with_auditing_info.xml"),
576
        @DataSet(value="DistributionAggregationTest.xml"),
577
    })
578
    public void testArea_rank_and_area_4() {
579

    
580
        Set<Distribution> distributions_LCA = new HashSet<>();
581
        distributions_LCA.add(newDistribution(book_a, yug_ko, PresenceAbsenceTerm.NATIVE(), "1"));
582
        addDistributions(T_LAPSANA_COMMUNIS_ALPINA_UUID, distributions_LCA);
583

    
584
        Set<Distribution> distributions_LC = new HashSet<>();
585
        distributions_LC.add(newDistribution(book_a, yug, PresenceAbsenceTerm.NATIVE(), "2")); //  should succeed
586
        addDistributions(T_LAPSANA_COMMUNIS_UUID, distributions_LC);
587

    
588
        TaxonNodeFilter filter = TaxonNodeFilter.NewInstance(null, null, null, null, null, lowerRank.getUuid(), upperRank.getUuid());
589
        DistributionAggregationConfiguration config = DistributionAggregationConfiguration.NewInstance(
590
                AggregationMode.byWithinTaxonAndToParent(), superAreas, filter, monitor);
591
        config.setToParentSourceMode(AggregationSourceMode.DESCRIPTION);  //this is default anyway
592
        commitAndStartNewTransaction();
593
        DeleteResult result = engine.invoke(config, repository);
594
        testStatusOk(result);
595
        commitAndStartNewTransaction();
596

    
597
        Taxon lapsana_communis = (Taxon) taxonService.load(T_LAPSANA_COMMUNIS_UUID);
598

    
599
        assertEquals(1, lapsana_communis.getDescriptions().stream().filter(d->d.isAggregatedDistribution()).count());
600
        TaxonDescription lc_description = lapsana_communis.getDescriptions().stream().filter(d->d.isAggregatedDistribution()).findFirst().get();
601
        assertEquals(2, lc_description.getElements().size());
602

    
603
        Distribution dist_yu_ko = lc_description.getElements().stream()
604
                .map(el->(Distribution)el).filter(d->d.getArea().equals(yug_ko)).findFirst().get();
605
        assertEquals(1, dist_yu_ko.getSources().size());
606
        DescriptionElementSource source = dist_yu_ko.getSources().iterator().next();
607
        assertNotNull("", source.getCdmSource());
608
        //TODO more checks
609

    
610
        Distribution dist_yu = lc_description.getElements().stream()
611
                .map(el->(Distribution)el).filter(d->d.getArea().equals(yug)).findFirst().get();
612
        assertEquals(1, dist_yu.getSources().size());
613
        source = dist_yu.getSources().iterator().next();
614
        assertNotNull("", source.getCdmSource());
615
        //TODO more checks
616
    }
617

    
618
    /**
619
     * Test to check if {@link AggregationSourceMode#DESCRIPTION} works for toParentAggregation.
620
     */
621
    @Test
622
    @DataSets({
623
        @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="/eu/etaxonomy/cdm/database/ClearDB_with_Terms_DataSet.xml"),
624
        @DataSet(value="/eu/etaxonomy/cdm/database/TermsDataSet-with_auditing_info.xml"),
625
        @DataSet(value="DistributionAggregationTest.xml"),
626
    })
627
    public void test_rank_descriptionMode() throws JvmLimitsException {
628

    
629
        Set<Distribution> distributions_LCA = new HashSet<>();
630
        distributions_LCA.add(newDistribution(book_a, yug_ko, PresenceAbsenceTerm.NATIVE(), "1"));
631

    
632
        TaxonDescription descLCA = addDistributions(T_LAPSANA_COMMUNIS_ALPINA_UUID, distributions_LCA);
633

    
634
        Set<Distribution> distributions_LCAD = new HashSet<>();
635
        distributions_LCAD.add(newDistribution(book_a, yug_ko, PresenceAbsenceTerm.NATIVE(), "2"));
636

    
637
        TaxonDescription descLCAD = addDistributions(T_LAPSANA_COMMUNIS_ADENOPHORA_UUID, distributions_LCAD);
638

    
639
        TaxonNodeFilter filter = TaxonNodeFilter.NewInstance(null, null, null, null, null, lowerRank.getUuid(), upperRank.getUuid());
640
        DistributionAggregationConfiguration config = DistributionAggregationConfiguration.NewInstance(
641
                AggregationMode.byToParent(), superAreas, filter, monitor);
642
        config.setToParentSourceMode(AggregationSourceMode.DESCRIPTION);
643
        commitAndStartNewTransaction();
644
        DeleteResult result = engine.invoke(config, repository);
645
        testStatusOk(result);
646
        commitAndStartNewTransaction();
647

    
648
        Taxon lapsana_communis = (Taxon) taxonService.load(T_LAPSANA_COMMUNIS_UUID);
649
        assertEquals(1, lapsana_communis.getDescriptions().size());
650
        TaxonDescription description = lapsana_communis.getDescriptions().iterator().next();
651
        assertTrue(description.isAggregatedDistribution());
652
        assertEquals(1, description.getElements().size());
653
        Distribution distribution = CdmBase.deproxy(description.getElements().iterator().next(), Distribution.class);
654
        assertEquals(2, distribution.getSources().size());
655
        assertTrue(sourceExists(distribution.getSources(), descLCA));
656
        assertTrue(sourceExists(distribution.getSources(), descLCAD));
657
    }
658

    
659
    /**
660
     * Test to check if {@link AggregationSourceMode#DESCRIPTION} works for toParentAggregation.
661
     */
662
    @Test
663
    @DataSets({
664
        @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="/eu/etaxonomy/cdm/database/ClearDB_with_Terms_DataSet.xml"),
665
        @DataSet(value="/eu/etaxonomy/cdm/database/TermsDataSet-with_auditing_info.xml"),
666
        @DataSet(value="DistributionAggregationTest.xml"),
667
    })
668
    public void test_areaRank_sourceType() throws JvmLimitsException {
669

    
670
        Set<Distribution> distributions_LCA = new HashSet<>();
671
        Distribution dist1 = newDistribution(book_a, yug_ko, PresenceAbsenceTerm.NATIVE(), "1");
672
        Distribution dist2 = newDistribution(book_a, yug_mn, PresenceAbsenceTerm.NATIVE(), "2");
673
        dist2.getSources().iterator().next().setType(OriginalSourceType.Other);
674
        distributions_LCA.add(dist1);
675
        distributions_LCA.add(dist2);
676

    
677
        addDistributions(T_LAPSANA_COMMUNIS_ALPINA_UUID, distributions_LCA);
678

    
679
        //aggregate
680
        TaxonNodeFilter filter = TaxonNodeFilter.NewInstance(null, null, null, null, null, lowerRank.getUuid(), upperRank.getUuid());
681
        DistributionAggregationConfiguration config = DistributionAggregationConfiguration.NewInstance(
682
                AggregationMode.byWithinTaxonAndToParent(), superAreas, filter, monitor);
683
        config.setAggregatingSourceTypes(EnumSet.of(OriginalSourceType.PrimaryTaxonomicSource));
684
        config.setToParentSourceMode(AggregationSourceMode.ALL);
685
        commitAndStartNewTransaction();
686
        DeleteResult result = engine.invoke(config, repository);
687
        testStatusOk(result);
688
        commitAndStartNewTransaction();
689

    
690
        //test
691
        Taxon lapsana_communis_alpina = (Taxon) taxonService.load(T_LAPSANA_COMMUNIS_ALPINA_UUID);
692
        assertEquals(1, lapsana_communis_alpina.getDescriptions(DescriptionType.AGGREGATED_DISTRIBUTION).size());
693
        TaxonDescription description = lapsana_communis_alpina.getDescriptions(DescriptionType.AGGREGATED_DISTRIBUTION).iterator().next();
694
        assertEquals(1, description.getElements().size());
695
        Distribution distribution = CdmBase.deproxy(description.getElements().iterator().next(), Distribution.class);
696
        assertEquals(1, distribution.getSources().size());
697
        assertTrue(sourceExists(distribution.getSources(), book_a, "1"));
698
        assertFalse(sourceExists(distribution.getSources(), book_a, "2"));
699

    
700
        Taxon lapsana_communis = (Taxon) taxonService.load(T_LAPSANA_COMMUNIS_UUID);
701
        assertEquals(1, lapsana_communis.getDescriptions(DescriptionType.AGGREGATED_DISTRIBUTION).size());
702
        description = lapsana_communis.getDescriptions(DescriptionType.AGGREGATED_DISTRIBUTION).iterator().next();
703
        assertEquals(3, description.getElements().size());
704
        int testAll = 0;
705
        for(DescriptionElementBase deb : description.getElements()){
706
            distribution = CdmBase.deproxy(deb, Distribution.class);
707
            if(distribution.getArea().equals(yug)){
708
                assertEquals(1, distribution.getSources().size());
709
                testAll++;
710
            }else if(distribution.getArea().equals(yug_mn)){
711
                assertEquals(0, distribution.getSources().size());
712
                testAll = testAll+2;
713
            }else if(distribution.getArea().equals(yug_ko)){
714
                assertEquals(1, distribution.getSources().size());
715
                testAll = testAll+4;
716
            }
717
        }
718
        Assert.assertTrue(testAll == 7);
719
    }
720

    
721
    private Distribution newDistribution(Reference reference, NamedArea area, PresenceAbsenceTerm status,
722
            String microCitation) {
723
        Distribution distribution = Distribution.NewInstance(area, status);
724
        distribution.addPrimaryTaxonomicSource(reference, microCitation);
725
        return distribution;
726
    }
727

    
728
    /**
729
     * Creates a new description for the taxon identified by the UUIDs
730
     */
731
    private TaxonDescription addDistributions(UUID taxonUuid, Collection<Distribution> distributions) {
732
        Taxon taxon = (Taxon) taxonService.load(taxonUuid);
733
        if(taxon == null) {
734
            throw new NullPointerException("No taxon found for " + taxonUuid);
735
        }
736
        TaxonDescription description = TaxonDescription.NewInstance(taxon);
737

    
738
        for (Distribution distribution : distributions) {
739
            description.addElement(distribution);
740
        }
741
        commitAndStartNewTransaction(null);
742
        return description;
743
    }
744

    
745
    private void removeDistributions(UUID taxonUuid, Distribution distribution) {
746
        Taxon taxon = (Taxon) taxonService.load(taxonUuid);
747
        if(taxon == null) {
748
            throw new NullPointerException("No taxon found for " + taxonUuid);
749
        }
750
        TaxonDescription deleteFrom = null;
751
        for (TaxonDescription description : taxon.getDescriptions()){
752
            if (!description.isAggregatedDistribution()){
753
                for (DescriptionElementBase el : description.getElements()){
754
                    if (el.equals(distribution)){
755
                        deleteFrom = description;
756
                    }
757
                }
758
            }
759
        }
760
        if (deleteFrom != null){
761
            deleteFrom.removeElement(distribution);
762
        }
763
        commitAndStartNewTransaction(null);
764
    }
765

    
766
    private String sourcesToString(DescriptionElementBase deb) {
767
        StringBuffer out = new StringBuffer();
768
        for ( DescriptionElementSource source : deb.getSources()) {
769
            out.append(source.getCitation()==null?"":source.getCitation().getTitle() + " : " + source.getCitationMicroReference() + ", ");
770
        }
771
        return out.toString();
772
    }
773

    
774
    private void testStatusOk(DeleteResult result) {
775
        if (result.getStatus() != DeleteResult.Status.OK){
776
            Assert.fail("Aggregation should have status OK but was " + result.toString());
777
            for (Exception ex : result.getExceptions()){
778
                ex.printStackTrace();
779
            }
780
        }
781
    }
782

    
783
    //@Test //  uncomment to create test data file//
784
    @Override
785
    public void createTestDataSet() throws FileNotFoundException {
786

    
787
        // --- References --- //
788
        Reference sec = ReferenceFactory.newDatabase();
789
        sec.setTitleCache("Test", true);
790
        Reference nomRef = ReferenceFactory.newBook();
791
        sec.setTitleCache("Sp.Pl.", true);
792

    
793
        referenceService.save(sec);
794
        referenceService.save(nomRef);
795

    
796

    
797
        // --- Taxa --- //
798
        //  Lapsana
799
        //        L. communis
800
        //            L. communis subsp. communis
801
        //            L. communis subsp. adenophora
802
        //            L. communis subsp. alpina
803
        //  Sonchella
804
        //        S. dentata
805
        //        S. stenoma
806
        IBotanicalName n_lapsana = TaxonNameFactory.NewBotanicalInstance(Rank.GENUS());
807
        n_lapsana.setTitleCache("Lapsana", true);
808
        Taxon t_lapsana = Taxon.NewInstance(n_lapsana, sec);
809
        t_lapsana.setUuid(T_LAPSANA_UUID);
810
        taxonService.saveOrUpdate(t_lapsana);
811

    
812
        IBotanicalName n_lapsana_communis = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
813
        n_lapsana_communis.setTitleCache("L. communis", true);
814
        Taxon t_lapsana_communis = Taxon.NewInstance(n_lapsana_communis, sec);
815
        t_lapsana_communis.setUuid(T_LAPSANA_COMMUNIS_UUID);
816
        taxonService.saveOrUpdate(t_lapsana_communis);
817

    
818
        IBotanicalName n_lapsana_communis_communis = TaxonNameFactory.NewBotanicalInstance(Rank.SUBSPECIES());
819
        n_lapsana_communis_communis.setTitleCache("L. communis subsp. communis", true);
820
        Taxon t_lapsana_communis_communis = Taxon.NewInstance(n_lapsana_communis_communis, sec);
821
        t_lapsana_communis_communis.setUuid(T_LAPSANA_COMMUNIS_COMMUNIS_UUID);
822
        taxonService.saveOrUpdate(t_lapsana_communis_communis);
823

    
824
        IBotanicalName n_lapsana_communis_adenophora = TaxonNameFactory.NewBotanicalInstance(Rank.SUBSPECIES());
825
        n_lapsana_communis_adenophora.setTitleCache("L. communis subsp. adenophora", true);
826
        Taxon t_lapsana_communis_adenophora = Taxon.NewInstance(n_lapsana_communis_adenophora, sec);
827
        t_lapsana_communis_adenophora.setUuid(T_LAPSANA_COMMUNIS_ADENOPHORA_UUID);
828
        taxonService.saveOrUpdate(t_lapsana_communis_adenophora);
829

    
830
        IBotanicalName n_lapsana_communis_alpina = TaxonNameFactory.NewBotanicalInstance(Rank.SUBSPECIES());
831
        n_lapsana_communis_alpina.setTitleCache("L. communis subsp. alpina", true);
832
        Taxon t_lapsana_communis_alpina = Taxon.NewInstance(n_lapsana_communis_alpina, sec);
833
        t_lapsana_communis_alpina.setUuid(T_LAPSANA_COMMUNIS_ALPINA_UUID);
834
        taxonService.saveOrUpdate(t_lapsana_communis_alpina);
835

    
836
        // --- Classification --- //
837
        Classification classification = Classification.NewInstance("TestClassification");
838
        classification.setUuid(CLASSIFICATION_UUID);
839
        classificationService.save(classification);
840
        TaxonNode node_lapsana = classification.addChildTaxon(t_lapsana, sec, null);
841
        TaxonNode node_lapsana_communis = node_lapsana.addChildTaxon(t_lapsana_communis, sec, null);
842
        node_lapsana_communis.addChildTaxon(t_lapsana_communis_communis, sec, null);
843
        node_lapsana_communis.addChildTaxon(t_lapsana_communis_adenophora, sec, null);
844
        node_lapsana_communis.addChildTaxon(t_lapsana_communis_alpina, sec, null);
845
        classificationService.saveOrUpdate(classification);
846

    
847
        // --- Distributions --- //
848
        // tdwg3 level YUG :  Yugoslavia
849
        // contains tdwg4 level areas :
850
        //   YUG-BH	Bosnia-Herzegovina
851
        //   YUG-CR	Croatia
852
        //   YUG-KO	Kosovo
853
        //   YUG-MA	Macedonia
854
        //   YUG-MN	Montenegro
855

    
856
        // assigning distribution information to taxa
857
        // expectations regarding the aggregation can be found in the comments below
858
//        TaxonDescription d_lapsana_communis_communis = TaxonDescription.NewInstance(t_lapsana_communis_communis);
859
//        d_lapsana_communis_communis.addElement(Distribution.NewInstance(
860
//                    TdwgArea.getAreaByTdwgAbbreviation("YUG-MN"),
861
//                    PresenceTerm.ENDEMIC_FOR_THE_RELEVANT_AREA() // should be ignored
862
//                    );
863

    
864
        commitAndStartNewTransaction(null);
865

    
866
        writeDbUnitDataSetFile(new String[] {
867
                "TAXONBASE", "TAXONNAME",
868
                "REFERENCE", "DESCRIPTIONELEMENTBASE", "DESCRIPTIONBASE",
869
                "AGENTBASE", "CLASSIFICATION",  "TAXONNODE",
870
                "HOMOTYPICALGROUP", "LANGUAGESTRING",
871
                "HIBERNATE_SEQUENCES"
872
         });
873

    
874
    }
875

    
876
}
(2-2/3)