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