Project

General

Profile

Download (17.1 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.List;
17

    
18
import org.apache.commons.lang.RandomStringUtils;
19
import org.junit.Before;
20
import org.junit.Test;
21
import org.unitils.dbunit.annotation.DataSet;
22
import org.unitils.spring.annotation.SpringBeanByType;
23

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

    
47
public class StatisticsServiceImplTest2 extends CdmTransactionalIntegrationTest {
48

    
49
	// ************constants to set up the expected results for all:
50
	// ********************
51

    
52
	// ............................................
53

    
54
	// here is the list of the types that will be test counted in the
55
	// parts (ALL, CLASSIFICATION)
56
	private static final List<StatisticsTypeEnum> TYPES = Arrays
57
			.asList(new StatisticsTypeEnum[] {
58
					StatisticsTypeEnum.CLASSIFICATION,
59
					StatisticsTypeEnum.ACCEPTED_TAXA,
60
					StatisticsTypeEnum.ALL_TAXA,
61
					StatisticsTypeEnum.ALL_REFERENCES, // this functionality
62
					// for
63
					// classifications is still missing for in the Statistics
64
					// Service
65
					StatisticsTypeEnum.SYNONYMS,
66
					StatisticsTypeEnum.TAXON_NAMES,
67
					StatisticsTypeEnum.NOMENCLATURAL_REFERENCES,
68
					StatisticsTypeEnum.DESCRIPTIVE_SOURCE_REFERENCES });
69

    
70
	// private static final String[] TYPES = { "CLASSIFICATION",
71
	// "ACCEPTED_TAXA",
72
	// "ALL_TAXA", "ALL_REFERENCES" };
73

    
74
	// ................parts ..............................
75

    
76
	private static final List<String> PARTS = Arrays.asList(new String[] {
77
			"ALL", "CLASSIFICATION" });
78
	// .........................................................
79

    
80
	private ArrayList<Classification> classifications;
81

    
82
	// ****************** services: ************************
83
	@SpringBeanByType
84
	private IStatisticsService service;
85
	@SpringBeanByType
86
	private IClassificationService classificationService;
87
	@SpringBeanByType
88
	private ITaxonService taxonService;
89
	@SpringBeanByType
90
	private IReferenceService referenceService;
91
	@SpringBeanByType
92
	private IDescriptionService descriptionService;
93
    @SpringBeanByType
94
    private IDescriptionElementService descriptionElementService;
95

    
96
	// ............................................
97

    
98
	@Before
99
	// @DataSet
100
	public void setUp() throws Exception {
101
//		 createTestData(3, 10, 7, 16, 4);
102
		// OutputStream out= new ByteArrayOutputStream();
103
		// printDataSet(out);
104
		// System.out.println(out.toString());
105
	}
106

    
107
	@Test
108
	@DataSet
109
	public void testGetCountStatistics() {
110

    
111
		// create configurator needed to call
112
		// StatisticsService.getCountStatistics()
113
		List<StatisticsConfigurator> configuratorList = createConfiguratorList(
114
				(String[]) PARTS.toArray(), TYPES);
115

    
116
		// run method of StatisticsService
117
		List<Statistics> statisticsList = service
118
				.getCountStatistics(configuratorList);
119

    
120
		// print out result
121
		logger.info("statistics service result: ");
122
		for (Statistics statistics : statisticsList) {
123
			logger.info(statistics.getCountMap().toString());
124
		}
125

    
126
		assertTrue(true);
127
	}
128

    
129
	private List<StatisticsConfigurator> createConfiguratorList(String[] part,
130
			List<StatisticsTypeEnum> types) {
131

    
132
		ArrayList<StatisticsConfigurator> configuratorList = new ArrayList<>();
133

    
134
		// 1. get types for configurators:
135
		// in our case all the configurators will have the same types
136
		// so we calculate the types once and save them in a helperConfigurator
137
		StatisticsConfigurator helperConfigurator = new StatisticsConfigurator();
138

    
139
		if (types != null) {
140
			for (StatisticsTypeEnum type : types) {
141
				helperConfigurator.addType(type);
142
			}
143
		} else {
144
			for (StatisticsTypeEnum enumValue : StatisticsTypeEnum.values()) {
145
				helperConfigurator.addType(enumValue);
146
			}
147
		}
148

    
149
		// 2. determine the entities and put each of them in a configurator:
150

    
151
		// if no part was given:
152
		if (part == null) {
153
			helperConfigurator.addFilter(null); // part= null means search all
154
												// DB
155
			configuratorList.add(helperConfigurator);
156
		}
157
		// else parse list of parts and create configurator for each:
158
		else {
159
			for (String string : part) {
160
				if (string.equals(StatisticsPartEnum.ALL.toString())) {
161
					helperConfigurator.addFilter(null);
162
					configuratorList.add(helperConfigurator);
163
				} else if (string.equals(StatisticsPartEnum.CLASSIFICATION
164
						.toString())) {
165
					List<Classification> classificationsList = classificationService
166
							.listClassifications(null, 0, null, null);
167
					for (Classification classification : classificationsList) {
168
						StatisticsConfigurator newConfigurator = new StatisticsConfigurator();
169
						newConfigurator.setType(helperConfigurator.getType());
170
						newConfigurator.getFilter().addAll(
171
								helperConfigurator.getFilter());
172
						newConfigurator.addFilter(classification);
173
						configuratorList.add(newConfigurator);
174
					}
175
				}
176
			}
177
		}
178

    
179
		return configuratorList;
180
	}
181

    
182
	public void createTestDataSet(int noOfClassifications, int noOfAcceptedTaxa,
183
			int noOfSynonyms, int noOfDescrSrcReferences, int sharedTaxa)
184
			throws Exception {
185

    
186
		// create more parameters:
187
		int noOfNomRefs = noOfAcceptedTaxa + noOfSynonyms - 4;
188

    
189
		// missing in this example data:
190
		// synonyms, that are attached to several taxa (same or different
191
		// classification)
192

    
193
		// --------------------variables for counting produced elements
194
		// ------------------
195

    
196
		int descrSrcReferencesCounter = 0;
197

    
198
		// create noOfClassifications classifications
199
		classifications = new ArrayList<Classification>();
200

    
201
		for (int i = 1; i <= noOfClassifications; i++) {
202
			Classification classification = Classification
203
					.NewInstance("European Abies" + i);
204
			classifications.add(classification);
205
			classificationService.save(classification);
206

    
207
		}
208
		// create all taxa, references and synonyms and attach them to one or
209
		// more classifications
210

    
211
		// variables: flags
212
		int remainder = noOfAcceptedTaxa;
213
		Reference sec = ReferenceFactory.newBook();
214
		boolean secondClassificationForTaxonFlag = false;
215
		boolean synonymFlag = false;
216
		boolean tNomRefFlag = false;
217
		boolean sNomRefFlag = false;
218
		boolean tDescrSourceRefFlag = false;
219
		boolean sDescrSourceRefFlag = false;
220

    
221
		// variables: counter (pre-loop)
222
		int descriptiveElementsPerTaxon = (noOfDescrSrcReferences / noOfAcceptedTaxa) + 1;
223

    
224
		int taxaInClass;
225
		int classiCounter = 0, sharedClassification = 0, synonymCounter = 0, nomRefCounter = 0;
226

    
227
		// iterate over classifications and add taxa
228
		for (/* see above */; remainder > 0
229
				&& classiCounter < noOfClassifications; /* see below */) {
230

    
231
			// compute no of taxa to be created in this classification
232
			if (classiCounter >= noOfClassifications - 1) { // last classification
233
															// gets all left taxa
234
				taxaInClass = remainder;
235
			} else { // take half of left taxa for this class:
236
				taxaInClass = remainder / 2;
237
			}
238

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

    
242
				// create a String for the Name
243
				RandomStringUtils.randomAlphabetic(10);
244
				String randomName = RandomStringUtils.randomAlphabetic(5) + " "
245
						+ RandomStringUtils.randomAlphabetic(10);
246

    
247
				// create a name for the taxon
248
				IBotanicalName name = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
249
				name.setNameCache(randomName, true);
250

    
251
				// create nomenclatural reference for taxon name (if left)
252
				if (nomRefCounter < noOfNomRefs) {
253
					// we remember this taxon has a nomenclatural reference:
254
					tNomRefFlag = true;
255
					Reference nomRef = ReferenceFactory.newBook();
256
					name.setNomenclaturalReference(nomRef);
257
					referenceService.save(nomRef);
258
					nomRefCounter++;
259
				}
260

    
261
				// create a new sec for every other taxon
262
				if (taxonCounter % 2 != 0) {
263
					sec = createSecReference(classiCounter, taxonCounter);
264
				}
265

    
266
				// create the taxon
267
				Taxon taxon = Taxon.NewInstance(name, sec);
268

    
269
				// create descriptions, description sources and their references
270

    
271
				if (descrSrcReferencesCounter < noOfDescrSrcReferences) {
272

    
273
					tDescrSourceRefFlag = true;
274

    
275
					// create a description and 2 description elements with
276
					// references for taxon name
277
					TaxonNameDescription nameDescr = TaxonNameDescription
278
							.NewInstance();
279
					CommonTaxonName nameElement = CommonTaxonName.NewInstance(
280
							"Veilchen" + taxonCounter, Language.GERMAN());
281
					TextData textElement = new TextData();
282
					Reference nameElementRef = ReferenceFactory.newArticle();
283
					Reference textElementRef = ReferenceFactory
284
							.newBookSection();
285
					nameElement.addSource(
286
							OriginalSourceType.PrimaryTaxonomicSource, null,
287
							null, nameElementRef, "name: ");
288
					textElement.addSource(
289
							OriginalSourceType.PrimaryTaxonomicSource, null,
290
							null, textElementRef, "text: ");
291
					nameDescr.addElement(nameElement);
292
					nameDescr.addElement(textElement);
293
					name.addDescription(nameDescr);
294
					// taxon.getName().addDescription(nameDescr);
295
					referenceService.save(nameElementRef);
296
					referenceService.save(textElementRef);
297
					descriptionService.save(nameDescr);
298
//					System.out.println("Descriptive Src Ref for TaxonName: "+nameElementRef.getId()+" Taxon: "+taxon.getId()+" name: "+taxon.getTitleCache());
299
//					System.out.println("Descriptive Src Ref for TaxonName: "+textElementRef.getId()+" Taxon: "+taxon.getId()+" name: "+taxon.getTitleCache());
300

    
301
					// ###
302
					// create descriptions, description sources and their
303
					// references
304
					// for taxon
305
					TaxonDescription taxonDescription = new TaxonDescription();
306
					for (int i = 0; i < descriptiveElementsPerTaxon; i++) {
307
						DescriptionElementBase descriptionElement = new TextData();
308
						DescriptionElementSource descriptionElementSource = DescriptionElementSource
309
								.NewInstance(OriginalSourceType.PrimaryTaxonomicSource);
310
						Reference article = ReferenceFactory.newArticle();
311

    
312
						descriptionElementSource.setCitation(article);
313
						descriptionElement.addSource(descriptionElementSource);
314
						taxonDescription.addElement(descriptionElement);
315
						referenceService.save(article);
316
						descriptionElementService.save(descriptionElement);
317
						System.out.println("Descriptive Src Ref for Taxon: "+article.getId()+" Taxon: "+taxon.getId()+" name: "+taxon.getTitleCache());
318

    
319
					}
320
					descriptionService.save(taxonDescription);
321
					taxon.addDescription(taxonDescription);
322

    
323
					//TODO create Sspecimen connected to taxon via TaxonDescription->DescriptionElement=IndividualAssoziation->setAssociatedSpecimenOrObservation(SpecimenOrObservationBase)
324
					// TODO and NameBase->SpecimenTypeDesignation->
325
					// DerrivedUnit???
326

    
327
					// create a Specimen for taxon with description, descr.
328
					// element and referece
329
					//
330
//					 SpecimenOrObservationBase specimen = DerivedUnit.NewInstance(SpecimenOrObservationType.Fossil);
331
//					 SpecimenDescription specimenDescription =
332
//					 SpecimenDescription.NewInstance(specimen);
333
//					 DescriptionElementBase descrElement = new TextData();
334
//					 Reference specimenRef = ReferenceFactory.newArticle();
335
////					 descrElement.add;
336
//
337
//
338
//					 descriptionService.save(specimenDescription);
339
//					 taxon.addSource(
340
//								OriginalSourceType.PrimaryTaxonomicSource,
341
//								null, null, nameElementRef, " ");
342
//					 taxon.add(specimen);
343

    
344
					descrSrcReferencesCounter += descriptiveElementsPerTaxon + 2 + 1;
345

    
346
				}
347

    
348
				// add taxon to classification
349
				classifications.get(classiCounter).addChildTaxon(taxon, null,
350
						null);
351

    
352
				// now if there are any left, we create a synonym for the taxon
353
				if (synonymCounter < noOfSynonyms) {
354
					synonymFlag = true;
355
					randomName = RandomStringUtils.randomAlphabetic(5) + " "
356
							+ RandomStringUtils.randomAlphabetic(10);
357
					// name for synonym
358
					name = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
359
					name.setNameCache(randomName, true);
360

    
361
					// create nomenclatural reference for synonym name (if left)
362
					if (nomRefCounter < noOfNomRefs) {
363
						sNomRefFlag = true;
364
						Reference nomRef = ReferenceFactory.newBook();
365
						name.setNomenclaturalReference(nomRef);
366
						referenceService.save(nomRef);
367
						nomRefCounter++;
368
					}
369

    
370
					if (descrSrcReferencesCounter < noOfDescrSrcReferences) {
371
						sDescrSourceRefFlag = true;
372

    
373
						// create a description and 2 description elements with
374
						// references for synonym name
375
						TaxonNameDescription nameDescr = TaxonNameDescription
376
								.NewInstance();
377
						CommonTaxonName nameElement = CommonTaxonName
378
								.NewInstance("anderes Veilchen" + taxonCounter,
379
										Language.GERMAN());
380
						TextData textElement = new TextData();
381
						Reference nameElementRef = ReferenceFactory
382
								.newArticle();
383
						Reference textElementRef = ReferenceFactory
384
								.newBookSection();
385
						nameElement.addSource(
386
								OriginalSourceType.PrimaryTaxonomicSource,
387
								null, null, nameElementRef, "name: ");
388
						textElement.addSource(
389
								OriginalSourceType.PrimaryTaxonomicSource,
390
								null, null, textElementRef, "text: ");
391
						nameDescr.addElement(nameElement);
392
						nameDescr.addElement(textElement);
393
						name.addDescription(nameDescr);
394
						// taxon.getName().addDescription(nameDescr);
395
						referenceService.save(nameElementRef);
396
						referenceService.save(textElementRef);
397
						descriptionService.save(nameDescr);
398
						descrSrcReferencesCounter += 2;
399
						System.out.println("Descriptive Src Ref for Synonym: "+nameElementRef.getId()+" Taxon: "+taxon.getId()+" name: "+taxon.getTitleCache());
400
						System.out.println("Descriptive Src Ref for Synonym: "+textElementRef.getId()+" Taxon: "+taxon.getId()+" name: "+taxon.getTitleCache());
401
					}
402

    
403
					// create a new reference for every other synonym:
404
					if (taxonCounter % 2 != 0) {
405
						sec = createSecReference(classiCounter, taxonCounter);
406
					}
407
					Synonym synonym = Synonym.NewInstance(name, sec);
408
					taxonService.save(synonym);
409
					taxon.addSynonym(synonym,
410
							SynonymType.SYNONYM_OF());
411

    
412
					synonymCounter++;
413
				}
414

    
415
				// if this is not the last classification and there are
416
				// taxa left that should be in more than one classification
417
				// we add the taxon to the next class in the list too.
418

    
419
				if (classiCounter < noOfClassifications
420
						&& sharedClassification < sharedTaxa) {
421
					classifications.get(classiCounter + 1).addChildTaxon(taxon,
422
							null, null);
423

    
424
					// we remember that this taxon is attached to 2
425
					// classifications:
426
					secondClassificationForTaxonFlag = true;
427
					sharedClassification++;
428
					classificationService.saveOrUpdate(classifications
429
							.get(classiCounter + 1));
430

    
431
				}
432

    
433
				taxonService.save(taxon);
434
				classificationService.saveOrUpdate(classifications
435
						.get(classiCounter));
436

    
437
				// count the data created with this taxon:
438
				int c = classiCounter;
439

    
440
				if (secondClassificationForTaxonFlag) {
441
					c++;
442
				}
443

    
444
				// put flags back:
445
				secondClassificationForTaxonFlag = false;
446
				tNomRefFlag = false;
447
				sNomRefFlag = false;
448
				synonymFlag = false;
449
				tDescrSourceRefFlag = false;
450
				sDescrSourceRefFlag = false;
451
			}
452

    
453
			// modify variables (post-loop)
454
			classiCounter++;
455
			remainder -= taxaInClass;
456

    
457
		}
458

    
459
		commit();
460

    
461
		writeDbUnitDataSetFile(new String[] { "TAXONBASE", "TAXONNAME",
462
				"TAXONRELATIONSHIP", "REFERENCE",
463
				"DESCRIPTIONELEMENTBASE",
464
				"DESCRIPTIONELEMENTBASE_ORIGINALSOURCEBASE",
465
				"ORIGINALSOURCEBASE", "DESCRIPTIONBASE", "REFERENCE_ORIGINALSOURCEBASE","LANGUAGESTRING",
466
				"CLASSIFICATION",  "TAXONNODE",
467
				"HIBERNATE_SEQUENCES" });
468

    
469
		// "AGENTBASE","HOMOTYPICALGROUP","LANGUAGESTRING",
470
		// "DESCRIPTIONELEMENTBASE_LANGUAGESTRING", "HIBERNATE_SEQUENCES"
471
	}
472

    
473
	/**
474
	 * create and count a new sec Reference
475
	 */
476
	private Reference createSecReference(int classiCounter, int taxonCounter) {
477
		Reference sec;
478
		sec = ReferenceFactory.newBook();
479
		sec.setTitle("book " + classiCounter + "." + taxonCounter);
480
		referenceService.save(sec);
481
		return sec;
482
	}
483

    
484
    @Override
485
    public void createTestDataSet() throws FileNotFoundException {}
486

    
487
}
(26-26/37)