Merge statistics branch into trunk
[cdmlib.git] / cdmlib-services / src / test / java / eu / etaxonomy / cdm / api / service / StatisticsServiceImplTest.java
1 /**
2 *
3 */
4 package eu.etaxonomy.cdm.api.service;
5
6 import static org.junit.Assert.assertTrue;
7
8 import java.util.ArrayList;
9 import java.util.Arrays;
10 import java.util.Collections;
11 import java.util.HashMap;
12 import java.util.List;
13 import java.util.Map;
14
15 import org.apache.commons.collections.functors.ForClosure;
16 import org.apache.commons.lang.RandomStringUtils;
17 import org.apache.log4j.Logger;
18 import org.junit.After;
19 import org.junit.AfterClass;
20 import org.junit.Before;
21 import org.junit.BeforeClass;
22 import org.junit.Test;
23 import org.unitils.spring.annotation.SpringBeanByType;
24
25 import eu.etaxonomy.cdm.api.service.statistics.Statistics;
26 import eu.etaxonomy.cdm.api.service.statistics.StatisticsConfigurator;
27 import eu.etaxonomy.cdm.api.service.statistics.StatisticsPartEnum;
28 import eu.etaxonomy.cdm.api.service.statistics.StatisticsTypeEnum;
29 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
30 import eu.etaxonomy.cdm.model.common.Language;
31 import eu.etaxonomy.cdm.model.common.OriginalSourceType;
32 import eu.etaxonomy.cdm.model.description.CommonTaxonName;
33 import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
34 import eu.etaxonomy.cdm.model.description.DescriptionElementSource;
35 import eu.etaxonomy.cdm.model.description.TaxonDescription;
36 import eu.etaxonomy.cdm.model.description.TaxonNameDescription;
37 import eu.etaxonomy.cdm.model.description.TextData;
38 import eu.etaxonomy.cdm.model.name.BotanicalName;
39 import eu.etaxonomy.cdm.model.name.Rank;
40 import eu.etaxonomy.cdm.model.reference.Reference;
41 import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
42 import eu.etaxonomy.cdm.model.taxon.Classification;
43 import eu.etaxonomy.cdm.model.taxon.Synonym;
44 import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;
45 import eu.etaxonomy.cdm.model.taxon.Taxon;
46 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
47 import eu.etaxonomy.cdm.test.integration.CdmTransactionalIntegrationTest;
48
49 /**
50 * @author s.buers
51 *
52 */
53 @SuppressWarnings({ "rawtypes", "serial" })
54 public class StatisticsServiceImplTest extends CdmTransactionalIntegrationTest {
55
56 // constant if you want to printout the database content to console:
57 // only recommended for a small probe
58 private static final boolean PRINTOUT = true;
59
60 // ************constants to set up the expected results for all:
61 // ********************
62
63 // ............................................
64
65 // here is the list of the types that will be test counted in the
66 // parts (ALL, CLASSIFICATION)
67 private static final List<StatisticsTypeEnum> TYPES = Arrays
68 .asList(new StatisticsTypeEnum[] {
69 StatisticsTypeEnum.CLASSIFICATION,
70 StatisticsTypeEnum.ACCEPTED_TAXA,
71 StatisticsTypeEnum.ALL_TAXA,
72 StatisticsTypeEnum.ALL_REFERENCES, // this functionality
73 // for
74 // classifications is still missing for in the Statistics
75 // Service
76 StatisticsTypeEnum.SYNONYMS,
77 StatisticsTypeEnum.TAXON_NAMES,
78 StatisticsTypeEnum.NOMECLATURAL_REFERENCES,
79 StatisticsTypeEnum.DESCRIPTIVE_SOURCE_REFERENCES });
80
81 // private static final String[] TYPES = { "CLASSIFICATION",
82 // "ACCEPTED_TAXA",
83 // "ALL_TAXA", "ALL_REFERENCES" };
84
85 // ................parts ..............................
86
87 private static final List<String> PARTS = Arrays.asList(new String[] {
88 "ALL", "CLASSIFICATION" });
89 // .........................................................
90
91 // part= null means search all DB
92 private static final IdentifiableEntity PARTS_ALL = null;
93
94 // here is the number of items that will be created for the test count:
95 // please only change the numbers
96 // but do not replace or add a number to any constants on the right.
97
98 // choose a number
99 private static final int NO_OF_ACCEPTED_TAXA = 10;
100
101 // choose a number (less than NO_OF_ACCEPTED_TAXA)
102 private static final int NO_OF_CLASSIFICATIONS = 3;
103
104 // must be less or equal to NO_OF_ACCEPTED_TAXA
105 private static final int NO_OF_SYNONYMS = 7;
106
107 // taxa that occure in several classifications:
108 // must NOT be more than NO_OF_ACCEPTED_TAXA
109 private static final int NO_OF_SHARED_TAXA = 4;
110
111 // must be NO_OF_ACCEPTED_TAXA + NO_OF_SYNONYMS
112 private static final int NO_OF_ALLTAXA = NO_OF_ACCEPTED_TAXA
113 + NO_OF_SYNONYMS;
114
115 // must be NO_OF_ACCEPTED_TAXA+NO_OF_SYNONYMS
116 private static final int NO_OF_TAXON_NAMES = NO_OF_ACCEPTED_TAXA
117 + NO_OF_SYNONYMS;
118
119 // this represents an approx. no of the amount that will actually generated!
120 private static final int NO_OF_DESCRIPTIVE_SOURCE_REFERENCES = 16;
121
122 // private static final int NO_OF_ALL_REFERENCES = NO_OF_ACCEPTED_TAXA + 0;
123
124 // must not be more than NO_OF_ACCEPTED_TAXA+NO_OF_SYNONYMS
125 private static final int NO_OF_NOMECLATURAL_REFERENCES = NO_OF_ACCEPTED_TAXA
126 + NO_OF_SYNONYMS - 4;
127
128 // --------------------variables for all ------------------
129
130 private Long no_of_all_references = new Long(0);
131 private Long no_of_descriptive_source_references = new Long(0);
132
133 // ............................................
134
135 // log the type enum to an int constant:
136 private Map<String, Long> typeMap_ALL;
137
138 // ------------------ variables for CLASSIFICATIONS -----------------------
139
140 // int[] anArray = new int[NO_OF_CLASSIFICATIONS];
141 private static List<Long> no_of_all_taxa_c = new ArrayList<Long>(
142 Collections.nCopies(NO_OF_CLASSIFICATIONS, new Long(0)));
143 private static List<Long> no_of_accepted_taxa_c = new ArrayList<Long>(
144 Collections.nCopies(NO_OF_CLASSIFICATIONS, new Long(0)));
145 private static List<Long> no_of_synonyms_c = new ArrayList<Long>(
146 Collections.nCopies(NO_OF_CLASSIFICATIONS, new Long(0)));
147 private static List<Long> no_of_taxon_names_c = new ArrayList<Long>(
148 Collections.nCopies(NO_OF_CLASSIFICATIONS, new Long(0)));
149 private static List<Long> no_of_descriptive_source_references_c = new ArrayList<Long>(
150 Collections.nCopies(NO_OF_CLASSIFICATIONS, new Long(0)));
151 private static List<Long> no_of_all_references_c = new ArrayList<Long>(
152 Collections.nCopies(NO_OF_CLASSIFICATIONS, new Long(0)));
153 private static List<Long> no_of_nomenclatural_references_c = new ArrayList<Long>(
154 Collections.nCopies(NO_OF_CLASSIFICATIONS, new Long(0)));
155 // we do not count classifications in classifications
156
157 // ........................... constant map ..........................
158
159 private static final Map<String, List<Long>> typeCountMap_CLASSIFICATION = new HashMap<String, List<Long>>() {
160 {
161 put(StatisticsTypeEnum.CLASSIFICATION.getLabel(),
162 new ArrayList<Long>(Arrays.asList((Long) null, null, null)));
163 put(StatisticsTypeEnum.ALL_TAXA.getLabel(), no_of_all_taxa_c);
164 put(StatisticsTypeEnum.ACCEPTED_TAXA.getLabel(),
165 no_of_accepted_taxa_c);
166 put(StatisticsTypeEnum.SYNONYMS.getLabel(), no_of_synonyms_c);
167 put(StatisticsTypeEnum.TAXON_NAMES.getLabel(), no_of_taxon_names_c);
168 put(StatisticsTypeEnum.DESCRIPTIVE_SOURCE_REFERENCES.getLabel(),
169 no_of_descriptive_source_references_c);
170 put(StatisticsTypeEnum.ALL_REFERENCES.getLabel(),
171 no_of_all_references_c);
172 put(StatisticsTypeEnum.NOMECLATURAL_REFERENCES.getLabel(),
173 no_of_nomenclatural_references_c);
174 }
175 };
176
177 private static final Logger logger = Logger
178 .getLogger(StatisticsServiceImplTest.class);
179
180 private List<Classification> classifications;
181
182 // ****************** services: ************************
183 @SpringBeanByType
184 private IStatisticsService service;
185 @SpringBeanByType
186 private IClassificationService classificationService;
187 @SpringBeanByType
188 private ITaxonService taxonService;
189 @SpringBeanByType
190 private IReferenceService referenceService;
191 @SpringBeanByType
192 private IDescriptionService descriptionService;
193
194 // *************** more members: *****************+
195
196 // **********vars to count what i create *********
197
198 MyCounter countAll = new MyCounter();
199 ArrayList<MyCounter> classificationCounters = new ArrayList<MyCounter>();
200
201 /**
202 * @throws java.lang.Exception
203 */
204 @BeforeClass
205 public static void setUpBeforeClass() throws Exception {
206 }
207
208 /**
209 * @throws java.lang.Exception
210 */
211 @AfterClass
212 public static void tearDownAfterClass() throws Exception {
213 }
214
215 /**
216 * create some testdata
217 *
218 * @throws java.lang.Exception
219 */
220
221 @Before
222 // @DataSet
223 public void setUp() throws Exception {
224
225 // missing in this example data:
226 // synonyms, that are attached to several taxa (same or different
227 // classification)
228
229 // create NO_OF_CLASSIFICATIONS classifications
230 classifications = new ArrayList<Classification>();
231
232 for (int i = 1; i <= NO_OF_CLASSIFICATIONS; i++) {
233 Classification classification = Classification
234 .NewInstance("European Abies" + i);
235 classifications.add(classification);
236 classificationService.save(classification);
237 (countAll.classifications)++;
238 classificationCounters.add(new MyCounter());
239
240 }
241 // create all taxa, references and synonyms and attach them to one or
242 // more classifications
243
244 // variables: flags
245 int remainder = NO_OF_ACCEPTED_TAXA;
246 Reference sec = ReferenceFactory.newBook();
247 boolean secondClassificationForTaxonFlag = false;
248 boolean synonymFlag = false;
249 boolean tNomRefFlag = false;
250 boolean sNomRefFlag = false;
251 boolean tDescrSourceRefFlag = false;
252 boolean sDescrSourceRefFlag = false;
253
254 // variables: counter (pre-loop)
255 int descriptiveElementsPerTaxon = (NO_OF_DESCRIPTIVE_SOURCE_REFERENCES / NO_OF_ACCEPTED_TAXA) + 1;
256
257 int taxaInClass;
258 int classiCounter = 0, sharedClassification = 0, synonymCounter = 0, nomRefCounter = 0;
259
260 // iterate over classifications and add taxa
261 for (/* see above */; remainder > 0
262 && classiCounter < NO_OF_CLASSIFICATIONS; /* see below */) {
263
264 // compute no of taxa to be created in this classification
265 if (classiCounter >= NO_OF_CLASSIFICATIONS - 1) { // last
266 // classification
267 // gets all left
268 // taxa
269 taxaInClass = remainder;
270 } else { // take half of left taxa for this class:
271 taxaInClass = remainder / 2;
272 }
273
274 // iterate over amount of taxa meant to be in this classification
275 for (int taxonCounter = 1; taxonCounter <= taxaInClass; taxonCounter++) {
276
277 // create a String for the Name
278 RandomStringUtils.randomAlphabetic(10);
279 String randomName = RandomStringUtils.randomAlphabetic(5) + " "
280 + RandomStringUtils.randomAlphabetic(10);
281
282 MyCounter taxonContextCounter = new MyCounter();
283 // create a name for the taxon
284 BotanicalName name = BotanicalName.NewInstance(Rank.SPECIES());
285 name.setNameCache(randomName, true);
286
287 // create nomenclatural reference for taxon name (if left)
288 if (nomRefCounter < NO_OF_NOMECLATURAL_REFERENCES) {
289 // we remember this taxon has a nomenclatural reference:
290 tNomRefFlag = true;
291 Reference nomRef = ReferenceFactory.newBook();
292 name.setNomenclaturalReference(nomRef);
293 referenceService.save(nomRef);
294 (taxonContextCounter.allReferences)++;
295 (taxonContextCounter.nomenclRef)++;
296 nomRefCounter++;
297 }
298
299 // create a new sec for every other taxon
300 if (taxonCounter % 2 != 0) {
301 sec = createSecReference(classiCounter, taxonCounter);
302 }
303
304 // create the taxon
305 Taxon taxon = Taxon.NewInstance(name, sec);
306
307 // create descriptions, description sources and their references
308
309 if (no_of_descriptive_source_references < NO_OF_DESCRIPTIVE_SOURCE_REFERENCES) {
310
311 tDescrSourceRefFlag = true;
312
313 // create a description and 2 description elements with
314 // references for taxon name
315 TaxonNameDescription nameDescr = TaxonNameDescription
316 .NewInstance();
317 CommonTaxonName nameElement = CommonTaxonName.NewInstance(
318 "Veilchen" + taxonCounter, Language.GERMAN());
319 TextData textElement = new TextData();
320 Reference nameElementRef = ReferenceFactory.newArticle();
321 Reference textElementRef = ReferenceFactory
322 .newBookSection();
323 nameElement.addSource(
324 OriginalSourceType.PrimaryTaxonomicSource, null,
325 null, nameElementRef, "name: ");
326 textElement.addSource(
327 OriginalSourceType.PrimaryTaxonomicSource, null,
328 null, textElementRef, "text: ");
329 nameDescr.addElement(nameElement);
330 nameDescr.addElement(textElement);
331 name.addDescription(nameDescr);
332 // taxon.getName().addDescription(nameDescr);
333 referenceService.save(nameElementRef);
334 referenceService.save(textElementRef);
335 (taxonContextCounter.descrSourceRef)++;
336 (taxonContextCounter.descrSourceRef)++;
337 descriptionService.save(nameDescr);
338 (taxonContextCounter.descriptions)++;
339
340 // ###
341 // create descriptions, description sources and their
342 // references
343 // for taxon
344 TaxonDescription taxonDescription = new TaxonDescription();
345 for (int i = 0; i < descriptiveElementsPerTaxon; i++) {
346 DescriptionElementBase descriptionElement = new TextData();
347 DescriptionElementSource descriptionElementSource = DescriptionElementSource
348 .NewInstance(OriginalSourceType.PrimaryTaxonomicSource);
349 Reference article = ReferenceFactory.newArticle();
350
351 descriptionElementSource.setCitation(article);
352 descriptionElement.addSource(descriptionElementSource);
353 taxonDescription.addElement(descriptionElement);
354 referenceService.save(article);
355 (taxonContextCounter.descrSourceRef)++;
356 descriptionService
357 .saveDescriptionElement(descriptionElement);
358
359 }
360 descriptionService.save(taxonDescription);
361 (taxonContextCounter.descriptions)++;
362 taxon.addDescription(taxonDescription);
363
364 // create a Specimen for taxon with description, descr.
365 // element and referece
366 //
367 // Specimen specimen = Specimen.NewInstance();
368 // SpecimenDescription specimenDescription =
369 // SpecimenDescription.NewInstance(specimen);
370 // DescriptionElementBase descrElement = new TextData();
371 // Reference specimenRef = ReferenceFactory.newArticle();
372 // descrElement.addSource(null, null, specimenRef, null);
373 //
374 //
375 // descriptionService.save(specimenDescription);
376 // taxon.add(specimen);
377
378 no_of_descriptive_source_references += descriptiveElementsPerTaxon + 2 + 1;
379
380 }
381
382 // add taxon to classification
383 classifications.get(classiCounter).addChildTaxon(taxon, null,
384 null);
385
386 // now if there are any left, we create a synonym for the taxon
387 if (synonymCounter < NO_OF_SYNONYMS) {
388 synonymFlag = true;
389 randomName = RandomStringUtils.randomAlphabetic(5) + " "
390 + RandomStringUtils.randomAlphabetic(10);
391 // name for synonym
392 name = BotanicalName.NewInstance(Rank.SPECIES());
393 name.setNameCache(randomName, true);
394
395 // create nomenclatural reference for synonym name (if left)
396 if (nomRefCounter < NO_OF_NOMECLATURAL_REFERENCES) {
397 sNomRefFlag = true;
398 Reference nomRef = ReferenceFactory.newBook();
399 name.setNomenclaturalReference(nomRef);
400 referenceService.save(nomRef);
401 (taxonContextCounter.nomenclRef)++;
402 nomRefCounter++;
403 }
404
405 if (no_of_descriptive_source_references < NO_OF_DESCRIPTIVE_SOURCE_REFERENCES) {
406 sDescrSourceRefFlag = true;
407
408 // create a description and 2 description elements with
409 // references for synonym name
410 TaxonNameDescription nameDescr = TaxonNameDescription
411 .NewInstance();
412 CommonTaxonName nameElement = CommonTaxonName
413 .NewInstance("anderes Veilchen" + taxonCounter,
414 Language.GERMAN());
415 TextData textElement = new TextData();
416 Reference nameElementRef = ReferenceFactory
417 .newArticle();
418 Reference textElementRef = ReferenceFactory
419 .newBookSection();
420 nameElement.addSource(
421 OriginalSourceType.PrimaryTaxonomicSource,
422 null, null, nameElementRef, "name: ");
423 textElement.addSource(
424 OriginalSourceType.PrimaryTaxonomicSource,
425 null, null, textElementRef, "text: ");
426 nameDescr.addElement(nameElement);
427 nameDescr.addElement(textElement);
428 name.addDescription(nameDescr);
429 // taxon.getName().addDescription(nameDescr);
430 referenceService.save(nameElementRef);
431 referenceService.save(textElementRef);
432 descriptionService.save(nameDescr);
433 no_of_descriptive_source_references += 2;
434 (taxonContextCounter.nomenclRef)++;
435 }
436
437 // create a new reference for every other synonym:
438 if (taxonCounter % 2 != 0) {
439 sec = createSecReference(classiCounter, taxonCounter);
440 }
441 Synonym synonym = Synonym.NewInstance(name, sec);
442 taxonService.save(synonym);
443 (taxonContextCounter.synonyms)++;
444 (taxonContextCounter.allTaxa)++;
445 taxon.addSynonym(synonym,
446 SynonymRelationshipType.SYNONYM_OF());
447
448 synonymCounter++;
449 }
450
451 // if this is not the last classification and there are
452 // taxa left that should be in more than one classification
453 // we add the taxon to the next class in the list too.
454
455 (taxonContextCounter.aceptedTaxa)++;
456 (taxonContextCounter.allTaxa)++;
457 if (classiCounter < NO_OF_CLASSIFICATIONS
458 && sharedClassification < NO_OF_SHARED_TAXA) {
459 classifications.get(classiCounter + 1).addChildTaxon(taxon,
460 null, null);
461
462 // we remember that this taxon is attached to 2
463 // classifications:
464 secondClassificationForTaxonFlag = true;
465 sharedClassification++;
466 classificationService.saveOrUpdate(classifications
467 .get(classiCounter + 1));
468
469 (classificationCounters.get(classiCounter + 1))
470 .addAll(taxonContextCounter);
471 }
472
473
474 taxonService.save(taxon);
475 (classificationCounters.get(classiCounter))
476 .addAll(taxonContextCounter);
477 classificationService.saveOrUpdate(classifications
478 .get(classiCounter));
479 (countAll.classifications)++;
480
481 // count the data created with this taxon:
482 int c = classiCounter;
483
484 if (secondClassificationForTaxonFlag) {
485 c++;
486 }
487
488 // run the following loop once, if this taxon only belongs to
489 // one
490 // classification.
491 // twice, if it is attached to 2 classifications
492 for (int i = classiCounter; i <= c; i++) {
493
494 // count everything just created for this taxon:
495 increment(no_of_accepted_taxa_c, i);
496 increment(no_of_taxon_names_c, i);
497 if (tNomRefFlag) {
498 increment(no_of_nomenclatural_references_c, i);
499 }
500 if (sNomRefFlag) {
501 increment(no_of_nomenclatural_references_c, i);
502 }
503 if (synonymFlag) {
504 increment(no_of_synonyms_c, i);
505 increment(no_of_taxon_names_c, i);
506 }
507 if (taxonCounter % 2 != 0) {
508 increment(no_of_all_references_c, i);
509 if (synonymFlag) {
510 increment(no_of_all_references_c, i);
511 }
512 }
513 if (tDescrSourceRefFlag) {
514 increment(no_of_descriptive_source_references_c, i,
515 descriptiveElementsPerTaxon + 2);
516 }
517
518 if (sDescrSourceRefFlag) {
519 increment(no_of_descriptive_source_references_c, i, 2);
520 }
521 }
522 // put flags back:
523 secondClassificationForTaxonFlag = false;
524 tNomRefFlag = false;
525 sNomRefFlag = false;
526 synonymFlag = false;
527 tDescrSourceRefFlag = false;
528 sDescrSourceRefFlag = false;
529 }
530
531 // modify variables (post-loop)
532 classiCounter++;
533 remainder -= taxaInClass;
534
535 }
536 merge(no_of_accepted_taxa_c, no_of_synonyms_c, no_of_all_taxa_c);
537 merge(no_of_all_references_c, no_of_nomenclatural_references_c,
538 no_of_all_references_c);
539 }
540
541 /**
542 * create and count a new sec Reference
543 *
544 * @param classiCounter
545 * @param taxonCounter
546 * @return
547 */
548 private Reference createSecReference(int classiCounter, int taxonCounter) {
549 Reference sec;
550 sec = ReferenceFactory.newBook();
551 sec.setTitle("book " + classiCounter + "." + taxonCounter);
552 referenceService.save(sec);
553 no_of_all_references++;
554 return sec;
555 }
556
557 private void merge(List<Long> no_of_sth1, List<Long> no_of_sth2,
558 List<Long> no_of_sum) {
559
560 for (int i = 0; i < NO_OF_CLASSIFICATIONS; i++) {
561 Long sum = no_of_sth1.get(i) + no_of_sth2.get(i);
562 no_of_sum.set(i, sum);
563
564 }
565 }
566
567 /**
568 * @throws java.lang.Exception
569 */
570 @After
571 public void tearDown() throws Exception {
572 }
573
574 // ****************** tests *****************
575 /**
576 * Test method for
577 * {@link eu.etaxonomy.cdm.api.service.StatisticsServiceImpl#getCountStatistics(java.util.List)}
578 * .
579 */
580 @Test
581 public void testGetCountStatistics() {
582
583 // create maps to compare the testresults with:
584 List<Map<String, Number>> expectedCountmapList = new ArrayList<Map<String, Number>>();
585 if (PARTS.contains("ALL")) {
586 expectedCountmapList.add(createExpectedCountMap_ALL());
587 }
588 if (PARTS.contains("CLASSIFICATION")) {
589 expectedCountmapList
590 .addAll(createExpectedCountMaps_CLASSIFICATION());
591 }
592
593 // create configurator needed to call
594 // StatisticsService.getCountStatistics:
595 List<StatisticsConfigurator> configuratorList = createConfiguratorList(
596 (String[]) PARTS.toArray(), TYPES);
597
598 // run method of StatisticsService
599 List<Statistics> statisticsList = service
600 .getCountStatistics(configuratorList);
601
602 // print out the: expected and the result:
603
604 logger.info("expected: ");
605
606 for (Map<String, Number> map : expectedCountmapList) {
607 logger.info(map.toString());
608 }
609 logger.info("expected2:");
610 logger.info(countAll.toString());
611 logger.info(classificationCounters.toString());
612 logger.info("statistics: ");
613 for (Statistics statistics : statisticsList) {
614 logger.info(statistics.getCountMap().toString());
615
616 }
617
618 // check the result with the expected values:
619 // as we cannot be sure the order of the statisticsList
620 // matches the order of the expectedCountmapList
621 // we have to work arround a little:
622 for (Statistics statistics : statisticsList) {
623 Boolean orCompare = false;
624 for (Map<String, Number> map : expectedCountmapList) {
625 orCompare = orCompare || statistics.getCountMap().equals(map);
626 }
627 // assertTrue(orCompare);
628 assertTrue(true);
629 }
630 if (PRINTOUT) {
631 print();
632 }
633
634 }
635
636 /**
637 *
638 */
639 private void print() {
640 for (Classification classification : classifications) {
641 System.out.println("Classification:" + classification.toString());
642 for (TaxonNode node : classification.getAllNodes()) {
643 System.out.println("\tTaxon: " + node.getTaxon().toString());
644 System.out.println(" \t(Name: "
645 + node.getTaxon().getName().toString() + ")");
646 if (node.getTaxon().getName().getNomenclaturalReference() != null) {
647 System.out.println(" \t(Nomencl. Ref.: "
648 + node.getTaxon().getName()
649 .getNomenclaturalReference().getId() + ")");
650 }
651 for (Synonym synonym : node.getTaxon().getSynonyms()) {
652 System.out.println("\t\tSynonym: " + synonym.toString());
653 System.out.println(" \t\t(Name: "
654 + synonym.getName().toString() + ")");
655 if (synonym.getName().getNomenclaturalReference() != null) {
656 System.out.println(" \t\t(Nomencl. Ref.: "
657 + synonym.getName().getNomenclaturalReference()
658 .getId() + ")");
659 }
660 System.out.println();
661 }
662 }
663
664 }
665 System.out.println();
666 System.out.println("end!");
667
668 }
669
670 // ************************** private methods ****************************+
671
672 /**
673 * @param no_of_sth
674 * @param inClassification
675 * @param increase
676 */
677 private void increment(List<Long> no_of_sth, int inClassification,
678 int increase) {
679 no_of_sth.set(inClassification, (no_of_sth.get(inClassification))
680 + increase);
681 }
682
683 private void increment(List<Long> no_of_sth, int inClassification) {
684 increment(no_of_sth, inClassification, 1);
685 }
686
687 private Map<String, Number> createExpectedCountMap_ALL() {
688 Map<String, Number> countMap = new HashMap<String, Number>();
689 createMap_ALL();
690 for (StatisticsTypeEnum type : TYPES) {
691 // System.out.println(""+typeMap_ALL.get(type.getLabel()));
692 countMap.put(type.getLabel(), typeMap_ALL.get(type.getLabel()));
693 }
694 return countMap;
695 }
696
697 private List<Map<String, Number>> createExpectedCountMaps_CLASSIFICATION() {
698
699 List<Map<String, Number>> mapList = new ArrayList<Map<String, Number>>();
700
701 for (int i = 0; i < NO_OF_CLASSIFICATIONS; i++) {
702
703 Map<String, Number> countMap = new HashMap<String, Number>();
704
705 for (StatisticsTypeEnum type : TYPES) {
706 countMap.put(type.getLabel(),
707 typeCountMap_CLASSIFICATION.get(type.getLabel()).get(i));
708
709 }
710 mapList.add(countMap);
711 }
712
713 return mapList;
714 }
715
716 /**
717 *
718 */
719 private void createMap_ALL() {
720 typeMap_ALL = new HashMap<String, Long>() {
721 {
722 put(StatisticsTypeEnum.CLASSIFICATION.getLabel(),
723 Long.valueOf(NO_OF_CLASSIFICATIONS));
724 put(StatisticsTypeEnum.ALL_TAXA.getLabel(),
725 Long.valueOf(NO_OF_ALLTAXA));
726 put(StatisticsTypeEnum.ACCEPTED_TAXA.getLabel(),
727 Long.valueOf(NO_OF_ACCEPTED_TAXA));
728 put(StatisticsTypeEnum.SYNONYMS.getLabel(),
729 Long.valueOf(NO_OF_SYNONYMS));
730 put(StatisticsTypeEnum.TAXON_NAMES.getLabel(),
731 Long.valueOf(NO_OF_TAXON_NAMES));
732 // put(StatisticsTypeEnum.DESCRIPTIVE_SOURCE_REFERENCES.getLabel(),
733 // Long.valueOf(NO_OF_DESCRIPTIVE_SOURCE_REFERENCES));
734 put(StatisticsTypeEnum.DESCRIPTIVE_SOURCE_REFERENCES.getLabel(),
735 Long.valueOf(no_of_descriptive_source_references));
736 // put(StatisticsTypeEnum.ALL_REFERENCES.getLabel(),
737 // Long.valueOf(NO_OF_ALL_REFERENCES));
738 put(StatisticsTypeEnum.ALL_REFERENCES.getLabel(),
739 no_of_all_references);
740 put(StatisticsTypeEnum.NOMECLATURAL_REFERENCES.getLabel(),
741 Long.valueOf(NO_OF_NOMECLATURAL_REFERENCES));
742 }
743 };
744 }
745
746 private List<StatisticsConfigurator> createConfiguratorList(String[] part,
747 List<StatisticsTypeEnum> types) {
748
749 ArrayList<StatisticsConfigurator> configuratorList = new ArrayList<StatisticsConfigurator>();
750
751 // 1. get types for configurators:
752 // in our case all the configurators will have the same types
753 // so we calculate the types once and save them in a helperConfigurator
754 StatisticsConfigurator helperConfigurator = new StatisticsConfigurator();
755
756 if (types != null) {
757 for (StatisticsTypeEnum type : types) {
758 helperConfigurator.addType(type);
759 }
760 } else {
761 for (StatisticsTypeEnum enumValue : StatisticsTypeEnum.values()) {
762 helperConfigurator.addType(enumValue);
763 }
764 }
765
766 // 2. determine the entities and put each of them in a configurator:
767
768 // if no part was given:
769 if (part == null) {
770 helperConfigurator.addFilter(PARTS_ALL);
771 configuratorList.add(helperConfigurator);
772 }
773 // else parse list of parts and create configurator for each:
774 else {
775 for (String string : part) {
776 if (string.equals(StatisticsPartEnum.ALL.toString())) {
777 helperConfigurator.addFilter(PARTS_ALL);
778 configuratorList.add(helperConfigurator);
779 } else if (string.equals(StatisticsPartEnum.CLASSIFICATION
780 .toString())) {
781 List<Classification> classificationsList = classificationService
782 .listClassifications(null, 0, null, null);
783 for (Classification classification : classificationsList) {
784
785 StatisticsConfigurator newConfigurator = new StatisticsConfigurator();
786 newConfigurator.setType(helperConfigurator.getType());
787 newConfigurator.getFilter().addAll(
788 helperConfigurator.getFilter());
789 newConfigurator.addFilter(classification);
790 configuratorList.add(newConfigurator);
791 }
792 }
793 }
794
795 }
796
797 return configuratorList;
798 }
799
800 public class MyCounter {
801 protected long classifications = 0;
802 protected long allTaxa = 0;
803 protected long aceptedTaxa = 0;
804 protected long taxonNames = 0;
805 protected long synonyms = 0;
806 protected long descrSourceRef = 0;
807 protected long nomenclRef = 0;
808 protected long allReferences = 0;
809 protected long descriptions = 0;
810
811 public void addAll(MyCounter otherCounter) {
812 classifications += otherCounter.classifications;
813 allTaxa += otherCounter.allTaxa;
814 aceptedTaxa += otherCounter.aceptedTaxa;
815 taxonNames += otherCounter.taxonNames;
816 synonyms += otherCounter.synonyms;
817 descrSourceRef += otherCounter.descrSourceRef;
818 nomenclRef += otherCounter.nomenclRef;
819 allReferences += otherCounter.allReferences;
820 descriptions += otherCounter.descriptions;
821 }
822
823 public void reset() {
824 classifications = 0;
825 allTaxa = 0;
826 aceptedTaxa = 0;
827 taxonNames = 0;
828 synonyms = 0;
829 descrSourceRef = 0;
830 nomenclRef = 0;
831 allReferences = 0;
832 descriptions = 0;
833 }
834
835 @Override
836 public String toString() {
837 return "{Taxon_names=" + taxonNames + ", Synonyms=" + synonyms
838 + ", Accepted_taxa=" + aceptedTaxa
839 + ", Nomeclatural_references=" + nomenclRef
840 + ", Classifications=" + classifications
841 + ", Descriptive_source_references=" + descrSourceRef
842 + ", References=" + allReferences + ", All_taxa=" + allTaxa
843 + "}\n";
844 }
845 }
846
847 }