- extracted deepDelete tests to own java class
[cdmlib.git] / cdmlib-services / src / test / java / eu / etaxonomy / cdm / api / service / StatisticsServiceImplTest2.java
1 package eu.etaxonomy.cdm.api.service;
2
3 import static org.junit.Assert.assertTrue;
4
5 import java.io.FileNotFoundException;
6 import java.util.ArrayList;
7 import java.util.Arrays;
8 import java.util.List;
9
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;
15
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;
37
38 public class StatisticsServiceImplTest2 extends CdmTransactionalIntegrationTest {
39
40 // ************constants to set up the expected results for all:
41 // ********************
42
43 // ............................................
44
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
53 // for
54 // classifications is still missing for in the Statistics
55 // Service
56 StatisticsTypeEnum.SYNONYMS,
57 StatisticsTypeEnum.TAXON_NAMES,
58 StatisticsTypeEnum.NOMENCLATURAL_REFERENCES,
59 StatisticsTypeEnum.DESCRIPTIVE_SOURCE_REFERENCES });
60
61 // private static final String[] TYPES = { "CLASSIFICATION",
62 // "ACCEPTED_TAXA",
63 // "ALL_TAXA", "ALL_REFERENCES" };
64
65 // ................parts ..............................
66
67 private static final List<String> PARTS = Arrays.asList(new String[] {
68 "ALL", "CLASSIFICATION" });
69 // .........................................................
70
71 private ArrayList<Classification> classifications;
72
73 // ****************** services: ************************
74 @SpringBeanByType
75 private IStatisticsService service;
76 @SpringBeanByType
77 private IClassificationService classificationService;
78 @SpringBeanByType
79 private ITaxonService taxonService;
80 @SpringBeanByType
81 private IReferenceService referenceService;
82 @SpringBeanByType
83 private IDescriptionService descriptionService;
84
85 // ............................................
86
87 @Before
88 // @DataSet
89 public void setUp() throws Exception {
90 // createTestData(3, 10, 7, 16, 4);
91 // OutputStream out= new ByteArrayOutputStream();
92 // printDataSet(out);
93 // System.out.println(out.toString());
94 }
95
96 @Test
97 @DataSet
98 public void testGetCountStatistics() {
99
100 // create configurator needed to call
101 // StatisticsService.getCountStatistics()
102 List<StatisticsConfigurator> configuratorList = createConfiguratorList(
103 (String[]) PARTS.toArray(), TYPES);
104
105 // run method of StatisticsService
106 List<Statistics> statisticsList = service
107 .getCountStatistics(configuratorList);
108
109 // print out result
110 logger.info("statistics service result: ");
111 for (Statistics statistics : statisticsList) {
112 logger.info(statistics.getCountMap().toString());
113 }
114
115 assertTrue(true);
116 }
117
118 private List<StatisticsConfigurator> createConfiguratorList(String[] part,
119 List<StatisticsTypeEnum> types) {
120
121 ArrayList<StatisticsConfigurator> configuratorList = new ArrayList<StatisticsConfigurator>();
122
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();
127
128 if (types != null) {
129 for (StatisticsTypeEnum type : types) {
130 helperConfigurator.addType(type);
131 }
132 } else {
133 for (StatisticsTypeEnum enumValue : StatisticsTypeEnum.values()) {
134 helperConfigurator.addType(enumValue);
135 }
136 }
137
138 // 2. determine the entities and put each of them in a configurator:
139
140 // if no part was given:
141 if (part == null) {
142 helperConfigurator.addFilter(null); // part= null means search all
143 // DB
144 configuratorList.add(helperConfigurator);
145 }
146 // else parse list of parts and create configurator for each:
147 else {
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
153 .toString())) {
154 List<Classification> classificationsList = classificationService
155 .listClassifications(null, 0, null, null);
156 for (Classification classification : classificationsList) {
157
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);
164 }
165 }
166 }
167
168 }
169
170 return configuratorList;
171 }
172
173 public void createTestDataSet(int noOfClassifications, int noOfAcceptedTaxa,
174 int noOfSynonyms, int noOfDescrSrcReferences, int sharedTaxa)
175 throws Exception {
176
177 // create more parameters:
178 int noOfNomRefs = noOfAcceptedTaxa + noOfSynonyms - 4;
179
180 // missing in this example data:
181 // synonyms, that are attached to several taxa (same or different
182 // classification)
183
184 // --------------------variables for counting produced elements
185 // ------------------
186
187 int no_of_all_references = 0;
188 int descrSrcReferencesCounter = 0;
189
190 // create noOfClassifications classifications
191 classifications = new ArrayList<Classification>();
192
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);
198
199 }
200 // create all taxa, references and synonyms and attach them to one or
201 // more classifications
202
203 // variables: flags
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;
212
213 // variables: counter (pre-loop)
214 int descriptiveElementsPerTaxon = (noOfDescrSrcReferences / noOfAcceptedTaxa) + 1;
215
216 int taxaInClass;
217 int classiCounter = 0, sharedClassification = 0, synonymCounter = 0, nomRefCounter = 0;
218
219 // iterate over classifications and add taxa
220 for (/* see above */; remainder > 0
221 && classiCounter < noOfClassifications; /* see below */) {
222
223 // compute no of taxa to be created in this classification
224 if (classiCounter >= noOfClassifications - 1) { // last
225 // classification
226 // gets all left
227 // taxa
228 taxaInClass = remainder;
229 } else { // take half of left taxa for this class:
230 taxaInClass = remainder / 2;
231 }
232
233 // iterate over amount of taxa meant to be in this classification
234 for (int taxonCounter = 1; taxonCounter <= taxaInClass; taxonCounter++) {
235
236 // create a String for the Name
237 RandomStringUtils.randomAlphabetic(10);
238 String randomName = RandomStringUtils.randomAlphabetic(5) + " "
239 + RandomStringUtils.randomAlphabetic(10);
240
241 // create a name for the taxon
242 BotanicalName name = BotanicalName.NewInstance(Rank.SPECIES());
243 name.setNameCache(randomName, true);
244
245 // create nomenclatural reference for taxon name (if left)
246 if (nomRefCounter < noOfNomRefs) {
247 // we remember this taxon has a nomenclatural reference:
248 tNomRefFlag = true;
249 Reference nomRef = ReferenceFactory.newBook();
250 name.setNomenclaturalReference(nomRef);
251 referenceService.save(nomRef);
252 nomRefCounter++;
253 }
254
255 // create a new sec for every other taxon
256 if (taxonCounter % 2 != 0) {
257 sec = createSecReference(classiCounter, taxonCounter);
258 }
259
260 // create the taxon
261 Taxon taxon = Taxon.NewInstance(name, sec);
262
263 // create descriptions, description sources and their references
264
265 if (descrSrcReferencesCounter < noOfDescrSrcReferences) {
266
267 tDescrSourceRefFlag = true;
268
269 // create a description and 2 description elements with
270 // references for taxon name
271 TaxonNameDescription nameDescr = TaxonNameDescription
272 .NewInstance();
273 CommonTaxonName nameElement = CommonTaxonName.NewInstance(
274 "Veilchen" + taxonCounter, Language.GERMAN());
275 TextData textElement = new TextData();
276 Reference nameElementRef = ReferenceFactory.newArticle();
277 Reference textElementRef = ReferenceFactory
278 .newBookSection();
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());
294
295 // ###
296 // create descriptions, description sources and their
297 // references
298 // for taxon
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();
305
306 descriptionElementSource.setCitation(article);
307 descriptionElement.addSource(descriptionElementSource);
308 taxonDescription.addElement(descriptionElement);
309 referenceService.save(article);
310 descriptionService
311 .saveDescriptionElement(descriptionElement);
312 System.out.println("Descriptive Src Ref for Taxon: "+article.getId()+" Taxon: "+taxon.getId()+" name: "+taxon.getTitleCache());
313
314 }
315 descriptionService.save(taxonDescription);
316 taxon.addDescription(taxonDescription);
317
318 //TODO create Sspecimen connected to taxon via TaxonDescription->DescriptionElement=IndividualAssoziation->setAssociatedSpecimenOrObservation(SpecimenOrObservationBase)
319 // TODO and NameBase->SpecimenTypeDesignation->
320 // DerrivedUnit???
321
322 // create a Specimen for taxon with description, descr.
323 // element and referece
324 //
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;
331 //
332 //
333 // descriptionService.save(specimenDescription);
334 // taxon.addSource(
335 // OriginalSourceType.PrimaryTaxonomicSource,
336 // null, null, nameElementRef, " ");
337 // taxon.add(specimen);
338
339 descrSrcReferencesCounter += descriptiveElementsPerTaxon + 2 + 1;
340
341 }
342
343 // add taxon to classification
344 classifications.get(classiCounter).addChildTaxon(taxon, null,
345 null);
346
347 // now if there are any left, we create a synonym for the taxon
348 if (synonymCounter < noOfSynonyms) {
349 synonymFlag = true;
350 randomName = RandomStringUtils.randomAlphabetic(5) + " "
351 + RandomStringUtils.randomAlphabetic(10);
352 // name for synonym
353 name = BotanicalName.NewInstance(Rank.SPECIES());
354 name.setNameCache(randomName, true);
355
356 // create nomenclatural reference for synonym name (if left)
357 if (nomRefCounter < noOfNomRefs) {
358 sNomRefFlag = true;
359 Reference nomRef = ReferenceFactory.newBook();
360 name.setNomenclaturalReference(nomRef);
361 referenceService.save(nomRef);
362 nomRefCounter++;
363 }
364
365 if (descrSrcReferencesCounter < noOfDescrSrcReferences) {
366 sDescrSourceRefFlag = true;
367
368 // create a description and 2 description elements with
369 // references for synonym name
370 TaxonNameDescription nameDescr = TaxonNameDescription
371 .NewInstance();
372 CommonTaxonName nameElement = CommonTaxonName
373 .NewInstance("anderes Veilchen" + taxonCounter,
374 Language.GERMAN());
375 TextData textElement = new TextData();
376 Reference nameElementRef = ReferenceFactory
377 .newArticle();
378 Reference textElementRef = ReferenceFactory
379 .newBookSection();
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());
396 }
397
398 // create a new reference for every other synonym:
399 if (taxonCounter % 2 != 0) {
400 sec = createSecReference(classiCounter, taxonCounter);
401 }
402 Synonym synonym = Synonym.NewInstance(name, sec);
403 taxonService.save(synonym);
404 taxon.addSynonym(synonym,
405 SynonymRelationshipType.SYNONYM_OF());
406
407 synonymCounter++;
408 }
409
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.
413
414 if (classiCounter < noOfClassifications
415 && sharedClassification < sharedTaxa) {
416 classifications.get(classiCounter + 1).addChildTaxon(taxon,
417 null, null);
418
419 // we remember that this taxon is attached to 2
420 // classifications:
421 secondClassificationForTaxonFlag = true;
422 sharedClassification++;
423 classificationService.saveOrUpdate(classifications
424 .get(classiCounter + 1));
425
426 }
427
428 taxonService.save(taxon);
429 classificationService.saveOrUpdate(classifications
430 .get(classiCounter));
431
432 // count the data created with this taxon:
433 int c = classiCounter;
434
435 if (secondClassificationForTaxonFlag) {
436 c++;
437 }
438
439 // put flags back:
440 secondClassificationForTaxonFlag = false;
441 tNomRefFlag = false;
442 sNomRefFlag = false;
443 synonymFlag = false;
444 tDescrSourceRefFlag = false;
445 sDescrSourceRefFlag = false;
446 }
447
448 // modify variables (post-loop)
449 classiCounter++;
450 remainder -= taxaInClass;
451
452 }
453
454 commit();
455
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" });
463
464 // "AGENTBASE","HOMOTYPICALGROUP","LANGUAGESTRING",
465 // "DESCRIPTIONELEMENTBASE_LANGUAGESTRING", "HIBERNATE_SEQUENCES"
466 }
467
468 /**
469 * create and count a new sec Reference
470 *
471 * @param classiCounter
472 * @param taxonCounter
473 * @return
474 */
475 private Reference createSecReference(int classiCounter, int taxonCounter) {
476 Reference sec;
477 sec = ReferenceFactory.newBook();
478 sec.setTitle("book " + classiCounter + "." + taxonCounter);
479 referenceService.save(sec);
480 return sec;
481 }
482
483 /* (non-Javadoc)
484 * @see eu.etaxonomy.cdm.test.integration.CdmIntegrationTest#createTestData()
485 */
486 @Override
487 public void createTestDataSet() throws FileNotFoundException {
488 // TODO Auto-generated method stub
489
490 }
491
492 }