1 package eu
.etaxonomy
.cdm
.api
.service
;
3 import static org
.junit
.Assert
.assertTrue
;
5 import java
.io
.FileNotFoundException
;
6 import java
.util
.ArrayList
;
7 import java
.util
.Arrays
;
10 import org
.apache
.commons
.lang
.RandomStringUtils
;
11 import org
.junit
.Before
;
12 import org
.junit
.Test
;
13 import org
.unitils
.dbunit
.annotation
.DataSet
;
14 import org
.unitils
.spring
.annotation
.SpringBeanByType
;
16 import eu
.etaxonomy
.cdm
.api
.service
.statistics
.Statistics
;
17 import eu
.etaxonomy
.cdm
.api
.service
.statistics
.StatisticsConfigurator
;
18 import eu
.etaxonomy
.cdm
.api
.service
.statistics
.StatisticsPartEnum
;
19 import eu
.etaxonomy
.cdm
.api
.service
.statistics
.StatisticsTypeEnum
;
20 import eu
.etaxonomy
.cdm
.model
.common
.Language
;
21 import eu
.etaxonomy
.cdm
.model
.common
.OriginalSourceType
;
22 import eu
.etaxonomy
.cdm
.model
.description
.CommonTaxonName
;
23 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionElementBase
;
24 import eu
.etaxonomy
.cdm
.model
.description
.DescriptionElementSource
;
25 import eu
.etaxonomy
.cdm
.model
.description
.TaxonDescription
;
26 import eu
.etaxonomy
.cdm
.model
.description
.TaxonNameDescription
;
27 import eu
.etaxonomy
.cdm
.model
.description
.TextData
;
28 import eu
.etaxonomy
.cdm
.model
.name
.BotanicalName
;
29 import eu
.etaxonomy
.cdm
.model
.name
.Rank
;
30 import eu
.etaxonomy
.cdm
.model
.reference
.Reference
;
31 import eu
.etaxonomy
.cdm
.model
.reference
.ReferenceFactory
;
32 import eu
.etaxonomy
.cdm
.model
.taxon
.Classification
;
33 import eu
.etaxonomy
.cdm
.model
.taxon
.Synonym
;
34 import eu
.etaxonomy
.cdm
.model
.taxon
.SynonymRelationshipType
;
35 import eu
.etaxonomy
.cdm
.model
.taxon
.Taxon
;
36 import eu
.etaxonomy
.cdm
.test
.integration
.CdmTransactionalIntegrationTest
;
38 public class StatisticsServiceImplTest2
extends CdmTransactionalIntegrationTest
{
40 // ************constants to set up the expected results for all:
41 // ********************
43 // ............................................
45 // here is the list of the types that will be test counted in the
46 // parts (ALL, CLASSIFICATION)
47 private static final List
<StatisticsTypeEnum
> TYPES
= Arrays
48 .asList(new StatisticsTypeEnum
[] {
49 StatisticsTypeEnum
.CLASSIFICATION
,
50 StatisticsTypeEnum
.ACCEPTED_TAXA
,
51 StatisticsTypeEnum
.ALL_TAXA
,
52 StatisticsTypeEnum
.ALL_REFERENCES
, // this functionality
54 // classifications is still missing for in the Statistics
56 StatisticsTypeEnum
.SYNONYMS
,
57 StatisticsTypeEnum
.TAXON_NAMES
,
58 StatisticsTypeEnum
.NOMENCLATURAL_REFERENCES
,
59 StatisticsTypeEnum
.DESCRIPTIVE_SOURCE_REFERENCES
});
61 // private static final String[] TYPES = { "CLASSIFICATION",
63 // "ALL_TAXA", "ALL_REFERENCES" };
65 // ................parts ..............................
67 private static final List
<String
> PARTS
= Arrays
.asList(new String
[] {
68 "ALL", "CLASSIFICATION" });
69 // .........................................................
71 private ArrayList
<Classification
> classifications
;
73 // ****************** services: ************************
75 private IStatisticsService service
;
77 private IClassificationService classificationService
;
79 private ITaxonService taxonService
;
81 private IReferenceService referenceService
;
83 private IDescriptionService descriptionService
;
85 // ............................................
89 public void setUp() throws Exception
{
90 // createTestData(3, 10, 7, 16, 4);
91 // OutputStream out= new ByteArrayOutputStream();
93 // System.out.println(out.toString());
98 public void testGetCountStatistics() {
100 // create configurator needed to call
101 // StatisticsService.getCountStatistics()
102 List
<StatisticsConfigurator
> configuratorList
= createConfiguratorList(
103 (String
[]) PARTS
.toArray(), TYPES
);
105 // run method of StatisticsService
106 List
<Statistics
> statisticsList
= service
107 .getCountStatistics(configuratorList
);
110 logger
.info("statistics service result: ");
111 for (Statistics statistics
: statisticsList
) {
112 logger
.info(statistics
.getCountMap().toString());
118 private List
<StatisticsConfigurator
> createConfiguratorList(String
[] part
,
119 List
<StatisticsTypeEnum
> types
) {
121 ArrayList
<StatisticsConfigurator
> configuratorList
= new ArrayList
<StatisticsConfigurator
>();
123 // 1. get types for configurators:
124 // in our case all the configurators will have the same types
125 // so we calculate the types once and save them in a helperConfigurator
126 StatisticsConfigurator helperConfigurator
= new StatisticsConfigurator();
129 for (StatisticsTypeEnum type
: types
) {
130 helperConfigurator
.addType(type
);
133 for (StatisticsTypeEnum enumValue
: StatisticsTypeEnum
.values()) {
134 helperConfigurator
.addType(enumValue
);
138 // 2. determine the entities and put each of them in a configurator:
140 // if no part was given:
142 helperConfigurator
.addFilter(null); // part= null means search all
144 configuratorList
.add(helperConfigurator
);
146 // else parse list of parts and create configurator for each:
148 for (String string
: part
) {
149 if (string
.equals(StatisticsPartEnum
.ALL
.toString())) {
150 helperConfigurator
.addFilter(null);
151 configuratorList
.add(helperConfigurator
);
152 } else if (string
.equals(StatisticsPartEnum
.CLASSIFICATION
154 List
<Classification
> classificationsList
= classificationService
155 .listClassifications(null, 0, null, null);
156 for (Classification classification
: classificationsList
) {
158 StatisticsConfigurator newConfigurator
= new StatisticsConfigurator();
159 newConfigurator
.setType(helperConfigurator
.getType());
160 newConfigurator
.getFilter().addAll(
161 helperConfigurator
.getFilter());
162 newConfigurator
.addFilter(classification
);
163 configuratorList
.add(newConfigurator
);
170 return configuratorList
;
173 public void createTestDataSet(int noOfClassifications
, int noOfAcceptedTaxa
,
174 int noOfSynonyms
, int noOfDescrSrcReferences
, int sharedTaxa
)
177 // create more parameters:
178 int noOfNomRefs
= noOfAcceptedTaxa
+ noOfSynonyms
- 4;
180 // missing in this example data:
181 // synonyms, that are attached to several taxa (same or different
184 // --------------------variables for counting produced elements
185 // ------------------
187 int no_of_all_references
= 0;
188 int descrSrcReferencesCounter
= 0;
190 // create noOfClassifications classifications
191 classifications
= new ArrayList
<Classification
>();
193 for (int i
= 1; i
<= noOfClassifications
; i
++) {
194 Classification classification
= Classification
195 .NewInstance("European Abies" + i
);
196 classifications
.add(classification
);
197 classificationService
.save(classification
);
200 // create all taxa, references and synonyms and attach them to one or
201 // more classifications
204 int remainder
= noOfAcceptedTaxa
;
205 Reference sec
= ReferenceFactory
.newBook();
206 boolean secondClassificationForTaxonFlag
= false;
207 boolean synonymFlag
= false;
208 boolean tNomRefFlag
= false;
209 boolean sNomRefFlag
= false;
210 boolean tDescrSourceRefFlag
= false;
211 boolean sDescrSourceRefFlag
= false;
213 // variables: counter (pre-loop)
214 int descriptiveElementsPerTaxon
= (noOfDescrSrcReferences
/ noOfAcceptedTaxa
) + 1;
217 int classiCounter
= 0, sharedClassification
= 0, synonymCounter
= 0, nomRefCounter
= 0;
219 // iterate over classifications and add taxa
220 for (/* see above */; remainder
> 0
221 && classiCounter
< noOfClassifications
; /* see below */) {
223 // compute no of taxa to be created in this classification
224 if (classiCounter
>= noOfClassifications
- 1) { // last
228 taxaInClass
= remainder
;
229 } else { // take half of left taxa for this class:
230 taxaInClass
= remainder
/ 2;
233 // iterate over amount of taxa meant to be in this classification
234 for (int taxonCounter
= 1; taxonCounter
<= taxaInClass
; taxonCounter
++) {
236 // create a String for the Name
237 RandomStringUtils
.randomAlphabetic(10);
238 String randomName
= RandomStringUtils
.randomAlphabetic(5) + " "
239 + RandomStringUtils
.randomAlphabetic(10);
241 // create a name for the taxon
242 BotanicalName name
= BotanicalName
.NewInstance(Rank
.SPECIES());
243 name
.setNameCache(randomName
, true);
245 // create nomenclatural reference for taxon name (if left)
246 if (nomRefCounter
< noOfNomRefs
) {
247 // we remember this taxon has a nomenclatural reference:
249 Reference nomRef
= ReferenceFactory
.newBook();
250 name
.setNomenclaturalReference(nomRef
);
251 referenceService
.save(nomRef
);
255 // create a new sec for every other taxon
256 if (taxonCounter
% 2 != 0) {
257 sec
= createSecReference(classiCounter
, taxonCounter
);
261 Taxon taxon
= Taxon
.NewInstance(name
, sec
);
263 // create descriptions, description sources and their references
265 if (descrSrcReferencesCounter
< noOfDescrSrcReferences
) {
267 tDescrSourceRefFlag
= true;
269 // create a description and 2 description elements with
270 // references for taxon name
271 TaxonNameDescription nameDescr
= TaxonNameDescription
273 CommonTaxonName nameElement
= CommonTaxonName
.NewInstance(
274 "Veilchen" + taxonCounter
, Language
.GERMAN());
275 TextData textElement
= new TextData();
276 Reference nameElementRef
= ReferenceFactory
.newArticle();
277 Reference textElementRef
= ReferenceFactory
279 nameElement
.addSource(
280 OriginalSourceType
.PrimaryTaxonomicSource
, null,
281 null, nameElementRef
, "name: ");
282 textElement
.addSource(
283 OriginalSourceType
.PrimaryTaxonomicSource
, null,
284 null, textElementRef
, "text: ");
285 nameDescr
.addElement(nameElement
);
286 nameDescr
.addElement(textElement
);
287 name
.addDescription(nameDescr
);
288 // taxon.getName().addDescription(nameDescr);
289 referenceService
.save(nameElementRef
);
290 referenceService
.save(textElementRef
);
291 descriptionService
.save(nameDescr
);
292 System
.out
.println("Descriptive Src Ref for TaxonName: "+nameElementRef
.getId()+" Taxon: "+taxon
.getId()+" name: "+taxon
.getTitleCache());
293 System
.out
.println("Descriptive Src Ref for TaxonName: "+textElementRef
.getId()+" Taxon: "+taxon
.getId()+" name: "+taxon
.getTitleCache());
296 // create descriptions, description sources and their
299 TaxonDescription taxonDescription
= new TaxonDescription();
300 for (int i
= 0; i
< descriptiveElementsPerTaxon
; i
++) {
301 DescriptionElementBase descriptionElement
= new TextData();
302 DescriptionElementSource descriptionElementSource
= DescriptionElementSource
303 .NewInstance(OriginalSourceType
.PrimaryTaxonomicSource
);
304 Reference article
= ReferenceFactory
.newArticle();
306 descriptionElementSource
.setCitation(article
);
307 descriptionElement
.addSource(descriptionElementSource
);
308 taxonDescription
.addElement(descriptionElement
);
309 referenceService
.save(article
);
311 .saveDescriptionElement(descriptionElement
);
312 System
.out
.println("Descriptive Src Ref for Taxon: "+article
.getId()+" Taxon: "+taxon
.getId()+" name: "+taxon
.getTitleCache());
315 descriptionService
.save(taxonDescription
);
316 taxon
.addDescription(taxonDescription
);
318 //TODO create Sspecimen connected to taxon via TaxonDescription->DescriptionElement=IndividualAssoziation->setAssociatedSpecimenOrObservation(SpecimenOrObservationBase)
319 // TODO and NameBase->SpecimenTypeDesignation->
322 // create a Specimen for taxon with description, descr.
323 // element and referece
325 // SpecimenOrObservationBase specimen = DerivedUnit.NewInstance(SpecimenOrObservationType.Fossil);
326 // SpecimenDescription specimenDescription =
327 // SpecimenDescription.NewInstance(specimen);
328 // DescriptionElementBase descrElement = new TextData();
329 // Reference specimenRef = ReferenceFactory.newArticle();
330 //// descrElement.add;
333 // descriptionService.save(specimenDescription);
335 // OriginalSourceType.PrimaryTaxonomicSource,
336 // null, null, nameElementRef, " ");
337 // taxon.add(specimen);
339 descrSrcReferencesCounter
+= descriptiveElementsPerTaxon
+ 2 + 1;
343 // add taxon to classification
344 classifications
.get(classiCounter
).addChildTaxon(taxon
, null,
347 // now if there are any left, we create a synonym for the taxon
348 if (synonymCounter
< noOfSynonyms
) {
350 randomName
= RandomStringUtils
.randomAlphabetic(5) + " "
351 + RandomStringUtils
.randomAlphabetic(10);
353 name
= BotanicalName
.NewInstance(Rank
.SPECIES());
354 name
.setNameCache(randomName
, true);
356 // create nomenclatural reference for synonym name (if left)
357 if (nomRefCounter
< noOfNomRefs
) {
359 Reference nomRef
= ReferenceFactory
.newBook();
360 name
.setNomenclaturalReference(nomRef
);
361 referenceService
.save(nomRef
);
365 if (descrSrcReferencesCounter
< noOfDescrSrcReferences
) {
366 sDescrSourceRefFlag
= true;
368 // create a description and 2 description elements with
369 // references for synonym name
370 TaxonNameDescription nameDescr
= TaxonNameDescription
372 CommonTaxonName nameElement
= CommonTaxonName
373 .NewInstance("anderes Veilchen" + taxonCounter
,
375 TextData textElement
= new TextData();
376 Reference nameElementRef
= ReferenceFactory
378 Reference textElementRef
= ReferenceFactory
380 nameElement
.addSource(
381 OriginalSourceType
.PrimaryTaxonomicSource
,
382 null, null, nameElementRef
, "name: ");
383 textElement
.addSource(
384 OriginalSourceType
.PrimaryTaxonomicSource
,
385 null, null, textElementRef
, "text: ");
386 nameDescr
.addElement(nameElement
);
387 nameDescr
.addElement(textElement
);
388 name
.addDescription(nameDescr
);
389 // taxon.getName().addDescription(nameDescr);
390 referenceService
.save(nameElementRef
);
391 referenceService
.save(textElementRef
);
392 descriptionService
.save(nameDescr
);
393 descrSrcReferencesCounter
+= 2;
394 System
.out
.println("Descriptive Src Ref for Synonym: "+nameElementRef
.getId()+" Taxon: "+taxon
.getId()+" name: "+taxon
.getTitleCache());
395 System
.out
.println("Descriptive Src Ref for Synonym: "+textElementRef
.getId()+" Taxon: "+taxon
.getId()+" name: "+taxon
.getTitleCache());
398 // create a new reference for every other synonym:
399 if (taxonCounter
% 2 != 0) {
400 sec
= createSecReference(classiCounter
, taxonCounter
);
402 Synonym synonym
= Synonym
.NewInstance(name
, sec
);
403 taxonService
.save(synonym
);
404 taxon
.addSynonym(synonym
,
405 SynonymRelationshipType
.SYNONYM_OF());
410 // if this is not the last classification and there are
411 // taxa left that should be in more than one classification
412 // we add the taxon to the next class in the list too.
414 if (classiCounter
< noOfClassifications
415 && sharedClassification
< sharedTaxa
) {
416 classifications
.get(classiCounter
+ 1).addChildTaxon(taxon
,
419 // we remember that this taxon is attached to 2
421 secondClassificationForTaxonFlag
= true;
422 sharedClassification
++;
423 classificationService
.saveOrUpdate(classifications
424 .get(classiCounter
+ 1));
428 taxonService
.save(taxon
);
429 classificationService
.saveOrUpdate(classifications
430 .get(classiCounter
));
432 // count the data created with this taxon:
433 int c
= classiCounter
;
435 if (secondClassificationForTaxonFlag
) {
440 secondClassificationForTaxonFlag
= false;
444 tDescrSourceRefFlag
= false;
445 sDescrSourceRefFlag
= false;
448 // modify variables (post-loop)
450 remainder
-= taxaInClass
;
456 writeDbUnitDataSetFile(new String
[] { "TAXONBASE", "TAXONNAMEBASE",
457 "TAXONRELATIONSHIP", "SYNONYMRELATIONSHIP", "REFERENCE",
458 "DESCRIPTIONELEMENTBASE",
459 "DESCRIPTIONELEMENTBASE_ORIGINALSOURCEBASE",
460 "ORIGINALSOURCEBASE", "DESCRIPTIONBASE", "REFERENCE_ORIGINALSOURCEBASE","LANGUAGESTRING",
461 "CLASSIFICATION", "TAXONNODE",
462 "HIBERNATE_SEQUENCES" });
464 // "AGENTBASE","HOMOTYPICALGROUP","LANGUAGESTRING",
465 // "DESCRIPTIONELEMENTBASE_LANGUAGESTRING", "HIBERNATE_SEQUENCES"
469 * create and count a new sec Reference
471 * @param classiCounter
472 * @param taxonCounter
475 private Reference
createSecReference(int classiCounter
, int taxonCounter
) {
477 sec
= ReferenceFactory
.newBook();
478 sec
.setTitle("book " + classiCounter
+ "." + taxonCounter
);
479 referenceService
.save(sec
);
484 * @see eu.etaxonomy.cdm.test.integration.CdmIntegrationTest#createTestData()
487 public void createTestDataSet() throws FileNotFoundException
{
488 // TODO Auto-generated method stub