ref #10178: new methods for normalization of names
[cdmlib.git] / cdmlib-services / src / test / java / eu / etaxonomy / cdm / api / service / NameServiceImplTest.java
1 /**
2 * Copyright (C) 2009 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.assertEquals;
12 import static org.junit.Assert.assertTrue;
13
14 import java.io.FileNotFoundException;
15 import java.lang.reflect.Field;
16 import java.util.Arrays;
17 import java.util.List;
18 import java.util.Set;
19 import java.util.UUID;
20
21 import org.apache.logging.log4j.LogManager;
22 import org.apache.logging.log4j.Logger;
23 import org.junit.Assert;
24 import org.junit.Ignore;
25 import org.junit.Test;
26 import org.springframework.security.authentication.AbstractAuthenticationToken;
27 import org.springframework.security.authentication.AuthenticationManager;
28 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
29 import org.springframework.security.core.Authentication;
30 import org.springframework.security.core.context.SecurityContextHolder;
31 import org.springframework.security.core.context.SecurityContextImpl;
32 import org.unitils.dbunit.annotation.DataSet;
33 import org.unitils.spring.annotation.SpringBeanByName;
34 import org.unitils.spring.annotation.SpringBeanByType;
35
36 import eu.etaxonomy.cdm.api.service.config.IdentifiableServiceConfiguratorFactory;
37 import eu.etaxonomy.cdm.api.service.config.IdentifiableServiceConfiguratorImpl;
38 import eu.etaxonomy.cdm.api.service.config.NameDeletionConfigurator;
39 import eu.etaxonomy.cdm.api.service.pager.Pager;
40 import eu.etaxonomy.cdm.common.DoubleResult;
41 import eu.etaxonomy.cdm.model.common.CdmBase;
42 import eu.etaxonomy.cdm.model.common.IdentifiableEntity;
43 import eu.etaxonomy.cdm.model.common.Language;
44 import eu.etaxonomy.cdm.model.description.DescriptionElementSource;
45 import eu.etaxonomy.cdm.model.description.Feature;
46 import eu.etaxonomy.cdm.model.description.TaxonDescription;
47 import eu.etaxonomy.cdm.model.description.TaxonNameDescription;
48 import eu.etaxonomy.cdm.model.description.TextData;
49 import eu.etaxonomy.cdm.model.name.HybridRelationship;
50 import eu.etaxonomy.cdm.model.name.HybridRelationshipType;
51 import eu.etaxonomy.cdm.model.name.NameRelationshipType;
52 import eu.etaxonomy.cdm.model.name.NameTypeDesignation;
53 import eu.etaxonomy.cdm.model.name.NameTypeDesignationStatus;
54 import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
55 import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;
56 import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;
57 import eu.etaxonomy.cdm.model.name.Rank;
58 import eu.etaxonomy.cdm.model.name.Registration;
59 import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
60 import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignationStatus;
61 import eu.etaxonomy.cdm.model.name.TaxonName;
62 import eu.etaxonomy.cdm.model.name.TaxonNameFactory;
63 import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
64 import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
65 import eu.etaxonomy.cdm.model.taxon.Taxon;
66 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
67 import eu.etaxonomy.cdm.persistence.dao.common.Restriction;
68 import eu.etaxonomy.cdm.persistence.dao.common.Restriction.Operator;
69 import eu.etaxonomy.cdm.persistence.dto.TaxonNameParts;
70 import eu.etaxonomy.cdm.persistence.query.MatchMode;
71 import eu.etaxonomy.cdm.persistence.query.OrderHint;
72 import eu.etaxonomy.cdm.test.integration.CdmTransactionalIntegrationTest;
73 import eu.etaxonomy.cdm.test.unitils.CleanSweepInsertLoadStrategy;
74
75 /**
76 * @author a.mueller
77 */
78 public class NameServiceImplTest extends CdmTransactionalIntegrationTest {
79
80 private static final Logger logger = LogManager.getLogger();
81
82 private static final UUID NAME1_UUID = UUID.fromString("6dbd41d1-fe13-4d9c-bb58-31f051c2c384");
83 private static final int NAME1_ID = 10;
84 private static final UUID NAME2_UUID = UUID.fromString("f9e9c13f-5fa5-48d3-88cf-712c921a099e");
85 private static final int NAME2_ID = 11;
86 private static final UUID NAME3_UUID = UUID.fromString("e1e66264-f16a-4df9-80fd-6ab5028a3c28");
87 private static final int NAME3_ID = 12;
88
89 @SpringBeanByType
90 private INameService nameService;
91
92 @SpringBeanByType
93 private IOccurrenceService occurrenceService;
94
95 @SpringBeanByType
96 private IRegistrationService registrationService;
97
98 @SpringBeanByType
99 private ITaxonService taxonService;
100
101 @SpringBeanByType
102 private ITermService termService;
103
104 @SpringBeanByName
105 private AuthenticationManager authenticationManager;
106
107
108 private void setAuthentication(AbstractAuthenticationToken token) {
109 Authentication authentication = authenticationManager.authenticate(token);
110
111 SecurityContextImpl secureContext = new SecurityContextImpl();
112 SecurityContextHolder.setContext(secureContext);
113 secureContext.setAuthentication(authentication);
114 }
115
116 private void unsetAuthentication() {
117
118 SecurityContextImpl secureContext = new SecurityContextImpl();
119 SecurityContextHolder.setContext(secureContext);
120 secureContext.setAuthentication(null);
121 }
122
123 /* ******************** TESTS ********************************************/
124
125 /**
126 * Test method for {@link eu.etaxonomy.cdm.api.service.NameServiceImpl#setDao(eu.etaxonomy.cdm.persistence.dao.name.ITaxonNameDao)}.
127 */
128 @Test
129 public void testSetDao() {
130 // Assert.assertNotNull(((NameServiceImpl)nameService).dao);
131 }
132
133 /**
134 * Test method for {@link eu.etaxonomy.cdm.api.service.NameServiceImpl#setVocabularyDao(eu.etaxonomy.cdm.persistence.dao.common.ITermVocabularyDao)}.
135 */
136 @Test
137 public void testSetVocabularyDao() {
138 // Assert.assertNotNull(( (NameServiceImpl)nameService.vocabularyDao);
139 }
140
141 /**
142 * Test method for {@link eu.etaxonomy.cdm.api.service.NameServiceImpl#getNamesByName(java.lang.String)}.
143 */
144 @Test
145 public void testGetNamesByName() {
146 logger.warn("Not yet implemented");
147 }
148
149
150 @Test
151 @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class)
152 public void testDeleteTaxonNameWithNameRelations() {
153
154 final String[] tableNames = new String[]{"USERACCOUNT", "TaxonName","NameRelationship","HybridRelationship","DescriptionBase","NomenclaturalStatus","TaxonBase","SpecimenOrObservationBase","OriginalSourceBase","DescriptionElementBase"};
155 // printDataSet(System.err, true, null);
156
157 TaxonName name1 = TaxonNameFactory.NewBotanicalInstance(getSpeciesRank());
158 name1.setTitleCache("Name1", true);
159 TaxonName nameWithBasionym = TaxonNameFactory.NewBotanicalInstance(getSpeciesRank());
160 nameWithBasionym.setTitleCache("nameWithBasionym", true);
161
162 NameRelationshipType nameRelType = (NameRelationshipType)termService.find(NameRelationshipType.BASIONYM().getUuid());
163 name1.addRelationshipToName(nameWithBasionym,nameRelType , null, null, null, null);
164 // nameWithBasionym.addBasionym(name1);
165 nameService.save(name1);
166 nameService.save(nameWithBasionym);
167 commitAndStartNewTransaction(tableNames);
168
169
170 name1 = nameService.find(name1.getUuid());
171 DeleteResult result = nameService.delete(name1);
172 if (!result.isOk()){
173 Exception e = result.getExceptions().iterator().next();
174 Assert.assertEquals("The Ecxeption should be a ReferencedObjectException because it is a basionym", "Name can't be deleted as it is a basionym.", e.getMessage());
175 } else{
176 Assert.fail();
177 }
178 name1 = nameService.find(name1.getUuid());
179 Assert.assertNotNull("Name should still be in database",name1);
180 nameWithBasionym = name1.getNameRelations().iterator().next().getToName();
181 nameWithBasionym.removeBasionyms();
182
183 result = nameService.delete(name1); //should throw now exception
184
185
186
187 commitAndStartNewTransaction(tableNames);
188 name1 = nameService.find(name1.getUuid());
189 Assert.assertNull("Name should not be in database anymore",name1);
190
191 }
192
193 @Test
194 @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class)
195 public void testDeleteTaxonNameConfiguratorWithNameRelations() {
196 final String[] tableNames = new String[]{"TaxonName","NameRelationship","HybridRelationship"};
197
198 // printDataSet(System.err, new String[]{"TaxonName","NameRelationship","HybridRelationship","DescriptionBase","NomenclaturalStatus","TaxonBase","SpecimenOrObservationBase","OriginalSourceBase",
199 // "DescriptionElementBase",
200 // "AGENTBASE", "USERACCOUNT", "PERMISSIONGROUP", "USERACCOUNT_PERMISSIONGROUP", "USERACCOUNT_GRANTEDAUTHORITYIMPL", "GRANTEDAUTHORITYIMPL"});
201
202 TaxonName name1 = TaxonNameFactory.NewBotanicalInstance(getSpeciesRank());
203 name1.setTitleCache("Name1", true);
204 TaxonName nameWithBasionym = TaxonNameFactory.NewBotanicalInstance(getSpeciesRank());
205 nameWithBasionym.setTitleCache("nameWithBasionym", true);
206
207 NameRelationshipType nameRelType = (NameRelationshipType)termService.find(NameRelationshipType.BASIONYM().getUuid());
208 name1.addRelationshipToName(nameWithBasionym,nameRelType , null, null, null, null);
209 nameService.save(name1);
210 nameService.save(nameWithBasionym);
211 commitAndStartNewTransaction(tableNames);
212 NameDeletionConfigurator config = new NameDeletionConfigurator();
213
214 name1 = nameService.find(name1.getUuid());
215 DeleteResult result = nameService.delete(name1.getUuid(), config);
216 if (result.isOk()){
217 Assert.fail("This should throw an error as long as name relationships exist.");
218 }
219
220
221 name1 = nameService.find(name1.getUuid());
222 Assert.assertNotNull("Name should still be in database",name1);
223
224 //ignore is basionym for
225 config.setIgnoreIsBasionymFor(true);
226
227 name1 = nameService.find(name1.getUuid());
228 nameService.delete(name1.getUuid(), config);
229 commitAndStartNewTransaction(tableNames);
230 name1 = nameService.find(name1.getUuid());
231 Assert.assertNull("Name should not be in database anymore",name1);
232
233 }
234
235 @Test
236 public void testDeleteTaxonNameConfiguratorWithNameRelationsAll() {
237 final String[] tableNames = new String[]{"TaxonName","NameRelationship","HybridRelationship"};
238
239 TaxonName name1 = TaxonNameFactory.NewBotanicalInstance(getSpeciesRank());
240 name1.setTitleCache("Name1", true);
241 TaxonName nameWithBasionym = TaxonNameFactory.NewBotanicalInstance(getSpeciesRank());
242 nameWithBasionym.setTitleCache("nameWithBasionym", true);
243
244 NameRelationshipType nameRelType = (NameRelationshipType)termService.find(NameRelationshipType.BASIONYM().getUuid());
245 name1.addRelationshipToName(nameWithBasionym,nameRelType , null, null, null, null);
246 nameService.save(name1);
247 nameService.save(nameWithBasionym);
248 commitAndStartNewTransaction(tableNames);
249 NameDeletionConfigurator config = new NameDeletionConfigurator();
250
251 name1 = nameService.find(name1.getUuid());
252 DeleteResult result = nameService.delete(name1.getUuid(), config);
253 if (result.isOk()){
254 Assert.fail("Delete should throw an error as long as name relationships exist.");
255 }
256
257 name1 = nameService.find(name1.getUuid());
258 Assert.assertNotNull("Name should still be in database",name1);
259
260 //ignore all name relationships
261 config.setRemoveAllNameRelationships(true);
262
263 name1 = nameService.find(name1.getUuid());
264 result = nameService.delete(name1.getUuid(), config);
265 logger.debug(result);
266 commitAndStartNewTransaction(tableNames);
267 name1 = nameService.find(name1.getUuid());
268 Assert.assertNull("Name should not be in database anymore",name1);
269 }
270
271 @Test
272 public void testDeleteTaxonNameConfiguratorWithHasBasionym() {
273 final String[] tableNames = new String[]{"TaxonName","NameRelationship","HybridRelationship"};
274
275 TaxonName name1 = TaxonNameFactory.NewBotanicalInstance(getSpeciesRank());
276 name1.setTitleCache("Name1", true);
277 TaxonName basionym = TaxonNameFactory.NewBotanicalInstance(getSpeciesRank());
278 basionym.setTitleCache("basionym", true);
279
280 NameRelationshipType nameRelType = (NameRelationshipType)termService.find(NameRelationshipType.BASIONYM().getUuid());
281 basionym.addRelationshipToName(name1,nameRelType , null, null, null, null);
282 nameService.save(name1);
283 nameService.save(basionym);
284 commitAndStartNewTransaction(tableNames);
285 NameDeletionConfigurator config = new NameDeletionConfigurator();
286 config.setIgnoreHasBasionym(false);
287
288 name1 = nameService.find(name1.getUuid());
289 DeleteResult result = nameService.delete(name1.getUuid(), config);
290 if (result.isOk()){
291 Assert.fail("Delete should throw an error as long as name relationships exist.");
292 }
293
294 name1 = nameService.find(name1.getUuid());
295 Assert.assertNotNull("Name should still be in database",name1);
296
297 //ignore has basionym
298 config.setIgnoreHasBasionym(true);
299 try {
300 name1 = nameService.find(name1.getUuid());
301 result = nameService.delete(name1.getUuid(), config);
302 logger.debug(result);
303 commitAndStartNewTransaction(tableNames);
304 name1 = nameService.find(name1.getUuid());
305 Assert.assertNull("Name should not be in database anymore",name1);
306 } catch (Exception e) {
307 Assert.fail("Delete should not throw an error for .");
308 }
309 }
310
311 @Test
312 public void testDeleteTaxonNameWithHybridRelations() {
313 final String[] tableNames = new String[]{"TaxonName","NameRelationship","HybridRelationship"};
314
315 TaxonName name1 = TaxonNameFactory.NewBotanicalInstance(getSpeciesRank());
316 name1.setTitleCache("Name1", true);
317 TaxonName parent = TaxonNameFactory.NewBotanicalInstance(getSpeciesRank());
318 parent.setTitleCache("parent", true);
319 TaxonName child = TaxonNameFactory.NewBotanicalInstance(getSpeciesRank());
320 child.setTitleCache("child", true);
321
322 TaxonName hybrid = TaxonNameFactory.PARSED_BOTANICAL("Abies alba x Pinus beta");
323
324 Set<HybridRelationship> childRelations = hybrid.getHybridChildRelations();
325 for (HybridRelationship rel : childRelations){
326 nameService.save(rel.getHybridName());
327 nameService.save(rel.getParentName());
328 }
329
330 commitAndStartNewTransaction(tableNames); //otherwise first save is rolled back with following failing delete
331 HybridRelationshipType relType = (HybridRelationshipType)termService.find(HybridRelationshipType.FIRST_PARENT().getUuid());
332 name1.addHybridParent(parent, relType, null);
333 nameService.save(name1);
334 nameService.save(parent);
335 commitAndStartNewTransaction(tableNames); //otherwise first save is rolled back with following failing delete
336 Assert.assertEquals("'Parent' should be a parent in a hybrid relation.", 1,parent.getHybridParentRelations().size());
337
338 //parent
339
340 name1 = nameService.find(name1.getUuid());
341 DeleteResult result = nameService.delete(name1);
342 if (result.isError()){
343 Assert.fail("Delete should throw NO exception when deleting a hybrid child: " + result.getExceptions().iterator().next().getMessage());
344 }
345 commitAndStartNewTransaction(tableNames);
346 name1 = nameService.find(name1.getUuid());
347 Assert.assertNull("Name should not be in database anymore",name1);
348 parent = nameService.find(parent.getUuid());
349 Assert.assertEquals("'Parent' should not be a parent anymore.", 0,parent.getHybridParentRelations().size());
350
351 //child
352 name1 = TaxonNameFactory.NewBotanicalInstance(getSpeciesRank());
353 name1.addHybridChild(child, relType, null);
354 nameService.save(name1);
355 nameService.save(child);
356 commitAndStartNewTransaction(tableNames);
357
358
359 result = nameService.delete(name1);
360 if (result.isOk()){
361 Assert.fail("Delete should throw an error as long as hybrid child exist.");
362 }
363 name1 = nameService.find(name1.getUuid());
364 Assert.assertNotNull("Name should still be in database",name1);
365 name1.removeHybridChild(child);
366
367 result = nameService.delete(name1); //should throw now exception
368 if (result.isError()){
369 Assert.fail("Delete should throw NO exception when deleting a hybrid child: " +result.getExceptions().iterator().next().getMessage());
370 }
371
372 commitAndStartNewTransaction(tableNames);
373 name1 = nameService.find(name1.getUuid());
374 Assert.assertNull("Name should not be in database anymore",name1);
375 }
376
377 @Test
378 @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class)
379 public void testDeleteTaxonNameInConcept() {
380 final String[] tableNames = new String[]{"TaxonName","TaxonBase"};
381
382 TaxonName name1 = TaxonNameFactory.NewBotanicalInstance(getSpeciesRank());
383 name1.setTitleCache("Name1", true);
384 TaxonName basionym = TaxonNameFactory.NewBotanicalInstance(getSpeciesRank());
385 basionym.setTitleCache("basionym", true);
386
387 Taxon taxon = Taxon.NewInstance(name1, null);
388 nameService.save(name1);
389 taxonService.save(taxon);
390 commitAndStartNewTransaction(tableNames);
391
392 DeleteResult result = nameService.delete(name1);
393
394 if (result.isOk()){
395 Assert.fail("Delete should throw an error as long as name is used in a concept.");
396 }
397 TaxonName nameBase =nameService.find(name1.getUuid());
398 Assert.assertNotNull("Name should still be in database",nameBase);
399 TaxonBase<?> taxonBase = taxonService.find(taxon.getUuid());
400 Assert.assertNotNull("Taxon should still be in database",taxonBase);
401 taxon = (Taxon)taxonBase;
402 taxon.setName(basionym);
403 taxonService.save(taxon);
404 nameBase =nameService.find(name1.getUuid());
405
406
407 result = nameService.delete(nameBase); //should throw no exception
408 if (result.isError()){
409 Assert.fail("Delete should throw NO error ");
410 }
411 commitAndStartNewTransaction(tableNames);
412 name1 = nameService.find(name1.getUuid());
413 Assert.assertNull("Name should still be in database",name1);
414 taxon = (Taxon)taxonService.find(taxon.getUuid());
415 Assert.assertNotNull("Taxon should still be in database",taxon);
416 }
417
418 @Test
419 @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class)
420 public void testDeleteTaxonNameAsStoredUnder() {
421 final String[] tableNames = new String[]{"TaxonName","SpecimenOrObservationBase"};
422
423 TaxonName name1 = TaxonNameFactory.NewBotanicalInstance(getSpeciesRank());
424 name1.setTitleCache("Name1", true);
425 DerivedUnit specimen = DerivedUnit.NewPreservedSpecimenInstance();
426 specimen.setStoredUnder(name1);
427
428 occurrenceService.save(specimen);
429 UUID uuidName1 = nameService.save(name1).getUuid();
430
431 commitAndStartNewTransaction(tableNames);
432 DeleteResult result = nameService.delete(name1);
433 if (result.isOk()){
434 Assert.fail("This should throw an error because name is used for specimen#storedUnder.");
435 }
436 commitAndStartNewTransaction(tableNames);
437
438 name1 = nameService.find(uuidName1);
439 Assert.assertNotNull("Name should still be in database",name1);
440 specimen = (DerivedUnit)occurrenceService.find(specimen.getUuid());
441 Assert.assertNotNull("Specimen should still be in database",name1);
442 specimen.setStoredUnder(null);
443 occurrenceService.saveOrUpdate(specimen);
444
445 nameService.delete(name1); //should throw no exception
446 commitAndStartNewTransaction(tableNames);
447
448 name1 = nameService.find(uuidName1);
449 Assert.assertNull("Name should not be in database anymore",name1);
450 specimen = (DerivedUnit)occurrenceService.find(specimen.getUuid());
451 Assert.assertNotNull("Specimen should still be in database",specimen);
452
453 occurrenceService.delete(specimen); //this is to better run this test in the test suit
454
455 }
456
457 @Test
458 @Ignore //currently does not run in suite
459 public void testDeleteTaxonNameInSource() {
460 final String[] tableNames = new String[]{"TaxonName","DescriptionBase","TaxonBase","OriginalSourceBase","DescriptionElementBase"};
461
462 TaxonName name1 = TaxonNameFactory.NewBotanicalInstance(getSpeciesRank());
463 name1.setTitleCache("Name1", true);
464 TaxonName taxonName = TaxonNameFactory.NewBotanicalInstance(getSpeciesRank());
465 taxonName.setTitleCache("taxonName", true);
466 Taxon taxon = Taxon.NewInstance(taxonName, null);
467
468 TaxonDescription taxonDescription = TaxonDescription.NewInstance(taxon);
469 Feature feature = (Feature)termService.find(Feature.DESCRIPTION().getUuid());
470 Language lang = (Language)termService.find(Language.DEFAULT().getUuid());
471 TextData textData = TextData.NewInstance("Any text", lang, null);
472 textData.setFeature(feature);
473 taxonDescription.addElement(textData);
474 DescriptionElementSource source = DescriptionElementSource.NewPrimarySourceInstance(null, null, name1, "");
475 textData.addSource(source);
476 taxonService.saveOrUpdate(taxon);
477 nameService.save(name1);
478 try {
479 commitAndStartNewTransaction(tableNames);
480 name1 = nameService.find(name1.getUuid());
481 nameService.delete(name1);
482 Assert.fail("Delete should throw an error as long as name is used in a source.");
483 } catch (Exception e) {
484 if (e.getMessage().contains("Name can't be deleted as it is used as descriptionElementSource#nameUsedInSource")){
485 //ok
486 endTransaction(); //exception rolls back transaction!
487 startNewTransaction();
488 }else{
489 Assert.fail("Unexpected error occurred when trying to delete taxon name: " + e.getMessage());
490 }
491 }
492 name1 = nameService.find(name1.getUuid());
493 Assert.assertNotNull("Name should still be in database",name1);
494 taxon = (Taxon)taxonService.find(taxon.getUuid());
495 Assert.assertNotNull("Taxon should still be in database",name1);
496 source = taxon.getDescriptions().iterator().next().getElements().iterator().next().getSources().iterator().next();
497 source.setNameUsedInSource(null);
498 taxonService.saveOrUpdate(taxon);
499
500 nameService.delete(name1); //should throw now exception
501
502 commitAndStartNewTransaction(tableNames);
503 name1 = nameService.find(name1.getUuid());
504 Assert.assertNull("Name should not be in database anymore",name1);
505 taxon = (Taxon)taxonService.find(taxon.getUuid());
506 Assert.assertNotNull("Taxon should still be in database",taxon);
507 source = taxon.getDescriptions().iterator().next().getElements().iterator().next().getSources().iterator().next();
508 Assert.assertNull("Source should not have a nameUsedInSource anymore",source.getNameUsedInSource());
509 }
510
511
512 @Test
513 public void testDeleteTaxonNameAsType() {
514 final String[] tableNames = new String[]{"TaxonName","TypeDesignationBase","TaxonName_TypeDesignationBase"};
515
516 TaxonName name1 = TaxonNameFactory.NewBotanicalInstance(getSpeciesRank());
517 name1.setTitleCache("Name used as type", true);
518
519 TaxonName higherName = TaxonNameFactory.NewBotanicalInstance(getGenusRank());
520 higherName.setTitleCache("genus name", true);
521 NameTypeDesignationStatus typeStatus = (NameTypeDesignationStatus)termService.find(NameTypeDesignationStatus.AUTOMATIC().getUuid());
522 boolean addToAllHomotypicNames = true;
523 higherName.addNameTypeDesignation(name1, null, null, null, typeStatus, addToAllHomotypicNames);
524 nameService.save(higherName);
525
526 commitAndStartNewTransaction(tableNames);
527 name1 = nameService.find(name1.getUuid());
528 DeleteResult result = nameService.delete(name1);
529 if (result.isOk()){
530 Assert.fail("This should throw an error because name is used in a type designation.");
531 }
532
533 commitAndStartNewTransaction(tableNames);
534 name1 = nameService.find(name1.getUuid());
535 Assert.assertNotNull("Name should still be in database",name1);
536 higherName = nameService.find(higherName.getUuid());
537 higherName.getNameTypeDesignations().iterator().next().removeType(); //keeps the designation but removes the name from it
538 // nameService.deleteTypeDesignation(higherName,commitAndStartNewTransaction(tableNames) ); //deletes the complete designation //both options can be used
539
540 nameService.delete(name1); //should throw now exception
541
542 commitAndStartNewTransaction(tableNames);
543 name1 = nameService.find(name1.getUuid());
544 Assert.assertNull("Name should not be in database anymore",name1);
545 higherName = nameService.find(higherName.getUuid());
546 Assert.assertNotNull("Higher name should still exist in database",higherName);
547 Assert.assertEquals("Higher name should not have type designations anymore",1, higherName.getTypeDesignations().size());
548 }
549
550
551 @Test
552 public void testDeleteTaxonName() {
553 final String[] tableNames = new String[]{"TaxonName","NameRelationship","HybridRelationship","DescriptionBase","NomenclaturalStatus","TaxonBase","SpecimenOrObservationBase","OriginalSourceBase","DescriptionElementBase","TypeDesignationBase","TaxonName_TypeDesignationBase"};
554
555 TaxonName name1 = TaxonNameFactory.NewBotanicalInstance(getSpeciesRank());
556 name1.setTitleCache("Name1", true);
557
558 //TaxonNameDescription
559 name1 = TaxonNameFactory.NewBotanicalInstance(getSpeciesRank());
560 TaxonNameDescription.NewInstance(name1);
561 nameService.saveOrUpdate(name1);
562 commitAndStartNewTransaction(tableNames);
563
564 name1 = nameService.find(name1.getUuid());
565 DeleteResult result = nameService.delete(name1);//should throw now exception
566
567 setComplete();
568 endTransaction();
569 name1 = nameService.find(name1.getUuid());
570 Assert.assertNull("Name should not be in database anymore",name1);
571
572 // printDataSet(System.out, tableNames);
573
574
575 //NomenclaturalStatus
576 name1 = TaxonNameFactory.NewBotanicalInstance(getSpeciesRank());
577 NomenclaturalStatusType nomStatusType = (NomenclaturalStatusType)termService.find(NomenclaturalStatusType.ILLEGITIMATE().getUuid());
578 NomenclaturalStatus status = NomenclaturalStatus.NewInstance(nomStatusType);
579 name1.addStatus(status);
580 nameService.saveOrUpdate(name1);
581 commitAndStartNewTransaction(tableNames);
582
583 name1 = nameService.find(name1.getUuid());
584
585 nameService.delete(name1); //should throw now exception
586 if (!result.isOk()){
587 Assert.fail();
588 }
589 setComplete();
590 endTransaction();
591 // printDataSet(System.out, tableNames);
592
593
594 //Type Designations
595 name1 = TaxonNameFactory.NewBotanicalInstance(getSpeciesRank());
596 name1.setTitleCache("Name with type designation", true);
597 SpecimenTypeDesignation typeDesignation = SpecimenTypeDesignation.NewInstance();
598 SpecimenTypeDesignationStatus typeStatus = (SpecimenTypeDesignationStatus)termService.find(SpecimenTypeDesignationStatus.HOLOTYPE().getUuid());
599 typeDesignation.setTypeStatus(typeStatus);
600 DerivedUnit specimen = DerivedUnit.NewPreservedSpecimenInstance();
601 specimen.setTitleCache("Type specimen", true);
602 occurrenceService.save(specimen);
603 typeDesignation.setTypeSpecimen(specimen);
604
605 name1.addTypeDesignation(typeDesignation, true);
606 nameService.save(name1);
607 commitAndStartNewTransaction(tableNames);
608 // printDataSet(System.out, tableNames);
609
610 name1 = nameService.find(name1.getUuid());
611
612 result = nameService.delete(name1); //should throw now exception
613 if (!result.isOk()){
614 Assert.fail();
615 }
616 setComplete();
617 endTransaction();
618 // printDataSet(System.out, tableNames);
619
620 }
621
622 @Test
623 public void testDeleteTaxonNameWithTypeInHomotypicalGroup() {
624 final String[] tableNames = new String[]{"TaxonName","NameRelationship","HybridRelationship","DescriptionBase","NomenclaturalStatus","TaxonBase","SpecimenOrObservationBase","OriginalSourceBase","DescriptionElementBase","TypeDesignationBase","TaxonName_TypeDesignationBase"};
625
626 //Type Designations for homotypical group with > 1 names
627 TaxonName name1 = TaxonNameFactory.NewBotanicalInstance(getSpeciesRank());
628 name1.setTitleCache("Name1 with type designation", true);
629 TaxonName name2 = TaxonNameFactory.NewBotanicalInstance(getSpeciesRank());
630 name2.setTitleCache("Name2 with type designation", true);
631 name2.setHomotypicalGroup(name1.getHomotypicalGroup());
632
633 DerivedUnit specimen = DerivedUnit.NewPreservedSpecimenInstance();
634 specimen.setTitleCache("Type specimen 2", true);
635 occurrenceService.save(specimen);
636 SpecimenTypeDesignationStatus typeStatus = (SpecimenTypeDesignationStatus)termService.find(SpecimenTypeDesignationStatus.HOLOTYPE().getUuid());
637
638 SpecimenTypeDesignation typeDesignation = SpecimenTypeDesignation.NewInstance();
639 typeDesignation.setTypeStatus(typeStatus);
640 typeDesignation.setTypeSpecimen(specimen);
641
642 boolean addToAllNames = true;
643 name1.addTypeDesignation(typeDesignation, addToAllNames);
644 nameService.saveOrUpdate(name1);
645 commitAndStartNewTransaction(tableNames);
646
647 name1 = nameService.find(name1.getUuid());
648
649 nameService.delete(name1); //should throw now exception
650
651 setComplete();
652 endTransaction();
653 }
654
655 @Test
656 @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class)
657 public void testDeleteTypeDesignation() {
658
659 // final String[] tableNames = new String[]{
660 // "TaxonName","TypeDesignationBase","TaxonName_TypeDesignationBase",
661 // "SpecimenOrObservationBase"};
662
663 TaxonName name1 = this.nameService.load(UUID.fromString("6dbd41d1-fe13-4d9c-bb58-31f051c2c384"));
664 TaxonName name2 = this.nameService.load(UUID.fromString("f9e9c13f-5fa5-48d3-88cf-712c921a099e"));
665 TaxonName name3 = this.nameService.load(UUID.fromString("e1e66264-f16a-4df9-80fd-6ab5028a3c28"));
666 DerivedUnit specimen1 = CdmBase.deproxy(this.occurrenceService.load(UUID.fromString("0d19a9ca-21a7-4adb-8640-8d6719e15eea")), DerivedUnit.class);
667 DerivedUnit fossil = CdmBase.deproxy(this.occurrenceService.load(UUID.fromString("4c48b7c8-4c8d-4e48-b083-0837fe51a0a9")), DerivedUnit.class);
668
669 @SuppressWarnings("rawtypes")
670 Set<TypeDesignationBase> desigs1 = name1.getTypeDesignations();
671 @SuppressWarnings("rawtypes")
672 Set<TypeDesignationBase> desigs2 = name2.getTypeDesignations();
673 @SuppressWarnings("rawtypes")
674 Set<TypeDesignationBase> desigs3 = name3.getTypeDesignations();
675
676 Assert.assertEquals("name1 should have 2 type designations", 2, desigs1.size());
677 Assert.assertEquals("name2 should have 1 type designations", 1, desigs2.size());
678 Assert.assertEquals("name3 should have 1 type designations", 1, desigs3.size());
679 Assert.assertEquals("Specimen1 should be used in 1 type designation", 1, specimen1.getSpecimenTypeDesignations().size());
680 Assert.assertEquals("Fossil should be used in 1 type designation", 1, fossil.getSpecimenTypeDesignations().size());
681
682 nameService.deleteTypeDesignation((TaxonName)null, null);
683
684 commitAndStartNewTransaction(/*tableNames*/);
685
686 name1 = this.nameService.load(UUID.fromString("6dbd41d1-fe13-4d9c-bb58-31f051c2c384"));
687 name2 = this.nameService.load(UUID.fromString("f9e9c13f-5fa5-48d3-88cf-712c921a099e"));
688 name3 = this.nameService.load(UUID.fromString("e1e66264-f16a-4df9-80fd-6ab5028a3c28"));
689 specimen1 = CdmBase.deproxy(this.occurrenceService.load(UUID.fromString("0d19a9ca-21a7-4adb-8640-8d6719e15eea")), DerivedUnit.class);
690 fossil = CdmBase.deproxy(this.occurrenceService.load(UUID.fromString("4c48b7c8-4c8d-4e48-b083-0837fe51a0a9")), DerivedUnit.class);
691
692 desigs1 = name1.getTypeDesignations();
693 desigs2 = name2.getTypeDesignations();
694 desigs3 = name3.getTypeDesignations();
695 //nothing should be deleted
696 Assert.assertEquals("name1 should have 2 type designations", 2, desigs1.size());
697 Assert.assertEquals("name2 should have 1 type designations", 1, desigs2.size());
698 Assert.assertEquals("name3 should have 1 type designations", 1, desigs3.size());
699 Assert.assertEquals("Specimen1 should be used in 1 type designation", 1, specimen1.getSpecimenTypeDesignations().size());
700 Assert.assertEquals("Fossil should be used in 1 type designation", 1, fossil.getSpecimenTypeDesignations().size());
701
702 nameService.deleteTypeDesignation(name1, null);
703
704 commitAndStartNewTransaction(/*tableNames*/);
705
706 name1 = this.nameService.load(UUID.fromString("6dbd41d1-fe13-4d9c-bb58-31f051c2c384"));
707 name2 = this.nameService.load(UUID.fromString("f9e9c13f-5fa5-48d3-88cf-712c921a099e"));
708 name3 = this.nameService.load(UUID.fromString("e1e66264-f16a-4df9-80fd-6ab5028a3c28"));
709 specimen1 = CdmBase.deproxy(this.occurrenceService.load(UUID.fromString("0d19a9ca-21a7-4adb-8640-8d6719e15eea")), DerivedUnit.class);
710 fossil = CdmBase.deproxy(this.occurrenceService.load(UUID.fromString("4c48b7c8-4c8d-4e48-b083-0837fe51a0a9")), DerivedUnit.class);
711
712 desigs1 = name1.getTypeDesignations();
713 desigs2 = name2.getTypeDesignations();
714 desigs3 = name3.getTypeDesignations();
715 //only the types of name1 should be deleted
716 Assert.assertEquals("name1 should have 0 type designations", 0, desigs1.size());
717 Assert.assertEquals("name2 should have 1 type designations", 1, desigs2.size());
718 Assert.assertEquals("name3 should have 1 type designations", 1, desigs3.size());
719 Assert.assertEquals("Specimen1 should be used in 1 type designation", 1, specimen1.getSpecimenTypeDesignations().size());
720 Assert.assertEquals("Fossil should be used in 0 type designation", 0, fossil.getSpecimenTypeDesignations().size());
721
722 SpecimenTypeDesignation desig2 = (SpecimenTypeDesignation)name2.getTypeDesignations().iterator().next();
723 nameService.deleteTypeDesignation(name2, desig2);
724
725 commitAndStartNewTransaction(/*tableNames*/);
726
727 name1 = this.nameService.load(UUID.fromString("6dbd41d1-fe13-4d9c-bb58-31f051c2c384"));
728 name2 = this.nameService.load(UUID.fromString("f9e9c13f-5fa5-48d3-88cf-712c921a099e"));
729 name3 = this.nameService.load(UUID.fromString("e1e66264-f16a-4df9-80fd-6ab5028a3c28"));
730 specimen1 = CdmBase.deproxy(this.occurrenceService.load(UUID.fromString("0d19a9ca-21a7-4adb-8640-8d6719e15eea")), DerivedUnit.class);
731 fossil = CdmBase.deproxy(this.occurrenceService.load(UUID.fromString("4c48b7c8-4c8d-4e48-b083-0837fe51a0a9")), DerivedUnit.class);
732
733 desigs1 = name1.getTypeDesignations();
734 desigs2 = name2.getTypeDesignations();
735 desigs3 = name3.getTypeDesignations();
736
737 Assert.assertEquals("name1 should have 0 type designations", 0, desigs1.size());
738 Assert.assertEquals("name2 should have 0 type designations", 0, desigs2.size());
739 Assert.assertEquals("name3 should have 1 type designations", 1, desigs3.size());
740 Assert.assertEquals("Specimen1 should be used in 0 type designation", 0, specimen1.getSpecimenTypeDesignations().size());
741 Assert.assertEquals("Fossil should be used in 0 type designation", 0, fossil.getSpecimenTypeDesignations().size());
742
743 NameTypeDesignation desig3 = (NameTypeDesignation)name3.getTypeDesignations().iterator().next();
744 name3.addTypeDesignation(SpecimenTypeDesignation.NewInstance(), false);
745 this.nameService.update(name3);
746
747 this.nameService.load(UUID.fromString("e1e66264-f16a-4df9-80fd-6ab5028a3c28"));
748 desigs3 = name3.getTypeDesignations();
749
750 commitAndStartNewTransaction(/*tableNames*/);
751 name3 = nameService.load(name3.getUuid());
752
753 Assert.assertEquals("name3 should have 2 type designations", 2, desigs3.size());
754
755 nameService.deleteTypeDesignation(name3, desig3);
756 commitAndStartNewTransaction(/*tableNames*/);
757
758 name1 = this.nameService.load(UUID.fromString("6dbd41d1-fe13-4d9c-bb58-31f051c2c384"));
759 name2 = this.nameService.load(UUID.fromString("f9e9c13f-5fa5-48d3-88cf-712c921a099e"));
760 name3 = this.nameService.load(UUID.fromString("e1e66264-f16a-4df9-80fd-6ab5028a3c28"));
761 specimen1 = CdmBase.deproxy(this.occurrenceService.load(UUID.fromString("0d19a9ca-21a7-4adb-8640-8d6719e15eea")), DerivedUnit.class);
762 fossil = CdmBase.deproxy(this.occurrenceService.load(UUID.fromString("4c48b7c8-4c8d-4e48-b083-0837fe51a0a9")), DerivedUnit.class);
763
764 desigs1 = name1.getTypeDesignations();
765 desigs2 = name2.getTypeDesignations();
766 desigs3 = name3.getTypeDesignations();
767
768 Assert.assertEquals("name1 should have 0 type designations", 0, desigs1.size());
769 Assert.assertEquals("name2 should have 0 type designations", 0, desigs2.size());
770 Assert.assertEquals("name3 should have 0 type designations", 1, desigs3.size());
771 Assert.assertEquals("Specimen1 should be used in 0 type designation", 0, specimen1.getSpecimenTypeDesignations().size());
772 Assert.assertEquals("Fossil should be used in 0 type designation", 0, fossil.getSpecimenTypeDesignations().size());
773 }
774
775 @Test
776 @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class)
777 public void testDeleteTypeDesignationWithRegistration() {
778 // final String[] tableNames = new String[]{
779 // "TaxonName","TypeDesignationBase","TaxonName_TypeDesignationBase",
780 // "SpecimenOrObservationBase"};
781
782 TaxonName name3 = this.nameService.load(UUID.fromString("e1e66264-f16a-4df9-80fd-6ab5028a3c28"));
783
784 @SuppressWarnings("rawtypes")
785 Set<TypeDesignationBase> desigs3 = name3.getTypeDesignations();
786
787 NameTypeDesignation desig3 = (NameTypeDesignation)name3.getTypeDesignations().iterator().next();
788 name3.addTypeDesignation(SpecimenTypeDesignation.NewInstance(), false);
789 this.nameService.update(name3);
790
791 name3 = this.nameService.load(UUID.fromString("e1e66264-f16a-4df9-80fd-6ab5028a3c28"));
792 desigs3 = name3.getTypeDesignations();
793
794 NameTypeDesignation desigNew = NameTypeDesignation.NewInstance();
795
796 UsernamePasswordAuthenticationToken submiterToken = new UsernamePasswordAuthenticationToken("admin","sPePhAz6");
797 setAuthentication(submiterToken);
798 Registration registration = Registration.NewInstance("abc", "abc", name3, null);
799 registration.addTypeDesignation(desigNew);
800 registrationService.saveOrUpdate(registration);
801 unsetAuthentication();
802
803 commitAndStartNewTransaction(/*tableNames*/);
804
805 name3 = nameService.load(name3.getUuid());
806
807 Set<Registration> regs = name3.getRegistrations();
808 desigs3 = name3.getTypeDesignations();
809 Assert.assertEquals("name3 should have 2 type designations", 2, desigs3.size());
810 Assert.assertEquals("name should have 1 registrations", 1, regs.size());
811 Assert.assertEquals("registration should have 1 type designations",1, regs.iterator().next().getTypeDesignations().size());
812
813 nameService.deleteTypeDesignation(name3, desig3);
814 commitAndStartNewTransaction(/*tableNames*/);
815
816 name3 = this.nameService.load(UUID.fromString("e1e66264-f16a-4df9-80fd-6ab5028a3c28"));
817
818 regs = name3.getRegistrations();
819 Assert.assertEquals("name3 should have 1 registration", 1, regs.size());
820 Assert.assertEquals("registration should have 1 type designations",1, regs.iterator().next().getTypeDesignations().size());
821
822 desigs3 = name3.getTypeDesignations();
823
824 nameService.deleteTypeDesignation(name3, desigNew);
825 commitAndStartNewTransaction(/*tableNames*/);
826 name3 = this.nameService.load(UUID.fromString("e1e66264-f16a-4df9-80fd-6ab5028a3c28"));
827 regs = name3.getRegistrations();
828 desigs3 = name3.getTypeDesignations();
829
830 Assert.assertEquals("name3 should have 1 type designations", 1, desigs3.size());
831 Assert.assertEquals("registration should have 0 type designations",0, regs.iterator().next().getTypeDesignations().size());
832 }
833
834 @Test
835 @DataSet
836 public void testDeleteTypeDesignationAllNames() {
837 // final String[] tableNames = new String[]{
838 // "TaxonName","TypeDesignationBase",
839 // "TaxonName_TypeDesignationBase","SpecimenOrObservationBase"};
840
841 TaxonName name1 = this.nameService.load(UUID.fromString("6dbd41d1-fe13-4d9c-bb58-31f051c2c384"));
842 TaxonName name2 = this.nameService.load(UUID.fromString("f9e9c13f-5fa5-48d3-88cf-712c921a099e"));
843 TaxonName name3 = this.nameService.load(UUID.fromString("e1e66264-f16a-4df9-80fd-6ab5028a3c28"));
844 DerivedUnit specimen1 = CdmBase.deproxy(this.occurrenceService.load(UUID.fromString("0d19a9ca-21a7-4adb-8640-8d6719e15eea")), DerivedUnit.class);
845 DerivedUnit fossil = CdmBase.deproxy(this.occurrenceService.load(UUID.fromString("4c48b7c8-4c8d-4e48-b083-0837fe51a0a9")), DerivedUnit.class);
846
847 @SuppressWarnings("rawtypes")
848 Set<TypeDesignationBase> desigs1 = name1.getTypeDesignations();
849 @SuppressWarnings("rawtypes")
850 Set<TypeDesignationBase> desigs2 = name2.getTypeDesignations();
851 @SuppressWarnings("rawtypes")
852 Set<TypeDesignationBase> desigs3 = name3.getTypeDesignations();
853
854 Assert.assertEquals("name1 should have 2 type designations", 2, desigs1.size());
855 Assert.assertEquals("name2 should have 1 type designations", 1, desigs2.size());
856 Assert.assertEquals("name3 should have 1 type designations", 1, desigs3.size());
857 Assert.assertEquals("Specimen1 should be used in 1 type designation", 1, specimen1.getSpecimenTypeDesignations().size());
858 Assert.assertEquals("Fossil should be used in 1 type designation", 1, fossil.getSpecimenTypeDesignations().size());
859
860 SpecimenTypeDesignation desig2 = (SpecimenTypeDesignation)name2.getTypeDesignations().iterator().next();
861
862 nameService.deleteTypeDesignation(null, desig2);
863
864 commitAndStartNewTransaction(/*tableNames*/);
865
866 name1 = this.nameService.load(UUID.fromString("6dbd41d1-fe13-4d9c-bb58-31f051c2c384"));
867 name2 = this.nameService.load(UUID.fromString("f9e9c13f-5fa5-48d3-88cf-712c921a099e"));
868 name3 = this.nameService.load(UUID.fromString("e1e66264-f16a-4df9-80fd-6ab5028a3c28"));
869 specimen1 = CdmBase.deproxy(this.occurrenceService.load(UUID.fromString("0d19a9ca-21a7-4adb-8640-8d6719e15eea")), DerivedUnit.class);
870 fossil = CdmBase.deproxy(this.occurrenceService.load(UUID.fromString("4c48b7c8-4c8d-4e48-b083-0837fe51a0a9")), DerivedUnit.class);
871
872 desigs1 = name1.getTypeDesignations();
873 desigs2 = name2.getTypeDesignations();
874 desigs3 = name3.getTypeDesignations();
875
876 Assert.assertEquals("name1 should have 1 type designations", 1, desigs1.size());
877 Assert.assertEquals("name2 should have 0 type designations", 0, desigs2.size());
878 Assert.assertEquals("name3 should have 1 type designations", 1, desigs3.size());
879 Assert.assertEquals("Specimen1 should be used in 0 type designation", 0, specimen1.getSpecimenTypeDesignations().size());
880 Assert.assertEquals("Fossil should be used in 1 type designation", 1, fossil.getSpecimenTypeDesignations().size());
881 }
882
883 @Test
884 @DataSet
885 public void findByTitleWithRestrictions(){
886
887 // The following typeDesignations per name are assumed:
888 // Name1 -> SpecimenTypeDesignation -> Specimen1
889 // -> SpecimenTypeDesignation -> Specimen2
890 // Name2 -> SpecimenTypeDesignation -> Specimen2
891
892 // LogUtils.setLevel("org.hibernate.SQL", Level.TRACE);
893
894
895 List<Restriction<?>> restrictions;
896 Pager<TaxonName> result;
897
898 result = nameService.findByTitleWithRestrictions(null, "Name1", MatchMode.EXACT, null, null, null, null, null);
899 assertEquals(1l, result.getCount().longValue());
900 assertEquals("Name1", result.getRecords().iterator().next().getTitleCache());
901
902 result = nameService.findByTitleWithRestrictions(null, "Name", MatchMode.BEGINNING, null, null, null, null, null);
903 assertEquals(3l, result.getCount().longValue());
904
905 restrictions = Arrays.asList(new Restriction<UUID>("typeDesignations.uuid", null, UUID.fromString("9bbda70b-7272-4e65-a807-852a3f2eba63")));
906 result = nameService.findByTitleWithRestrictions(null, "Name", MatchMode.BEGINNING, restrictions, null, null, null, null);
907 assertEquals(1l, result.getCount().longValue());
908 assertEquals("Name1", result.getRecords().iterator().next().getTitleCache());
909
910 result = nameService.findByTitleWithRestrictions(null, "me1", MatchMode.END, restrictions, null, null, null, null);
911 assertEquals(1l, result.getCount().longValue());
912 assertEquals("Name1", result.getRecords().iterator().next().getTitleCache());
913
914 result = nameService.findByTitleWithRestrictions(null, "Name2", MatchMode.EXACT, restrictions, null, null, null, null);
915 assertEquals(0l, result.getCount().longValue());
916
917 // LogUtils.setLevel("eu.etaxonomy.cdm.persistence.dao.hibernate.common", Level.DEBUG);
918
919 restrictions = Arrays.asList(new Restriction<String>("typeDesignations.typeSpecimen.titleCache", MatchMode.EXACT, "Specimen2"));
920 result = nameService.findByTitleWithRestrictions(null, "Name2", MatchMode.EXACT, restrictions, null, null, null, null);
921 assertEquals(1l, result.getCount().longValue());
922 assertEquals("Name2", result.getRecords().iterator().next().getTitleCache());
923
924 restrictions = Arrays.asList(new Restriction<String>("typeDesignations.typeSpecimen.titleCache", MatchMode.EXACT, "Specimen1"));
925 result = nameService.findByTitleWithRestrictions(null, "Name2", MatchMode.EXACT, restrictions, null, null, null, null);
926 assertEquals(0l, result.getCount().longValue());
927
928 restrictions = Arrays.asList(new Restriction<String>("typeDesignations.typeSpecimen.titleCache", Restriction.Operator.OR, MatchMode.EXACT, "Specimen1"));
929 result = nameService.findByTitleWithRestrictions(null, "Name2", MatchMode.EXACT, restrictions, null, null, null, null);
930 assertEquals(2l, result.getCount().longValue());
931
932 restrictions = Arrays.asList(new Restriction<String>("typeDesignations.typeSpecimen.titleCache", MatchMode.BEGINNING, "Specimen"));
933 result = nameService.findByTitleWithRestrictions(null, "Name1", MatchMode.EXACT, restrictions, null, null, null, null);
934 assertEquals("names with multiple matching typeSpecimens must be deduplicated", 1l, result.getCount().longValue());
935 assertEquals("Name1", result.getRecords().iterator().next().getTitleCache());
936
937 restrictions = Arrays.asList(new Restriction<String>("typeDesignations.typeSpecimen.titleCache", MatchMode.BEGINNING, "Specimen"));
938 result = nameService.findByTitleWithRestrictions(null, "Name", MatchMode.BEGINNING, restrictions, null, null, null, null);
939 assertEquals(2l, result.getCount().longValue());
940 }
941
942 @Test
943 @DataSet
944 public void testFindByTitleTitleWithRestrictionsMultiValue(){
945
946 // The following typedesigbnations per name are assumed:
947 // Name1 -> SpecimenTypeDesignation -> Specimen1
948 // -> SpecimenTypeDesignation -> Specimen2
949 // Name2 -> SpecimenTypeDesignation -> Specimen2
950 // Name3 -> NameTypeDesignaton-> typeName = Name1
951
952 List<Restriction<?>> restrictions;
953 Pager<TaxonName> result;
954
955 restrictions = Arrays.asList(new Restriction<UUID>("typeDesignations.uuid", null, UUID.fromString("9bbda70b-7272-4e65-a807-852a3f2eba63"), UUID.fromString("1357c307-00c3-499c-8e20-0849d4706125")));
956 result = nameService.findByTitleWithRestrictions(null, "Name", MatchMode.BEGINNING, restrictions, null, null, null, null);
957 assertEquals(2l, result.getCount().longValue());
958
959 restrictions = Arrays.asList(new Restriction<String>("typeDesignations.typeSpecimen.titleCache", null, "Specimen1", "Specimen2"));
960 result = nameService.findByTitleWithRestrictions(null, "Name1", MatchMode.EXACT, restrictions, null, null, null, null);
961 assertEquals("names with multiple matching typeSpecimens must be distinct", 1l, result.getCount().longValue());
962 assertEquals("Name1", result.getRecords().iterator().next().getTitleCache());
963 }
964
965 @Test
966 @DataSet
967 public void testFindByTitleTitleWithRestrictionsLogicalOperators(){
968
969 // The following typedesigbnations per name are assumed:
970 // Name1 -> SpecimenTypeDesignation -> Specimen1
971 // -> SpecimenTypeDesignation -> Specimen2
972 // Name2 -> SpecimenTypeDesignation -> Specimen2
973 // Name3 -> NameTypeDesignaton-> typeName = Name1
974
975 List<Restriction<?>> restrictions;
976 Pager<TaxonName> result;
977
978 // LogUtils.setLevel("org.hibernate.SQL", Level.TRACE);
979
980
981 restrictions = Arrays.asList(new Restriction<String>("typeDesignations.typeName.titleCache", Operator.AND, null, "Name1"));
982 result = nameService.findByTitleWithRestrictions(null, "Name3", MatchMode.EXACT, restrictions, null, null, null, null);
983 assertEquals(1l, result.getCount().longValue());
984
985 restrictions = Arrays.asList(new Restriction<String>("typeDesignations.typeName.titleCache", Operator.AND_NOT, null, "Name1"));
986 result = nameService.findByTitleWithRestrictions(null, "Name", MatchMode.BEGINNING, restrictions, null, null, null, null);
987 assertEquals(2l, result.getCount().longValue());
988
989 restrictions = Arrays.asList(new Restriction<String>("titleCache", Operator.AND_NOT, null, "Name1", "Name2"));
990 result = nameService.findByTitleWithRestrictions(null, "Name", MatchMode.BEGINNING, restrictions, null, null, null, null);
991 assertEquals(1l, result.getCount().longValue());
992 assertEquals("Name3", result.getRecords().get(0).getTitleCache());
993
994 restrictions = Arrays.asList(new Restriction<String>("typeDesignations.typeName.titleCache", Operator.OR, null, "Name1"));
995 result = nameService.findByTitleWithRestrictions(null, "Name1", MatchMode.EXACT, restrictions, null, null, null, null);
996 assertEquals(2l, result.getCount().longValue());
997
998 restrictions = Arrays.asList(new Restriction<String>("typeDesignations.typeName.titleCache", Operator.OR_NOT, null, "Name1"));
999 result = nameService.findByTitleWithRestrictions(null, "Name1", MatchMode.EXACT, restrictions, null, null, null, null);
1000 assertEquals(2l, result.getCount().longValue());
1001 }
1002
1003 @Test
1004 @DataSet
1005 public void testFindByTitleTitle_using_Configurator(){
1006
1007 String searchString = "*";
1008 IdentifiableServiceConfiguratorImpl<TaxonName> searchConfigurator = new IdentifiableServiceConfiguratorImpl<TaxonName>();
1009
1010 searchConfigurator = IdentifiableServiceConfiguratorFactory.getConfigurator(TaxonName.class);
1011 searchConfigurator.setTitleSearchString(searchString);
1012 searchConfigurator.setMatchMode(null);
1013 searchConfigurator.setOrderHints(OrderHint.ORDER_BY_TITLE_CACHE.asList());
1014
1015 Pager<TaxonName> results = nameService.findByTitle(searchConfigurator);
1016 assertTrue(results.getRecords().size() > 0);
1017 }
1018
1019 @Test //7874 //8030
1020 @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="NameServiceImplTest.testUpdateCaches.xml")
1021 public void testUpdateCaches() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException{
1022
1023 Field titleCacheField = IdentifiableEntity.class.getDeclaredField("titleCache");
1024 titleCacheField.setAccessible(true);
1025 Field nameCacheField = TaxonName.class.getDeclaredField("nameCache");
1026 nameCacheField.setAccessible(true);
1027 Field authorCacheField = TaxonName.class.getDeclaredField("authorshipCache");
1028 authorCacheField.setAccessible(true);
1029 Field fullTitleCacheField = TaxonName.class.getDeclaredField("fullTitleCache");
1030 fullTitleCacheField.setAccessible(true);
1031
1032 TaxonName name1 = nameService.loadWithoutInitializing(NAME1_ID);
1033 TaxonName name2 = nameService.loadWithoutInitializing(NAME2_ID);
1034 TaxonName name3 = nameService.loadWithoutInitializing(NAME3_ID);
1035
1036 name1 = CdmBase.deproxy(name1);
1037 assertEquals("TitleCache should be the persisted one", "Name1", titleCacheField.get(name1));
1038 assertEquals("NameCache should be the persisted one", "", nameCacheField.get(name1));
1039 assertEquals("AuthorCache should be the persisted one", "", authorCacheField.get(name1));
1040 assertEquals("FullTitleCache should be the persisted one", "", fullTitleCacheField.get(name1));
1041
1042 name2 = CdmBase.deproxy(name2);
1043 assertEquals("TitleCache should be the persisted one", "Name2", titleCacheField.get(name2));
1044 assertEquals("NameCache should be the persisted one", "Protected name", nameCacheField.get(name2));
1045 assertEquals("AuthorCache should be the persisted one", null, authorCacheField.get(name2));
1046 assertEquals("FullTitleCache should be the persisted one", "", fullTitleCacheField.get(name2));
1047
1048 name3 = CdmBase.deproxy(name3);
1049 assertEquals("TitleCache should be the persisted one", "Name3", titleCacheField.get(name3));
1050 assertEquals("NameCache should be the persisted one", "", nameCacheField.get(name3));
1051 assertEquals("AuthorCache should be the persisted one", "No-author", authorCacheField.get(name3));
1052 assertEquals("FullTitleCache should be the persisted one", "", fullTitleCacheField.get(name3));
1053
1054 nameService.updateCaches();
1055
1056 assertEquals("Expecting titleCache to be updated", "First name Turl.", titleCacheField.get(name1));
1057 assertEquals("Expecting nameCache to be updated", "First name", nameCacheField.get(name1));
1058 assertEquals("Expecting authorshipCache to be updated", "Turl.", authorCacheField.get(name1));
1059 assertEquals("Expecting fullTitleCache to be updated", "First name Turl.", fullTitleCacheField.get(name1));
1060
1061 assertEquals("Expecting titleCache to be updated", "Protected name", titleCacheField.get(name2));
1062 assertEquals("Expecting nameCache to not be updated", "Protected name", nameCacheField.get(name2));
1063 assertEquals("Expecting authorshipCache to be updated", "", authorCacheField.get(name2));
1064 assertEquals("Expecting fullTitleCache to be updated", "Protected name", fullTitleCacheField.get(name2));
1065
1066 assertEquals("Expecting titleCache to be updated", "Name3", titleCacheField.get(name3));
1067 assertEquals("Expecting nameCache to be updated", "Third", nameCacheField.get(name3));
1068 assertEquals("Expecting authorshipCache to be updated", "No-author", authorCacheField.get(name3));
1069 assertEquals("Expecting fullTitleCache to be updated", "Name3", fullTitleCacheField.get(name3));
1070 }
1071
1072 @Test //#3666 and others
1073 @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="NameServiceImplTest.xml")
1074 public void testParseName() {
1075 Assert.assertEquals(3, nameService.count(TaxonName.class));
1076 String nameToParseStr = "Abies alba Mill, Sp. Pl. 2: 333. 1751 [as \"alpa\"]";
1077 TaxonName parsedName = (TaxonName)nameService.parseName(nameToParseStr, NomenclaturalCode.ICNAFP, Rank.SPECIES(), true).getCdmEntity();
1078 UUID parsedNameUuid = parsedName.getUuid();
1079 UUID originalSpellingUuid = parsedName.getOriginalSpelling().getUuid();
1080 nameService.save(parsedName);
1081
1082 TaxonName parsedName2 = (TaxonName)nameService.parseName(nameToParseStr, NomenclaturalCode.ICNAFP, Rank.SPECIES(), true).getCdmEntity();
1083 UUID parsedNameUuid2 = parsedName2.getUuid();
1084 UUID originalSpelling2Uuid = parsedName2.getOriginalSpelling().getUuid();
1085 Assert.assertEquals(originalSpellingUuid, originalSpelling2Uuid);
1086 Assert.assertNotEquals(parsedNameUuid, parsedNameUuid2); //currently we do not deduplicate the main name yet
1087
1088 //tbc
1089 }
1090
1091 private Rank getSpeciesRank() {
1092 return (Rank)termService.find(Rank.uuidSpecies);
1093 }
1094
1095 private Rank getGenusRank() {
1096 return (Rank)termService.find(Rank.uuidGenus);
1097 }
1098
1099 @Override
1100 public void createTestDataSet() throws FileNotFoundException {}
1101
1102
1103 @Test
1104 @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="NameServiceImplTest.testFindMatchingNames.xml")
1105 public void testFindingMatchingNames () {
1106
1107 List<DoubleResult<TaxonNameParts, Integer>> matchResult = nameService.findMatchingNames("Gynxya asrerotciha", 0, 0, 10);
1108 Assert.assertEquals(1, matchResult.size());
1109
1110 matchResult = nameService.findMatchingNames("Gynxya asrerotciha", 1, 0, 10);
1111 Assert.assertEquals(2, matchResult.size());
1112
1113 DoubleResult<TaxonNameParts, Integer> gynxyaAsrerotciha = matchResult.get(0);
1114 Assert.assertNotNull(gynxyaAsrerotciha);
1115 Assert.assertEquals(10, (int)gynxyaAsrerotciha.getFirstResult().getTaxonNameId());
1116 Assert.assertEquals("Gynxya", matchResult.get(0).getFirstResult().getGenusOrUninomial());
1117 Assert.assertEquals("asrerotciha", matchResult.get(0).getFirstResult().getSpecificEpithet());
1118 Assert.assertEquals("Distance should be 0", 0, (int)gynxyaAsrerotciha.getSecondResult());
1119
1120 DoubleResult<TaxonNameParts, Integer> gynxyasAsrerotciha = matchResult.get(1);
1121 Assert.assertNotNull(gynxyasAsrerotciha);
1122 Assert.assertEquals(12, (int)gynxyasAsrerotciha.getFirstResult().getTaxonNameId());
1123 Assert.assertEquals("Gynxyas", matchResult.get(1).getFirstResult().getGenusOrUninomial());
1124 Assert.assertEquals("asrerotciha", matchResult.get(1).getFirstResult().getSpecificEpithet());
1125 Assert.assertEquals("Distance should be 1", 1, (int)gynxyasAsrerotciha.getSecondResult());
1126 }
1127 }