Project

General

Profile

Download (29.3 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2021 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.assertTrue;
13

    
14
import java.io.FileNotFoundException;
15
import java.math.BigDecimal;
16
import java.util.ArrayList;
17
import java.util.HashSet;
18
import java.util.Iterator;
19
import java.util.List;
20
import java.util.Set;
21
import java.util.UUID;
22
import java.util.stream.Collectors;
23

    
24
import org.apache.log4j.Logger;
25
import org.junit.Assert;
26
import org.junit.Before;
27
import org.junit.Ignore;
28
import org.junit.Test;
29
import org.unitils.dbunit.annotation.DataSet;
30
import org.unitils.dbunit.annotation.DataSets;
31
import org.unitils.spring.annotation.SpringBeanByType;
32

    
33
import eu.etaxonomy.cdm.api.application.ICdmRepository;
34
import eu.etaxonomy.cdm.api.service.IClassificationService;
35
import eu.etaxonomy.cdm.api.service.IDescriptionService;
36
import eu.etaxonomy.cdm.api.service.IDescriptiveDataSetService;
37
import eu.etaxonomy.cdm.api.service.IReferenceService;
38
import eu.etaxonomy.cdm.api.service.ITaxonNodeService;
39
import eu.etaxonomy.cdm.api.service.ITaxonService;
40
import eu.etaxonomy.cdm.api.service.ITermService;
41
import eu.etaxonomy.cdm.api.service.ITermTreeService;
42
import eu.etaxonomy.cdm.api.service.IVocabularyService;
43
import eu.etaxonomy.cdm.api.service.UpdateResult;
44
import eu.etaxonomy.cdm.api.service.dto.CategoricalDataDto;
45
import eu.etaxonomy.cdm.api.service.dto.DescriptionBaseDto;
46
import eu.etaxonomy.cdm.api.service.dto.DescriptionElementDto;
47
import eu.etaxonomy.cdm.api.service.dto.QuantitativeDataDto;
48
import eu.etaxonomy.cdm.api.service.dto.RowWrapperDTO;
49
import eu.etaxonomy.cdm.api.service.dto.SpecimenRowWrapperDTO;
50
import eu.etaxonomy.cdm.api.service.dto.StateDataDto;
51
import eu.etaxonomy.cdm.api.service.dto.StatisticalMeasurementValueDto;
52
import eu.etaxonomy.cdm.common.monitor.DefaultProgressMonitor;
53
import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
54
import eu.etaxonomy.cdm.model.common.CdmBase;
55
import eu.etaxonomy.cdm.model.description.CategoricalData;
56
import eu.etaxonomy.cdm.model.description.DescriptionBase;
57
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
58
import eu.etaxonomy.cdm.model.description.DescriptionType;
59
import eu.etaxonomy.cdm.model.description.DescriptiveDataSet;
60
import eu.etaxonomy.cdm.model.description.Feature;
61
import eu.etaxonomy.cdm.model.description.IndividualsAssociation;
62
import eu.etaxonomy.cdm.model.description.QuantitativeData;
63
import eu.etaxonomy.cdm.model.description.SpecimenDescription;
64
import eu.etaxonomy.cdm.model.description.State;
65
import eu.etaxonomy.cdm.model.description.StateData;
66
import eu.etaxonomy.cdm.model.description.StatisticalMeasure;
67
import eu.etaxonomy.cdm.model.description.StatisticalMeasurementValue;
68
import eu.etaxonomy.cdm.model.description.TaxonDescription;
69
import eu.etaxonomy.cdm.model.name.IBotanicalName;
70
import eu.etaxonomy.cdm.model.name.Rank;
71
import eu.etaxonomy.cdm.model.name.TaxonNameFactory;
72
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
73
import eu.etaxonomy.cdm.model.reference.Reference;
74
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
75
import eu.etaxonomy.cdm.model.taxon.Classification;
76
import eu.etaxonomy.cdm.model.taxon.Taxon;
77
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
78
import eu.etaxonomy.cdm.model.term.TermNode;
79
import eu.etaxonomy.cdm.model.term.TermTree;
80
import eu.etaxonomy.cdm.model.term.TermType;
81
import eu.etaxonomy.cdm.model.term.TermVocabulary;
82
import eu.etaxonomy.cdm.persistence.dto.FeatureDto;
83
import eu.etaxonomy.cdm.persistence.dto.TermDto;
84
import eu.etaxonomy.cdm.test.integration.CdmTransactionalIntegrationTest;
85
import eu.etaxonomy.cdm.test.unitils.CleanSweepInsertLoadStrategy;
86

    
87
/**
88
 * @author k.luther
89
 * @since 01.10.2021
90
 */
91
public class DescriptiveDataSetServiceTest extends CdmTransactionalIntegrationTest {
92

    
93
    @SuppressWarnings("unused")
94
    private static Logger logger = Logger.getLogger(DescriptiveDataSetServiceTest.class);
95

    
96

    
97
    private static final UUID T_LAPSANA_UUID = UUID.fromString("f65d47bd-4f49-4ab1-bc4a-bc4551eaa1a8");
98
    private static final UUID TN_LAPSANA_UUID = UUID.fromString("f4d29e9f-6484-4184-af2e-9704e96a17e3");
99

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

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

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

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

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

    
110
    private static final UUID uuidFeatureLeafPA = UUID.fromString("c4dfd16f-f2ed-45e0-8f4d-7fe1ae880510");
111
    private static UUID uuidFeatureLeafLength = UUID.fromString("3c19b50b-4a8e-467e-b7d4-89ebc05a33e1");
112
    private static UUID uuidFeatureLeafColor = UUID.fromString("1e8f503c-5aeb-4788-b4f9-84128f7141c7");
113

    
114
    private static UUID uuidLeafColorBlue = UUID.fromString("9b4df19d-f89d-4788-9d71-d1f6f7cae910");
115
    private static UUID uuidLeafColorYellow = UUID.fromString("4cf0881b-0e7b-489a-9fdb-adbe6ae4e0ae");
116

    
117
    private static UUID uuidFeatureTree = UUID.fromString("c8a29a94-2754-4d78-9faa-dff3e1387b2d");
118

    
119

    
120
    @SpringBeanByType
121
    private ICdmRepository repository;
122

    
123
    @SpringBeanByType
124
    private ITermService termService;
125

    
126
    @SpringBeanByType
127
    private ITermTreeService termTreeService;
128

    
129
    @SpringBeanByType
130
    private IVocabularyService vocabularyService;
131

    
132
    @SpringBeanByType
133
    private IDescriptionService descriptionService;
134

    
135
    @SpringBeanByType
136
    private ITaxonService taxonService;
137

    
138
    @SpringBeanByType
139
    private ITaxonNodeService taxonNodeService;
140

    
141
    @SpringBeanByType
142
    private IClassificationService classificationService;
143

    
144
    @SpringBeanByType
145
    private IReferenceService referenceService;
146

    
147
    @SpringBeanByType
148
    private IDescriptiveDataSetService datasetService;
149

    
150
    private IProgressMonitor monitor;
151

    
152
    @Before
153
    public void setUp() {
154

    
155
//        engine.setBatchMinFreeHeap(100 * 1024 * 1024);
156
        monitor = DefaultProgressMonitor.NewInstance();
157
    }
158

    
159
    @Test
160
    @DataSets({
161
        @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="/eu/etaxonomy/cdm/database/ClearDB_with_Terms_DataSet.xml"),
162
        @DataSet(value="/eu/etaxonomy/cdm/database/TermsDataSet-with_auditing_info.xml"),
163
        @DataSet(value="StructuredDescriptionAggregationTest.xml"),
164
    })
165
    public void testGetRowWrapper(){
166
        createDefaultFeatureTree();
167
        DescriptiveDataSet dataSet = createTestDataset();
168
        commitAndStartNewTransaction();
169

    
170
        List<RowWrapperDTO<?>> result =  datasetService.getRowWrapper(dataSet.getUuid(), monitor);
171

    
172
        //There are 4 specimen descriptions and one literature description (taxon association)
173
        assertTrue(result.size() == 5);
174
        //check rowWrapper
175
        //specimen_1 2 categorical and 1 quantitative
176
        for (RowWrapperDTO<?> row: result){
177
            if (row instanceof SpecimenRowWrapperDTO){
178
                SpecimenRowWrapperDTO specimen = (SpecimenRowWrapperDTO)row;
179
                if (specimen.getSpecimenDto().getLabel().equals("alpina specimen1")){
180
                    Set<DescriptionElementDto> elements = specimen.getDataValueForFeature(uuidFeatureLeafColor);
181
                    if (elements != null && !elements.isEmpty() ){
182
                        Iterator<DescriptionElementDto> it = elements.iterator();
183
                        DescriptionElementDto dto = null;
184
                        if (it.hasNext()){
185
                            dto = it.next();
186
                        }else{
187
                            Assert.fail("There is no element for feature leaf color, but should.");
188
                        }
189
                        if (dto instanceof CategoricalDataDto){
190
                            assertTrue("The states should contain one element", ((CategoricalDataDto)dto).getStates().size() == 1);
191
                            StateDataDto stateData = ((CategoricalDataDto)dto).getStates().iterator().next();
192
                            assertEquals(uuidLeafColorBlue, stateData.getState().getUuid());
193
                        }else{
194
                            Assert.fail("The element is not of type categorical data");
195
                        }
196
                    }else{
197
                        Assert.fail();
198
                    }
199

    
200

    
201
                    elements = specimen.getDataValueForFeature(uuidFeatureLeafLength);
202
                    if (elements != null && !elements.isEmpty() ){
203
                        Iterator<DescriptionElementDto> it = elements.iterator();
204
                        DescriptionElementDto dto = null;
205
                        if (it.hasNext()){
206
                            dto = it.next();
207
                        }else{
208
                            Assert.fail("There is no element for feature leaf length, but should.");
209
                        }
210
                        if (dto instanceof QuantitativeDataDto){
211
                            assertTrue("The statistical values should contain one element", ((QuantitativeDataDto)dto).getValues().size() == 1);
212
                            StatisticalMeasurementValueDto statValue = ((QuantitativeDataDto)dto).getValues().iterator().next();
213
                            assertEquals(new BigDecimal("5.0"), statValue.getValue());
214
                        }else{
215
                            Assert.fail("The element is not of type quantitative data");
216
                        }
217
                    }else{
218
                        Assert.fail();
219
                    }
220

    
221

    
222
                    elements = specimen.getDataValueForFeature(uuidFeatureLeafPA);
223
//                    assertTrue("The element should be categorical data ", element instanceof CategoricalDataDto);
224
//                    assertTrue("The statistical values should contain one element", ((CategoricalDataDto)element).getStates().size() == 1);
225
//                    StateDataDto stateData2 = ((CategoricalDataDto)element).getStates().iterator().next();
226
//                    assertEquals(State.uuidPresent, stateData2.getState().getUuid());
227

    
228
                }
229
            }
230
//            if (row instanceof TaxonRowWrapperDTO){
231
//                TaxonRowWrapperDTO taxonRow = (TaxonRowWrapperDTO)row;
232
//                Set<DescriptionElementDto> element = taxonRow.getDataValueForFeature(uuidFeatureLeafLength);
233
//                assertTrue(element instanceof QuantitativeDataDto);
234
//                assertTrue(((QuantitativeDataDto)element).getValues().size() == 2);
235
//            }
236
        }
237

    
238

    
239
        commitAndStartNewTransaction();
240

    
241
    }
242

    
243
    @Ignore
244
    @Test
245
    @DataSets({
246
        @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="/eu/etaxonomy/cdm/database/ClearDB_with_Terms_DataSet.xml"),
247
        @DataSet(value="/eu/etaxonomy/cdm/database/TermsDataSet-with_auditing_info.xml"),
248
        @DataSet(value="StructuredDescriptionAggregationTest.xml"),
249
    })
250
    public void testAddQuantitativeData() {
251
        createDefaultFeatureTree();
252
        DescriptiveDataSet dataSet = createTestDataset();
253
        commitAndStartNewTransaction();
254

    
255
        List<RowWrapperDTO<?>> result = datasetService.getRowWrapper(dataSet.getUuid(), monitor);
256
        List<DescriptionBaseDto> descToUpdate = new ArrayList<>();
257
        UUID updatedDescription = null;
258
        int elementCount = 0;
259
        for (RowWrapperDTO<?> row: result){
260
            if (row instanceof SpecimenRowWrapperDTO){
261
                SpecimenRowWrapperDTO specimen = (SpecimenRowWrapperDTO)row;
262
                DescriptionBaseDto descDto = specimen.getDescription();
263
                elementCount = descDto.getElements().size();
264
                Feature feature = (Feature)termService.find(uuidFeatureLeafLength);
265
                QuantitativeDataDto quantDto = new QuantitativeDataDto(FeatureDto.fromFeature(feature));
266
                TermDto typeDto = new TermDto(StatisticalMeasure.EXACT_VALUE().getUuid(), null, StatisticalMeasure.EXACT_VALUE().getTermType(), StatisticalMeasure.EXACT_VALUE().getPartOf() != null?StatisticalMeasure.EXACT_VALUE().getPartOf().getUuid(): null, StatisticalMeasure.EXACT_VALUE().getKindOf()!= null? StatisticalMeasure.EXACT_VALUE().getKindOf().getUuid(): null,
267
                        StatisticalMeasure.EXACT_VALUE().getVocabulary() != null? StatisticalMeasure.EXACT_VALUE().getVocabulary().getUuid(): null, null, StatisticalMeasure.EXACT_VALUE().getIdInVocabulary(), StatisticalMeasure.EXACT_VALUE().getTitleCache());
268
                StatisticalMeasurementValueDto statValue = new StatisticalMeasurementValueDto(typeDto, new BigDecimal("4.5"), null);
269
                Set<StatisticalMeasurementValueDto> values = new HashSet<>();
270
                values.add(statValue);
271
                quantDto.setValues(values);
272
                descDto.addElement(quantDto);
273
                descToUpdate.add(descDto);
274
                updatedDescription = descDto.getDescriptionUuid();
275
            }
276
        }
277
        descriptionService.mergeDescriptions(descToUpdate, dataSet.getUuid());
278

    
279
        commitAndStartNewTransaction();
280
        DescriptionBase<?> description = descriptionService.load(updatedDescription);
281
        assertEquals(description.getElements().size(),elementCount +1);
282
        for(Object el: description.getElements()){
283
            if (el instanceof QuantitativeData){
284
                QuantitativeData descEl = (QuantitativeData)el;
285
                if (descEl.getFeature().getUuid().equals(uuidFeatureLeafLength)){
286
                    assertEquals(descEl.getExactValues().size(),1);
287
                }
288
            }
289
        }
290
    }
291

    
292
    @Test
293
    @DataSets({
294
        @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="/eu/etaxonomy/cdm/database/ClearDB_with_Terms_DataSet.xml"),
295
        @DataSet(value="/eu/etaxonomy/cdm/database/TermsDataSet-with_auditing_info.xml"),
296
        @DataSet(value="StructuredDescriptionAggregationTest.xml"),
297
    })
298
    @Ignore
299
    public void incompleteCategoricalDataTest(){
300
        createDefaultFeatureTree();
301
        DescriptiveDataSet dataSet = DescriptiveDataSet.NewInstance();
302
        datasetService.save(dataSet);
303

    
304
        SpecimenDescription specDescAlpina1 = createSpecimenDescription(dataSet, T_LAPSANA_COMMUNIS_ALPINA_UUID, "alpina specimen1");
305
        addCategoricalData(specDescAlpina1, uuidFeatureLeafColor, null);
306

    
307
        TaxonNode tnLapsana = taxonNodeService.find(TN_LAPSANA_UUID);
308
        Assert.assertNotNull(tnLapsana);
309
        dataSet.addTaxonSubtree(tnLapsana);
310

    
311
        @SuppressWarnings("unchecked")
312
        TermTree<Feature> descriptiveSystem = termTreeService.find(uuidFeatureTree);
313
        dataSet.setDescriptiveSystem(descriptiveSystem);
314
        commitAndStartNewTransaction();
315

    
316

    
317

    
318
        Taxon taxLapsanaCommunisAlpina = (Taxon)taxonService.find(T_LAPSANA_COMMUNIS_ALPINA_UUID);
319
        TaxonDescription aggrDescLapsanaCommunisAlpina = testTaxonDescriptions(taxLapsanaCommunisAlpina, 1);
320
        List<StateData> sdAlpinaLeafColor = testCategoricalData(uuidFeatureLeafColor, 1, aggrDescLapsanaCommunisAlpina, false);
321
        testState(sdAlpinaLeafColor, uuidLeafColorBlue, 0);
322
        testState(sdAlpinaLeafColor, uuidLeafColorYellow, 0);
323
    }
324

    
325

    
326
    private void testStatusOk(UpdateResult result) {
327
        if (result.getStatus() != UpdateResult.Status.OK){
328
            Assert.fail("Aggregation should have status OK but was " + result.toString());
329
            for (Exception ex : result.getExceptions()){
330
                ex.printStackTrace();
331
            }
332
        }
333
    }
334

    
335
    private void addLiterature(DescriptiveDataSet dataSet) {
336

    
337
        //literature description
338
        Taxon taxon = (Taxon)taxonService.find(T_LAPSANA_COMMUNIS_ALPINA_UUID);
339
        TaxonDescription literatureDescription = TaxonDescription.NewInstance(taxon);
340
        literatureDescription.addType(DescriptionType.SECONDARY_DATA);
341
        addQuantitativeData(literatureDescription, uuidFeatureLeafLength, new BigDecimal("4.5"), new BigDecimal("6.5"));
342
        addCategoricalData(literatureDescription, uuidFeatureLeafColor, uuidLeafColorBlue);
343
        dataSet.addDescription(literatureDescription);
344
    }
345

    
346
    private DescriptiveDataSet createTestDataset() {
347
        DescriptiveDataSet dataSet = DescriptiveDataSet.NewInstance();
348
        dataSet.setLabel("Test dataset");
349
        datasetService.save(dataSet);
350

    
351
        SpecimenDescription specDescAlpina1 = createSpecimenDescription(dataSet, T_LAPSANA_COMMUNIS_ALPINA_UUID, "alpina specimen1");
352
        addCategoricalData(specDescAlpina1, uuidFeatureLeafPA, State.uuidPresent);
353
        addQuantitativeData(specDescAlpina1, uuidFeatureLeafLength, StatisticalMeasure.EXACT_VALUE(), new BigDecimal("5.0"));
354
        addCategoricalData(specDescAlpina1, uuidFeatureLeafColor, uuidLeafColorBlue);
355

    
356
        SpecimenDescription specDescAlpina2 = createSpecimenDescription(dataSet, T_LAPSANA_COMMUNIS_ALPINA_UUID, "alpina specimen2");
357
        addCategoricalData(specDescAlpina2, uuidFeatureLeafPA, State.uuidPresent);
358
        addQuantitativeData(specDescAlpina2, uuidFeatureLeafLength, StatisticalMeasure.EXACT_VALUE(), new BigDecimal("7.0"));
359
        addCategoricalData(specDescAlpina2, uuidFeatureLeafColor, uuidLeafColorBlue);
360

    
361
        SpecimenDescription specDescAlpina3 = createSpecimenDescription(dataSet, T_LAPSANA_COMMUNIS_ALPINA_UUID, "alpina specimen3");
362
        addCategoricalData(specDescAlpina3, uuidFeatureLeafPA, State.uuidPresent);
363
        addQuantitativeData(specDescAlpina3, uuidFeatureLeafLength, StatisticalMeasure.EXACT_VALUE(), new BigDecimal("8.0"));
364

    
365
        SpecimenDescription specDescAdenophora = createSpecimenDescription(dataSet, T_LAPSANA_COMMUNIS_ADENOPHORA_UUID, "adenophora specimen");
366
        addCategoricalData(specDescAdenophora, uuidFeatureLeafPA, State.uuidPresent);
367
        addQuantitativeData(specDescAdenophora, uuidFeatureLeafLength, StatisticalMeasure.EXACT_VALUE(), new BigDecimal("10.0"));
368
        addCategoricalData(specDescAdenophora, uuidFeatureLeafColor, uuidLeafColorYellow);
369

    
370
        TaxonNode tnLapsana = taxonNodeService.find(TN_LAPSANA_UUID);
371
        Assert.assertNotNull(tnLapsana);
372
        dataSet.addTaxonSubtree(tnLapsana);
373

    
374
        @SuppressWarnings("unchecked")
375
        TermTree<Feature> descriptiveSystem = termTreeService.find(uuidFeatureTree);
376
        dataSet.setDescriptiveSystem(descriptiveSystem);
377

    
378
        addLiterature(dataSet);
379
        return dataSet;
380
    }
381

    
382
    private TaxonDescription testTaxonDescriptions(Taxon taxon, int elementSize){
383
        List<TaxonDescription> taxonDescriptions = taxon.getDescriptions().stream()
384
                .filter(desc->desc.getTypes().contains(DescriptionType.AGGREGATED_STRUC_DESC))
385
                .collect(Collectors.toList());
386

    
387
        Assert.assertEquals(1, taxonDescriptions.size());
388
        TaxonDescription aggrDesc = taxonDescriptions.iterator().next();
389
        Set<DescriptionElementBase> elements = aggrDesc.getElements();
390
        Assert.assertEquals(elementSize, elements.size());
391
        return aggrDesc;
392
    }
393

    
394
    private void testQuantitativeData(UUID featureUuid, BigDecimal sampleSize, BigDecimal min,
395
            BigDecimal max, BigDecimal avg, TaxonDescription aggrDesc) {
396
        List<QuantitativeData> quantitativeDatas = aggrDesc.getElements().stream()
397
                .filter(element->element.getFeature().getUuid().equals(featureUuid))
398
                .map(catData->CdmBase.deproxy(catData, QuantitativeData.class))
399
                .collect(Collectors.toList());
400
        Assert.assertEquals(1, quantitativeDatas.size());
401
        QuantitativeData leafLength = quantitativeDatas.iterator().next();
402
        Assert.assertEquals(sampleSize, leafLength.getSampleSize());
403
        Assert.assertEquals(min, leafLength.getMin());
404
        Assert.assertEquals(max, leafLength.getMax());
405
        Assert.assertEquals(avg, leafLength.getAverage());
406
    }
407

    
408

    
409
    private List<StateData> testCategoricalData(UUID featureUuid, int stateDataCount, TaxonDescription taxonDescription, boolean withAddedData) {
410
        List<CategoricalData> categoricalDatas = taxonDescription.getElements().stream()
411
                .filter(element->element.getFeature().getUuid().equals(featureUuid))
412
                .map(catData->CdmBase.deproxy(catData, CategoricalData.class))
413
                .collect(Collectors.toList());
414
        int nCD = withAddedData ? 2 : 1;
415
        Assert.assertEquals(nCD, categoricalDatas.size());
416
        CategoricalData categoricalData;
417
        if (withAddedData){
418
            categoricalData = categoricalDatas.stream().filter(cd->cd.getStateData().get(0).getCount() != null ).findFirst().get();
419
        }else{
420
            categoricalData = categoricalDatas.iterator().next(); // categoricalDatas.stream().filter(cd->cd.getStateData().size() != 1).collect(Collectors.toList());
421
        }
422
        List<StateData> stateDatas = categoricalData.getStateData();
423
        Assert.assertEquals(stateDataCount, stateDatas.size());
424
        return stateDatas;
425
    }
426

    
427
    private void testState(List<StateData> stateDatas, UUID stateUuid, Integer stateDataCount){
428
        List<StateData> filteredStateDatas = stateDatas.stream()
429
                .filter(stateData->stateData.getState()!=null && stateData.getState().getUuid().equals(stateUuid))
430
                .collect(Collectors.toList());
431
        if(stateDataCount==0){
432
            // non-existence test
433
            Assert.assertEquals(0, filteredStateDatas.size());
434
            return;
435
        }
436
        Assert.assertEquals(1, filteredStateDatas.size());
437
        StateData stateData = filteredStateDatas.iterator().next();
438
        Assert.assertEquals(stateDataCount, stateData.getCount());
439
        Assert.assertEquals(stateUuid, stateData.getState().getUuid());
440
    }
441

    
442
    private void addQuantitativeData(DescriptionBase<?> desc, UUID uuidFeature, StatisticalMeasure type, BigDecimal value) {
443
        Feature feature = (Feature)termService.find(uuidFeature);
444
        QuantitativeData qd = QuantitativeData.NewInstance(feature);
445
        StatisticalMeasurementValue smv = StatisticalMeasurementValue.NewInstance(type, value);
446
        qd.addStatisticalValue(smv);
447
        desc.addElement(qd);
448
    }
449

    
450
    private void addQuantitativeData(DescriptionBase<?> desc, UUID uuidFeature, BigDecimal min, BigDecimal max) {
451
        Feature feature = (Feature)termService.find(uuidFeature);
452
        QuantitativeData qd = QuantitativeData.NewInstance(feature);
453
        StatisticalMeasurementValue smv = StatisticalMeasurementValue.NewInstance(StatisticalMeasure.MIN(), min);
454
        qd.addStatisticalValue(smv);
455
        smv = StatisticalMeasurementValue.NewInstance(StatisticalMeasure.MAX(), max);
456
        qd.addStatisticalValue(smv);
457
        desc.addElement(qd);
458
    }
459

    
460
    private void addCategoricalData(DescriptionBase<?> desc, UUID featureUuid, UUID stateUUID) {
461
        Feature feature = (Feature)termService.find(featureUuid);
462
        State state = (State)termService.find(stateUUID);
463
        CategoricalData cd = CategoricalData.NewInstance(state, feature);
464
        desc.addElement(cd);
465
    }
466

    
467
    private SpecimenDescription createSpecimenDescription(DescriptiveDataSet dataSet, UUID taxonUuid, String specLabel ) {
468
        Taxon taxon = (Taxon)taxonService.find(taxonUuid);
469
        TaxonDescription taxonDescription = TaxonDescription.NewInstance(taxon);
470
        DerivedUnit specimen = DerivedUnit.NewPreservedSpecimenInstance();
471
        specimen.setTitleCache(specLabel, true);
472
        IndividualsAssociation individualsAssociation = IndividualsAssociation.NewInstance(specimen);
473
        // TODO this has to be discussed; currently the description with the InidividualsAssociation is
474
        // needed in the dataset for performance reasons
475
        taxonDescription.addElement(individualsAssociation);
476
        dataSet.addDescription(taxonDescription);
477
        SpecimenDescription specDesc = SpecimenDescription.NewInstance(specimen);
478

    
479
        dataSet.addDescription(specDesc);
480
        return specDesc;
481
    }
482

    
483
    private Feature createFeature(UUID uuid, String label, boolean isQuantitative) {
484
        Feature feature = Feature.NewInstance("", label, null);
485
        feature.setUuid(uuid);
486
        feature.setSupportsQuantitativeData(isQuantitative);
487
        feature.setSupportsCategoricalData(!isQuantitative);
488
        feature.setSupportsTextData(false);
489
        termService.save(feature);
490
        return feature;
491
    }
492

    
493
    private State createState(String label, UUID uuid) {
494
        State state = State.NewInstance("", label, "");
495
        state.getTitleCache();  //for better debugging
496
        state.setUuid(uuid);
497
        termService.save(state);
498
        return state;
499
    }
500

    
501
    private void createDefaultFeatureTree() {
502
        //feature tree
503
        //leaf p/a
504
        //  leaf length
505
        //  leaf color
506
        TermTree<Feature> featureTree = TermTree.NewFeatureInstance();
507
        featureTree.setUuid(uuidFeatureTree);
508
        Feature featureLeafPA = createFeature(uuidFeatureLeafPA, "LeafPA", false);
509
        TermNode<Feature> leafPANode = featureTree.getRoot().addChild(featureLeafPA);
510
        Feature featureLeafLength = createFeature(uuidFeatureLeafLength, "LeafLength", true);
511
        leafPANode.addChild(featureLeafLength);
512
        Feature featureLeafColor = createFeature(uuidFeatureLeafColor, "LeafColor", false);
513
        leafPANode.addChild(featureLeafColor);
514
        State yellow = createState("Yellow", uuidLeafColorYellow);
515
        State blue = createState("Blue", uuidLeafColorBlue);
516
        TermVocabulary<State> stateVoc = TermVocabulary.NewInstance(TermType.State, State.class, "", "Colors", null, null);
517
        stateVoc.addTerm(yellow);
518
        stateVoc.addTerm(blue);
519
        featureLeafColor.addSupportedCategoricalEnumeration(stateVoc);
520
        vocabularyService.save(stateVoc);
521
    }
522

    
523

    
524
    @Override
525
    public void createTestDataSet() throws FileNotFoundException {
526

    
527
        // --- References --- //
528
        Reference sec = ReferenceFactory.newDatabase();
529
        sec.setTitleCache("Test", true);
530
        Reference nomRef = ReferenceFactory.newBook();
531
        sec.setTitleCache("Sp.Pl.", true);
532

    
533
        referenceService.save(sec);
534
        referenceService.save(nomRef);
535

    
536

    
537
        // --- Taxa --- //
538
        //  Lapsana
539
        //        L. communis
540
        //            L. communis subsp. communis
541
        //            L. communis subsp. adenophora
542
        //            L. communis subsp. alpina
543
        //  Sonchella
544
        //        S. dentata
545
        //        S. stenoma
546
        IBotanicalName n_lapsana = TaxonNameFactory.NewBotanicalInstance(Rank.GENUS());
547
        n_lapsana.setTitleCache("Lapsana", true);
548
        Taxon t_lapsana = Taxon.NewInstance(n_lapsana, sec);
549
        t_lapsana.setUuid(T_LAPSANA_UUID);
550
        taxonService.saveOrUpdate(t_lapsana);
551

    
552
        IBotanicalName n_lapsana_communis = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
553
        n_lapsana_communis.setTitleCache("L. communis", true);
554
        Taxon t_lapsana_communis = Taxon.NewInstance(n_lapsana_communis, sec);
555
        t_lapsana_communis.setUuid(T_LAPSANA_COMMUNIS_UUID);
556
        taxonService.saveOrUpdate(t_lapsana_communis);
557

    
558
        IBotanicalName n_lapsana_communis_communis = TaxonNameFactory.NewBotanicalInstance(Rank.SUBSPECIES());
559
        n_lapsana_communis_communis.setTitleCache("L. communis subsp. communis", true);
560
        Taxon t_lapsana_communis_communis = Taxon.NewInstance(n_lapsana_communis_communis, sec);
561
        t_lapsana_communis_communis.setUuid(T_LAPSANA_COMMUNIS_COMMUNIS_UUID);
562
        taxonService.saveOrUpdate(t_lapsana_communis_communis);
563

    
564
        IBotanicalName n_lapsana_communis_adenophora = TaxonNameFactory.NewBotanicalInstance(Rank.SUBSPECIES());
565
        n_lapsana_communis_adenophora.setTitleCache("L. communis subsp. adenophora", true);
566
        Taxon t_lapsana_communis_adenophora = Taxon.NewInstance(n_lapsana_communis_adenophora, sec);
567
        t_lapsana_communis_adenophora.setUuid(T_LAPSANA_COMMUNIS_ADENOPHORA_UUID);
568
        taxonService.saveOrUpdate(t_lapsana_communis_adenophora);
569

    
570
        IBotanicalName n_lapsana_communis_alpina = TaxonNameFactory.NewBotanicalInstance(Rank.SUBSPECIES());
571
        n_lapsana_communis_alpina.setTitleCache("L. communis subsp. alpina", true);
572
        Taxon t_lapsana_communis_alpina = Taxon.NewInstance(n_lapsana_communis_alpina, sec);
573
        t_lapsana_communis_alpina.setUuid(T_LAPSANA_COMMUNIS_ALPINA_UUID);
574
        taxonService.saveOrUpdate(t_lapsana_communis_alpina);
575

    
576
        // --- Classification --- //
577
        Classification classification = Classification.NewInstance("TestClassification");
578
        classification.setUuid(CLASSIFICATION_UUID);
579
        classificationService.save(classification);
580
        TaxonNode node_lapsana = classification.addChildTaxon(t_lapsana, sec, null);
581
        node_lapsana.setUuid(TN_LAPSANA_UUID);
582
        TaxonNode node_lapsana_communis = node_lapsana.addChildTaxon(t_lapsana_communis, sec, null);
583
        node_lapsana_communis.addChildTaxon(t_lapsana_communis_communis, sec, null);
584
        node_lapsana_communis.addChildTaxon(t_lapsana_communis_adenophora, sec, null);
585
        node_lapsana_communis.addChildTaxon(t_lapsana_communis_alpina, sec, null);
586
        classificationService.saveOrUpdate(classification);
587

    
588
        commitAndStartNewTransaction(null);
589

    
590
        writeDbUnitDataSetFile(new String[] {
591
                "TAXONBASE", "TAXONNAME","CLASSIFICATION",  "TAXONNODE","HOMOTYPICALGROUP",
592
                "REFERENCE", "AGENTBASE",
593
                "DESCRIPTIONELEMENTBASE", "DESCRIPTIONBASE",
594
                "LANGUAGESTRING",
595
                "HIBERNATE_SEQUENCES"
596
         });
597
    }
598

    
599
}
(1-1/3)