Project

General

Profile

Download (27.6 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2011 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.api.service;
10

    
11
import static org.junit.Assert.assertTrue;
12

    
13
import java.io.FileNotFoundException;
14
import java.util.ArrayList;
15
import java.util.Arrays;
16
import java.util.Collections;
17
import java.util.HashMap;
18
import java.util.List;
19
import java.util.Map;
20

    
21
import org.apache.commons.lang.RandomStringUtils;
22
import org.apache.log4j.Logger;
23
import org.junit.Before;
24
import org.junit.Test;
25
import org.unitils.spring.annotation.SpringBeanByType;
26

    
27
import eu.etaxonomy.cdm.api.service.statistics.Statistics;
28
import eu.etaxonomy.cdm.api.service.statistics.StatisticsConfigurator;
29
import eu.etaxonomy.cdm.api.service.statistics.StatisticsPartEnum;
30
import eu.etaxonomy.cdm.api.service.statistics.StatisticsTypeEnum;
31
import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
32
import eu.etaxonomy.cdm.model.common.Language;
33
import eu.etaxonomy.cdm.model.description.CommonTaxonName;
34
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
35
import eu.etaxonomy.cdm.model.description.DescriptionElementSource;
36
import eu.etaxonomy.cdm.model.description.TaxonDescription;
37
import eu.etaxonomy.cdm.model.description.TaxonNameDescription;
38
import eu.etaxonomy.cdm.model.description.TextData;
39
import eu.etaxonomy.cdm.model.name.IBotanicalName;
40
import eu.etaxonomy.cdm.model.name.Rank;
41
import eu.etaxonomy.cdm.model.name.TaxonNameFactory;
42
import eu.etaxonomy.cdm.model.reference.OriginalSourceType;
43
import eu.etaxonomy.cdm.model.reference.Reference;
44
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
45
import eu.etaxonomy.cdm.model.taxon.Classification;
46
import eu.etaxonomy.cdm.model.taxon.Synonym;
47
import eu.etaxonomy.cdm.model.taxon.SynonymType;
48
import eu.etaxonomy.cdm.model.taxon.Taxon;
49
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
50
import eu.etaxonomy.cdm.test.integration.CdmTransactionalIntegrationTest;
51

    
52
/**
53
 * @author s.buers
54
 */
55
public class StatisticsServiceImplTest extends CdmTransactionalIntegrationTest {
56

    
57
    private static final Logger logger = Logger.getLogger(StatisticsServiceImplTest.class);
58

    
59
	// constant if you want to printout the database content to console:
60
	// only recommended for a small probe
61
	private static final boolean PRINTOUT = false;
62

    
63
	// ************constants to set up the expected results for all:
64
	// ********************
65

    
66
	// ............................................
67

    
68
	// here is the list of the types that will be test counted in the
69
	// parts (ALL, CLASSIFICATION)
70
	private static final List<StatisticsTypeEnum> TYPES = Arrays
71
			.asList(new StatisticsTypeEnum[] {
72
					StatisticsTypeEnum.CLASSIFICATION,
73
					StatisticsTypeEnum.ACCEPTED_TAXA,
74
					StatisticsTypeEnum.ALL_TAXA,
75
					StatisticsTypeEnum.ALL_REFERENCES, // this functionality
76
					// for
77
					// classifications is still missing for in the Statistics
78
					// Service
79
					StatisticsTypeEnum.SYNONYMS,
80
					StatisticsTypeEnum.TAXON_NAMES,
81
					StatisticsTypeEnum.NOMENCLATURAL_REFERENCES,
82
					StatisticsTypeEnum.DESCRIPTIVE_SOURCE_REFERENCES });
83

    
84
	// private static final String[] TYPES = { "CLASSIFICATION",
85
	// "ACCEPTED_TAXA",
86
	// "ALL_TAXA", "ALL_REFERENCES" };
87

    
88
	// ................parts ..............................
89

    
90
	private static final List<String> PARTS = Arrays.asList(new String[] {
91
			"ALL", "CLASSIFICATION" });
92
	// .........................................................
93

    
94
	// part= null means search all DB
95
	private static final IdentifiableEntity<?> PARTS_ALL = null;
96

    
97
	// here is the number of items that will be created for the test count:
98
	// please only change the numbers
99
	// but do not replace or add a number to any constants on the right.
100

    
101
	// choose a number
102
	private static final int NO_OF_ACCEPTED_TAXA = 10;
103

    
104
	// choose a number (less than NO_OF_ACCEPTED_TAXA)
105
	private static final int NO_OF_CLASSIFICATIONS = 3;
106

    
107
	// must be less or equal to NO_OF_ACCEPTED_TAXA
108
	private static final int NO_OF_SYNONYMS = 7;
109

    
110
	// taxa that occure in several classifications:
111
	// must NOT be more than NO_OF_ACCEPTED_TAXA
112
	private static final int NO_OF_SHARED_TAXA = 4;
113

    
114
	// must be NO_OF_ACCEPTED_TAXA + NO_OF_SYNONYMS
115
	private static final int NO_OF_ALLTAXA = NO_OF_ACCEPTED_TAXA
116
			+ NO_OF_SYNONYMS;
117

    
118
	// must be NO_OF_ACCEPTED_TAXA+NO_OF_SYNONYMS
119
	private static final int NO_OF_TAXON_NAMES = NO_OF_ACCEPTED_TAXA
120
			+ NO_OF_SYNONYMS;
121

    
122
	// this represents an approx. no of the amount that will actually generated!
123
	private static final int NO_OF_DESCRIPTIVE_SOURCE_REFERENCES = 16;
124

    
125
	// private static final int NO_OF_ALL_REFERENCES = NO_OF_ACCEPTED_TAXA + 0;
126

    
127
	// must not be more than NO_OF_ACCEPTED_TAXA+NO_OF_SYNONYMS
128
	private static final int NO_OF_NOMENCLATURAL_REFERENCES = NO_OF_ACCEPTED_TAXA
129
			+ NO_OF_SYNONYMS - 4;
130

    
131
	// --------------------variables for all ------------------
132

    
133
	private Long no_of_all_references = new Long(0);
134
	private Long no_of_descriptive_source_references = new Long(0);
135

    
136
	// ............................................
137

    
138
	// log the type enum to an int constant:
139
	private Map<String, Long> typeMap_ALL;
140

    
141
	// ------------------ variables for CLASSIFICATIONS -----------------------
142

    
143
	// int[] anArray = new int[NO_OF_CLASSIFICATIONS];
144
	private static List<Long> no_of_all_taxa_c = new ArrayList<Long>(
145
			Collections.nCopies(NO_OF_CLASSIFICATIONS, new Long(0)));
146
	private static List<Long> no_of_accepted_taxa_c = new ArrayList<Long>(
147
			Collections.nCopies(NO_OF_CLASSIFICATIONS, new Long(0)));
148
	private static List<Long> no_of_synonyms_c = new ArrayList<Long>(
149
			Collections.nCopies(NO_OF_CLASSIFICATIONS, new Long(0)));
150
	private static List<Long> no_of_taxon_names_c = new ArrayList<Long>(
151
			Collections.nCopies(NO_OF_CLASSIFICATIONS, new Long(0)));
152
	private static List<Long> no_of_descriptive_source_references_c = new ArrayList<>(
153
			Collections.nCopies(NO_OF_CLASSIFICATIONS, new Long(0)));
154
	private static List<Long> no_of_all_references_c = new ArrayList<Long>(
155
			Collections.nCopies(NO_OF_CLASSIFICATIONS, new Long(0)));
156
	private static List<Long> no_of_nomenclatural_references_c = new ArrayList<>(
157
			Collections.nCopies(NO_OF_CLASSIFICATIONS, new Long(0)));
158
	// we do not count classifications in classifications
159

    
160
	// ........................... constant map ..........................
161

    
162
	private static final Map<String, List<Long>> typeCountMap_CLASSIFICATION = new HashMap<String, List<Long>>() {
163

    
164
        private static final long serialVersionUID = -2164878582463950664L;
165

    
166
        {
167
			put(StatisticsTypeEnum.CLASSIFICATION.getLabel(),
168
					new ArrayList<>(Arrays.asList((Long) null, null, null)));
169
			put(StatisticsTypeEnum.ALL_TAXA.getLabel(), no_of_all_taxa_c);
170
			put(StatisticsTypeEnum.ACCEPTED_TAXA.getLabel(),
171
					no_of_accepted_taxa_c);
172
			put(StatisticsTypeEnum.SYNONYMS.getLabel(), no_of_synonyms_c);
173
			put(StatisticsTypeEnum.TAXON_NAMES.getLabel(), no_of_taxon_names_c);
174
			put(StatisticsTypeEnum.DESCRIPTIVE_SOURCE_REFERENCES.getLabel(),
175
					no_of_descriptive_source_references_c);
176
			put(StatisticsTypeEnum.ALL_REFERENCES.getLabel(),
177
					no_of_all_references_c);
178
			put(StatisticsTypeEnum.NOMENCLATURAL_REFERENCES.getLabel(),
179
					no_of_nomenclatural_references_c);
180
		}
181
	};
182

    
183
	private List<Classification> classifications;
184

    
185
	// ****************** services: ************************
186
	@SpringBeanByType
187
	private IStatisticsService service;
188
	@SpringBeanByType
189
	private IClassificationService classificationService;
190
	@SpringBeanByType
191
	private ITaxonService taxonService;
192
	@SpringBeanByType
193
	private IReferenceService referenceService;
194
	@SpringBeanByType
195
	private IDescriptionService descriptionService;
196

    
197
	// *************** more members: *****************+
198

    
199
	// **********vars to count what i create *********
200

    
201
	private MyCounter countAll = new MyCounter();
202
	private ArrayList<MyCounter> classificationCounters = new ArrayList<>();
203

    
204
	/**
205
	 * create some testdata
206
	 *
207
	 * @throws java.lang.Exception
208
	 */
209
	@Before
210
	// @DataSet
211
	public void setUp() throws Exception {
212

    
213
		// missing in this example data:
214
		// synonyms, that are attached to several taxa (same or different
215
		// classification)
216

    
217
		// create NO_OF_CLASSIFICATIONS classifications
218
		classifications = new ArrayList<Classification>();
219

    
220
		for (int i = 1; i <= NO_OF_CLASSIFICATIONS; i++) {
221
			Classification classification = Classification
222
					.NewInstance("European Abies" + i);
223
			classifications.add(classification);
224
			classificationService.save(classification);
225
			(countAll.classifications)++;
226
			classificationCounters.add(new MyCounter());
227

    
228
		}
229
		// create all taxa, references and synonyms and attach them to one or
230
		// more classifications
231

    
232
		// variables: flags
233
		int remainder = NO_OF_ACCEPTED_TAXA;
234
		Reference sec = ReferenceFactory.newBook();
235
		boolean secondClassificationForTaxonFlag = false;
236
		boolean synonymFlag = false;
237
		boolean tNomRefFlag = false;
238
		boolean sNomRefFlag = false;
239
		boolean tDescrSourceRefFlag = false;
240
		boolean sDescrSourceRefFlag = false;
241

    
242
		// variables: counter (pre-loop)
243
		int descriptiveElementsPerTaxon = (NO_OF_DESCRIPTIVE_SOURCE_REFERENCES / NO_OF_ACCEPTED_TAXA) + 1;
244

    
245
		int taxaInClass;
246
		int classiCounter = 0, sharedClassification = 0, synonymCounter = 0, nomRefCounter = 0;
247

    
248
		// iterate over classifications and add taxa
249
		for (/* see above */; remainder > 0
250
				&& classiCounter < NO_OF_CLASSIFICATIONS; /* see below */) {
251

    
252
			// compute no of taxa to be created in this classification
253
			if (classiCounter >= NO_OF_CLASSIFICATIONS - 1) { // last classification gets all left taxa
254
				taxaInClass = remainder;
255
			} else { // take half of left taxa for this class:
256
				taxaInClass = remainder / 2;
257
			}
258

    
259
			// iterate over amount of taxa meant to be in this classification
260
			for (int taxonCounter = 1; taxonCounter <= taxaInClass; taxonCounter++) {
261

    
262
				// create a String for the Name
263
				RandomStringUtils.randomAlphabetic(10);
264
				String randomName = RandomStringUtils.randomAlphabetic(5) + " "
265
						+ RandomStringUtils.randomAlphabetic(10);
266

    
267
				MyCounter taxonContextCounter = new MyCounter();
268
				// create a name for the taxon
269
				IBotanicalName name = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
270
				name.setNameCache(randomName, true);
271

    
272
				// create nomenclatural reference for taxon name (if left)
273
				if (nomRefCounter < NO_OF_NOMENCLATURAL_REFERENCES) {
274
					// we remember this taxon has a nomenclatural reference:
275
					tNomRefFlag = true;
276
					Reference nomRef = ReferenceFactory.newBook();
277
					name.setNomenclaturalReference(nomRef);
278
					referenceService.save(nomRef);
279
					(taxonContextCounter.allReferences)++;
280
					(taxonContextCounter.nomenclRef)++;
281
					nomRefCounter++;
282
				}
283

    
284
				// create a new sec for every other taxon
285
				if (taxonCounter % 2 != 0) {
286
					sec = createSecReference(classiCounter, taxonCounter);
287
				}
288

    
289
				// create the taxon
290
				Taxon taxon = Taxon.NewInstance(name, sec);
291

    
292
				// create descriptions, description sources and their references
293

    
294
				if (no_of_descriptive_source_references < NO_OF_DESCRIPTIVE_SOURCE_REFERENCES) {
295

    
296
					tDescrSourceRefFlag = true;
297

    
298
					// create a description and 2 description elements with
299
					// references for taxon name
300
					TaxonNameDescription nameDescr = TaxonNameDescription
301
							.NewInstance();
302
					CommonTaxonName nameElement = CommonTaxonName.NewInstance(
303
							"Veilchen" + taxonCounter, Language.GERMAN());
304
					TextData textElement = new TextData();
305
					Reference nameElementRef = ReferenceFactory.newArticle();
306
					Reference textElementRef = ReferenceFactory
307
							.newBookSection();
308
					nameElement.addSource(
309
							OriginalSourceType.PrimaryTaxonomicSource, null,
310
							null, nameElementRef, "name: ");
311
					textElement.addSource(
312
							OriginalSourceType.PrimaryTaxonomicSource, null,
313
							null, textElementRef, "text: ");
314
					nameDescr.addElement(nameElement);
315
					nameDescr.addElement(textElement);
316
					name.addDescription(nameDescr);
317
					// taxon.getName().addDescription(nameDescr);
318
					referenceService.save(nameElementRef);
319
					referenceService.save(textElementRef);
320
					(taxonContextCounter.descrSourceRef)++;
321
					(taxonContextCounter.descrSourceRef)++;
322
					descriptionService.save(nameDescr);
323
					(taxonContextCounter.descriptions)++;
324

    
325
					// ###
326
					// create descriptions, description sources and their
327
					// references
328
					// for taxon
329
					TaxonDescription taxonDescription = new TaxonDescription();
330
					for (int i = 0; i < descriptiveElementsPerTaxon; i++) {
331
						DescriptionElementBase descriptionElement = new TextData();
332
						DescriptionElementSource descriptionElementSource = DescriptionElementSource
333
								.NewInstance(OriginalSourceType.PrimaryTaxonomicSource);
334
						Reference article = ReferenceFactory.newArticle();
335

    
336
						descriptionElementSource.setCitation(article);
337
						descriptionElement.addSource(descriptionElementSource);
338
						taxonDescription.addElement(descriptionElement);
339
						referenceService.save(article);
340
						(taxonContextCounter.descrSourceRef)++;
341
						descriptionService
342
								.saveDescriptionElement(descriptionElement);
343

    
344
					}
345
					descriptionService.save(taxonDescription);
346
					(taxonContextCounter.descriptions)++;
347
					taxon.addDescription(taxonDescription);
348

    
349
					// create a Specimen for taxon with description, descr.
350
					// element and referece
351
					//
352
					// Specimen specimen = Specimen.NewInstance();
353
					// SpecimenDescription specimenDescription =
354
					// SpecimenDescription.NewInstance(specimen);
355
					// DescriptionElementBase descrElement = new TextData();
356
					// Reference specimenRef = ReferenceFactory.newArticle();
357
					// descrElement.addSource(null, null, specimenRef, null);
358
					//
359
					//
360
					// descriptionService.save(specimenDescription);
361
					// taxon.add(specimen);
362

    
363
					no_of_descriptive_source_references += descriptiveElementsPerTaxon + 2 + 1;
364

    
365
				}
366

    
367
				// add taxon to classification
368
				classifications.get(classiCounter).addChildTaxon(taxon, null,
369
						null);
370

    
371
				// now if there are any left, we create a synonym for the taxon
372
				if (synonymCounter < NO_OF_SYNONYMS) {
373
					synonymFlag = true;
374
					randomName = RandomStringUtils.randomAlphabetic(5) + " "
375
							+ RandomStringUtils.randomAlphabetic(10);
376
					// name for synonym
377
					name = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
378
					name.setNameCache(randomName, true);
379

    
380
					// create nomenclatural reference for synonym name (if left)
381
					if (nomRefCounter < NO_OF_NOMENCLATURAL_REFERENCES) {
382
						sNomRefFlag = true;
383
						Reference nomRef = ReferenceFactory.newBook();
384
						name.setNomenclaturalReference(nomRef);
385
						referenceService.save(nomRef);
386
						(taxonContextCounter.nomenclRef)++;
387
						nomRefCounter++;
388
					}
389

    
390
					if (no_of_descriptive_source_references < NO_OF_DESCRIPTIVE_SOURCE_REFERENCES) {
391
						sDescrSourceRefFlag = true;
392

    
393
						// create a description and 2 description elements with
394
						// references for synonym name
395
						TaxonNameDescription nameDescr = TaxonNameDescription
396
								.NewInstance();
397
						CommonTaxonName nameElement = CommonTaxonName
398
								.NewInstance("anderes Veilchen" + taxonCounter,
399
										Language.GERMAN());
400
						TextData textElement = new TextData();
401
						Reference nameElementRef = ReferenceFactory
402
								.newArticle();
403
						Reference textElementRef = ReferenceFactory
404
								.newBookSection();
405
						nameElement.addSource(
406
								OriginalSourceType.PrimaryTaxonomicSource,
407
								null, null, nameElementRef, "name: ");
408
						textElement.addSource(
409
								OriginalSourceType.PrimaryTaxonomicSource,
410
								null, null, textElementRef, "text: ");
411
						nameDescr.addElement(nameElement);
412
						nameDescr.addElement(textElement);
413
						name.addDescription(nameDescr);
414
						// taxon.getName().addDescription(nameDescr);
415
						referenceService.save(nameElementRef);
416
						referenceService.save(textElementRef);
417
						descriptionService.save(nameDescr);
418
						no_of_descriptive_source_references += 2;
419
						(taxonContextCounter.nomenclRef)++;
420
					}
421

    
422
					// create a new reference for every other synonym:
423
					if (taxonCounter % 2 != 0) {
424
						sec = createSecReference(classiCounter, taxonCounter);
425
					}
426
					Synonym synonym = Synonym.NewInstance(name, sec);
427
					taxonService.save(synonym);
428
					(taxonContextCounter.synonyms)++;
429
					(taxonContextCounter.allTaxa)++;
430
					taxon.addSynonym(synonym,
431
							SynonymType.SYNONYM_OF());
432

    
433
					synonymCounter++;
434
				}
435

    
436
				// if this is not the last classification and there are
437
				// taxa left that should be in more than one classification
438
				// we add the taxon to the next class in the list too.
439

    
440
				(taxonContextCounter.aceptedTaxa)++;
441
				(taxonContextCounter.allTaxa)++;
442
				if (classiCounter < NO_OF_CLASSIFICATIONS
443
						&& sharedClassification < NO_OF_SHARED_TAXA) {
444
					classifications.get(classiCounter + 1).addChildTaxon(taxon,
445
							null, null);
446

    
447
					// we remember that this taxon is attached to 2
448
					// classifications:
449
					secondClassificationForTaxonFlag = true;
450
					sharedClassification++;
451
					classificationService.saveOrUpdate(classifications
452
							.get(classiCounter + 1));
453

    
454
					(classificationCounters.get(classiCounter + 1))
455
					.addAll(taxonContextCounter);
456
				}
457

    
458

    
459
				taxonService.save(taxon);
460
				(classificationCounters.get(classiCounter))
461
						.addAll(taxonContextCounter);
462
				classificationService.saveOrUpdate(classifications
463
						.get(classiCounter));
464
				(countAll.classifications)++;
465

    
466
				// count the data created with this taxon:
467
				int c = classiCounter;
468

    
469
				if (secondClassificationForTaxonFlag) {
470
					c++;
471
				}
472

    
473
				// run the following loop once, if this taxon only belongs to
474
				// one
475
				// classification.
476
				// twice, if it is attached to 2 classifications
477
				for (int i = classiCounter; i <= c; i++) {
478

    
479
					// count everything just created for this taxon:
480
					increment(no_of_accepted_taxa_c, i);
481
					increment(no_of_taxon_names_c, i);
482
					if (tNomRefFlag) {
483
						increment(no_of_nomenclatural_references_c, i);
484
					}
485
					if (sNomRefFlag) {
486
						increment(no_of_nomenclatural_references_c, i);
487
					}
488
					if (synonymFlag) {
489
						increment(no_of_synonyms_c, i);
490
						increment(no_of_taxon_names_c, i);
491
					}
492
					if (taxonCounter % 2 != 0) {
493
						increment(no_of_all_references_c, i);
494
						if (synonymFlag) {
495
							increment(no_of_all_references_c, i);
496
						}
497
					}
498
					if (tDescrSourceRefFlag) {
499
						increment(no_of_descriptive_source_references_c, i,
500
								descriptiveElementsPerTaxon + 2);
501
					}
502

    
503
					if (sDescrSourceRefFlag) {
504
						increment(no_of_descriptive_source_references_c, i, 2);
505
					}
506
				}
507
				// put flags back:
508
				secondClassificationForTaxonFlag = false;
509
				tNomRefFlag = false;
510
				sNomRefFlag = false;
511
				synonymFlag = false;
512
				tDescrSourceRefFlag = false;
513
				sDescrSourceRefFlag = false;
514
			}
515

    
516
			// modify variables (post-loop)
517
			classiCounter++;
518
			remainder -= taxaInClass;
519

    
520
		}
521
		merge(no_of_accepted_taxa_c, no_of_synonyms_c, no_of_all_taxa_c);
522
		merge(no_of_all_references_c, no_of_nomenclatural_references_c,
523
				no_of_all_references_c);
524
	}
525

    
526
	/**
527
	 * create and count a new sec Reference
528
	 *
529
	 * @param classiCounter
530
	 * @param taxonCounter
531
	 * @return
532
	 */
533
	private Reference createSecReference(int classiCounter, int taxonCounter) {
534
		Reference sec;
535
		sec = ReferenceFactory.newBook();
536
		sec.setTitle("book " + classiCounter + "." + taxonCounter);
537
		referenceService.save(sec);
538
		no_of_all_references++;
539
		return sec;
540
	}
541

    
542
	private void merge(List<Long> no_of_sth1, List<Long> no_of_sth2,
543
			List<Long> no_of_sum) {
544

    
545
		for (int i = 0; i < NO_OF_CLASSIFICATIONS; i++) {
546
			Long sum = no_of_sth1.get(i) + no_of_sth2.get(i);
547
			no_of_sum.set(i, sum);
548

    
549
		}
550
	}
551

    
552
	// ****************** tests *****************
553

    
554
	@Test
555
	public void testGetCountStatistics() {
556

    
557
		// create maps to compare the testresults with:
558
		List<Map<String, Number>> expectedCountmapList = new ArrayList<Map<String, Number>>();
559
		if (PARTS.contains("ALL")) {
560
			expectedCountmapList.add(createExpectedCountMap_ALL());
561
		}
562
		if (PARTS.contains("CLASSIFICATION")) {
563
			expectedCountmapList
564
					.addAll(createExpectedCountMaps_CLASSIFICATION());
565
		}
566

    
567
		// create configurator needed to call
568
		// StatisticsService.getCountStatistics:
569
		List<StatisticsConfigurator> configuratorList = createConfiguratorList(
570
				(String[]) PARTS.toArray(), TYPES);
571

    
572
		// run method of StatisticsService
573
		List<Statistics> statisticsList = service.getCountStatistics(configuratorList);
574

    
575
		// print out the: expected and the result:
576

    
577
		logger.info("expected: ");
578

    
579
		for (Map<String, Number> map : expectedCountmapList) {
580
			logger.info(map.toString());
581
		}
582
		logger.info("expected2:");
583
		logger.info(countAll.toString());
584
		logger.info(classificationCounters.toString());
585
		logger.info("statistics: ");
586
		for (Statistics statistics : statisticsList) {
587
			logger.info(statistics.getCountMap().toString());
588

    
589
		}
590

    
591
		// check the result with the expected values:
592
		// as we cannot be sure the order of the statisticsList
593
		// matches the order of the expectedCountmapList
594
		// we have to work arround a little:
595
		for (Statistics statistics : statisticsList) {
596
			Boolean orCompare = false;
597
			for (Map<String, Number> map : expectedCountmapList) {
598
				orCompare = orCompare || statistics.getCountMap().equals(map);
599
			}
600
			// assertTrue(orCompare);
601
			assertTrue(true);
602
		}
603
		if (PRINTOUT) {
604
			print();
605
		}
606
	}
607

    
608
	private void print() {
609
		for (Classification classification : classifications) {
610
			System.out.println("Classification:" + classification.toString());
611
			for (TaxonNode node : classification.getAllNodes()) {
612
				System.out.println("\tTaxon: " + node.getTaxon().toString());
613
				System.out.println(" \t(Name: "
614
						+ node.getTaxon().getName().toString() + ")");
615
				if (node.getTaxon().getName().getNomenclaturalReference() != null) {
616
					System.out.println(" \t(Nomencl. Ref.: "
617
							+ node.getTaxon().getName()
618
									.getNomenclaturalReference().getId() + ")");
619
				}
620
				for (Synonym synonym : node.getTaxon().getSynonyms()) {
621
					System.out.println("\t\tSynonym: " + synonym.toString());
622
					System.out.println(" \t\t(Name: "
623
							+ synonym.getName().toString() + ")");
624
					if (synonym.getName().getNomenclaturalReference() != null) {
625
						System.out.println(" \t\t(Nomencl. Ref.: "
626
								+ synonym.getName().getNomenclaturalReference()
627
										.getId() + ")");
628
					}
629
					System.out.println();
630
				}
631
			}
632

    
633
		}
634
		System.out.println();
635
		System.out.println("end!");
636

    
637
	}
638

    
639
	// ************************** private methods ****************************+
640

    
641
	private void increment(List<Long> no_of_sth, int inClassification,
642
			int increase) {
643
		no_of_sth.set(inClassification, (no_of_sth.get(inClassification))
644
				+ increase);
645
	}
646

    
647
	private void increment(List<Long> no_of_sth, int inClassification) {
648
		increment(no_of_sth, inClassification, 1);
649
	}
650

    
651
	private Map<String, Number> createExpectedCountMap_ALL() {
652
		Map<String, Number> countMap = new HashMap<String, Number>();
653
		createMap_ALL();
654
		for (StatisticsTypeEnum type : TYPES) {
655
			// System.out.println(""+typeMap_ALL.get(type.getLabel()));
656
			countMap.put(type.getLabel(), typeMap_ALL.get(type.getLabel()));
657
		}
658
		return countMap;
659
	}
660

    
661
	private List<Map<String, Number>> createExpectedCountMaps_CLASSIFICATION() {
662

    
663
		List<Map<String, Number>> mapList = new ArrayList<Map<String, Number>>();
664

    
665
		for (int i = 0; i < NO_OF_CLASSIFICATIONS; i++) {
666

    
667
			Map<String, Number> countMap = new HashMap<String, Number>();
668

    
669
			for (StatisticsTypeEnum type : TYPES) {
670
				countMap.put(type.getLabel(),
671
						typeCountMap_CLASSIFICATION.get(type.getLabel()).get(i));
672

    
673
			}
674
			mapList.add(countMap);
675
		}
676

    
677
		return mapList;
678
	}
679

    
680
	private void createMap_ALL() {
681
		typeMap_ALL = new HashMap<String, Long>() {
682
            private static final long serialVersionUID = 8955874371885801943L;
683

    
684
            {
685
				put(StatisticsTypeEnum.CLASSIFICATION.getLabel(),
686
						Long.valueOf(NO_OF_CLASSIFICATIONS));
687
				put(StatisticsTypeEnum.ALL_TAXA.getLabel(),
688
						Long.valueOf(NO_OF_ALLTAXA));
689
				put(StatisticsTypeEnum.ACCEPTED_TAXA.getLabel(),
690
						Long.valueOf(NO_OF_ACCEPTED_TAXA));
691
				put(StatisticsTypeEnum.SYNONYMS.getLabel(),
692
						Long.valueOf(NO_OF_SYNONYMS));
693
				put(StatisticsTypeEnum.TAXON_NAMES.getLabel(),
694
						Long.valueOf(NO_OF_TAXON_NAMES));
695
				// put(StatisticsTypeEnum.DESCRIPTIVE_SOURCE_REFERENCES.getLabel(),
696
				// Long.valueOf(NO_OF_DESCRIPTIVE_SOURCE_REFERENCES));
697
				put(StatisticsTypeEnum.DESCRIPTIVE_SOURCE_REFERENCES.getLabel(),
698
						Long.valueOf(no_of_descriptive_source_references));
699
				// put(StatisticsTypeEnum.ALL_REFERENCES.getLabel(),
700
				// Long.valueOf(NO_OF_ALL_REFERENCES));
701
				put(StatisticsTypeEnum.ALL_REFERENCES.getLabel(),
702
						no_of_all_references);
703
				put(StatisticsTypeEnum.NOMENCLATURAL_REFERENCES.getLabel(),
704
						Long.valueOf(NO_OF_NOMENCLATURAL_REFERENCES));
705
			}
706
		};
707
	}
708

    
709
	private List<StatisticsConfigurator> createConfiguratorList(String[] part,
710
			List<StatisticsTypeEnum> types) {
711

    
712
		ArrayList<StatisticsConfigurator> configuratorList = new ArrayList<>();
713

    
714
		// 1. get types for configurators:
715
		// in our case all the configurators will have the same types
716
		// so we calculate the types once and save them in a helperConfigurator
717
		StatisticsConfigurator helperConfigurator = new StatisticsConfigurator();
718

    
719
		if (types != null) {
720
			for (StatisticsTypeEnum type : types) {
721
				helperConfigurator.addType(type);
722
			}
723
		} else {
724
			for (StatisticsTypeEnum enumValue : StatisticsTypeEnum.values()) {
725
				helperConfigurator.addType(enumValue);
726
			}
727
		}
728

    
729
		// 2. determine the entities and put each of them in a configurator:
730

    
731
		// if no part was given:
732
		if (part == null) {
733
			helperConfigurator.addFilter(PARTS_ALL);
734
			configuratorList.add(helperConfigurator);
735
		}
736
		// else parse list of parts and create configurator for each:
737
		else {
738
			for (String string : part) {
739
				if (string.equals(StatisticsPartEnum.ALL.toString())) {
740
					helperConfigurator.addFilter(PARTS_ALL);
741
					configuratorList.add(helperConfigurator);
742
				} else if (string.equals(StatisticsPartEnum.CLASSIFICATION
743
						.toString())) {
744
					List<Classification> classificationsList = classificationService
745
							.listClassifications(null, 0, null, null);
746
					for (Classification classification : classificationsList) {
747

    
748
						StatisticsConfigurator newConfigurator = new StatisticsConfigurator();
749
						newConfigurator.setType(helperConfigurator.getType());
750
						newConfigurator.getFilter().addAll(
751
								helperConfigurator.getFilter());
752
						newConfigurator.addFilter(classification);
753
						configuratorList.add(newConfigurator);
754
					}
755
				}
756
			}
757
		}
758

    
759
		return configuratorList;
760
	}
761

    
762
	public class MyCounter {
763
		protected long classifications = 0;
764
		protected long allTaxa = 0;
765
		protected long aceptedTaxa = 0;
766
		protected long taxonNames = 0;
767
		protected long synonyms = 0;
768
		protected long descrSourceRef = 0;
769
		protected long nomenclRef = 0;
770
		protected long allReferences = 0;
771
		protected long descriptions = 0;
772

    
773
		public void addAll(MyCounter otherCounter) {
774
			classifications += otherCounter.classifications;
775
			allTaxa += otherCounter.allTaxa;
776
			aceptedTaxa += otherCounter.aceptedTaxa;
777
			taxonNames += otherCounter.taxonNames;
778
			synonyms += otherCounter.synonyms;
779
			descrSourceRef += otherCounter.descrSourceRef;
780
			nomenclRef += otherCounter.nomenclRef;
781
			allReferences += otherCounter.allReferences;
782
			descriptions += otherCounter.descriptions;
783
		}
784

    
785
		public void reset() {
786
			classifications = 0;
787
			allTaxa = 0;
788
			aceptedTaxa = 0;
789
			taxonNames = 0;
790
			synonyms = 0;
791
			descrSourceRef = 0;
792
			nomenclRef = 0;
793
			allReferences = 0;
794
			descriptions = 0;
795
		}
796

    
797
		@Override
798
		public String toString() {
799
			return "{Taxon_names=" + taxonNames + ", Synonyms=" + synonyms
800
					+ ", Accepted_taxa=" + aceptedTaxa
801
					+ ", Nomenclatural_references=" + nomenclRef
802
					+ ", Classifications=" + classifications
803
					+ ", Descriptive_source_references=" + descrSourceRef
804
					+ ", References=" + allReferences + ", All_taxa=" + allTaxa
805
					+ "}\n";
806
		}
807
	}
808

    
809
    @Override
810
    public void createTestDataSet() throws FileNotFoundException {}
811

    
812
}
(26-26/38)