for infrageneric unranked rank adding [unranked] (Art.37.7 Melbourne Code)
[cdmlib.git] / cdmlib-services / src / test / java / eu / etaxonomy / cdm / api / service / TaxonServiceImplTest.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
10 package eu.etaxonomy.cdm.api.service;
11
12 import static org.junit.Assert.assertEquals;
13 import static org.junit.Assert.assertNotNull;
14 import static org.junit.Assert.assertNull;
15 import static org.junit.Assert.assertTrue;
16
17 import java.io.FileNotFoundException;
18 import java.util.ArrayList;
19 import java.util.Iterator;
20 import java.util.List;
21 import java.util.Set;
22 import java.util.UUID;
23
24 import org.apache.log4j.Logger;
25 import org.junit.Assert;
26 import org.junit.Test;
27 import org.unitils.dbunit.annotation.DataSet;
28 import org.unitils.spring.annotation.SpringBeanByType;
29
30 import eu.etaxonomy.cdm.api.service.config.IncludedTaxonConfiguration;
31 import eu.etaxonomy.cdm.api.service.config.NameDeletionConfigurator;
32 import eu.etaxonomy.cdm.api.service.config.SynonymDeletionConfigurator;
33 import eu.etaxonomy.cdm.api.service.config.TaxonDeletionConfigurator;
34 import eu.etaxonomy.cdm.api.service.config.TaxonNodeDeletionConfigurator.ChildHandling;
35 import eu.etaxonomy.cdm.api.service.dto.IncludedTaxaDTO;
36 import eu.etaxonomy.cdm.api.service.exception.HomotypicalGroupChangeException;
37 import eu.etaxonomy.cdm.datagenerator.TaxonGenerator;
38 import eu.etaxonomy.cdm.model.common.CdmBase;
39 import eu.etaxonomy.cdm.model.common.Extension;
40 import eu.etaxonomy.cdm.model.common.IdentifiableSource;
41 import eu.etaxonomy.cdm.model.common.Marker;
42 import eu.etaxonomy.cdm.model.common.MarkerType;
43 import eu.etaxonomy.cdm.model.common.OriginalSourceType;
44 import eu.etaxonomy.cdm.model.common.RelationshipBase;
45 import eu.etaxonomy.cdm.model.description.DescriptionBase;
46 import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
47 import eu.etaxonomy.cdm.model.description.IndividualsAssociation;
48 import eu.etaxonomy.cdm.model.description.TaxonDescription;
49 import eu.etaxonomy.cdm.model.name.BotanicalName;
50 import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
51 import eu.etaxonomy.cdm.model.name.NameRelationship;
52 import eu.etaxonomy.cdm.model.name.NameRelationshipType;
53 import eu.etaxonomy.cdm.model.name.NonViralName;
54 import eu.etaxonomy.cdm.model.name.Rank;
55 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
56 import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
57 import eu.etaxonomy.cdm.model.occurrence.DeterminationEvent;
58 import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
59 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
60 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationType;
61 import eu.etaxonomy.cdm.model.reference.Reference;
62 import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
63 import eu.etaxonomy.cdm.model.taxon.Classification;
64 import eu.etaxonomy.cdm.model.taxon.Synonym;
65 import eu.etaxonomy.cdm.model.taxon.SynonymRelationship;
66 import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;
67 import eu.etaxonomy.cdm.model.taxon.Taxon;
68 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
69 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
70 import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
71 import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
72 import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy;
73 import eu.etaxonomy.cdm.test.integration.CdmTransactionalIntegrationTest;
74 import eu.etaxonomy.cdm.test.unitils.CleanSweepInsertLoadStrategy;
75
76 /**
77 * @author a.mueller
78 */
79
80
81 public class TaxonServiceImplTest extends CdmTransactionalIntegrationTest {
82 private static final Logger logger = Logger.getLogger(TaxonServiceImplTest.class);
83
84 @SpringBeanByType
85 private ITaxonService service;
86
87 @SpringBeanByType
88 private INameService nameService;
89
90 @SpringBeanByType
91 private IReferenceService referenceService;
92
93 @SpringBeanByType
94 private IClassificationService classificationService;
95
96 @SpringBeanByType
97 private ITaxonNodeService nodeService;
98
99 @SpringBeanByType
100 private IDescriptionService descriptionService;
101
102 @SpringBeanByType
103 private IMarkerService markerService;
104
105 @SpringBeanByType
106 private IEventBaseService eventService;
107
108 @SpringBeanByType
109 private IOccurrenceService occurenceService;
110
111 private Synonym synonym;
112 private Synonym synonym2;
113
114 private Taxon taxWithSyn;
115 private Taxon tax2WithSyn;
116 private Taxon taxWithoutSyn;
117 private UUID uuidSyn;
118 private UUID uuidTaxWithoutSyn;
119 private UUID uuidSyn2;
120 private UUID uuidTaxWithSyn;
121
122 /****************** TESTS *****************************/
123
124
125 /**
126 * Test method for {@link eu.etaxonomy.cdm.api.service.TaxonServiceImpl#getTaxonByUuid(java.util.UUID)}.
127 */
128 @Test
129 public final void testGetTaxonByUuid() {
130 Taxon expectedTaxon = Taxon.NewInstance(null, null);
131 UUID uuid = service.save(expectedTaxon);
132 TaxonBase<?> actualTaxon = service.find(uuid);
133 assertEquals(expectedTaxon, actualTaxon);
134 }
135
136 /**
137 * Test method for {@link eu.etaxonomy.cdm.api.service.TaxonServiceImpl#saveTaxon(eu.etaxonomy.cdm.model.taxon.TaxonBase)}.
138 */
139 @Test
140 public final void testSaveTaxon() {
141 Taxon expectedTaxon = Taxon.NewInstance(null, null);
142 UUID uuid = service.save(expectedTaxon);
143 TaxonBase<?> actualTaxon = service.find(uuid);
144 assertEquals(expectedTaxon, actualTaxon);
145 }
146
147 @Test
148 public final void testSaveOrUpdateTaxon() {
149 Taxon expectedTaxon = Taxon.NewInstance(null, null);
150 UUID uuid = service.save(expectedTaxon);
151 TaxonBase<?> actualTaxon = service.find(uuid);
152 assertEquals(expectedTaxon, actualTaxon);
153
154 actualTaxon.setName(BotanicalName.NewInstance(Rank.SPECIES()));
155 try{
156 service.saveOrUpdate(actualTaxon);
157 }catch(Exception e){
158 Assert.fail();
159 }
160 }
161 /**
162 * Test method for {@link eu.etaxonomy.cdm.api.service.TaxonServiceImpl#removeTaxon(eu.etaxonomy.cdm.model.taxon.TaxonBase)}.
163 */
164 @Test
165 public final void testRemoveTaxon() {
166 Taxon taxon = Taxon.NewInstance(BotanicalName.NewInstance(Rank.UNKNOWN_RANK()), null);
167 UUID uuid = service.save(taxon);
168 // try {
169 service.deleteTaxon(taxon, null, null);
170 /*} catch (DataChangeNoRollbackException e) {
171 // TODO Auto-generated catch block
172 e.printStackTrace();
173 }*/
174 TaxonBase<?> actualTaxon = service.find(uuid);
175 assertNull(actualTaxon);
176 }
177
178
179 @Test
180 public final void testMakeTaxonSynonym() {
181 try {
182 createTestDataSet();
183 } catch (FileNotFoundException e) {
184 // TODO Auto-generated catch block
185 e.printStackTrace();
186 }
187
188 service.swapSynonymAndAcceptedTaxon(synonym, taxWithSyn);
189
190 // find forces flush
191 Taxon tax = (Taxon)service.find(uuidTaxWithSyn);
192 tax.removeSynonym(synonym);
193 tax.addHomotypicSynonym(synonym, null, null);
194 service.saveOrUpdate(tax);
195 TaxonBase<?> syn = service.find(uuidSyn);
196
197 assertTrue(tax.getName().getTitleCache().equals("Test2"));
198
199 HomotypicalGroup groupTest = tax.getHomotypicGroup();
200 HomotypicalGroup groupTest2 = syn.getHomotypicGroup();
201 assertEquals(groupTest, groupTest2);
202
203 }
204
205 @Test
206 public final void testChangeSynonymToAcceptedTaxon(){
207 try {
208 createTestDataSet();
209 } catch (FileNotFoundException e1) {
210 // TODO Auto-generated catch block
211 e1.printStackTrace();
212 }
213
214
215 Taxon taxon = null;
216 try {
217 taxon = service.changeSynonymToAcceptedTaxon(synonym, taxWithSyn, true, true, null, null);
218 } catch (HomotypicalGroupChangeException e) {
219 Assert.fail("Invocation of change method should not throw an exception");
220 }
221 taxWithSyn = null;
222 //test flush (resave deleted object)
223 TaxonBase<?> syn = service.find(uuidSyn);
224 taxWithSyn = (Taxon)service.find(uuidTaxWithSyn);
225 Taxon taxNew = (Taxon)service.find(taxon.getUuid());
226 assertNull(syn);
227 assertNotNull(taxWithSyn);
228 assertNotNull(taxNew);
229
230 Assert.assertEquals("New taxon should have 1 synonym relationship (the old homotypic synonym)", 1, taxon.getSynonymRelations().size());
231 }
232
233
234
235 @Test
236 public final void testChangeSynonymToAcceptedTaxonSynonymForTwoTaxa(){
237 try {
238 createTestDataSet();
239 } catch (FileNotFoundException e1) {
240 // TODO Auto-generated catch block
241 e1.printStackTrace();
242 }
243
244
245 Taxon taxon = null;
246 try {
247 taxon = service.changeSynonymToAcceptedTaxon(synonym, taxWithSyn, true, true, null, null);
248 service.save(taxon);
249 } catch (HomotypicalGroupChangeException e) {
250 Assert.fail("Invocation of change method should not throw an exception");
251 }
252 taxWithSyn = null;
253 tax2WithSyn = null;
254
255 //test flush (resave deleted object)
256 TaxonBase<?> syn = service.find(uuidSyn);
257 taxWithSyn = (Taxon)service.find(uuidTaxWithSyn);
258 Taxon taxNew = (Taxon)service.find(taxon.getUuid());
259 assertNull(syn);
260 assertNotNull(taxWithSyn);
261 assertNotNull(taxNew);
262
263 // Assert.assertEquals("New taxon should have 1 synonym relationship (the old homotypic synonym)", 1, taxon.getSynonymRelations().size());
264 }
265
266 /**
267 * Old implementation taken from {@link TaxonServiceImplBusinessTest} for old version of method.
268 * Test method for {@link eu.etaxonomy.cdm.api.service.TaxonServiceImpl#moveSynonymToAnotherTaxon(eu.etaxonomy.cdm.model.taxon.SynonymRelationship, eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType, eu.etaxonomy.cdm.model.reference.Reference, java.lang.String)}.
269 */
270 @Test
271 public final void testMoveSynonymToAnotherTaxon_OLD() {
272 SynonymRelationshipType heteroTypicSynonymRelationshipType = SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF();
273 Reference<?> reference = ReferenceFactory.newGeneric();
274 String referenceDetail = "test";
275
276 NonViralName<?> t1n = NonViralName.NewInstance(null);
277 Taxon t1 = Taxon.NewInstance(t1n, reference);
278 NonViralName<?> t2n = NonViralName.NewInstance(null);
279 Taxon t2 = Taxon.NewInstance(t2n, reference);
280 NonViralName<?> s1n = NonViralName.NewInstance(null);
281 Synonym s1 = Synonym.NewInstance(s1n, reference);
282 t1.addSynonym(s1, heteroTypicSynonymRelationshipType);
283
284 SynonymRelationship synonymRelation = t1.getSynonymRelations().iterator().next();
285
286 boolean keepReference = false;
287 boolean moveHomotypicGroup = false;
288 try {
289 service.moveSynonymToAnotherTaxon(synonymRelation, t2, moveHomotypicGroup, heteroTypicSynonymRelationshipType, reference, referenceDetail, keepReference);
290 } catch (HomotypicalGroupChangeException e) {
291 Assert.fail("Method call should not throw exception");
292 }
293
294 Assert.assertTrue("t1 should have no synonym relationships", t1.getSynonymRelations().isEmpty());
295
296 Set<SynonymRelationship> synonymRelations = t2.getSynonymRelations();
297 Assert.assertTrue("t2 should have exactly one synonym relationship", synonymRelations.size() == 1);
298
299 synonymRelation = synonymRelations.iterator().next();
300
301 Assert.assertEquals(t2, synonymRelation.getAcceptedTaxon());
302 Assert.assertEquals(heteroTypicSynonymRelationshipType, synonymRelation.getType());
303 Assert.assertEquals(reference, synonymRelation.getCitation());
304 Assert.assertEquals(referenceDetail, synonymRelation.getCitationMicroReference());
305 }
306
307 @Test
308 @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="TaxonServiceImplTest.testMoveSynonymToAnotherTaxon.xml")
309 public final void testMoveSynonymToAnotherTaxon() throws Exception {
310 final String[] tableNames = new String[]{"SynonymRelationship"};
311
312 // printDataSet(System.err, new String[]{"AgentBase", "TaxonBase"});
313 // printDataSet(System.err, new String[]{"TaxonNode"});
314
315 UUID uuidNewTaxon = UUID.fromString("2d9a642d-5a82-442d-8fec-95efa978e8f8");
316 UUID uuidOldTaxon = UUID.fromString("c47fdb72-f32c-452e-8305-4b44f01179d0");
317 UUID uuidSyn1 = UUID.fromString("7da85381-ad9d-4886-9d4d-0eeef40e3d88");
318 UUID uuidSyn3 = UUID.fromString("3fba2b22-22ae-4291-af67-faab748a5232");
319 UUID uuidSyn4 = UUID.fromString("f9b589c7-50cf-4df2-a52e-1b85eb7e4805");
320 UUID uuidSyn5 = UUID.fromString("fcc0bcf8-8bac-43bd-9508-1e97821587dd");
321 UUID uuidSyn6 = UUID.fromString("0ccd4e7c-6fbd-4b7c-bd47-29e45b92f34b");
322 UUID uuidRef1 = UUID.fromString("336f9b38-698c-45d7-be7b-993ed3355bdc");
323 UUID uuidRef2 = UUID.fromString("c8f49d1a-69e1-48a3-98bb-45d61f3da3e7");
324
325
326 boolean moveHomotypicGroup = true;
327 SynonymRelationshipType newSynonymRelationshipType = null;
328 boolean keepReference = true;
329 Reference<?> newReference = null;
330 String newReferenceDetail = null;
331
332 Taxon newTaxon = (Taxon)service.load(uuidNewTaxon);
333 Synonym homotypicSynonym = (Synonym)service.load(uuidSyn1);
334 Assert.assertNotNull("Synonym should exist", homotypicSynonym);
335 Assert.assertEquals("Synonym should have 1 relation", 1, homotypicSynonym.getSynonymRelations().size());
336 SynonymRelationship rel = homotypicSynonym.getSynonymRelations().iterator().next();
337 Assert.assertEquals("Accepted taxon of single relation should be the old taxon", uuidOldTaxon, rel.getAcceptedTaxon().getUuid());
338 Taxon oldTaxon = rel.getAcceptedTaxon();
339
340 try {
341 service.moveSynonymToAnotherTaxon(rel, newTaxon, moveHomotypicGroup, newSynonymRelationshipType, newReference, newReferenceDetail, keepReference);
342 Assert.fail("Homotypic synonym move to other taxon should throw an exception");
343 } catch (HomotypicalGroupChangeException e) {
344 if (e.getMessage().contains("Synonym is in homotypic group with accepted taxon and other synonym(s). First remove synonym from homotypic group of accepted taxon before moving to other taxon")){
345 //OK
346 commitAndStartNewTransaction(tableNames);
347 }else{
348 Assert.fail("Unexpected exception occurred: " + e.getMessage());
349 }
350 }
351 //Asserts
352 homotypicSynonym = (Synonym)service.load(uuidSyn1);
353 Assert.assertNotNull("Synonym should still exist", homotypicSynonym);
354 Assert.assertEquals("Synonym should still have 1 relation", 1, homotypicSynonym.getSynonymRelations().size());
355 rel = homotypicSynonym.getSynonymRelations().iterator().next();
356 Assert.assertEquals("Accepted taxon of single relation should be the old taxon", oldTaxon, rel.getAcceptedTaxon());
357
358 //test heterotypic synonym with other synonym in homotypic group
359 newTaxon = (Taxon)service.load(uuidNewTaxon);
360 Synonym heterotypicSynonym = (Synonym)service.load(uuidSyn3);
361 Assert.assertNotNull("Synonym should exist", heterotypicSynonym);
362 Assert.assertEquals("Synonym should have 1 relation", 1, heterotypicSynonym.getSynonymRelations().size());
363 rel = heterotypicSynonym.getSynonymRelations().iterator().next();
364 Assert.assertEquals("Accepted taxon of single relation should be the old taxon", uuidOldTaxon, rel.getAcceptedTaxon().getUuid());
365 oldTaxon = rel.getAcceptedTaxon();
366 moveHomotypicGroup = false;
367
368 try {
369 service.moveSynonymToAnotherTaxon(rel, newTaxon, moveHomotypicGroup, newSynonymRelationshipType, newReference, newReferenceDetail, keepReference);
370 Assert.fail("Heterotypic synonym move to other taxon should throw an exception");
371 } catch (HomotypicalGroupChangeException e) {
372 if (e.getMessage().contains("Synonym is in homotypic group with other synonym(s). Either move complete homotypic group or remove synonym from homotypic group prior to moving to other taxon")){
373 //OK
374 commitAndStartNewTransaction(tableNames);
375 }else{
376 Assert.fail("Unexpected exception occurred: " + e.getMessage());
377 }
378 }
379 //Asserts
380 heterotypicSynonym = (Synonym)service.load(uuidSyn3);
381 Assert.assertNotNull("Synonym should still exist", heterotypicSynonym);
382 Assert.assertEquals("Synonym should still have 1 relation", 1, heterotypicSynonym.getSynonymRelations().size());
383 rel = heterotypicSynonym.getSynonymRelations().iterator().next();
384 Assert.assertEquals("Accepted taxon of single relation should still be the old taxon", oldTaxon, rel.getAcceptedTaxon());
385
386
387 //test heterotypic synonym with no other synonym in homotypic group
388 //+ keep reference
389
390 // printDataSet(System.err, new String[]{"TaxonBase"});
391
392 newTaxon = (Taxon)service.load(uuidNewTaxon);
393 heterotypicSynonym = (Synonym)service.load(uuidSyn5);
394 Assert.assertNotNull("Synonym should exist", heterotypicSynonym);
395 Assert.assertEquals("Synonym should have 1 relation", 1, heterotypicSynonym.getSynonymRelations().size());
396 rel = heterotypicSynonym.getSynonymRelations().iterator().next();
397 Assert.assertEquals("Accepted taxon of single relation should be the old taxon", uuidOldTaxon, rel.getAcceptedTaxon().getUuid());
398 oldTaxon = rel.getAcceptedTaxon();
399 moveHomotypicGroup = false;
400
401
402 try {
403 service.moveSynonymToAnotherTaxon(rel, newTaxon, moveHomotypicGroup, newSynonymRelationshipType, newReference, newReferenceDetail, keepReference);
404 } catch (HomotypicalGroupChangeException e) {
405 Assert.fail("Move of single heterotypic synonym should not throw exception: " + e.getMessage());
406 }
407 //Asserts
408 //FIXME throws exception
409 commitAndStartNewTransaction(tableNames);
410
411 // printDataSet(System.err, new String[]{"AgentBase", "TaxonBase"});
412 //
413 // printDataSet(System.err, new String[]{"TaxonBase"});
414
415 heterotypicSynonym = (Synonym)service.load(uuidSyn5);
416
417 // printDataSet(System.err, new String[]{"TaxonBase"});
418 // System.exit(0);
419
420 Assert.assertNotNull("Synonym should still exist", heterotypicSynonym);
421 Assert.assertEquals("Synonym should still have 1 relation", 1, heterotypicSynonym.getSynonymRelations().size());
422 rel = heterotypicSynonym.getSynonymRelations().iterator().next();
423 Assert.assertEquals("Accepted taxon of single relation should be new taxon", newTaxon, rel.getAcceptedTaxon());
424 Assert.assertEquals("Old detail should be kept", "rel5", rel.getCitationMicroReference());
425
426
427 //test heterotypic synonym with other synonym in homotypic group and moveHomotypicGroup="true"
428 //+ new detail
429 newTaxon = (Taxon)service.load(uuidNewTaxon);
430 heterotypicSynonym = (Synonym)service.load(uuidSyn3);
431 Reference<?> ref1 = referenceService.load(uuidRef1);
432 Assert.assertNotNull("Synonym should exist", heterotypicSynonym);
433 Assert.assertEquals("Synonym should have 1 relation", 1, heterotypicSynonym.getSynonymRelations().size());
434 rel = heterotypicSynonym.getSynonymRelations().iterator().next();
435 Assert.assertEquals("Accepted taxon of single relation should be the old taxon", uuidOldTaxon, rel.getAcceptedTaxon().getUuid());
436 oldTaxon = rel.getAcceptedTaxon();
437 Assert.assertEquals("Detail should be ref1", ref1, rel.getCitation());
438 Assert.assertEquals("Detail should be 'rel3'", "rel3", rel.getCitationMicroReference());
439 TaxonNameBase<?,?> oldSynName3 = heterotypicSynonym.getName();
440
441 Synonym heterotypicSynonym4 = (Synonym)service.load(uuidSyn4);
442 Assert.assertNotNull("Synonym should exist", heterotypicSynonym4);
443 Assert.assertEquals("Synonym should have 1 relation", 1, heterotypicSynonym4.getSynonymRelations().size());
444 SynonymRelationship rel4 = heterotypicSynonym4.getSynonymRelations().iterator().next();
445 Assert.assertEquals("Accepted taxon of other synonym in group should be the old taxon", uuidOldTaxon, rel4.getAcceptedTaxon().getUuid());
446 Assert.assertSame("Homotypic group of both synonyms should be same", oldSynName3.getHomotypicalGroup() , heterotypicSynonym4.getName().getHomotypicalGroup() );
447
448 moveHomotypicGroup = true;
449 keepReference = false;
450
451 try {
452 service.moveSynonymToAnotherTaxon(rel, newTaxon, moveHomotypicGroup, newSynonymRelationshipType, newReference, newReferenceDetail, keepReference);
453 } catch (HomotypicalGroupChangeException e) {
454 Assert.fail("Move with 'moveHomotypicGroup = true' should not throw exception: " + e.getMessage());
455 }
456 //Asserts
457 commitAndStartNewTransaction(tableNames);
458 heterotypicSynonym = (Synonym)service.load(uuidSyn3);
459 Assert.assertNotNull("Synonym should still exist", heterotypicSynonym);
460 Assert.assertEquals("Synonym should still have 1 relation", 1, heterotypicSynonym.getSynonymRelations().size());
461 rel = heterotypicSynonym.getSynonymRelations().iterator().next();
462 Assert.assertEquals("Accepted taxon of relation should be new taxon now", newTaxon, rel.getAcceptedTaxon());
463 TaxonNameBase<?,?> synName3 = rel.getSynonym().getName();
464
465 heterotypicSynonym = (Synonym)service.load(uuidSyn4);
466 Assert.assertNotNull("Synonym should still exist", heterotypicSynonym);
467 Assert.assertEquals("Synonym should still have 1 relation", 1, heterotypicSynonym.getSynonymRelations().size());
468 rel = heterotypicSynonym.getSynonymRelations().iterator().next();
469 Assert.assertEquals("Accepted taxon of relation should be new taxon now", newTaxon, rel.getAcceptedTaxon());
470 Assert.assertNull("Old citation should be removed", rel.getCitation());
471 Assert.assertNull("Old detail should be removed", rel.getCitationMicroReference());
472 TaxonNameBase<?,?> synName4 = rel.getSynonym().getName();
473 Assert.assertEquals("Homotypic group of both synonyms should be equal", synName3.getHomotypicalGroup() , synName4.getHomotypicalGroup() );
474 Assert.assertSame("Homotypic group of both synonyms should be same", synName3.getHomotypicalGroup() , synName4.getHomotypicalGroup() );
475 Assert.assertEquals("Homotypic group of both synonyms should be equal to old homotypic group", oldSynName3.getHomotypicalGroup() , synName3.getHomotypicalGroup() );
476
477
478 //test single heterotypic synonym to homotypic synonym of new taxon
479 //+ new reference
480 newTaxon = (Taxon)service.load(uuidNewTaxon);
481 Reference<?> ref2 = referenceService.load(uuidRef2);
482 heterotypicSynonym = (Synonym)service.load(uuidSyn6);
483 Assert.assertNotNull("Synonym should exist", heterotypicSynonym);
484 Assert.assertEquals("Synonym should have 1 relation", 1, heterotypicSynonym.getSynonymRelations().size());
485 rel = heterotypicSynonym.getSynonymRelations().iterator().next();
486 Assert.assertEquals("Accepted taxon of single relation should be the old taxon", uuidOldTaxon, rel.getAcceptedTaxon().getUuid());
487 oldTaxon = rel.getAcceptedTaxon();
488 moveHomotypicGroup = false;
489 keepReference = false;
490 newReference = ref2;
491 newReferenceDetail = "newRefDetail";
492 newSynonymRelationshipType = SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF();
493
494 try {
495 service.moveSynonymToAnotherTaxon(rel, newTaxon, moveHomotypicGroup, newSynonymRelationshipType, newReference, newReferenceDetail, keepReference);
496 } catch (HomotypicalGroupChangeException e) {
497 Assert.fail("Move of single heterotypic synonym should not throw exception: " + e.getMessage());
498 }
499 //Asserts
500 commitAndStartNewTransaction(tableNames);
501 heterotypicSynonym = (Synonym)service.load(uuidSyn6);
502 Assert.assertNotNull("Synonym should still exist", heterotypicSynonym);
503 Assert.assertEquals("Synonym should still have 1 relation", 1, heterotypicSynonym.getSynonymRelations().size());
504 rel = heterotypicSynonym.getSynonymRelations().iterator().next();
505 Assert.assertEquals("Relationship type should be 'homotypic synonym'", newSynonymRelationshipType, rel.getType());
506 Assert.assertEquals("Accepted taxon of single relation should be new taxon", newTaxon, rel.getAcceptedTaxon());
507 Assert.assertEquals("New citation should be ref2", ref2 ,rel.getCitation());
508 Assert.assertEquals("New detail should be kept", "newRefDetail", rel.getCitationMicroReference());
509
510 Assert.assertEquals("New taxon and new synonym should have equal homotypical group", rel.getSynonym().getHomotypicGroup(), rel.getAcceptedTaxon().getHomotypicGroup());
511 Assert.assertSame("New taxon and new synonym should have same homotypical group", rel.getSynonym().getHomotypicGroup(), rel.getAcceptedTaxon().getHomotypicGroup());
512 }
513
514
515
516 @Test
517 public final void testGetHeterotypicSynonymyGroups(){
518 Rank rank = Rank.SPECIES();
519 Reference<?> ref1 = ReferenceFactory.newGeneric();
520 //HomotypicalGroup group = HomotypicalGroup.NewInstance();
521 Taxon taxon1 = Taxon.NewInstance(BotanicalName.NewInstance(rank, "Test3", null, null, null, null, null, null, null), null);
522 Synonym synonym0 = Synonym.NewInstance(BotanicalName.NewInstance(rank, "Test2", null, null, null, null, null, null, null), null);
523 Synonym synonym1 = Synonym.NewInstance(BotanicalName.NewInstance(rank, "Test2", null, null, null, null, null, null, null), null);
524 Synonym synonym2 = Synonym.NewInstance(BotanicalName.NewInstance(rank, "Test4", null, null, null, null, null, null, null), null);
525 synonym0.getName().setHomotypicalGroup(taxon1.getHomotypicGroup());
526 synonym2.getName().setHomotypicalGroup(synonym1.getHomotypicGroup());
527 //tax2.addHeterotypicSynonymName(synonym.getName());
528 taxon1.addSynonym(synonym1, SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF());
529 taxon1.addSynonym(synonym2, SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF());
530
531 service.save(synonym1);
532 service.save(synonym2);
533 service.save(taxon1);
534
535 List<List<Synonym>> heteroSyns = service.getHeterotypicSynonymyGroups(taxon1, null);
536 Assert.assertEquals("There should be 1 heterotypic group", 1, heteroSyns.size());
537 List<Synonym> synList = heteroSyns.get(0);
538 Assert.assertEquals("There should be 2 heterotypic syns in group 1", 2, synList.size());
539
540 //test sec
541 synonym2.setSec(ref1);
542 heteroSyns = service.getHeterotypicSynonymyGroups(taxon1, null);
543 Assert.assertEquals("There should be 1 heterotypic group", 1, heteroSyns.size());
544 synList = heteroSyns.get(0);
545 Assert.assertEquals("getHeterotypicSynonymyGroups should be independent of sec reference", 2, synList.size());
546
547 }
548
549
550 @Test
551 public final void testGetHomotypicSynonymsByHomotypicGroup(){
552 Rank rank = Rank.SPECIES();
553 Reference<?> ref1 = ReferenceFactory.newGeneric();
554 //HomotypicalGroup group = HomotypicalGroup.NewInstance();
555 Taxon taxon1 = Taxon.NewInstance(BotanicalName.NewInstance(rank, "Test3", null, null, null, null, null, null, null), null);
556 Synonym synonym0 = Synonym.NewInstance(BotanicalName.NewInstance(rank, "Test2", null, null, null, null, null, null, null), null);
557 Synonym synonym1 = Synonym.NewInstance(BotanicalName.NewInstance(rank, "Test2", null, null, null, null, null, null, null), null);
558 Synonym synonym2 = Synonym.NewInstance(BotanicalName.NewInstance(rank, "Test4", null, null, null, null, null, null, null), null);
559 synonym0.getName().setHomotypicalGroup(taxon1.getHomotypicGroup());
560 synonym2.getName().setHomotypicalGroup(synonym1.getHomotypicGroup());
561 //tax2.addHeterotypicSynonymName(synonym.getName());
562 taxon1.addSynonym(synonym0, SynonymRelationshipType.HOMOTYPIC_SYNONYM_OF());
563 taxon1.addSynonym(synonym1, SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF());
564 taxon1.addSynonym(synonym2, SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF());
565
566 service.save(synonym1);
567 service.save(synonym2);
568 service.save(taxon1);
569
570 List<Synonym> homoSyns = service.getHomotypicSynonymsByHomotypicGroup(taxon1, null);
571 Assert.assertEquals("There should be 1 heterotypic group", 1, homoSyns.size());
572 Assert.assertSame("The homotypic synonym should be synonym0", synonym0, homoSyns.get(0));
573
574 //test sec
575 synonym0.setSec(ref1);
576 homoSyns = service.getHomotypicSynonymsByHomotypicGroup(taxon1, null);
577 Assert.assertEquals("getHeterotypicSynonymyGroups should be independent of sec reference", 1, homoSyns.size());
578
579 }
580
581 @Test
582 @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="TaxonServiceImplTest.testDeleteSynonym.xml")
583 //test delete synonym, but the name will not be deleted
584 public final void testDeleteSynonymSynonymTaxonDontDeleteName(){
585 final String[]tableNames = {"TaxonBase","TaxonBase_AUD", "TaxonNameBase","TaxonNameBase_AUD",
586 "SynonymRelationship","SynonymRelationship_AUD",
587 "HomotypicalGroup","HomotypicalGroup_AUD"};
588
589 int nSynonyms = service.count(Synonym.class);
590 Assert.assertEquals("There should be 2 synonyms in the database", 2, nSynonyms);
591 int nNames = nameService.count(TaxonNameBase.class);
592 Assert.assertEquals("There should be 4 names in the database", 4, nNames);
593 int nRelations = service.countAllRelationships();
594 Assert.assertEquals("There should be two relationship left in the database", 2, nRelations);
595
596 UUID uuidSynonym1=UUID.fromString("7da85381-ad9d-4886-9d4d-0eeef40e3d88");
597
598
599 Synonym synonym1 = (Synonym)service.load(uuidSynonym1);
600 SynonymDeletionConfigurator config = new SynonymDeletionConfigurator();
601 config.setDeleteNameIfPossible(false);
602 config.setNewHomotypicGroupIfNeeded(true);
603 service.deleteSynonym(synonym1, config);
604
605 this.commitAndStartNewTransaction(tableNames);
606
607 nSynonyms = service.count(Synonym.class);
608 Assert.assertEquals("There should be 1 synonym left in the database", 1, nSynonyms);
609 nNames = nameService.count(TaxonNameBase.class);
610 Assert.assertEquals("There should be 4 names left in the database", 4, nNames);
611 nRelations = service.countAllRelationships();
612 Assert.assertEquals("There should be no relationship left in the database", 1, nRelations);
613 }
614
615 @Test
616 @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="TaxonServiceImplTest.testDeleteSynonym.xml")
617 //test delete synonym and his name
618 public final void testDeleteSynonymSynonymTaxonDeleteName(){
619 final String[]tableNames = {"TaxonBase","TaxonBase_AUD", "TaxonNameBase","TaxonNameBase_AUD",
620 "SynonymRelationship","SynonymRelationship_AUD",
621 "HomotypicalGroup","HomotypicalGroup_AUD"};
622
623 int nSynonyms = service.count(Synonym.class);
624 Assert.assertEquals("There should be 2 synonyms in the database", 2, nSynonyms);
625 int nNames = nameService.count(TaxonNameBase.class);
626 Assert.assertEquals("There should be 4 names in the database", 4, nNames);
627 int nRelations = service.countAllRelationships();
628 Assert.assertEquals("There should be 2 relationship left in the database", 2, nRelations);
629
630 UUID uuidSynonym1=UUID.fromString("7da85381-ad9d-4886-9d4d-0eeef40e3d88");
631
632
633 Synonym synonym1 = (Synonym)service.load(uuidSynonym1);
634 service.deleteSynonym(synonym1, new SynonymDeletionConfigurator());
635
636 this.commitAndStartNewTransaction(tableNames);
637
638 nSynonyms = service.count(Synonym.class);
639 Assert.assertEquals("There should be 1 synonym left in the database", 1, nSynonyms);
640 nNames = nameService.count(TaxonNameBase.class);
641 Assert.assertEquals("There should be 3 names left in the database", 3, nNames);
642 nRelations = service.countAllRelationships();
643 Assert.assertEquals("There should be 1 relationship left in the database", 1, nRelations);
644
645 }
646
647 @Test
648 @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="TaxonServiceImplTest.testDeleteSynonym.xml")
649 //test remove synonym from taxon -> synonym and name still in the db and the synonymrelationship to the other taxon
650 //test delete synonym -> all relationships are deleted, the name is deleted and the synonym itself
651 public final void testDeleteSynonymSynonymTaxonBooleanRelToOneTaxon(){
652 final String[]tableNames = {"TaxonBase","TaxonBase_AUD", "TaxonNameBase","TaxonNameBase_AUD",
653 "SynonymRelationship","SynonymRelationship_AUD",
654 "HomotypicalGroup","HomotypicalGroup_AUD"};
655
656 int nSynonyms = service.count(Synonym.class);
657 Assert.assertEquals("There should be 2 synonyms in the database", 2, nSynonyms);
658 int nNames = nameService.count(TaxonNameBase.class);
659 Assert.assertEquals("There should be 4 names in the database", 4, nNames);
660
661 UUID uuidTaxon1=UUID.fromString("c47fdb72-f32c-452e-8305-4b44f01179d0");
662 UUID uuidTaxon2=UUID.fromString("2d9a642d-5a82-442d-8fec-95efa978e8f8");
663 UUID uuidSynonym1=UUID.fromString("7da85381-ad9d-4886-9d4d-0eeef40e3d88");
664
665
666 Taxon taxon2 = (Taxon)service.load(uuidTaxon1);
667
668 List<String> initStrat = new ArrayList<String>();
669 initStrat.add("markers");
670 Synonym synonym1 = (Synonym)service.load(uuidSynonym1, initStrat);
671 int nRelations = service.countAllRelationships();
672 Assert.assertEquals("There should be 2 relationship left in the database", 2, nRelations);
673
674 taxon2.removeSynonym(synonym1, false);
675 service.saveOrUpdate(taxon2);
676
677 commitAndStartNewTransaction(null);
678
679 nSynonyms = service.count(Synonym.class);
680 Assert.assertEquals("There should be 2 synonyms in the database", 2, nSynonyms);
681 nNames = nameService.count(TaxonNameBase.class);
682 Assert.assertEquals("There should be 4 names in the database", 4, nNames);
683 nRelations = service.countAllRelationships();
684 Assert.assertEquals("There should be 1 relationship left in the database", 1, nRelations);
685 Marker marker1 = Marker.NewInstance(MarkerType.IMPORTED(), true);
686 Marker marker2 = Marker.NewInstance(MarkerType.COMPUTED(), true);
687 synonym1.addMarker(marker1);
688 synonym1.addMarker(marker2);
689 service.update(synonym1);
690 synonym1 =(Synonym) service.load(uuidSynonym1);
691
692
693 Set<Marker> markers = synonym1.getMarkers();
694 Marker marker = markers.iterator().next();
695 UUID markerUUID = marker.getUuid();
696 // taxon2 = (Taxon)service.load(uuidTaxon2);
697 synonym1 = (Synonym)service.load(uuidSynonym1);
698 //the marker should not prevent the deletion
699 DeleteResult result = service.deleteSynonym(synonym1, new SynonymDeletionConfigurator());
700 if (!result.isOk()){
701 Assert.fail();
702 }
703
704
705
706
707 commitAndStartNewTransaction(tableNames);
708 nSynonyms = service.count(Synonym.class);
709 Assert.assertEquals("There should be 1 synonym left in the database", 1, nSynonyms);
710 nNames = nameService.count(TaxonNameBase.class);
711 Assert.assertEquals("There should be 3 names left in the database", 3, nNames);
712 nRelations = service.countAllRelationships();
713 Assert.assertEquals("There should be no relationship left in the database", 1, nRelations);
714 marker = markerService.load(markerUUID);
715 assertNull(marker);
716
717 }
718
719 @Test
720 @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="TaxonServiceImplTest.testDeleteSynonym.xml")
721 //test delete synonym, only for a special taxon, but because of other relationships it will not be deleted at all
722 public final void testDeleteSynonymSynonymTaxonBooleanDeleteOneTaxon(){
723 final String[]tableNames = {"TaxonBase","TaxonBase_AUD", "TaxonNameBase","TaxonNameBase_AUD",
724 "SynonymRelationship","SynonymRelationship_AUD",
725 "HomotypicalGroup","HomotypicalGroup_AUD"};
726
727
728 int nSynonyms = service.count(Synonym.class);
729 Assert.assertEquals("There should be 2 synonyms in the database", 2, nSynonyms);
730 int nNames = nameService.count(TaxonNameBase.class);
731 Assert.assertEquals("There should be 4 names in the database", 4, nNames);
732
733 UUID uuidTaxon1=UUID.fromString("c47fdb72-f32c-452e-8305-4b44f01179d0");
734 UUID uuidTaxon2=UUID.fromString("2d9a642d-5a82-442d-8fec-95efa978e8f8");
735 UUID uuidSynonym1=UUID.fromString("7da85381-ad9d-4886-9d4d-0eeef40e3d88");
736 UUID uuidSynonym2=UUID.fromString("f8d86dc9-5f18-4877-be46-fbb9412465e4");
737
738 Taxon taxon1 = (Taxon)service.load(uuidTaxon1);
739 Taxon taxon2 = (Taxon)service.load(uuidTaxon2);
740 Synonym synonym1 = (Synonym)service.load(uuidSynonym1);
741 taxon2.addSynonym(synonym1, SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF());
742 service.saveOrUpdate(synonym1);
743 int nRelations = service.countAllRelationships();
744 Assert.assertEquals("There should be 3 relationship left in the database", 3, nRelations);
745 service.deleteSynonym(synonym1, taxon1, new SynonymDeletionConfigurator());
746
747 this.commitAndStartNewTransaction(tableNames);
748
749 nSynonyms = service.count(Synonym.class);
750 Assert.assertEquals("There should still be 2 synonyms left in the database (synonym is related to taxon2)", 2, nSynonyms);
751 nNames = nameService.count(TaxonNameBase.class);
752 Assert.assertEquals("There should be 4 names left in the database (name not deleted as synonym was not deleted)", 4, nNames);
753 nRelations = service.countAllRelationships();
754 Assert.assertEquals("There should be 2 relationship left in the database", 2, nRelations);
755
756
757 }
758
759 @Test
760 @DataSet("TaxonServiceImplTest.testDeleteSynonym.xml")
761
762 public final void testDeleteSynonymSynonymTaxonBooleanWithRelatedName(){
763 final String[]tableNames = {"TaxonBase","TaxonBase_AUD", "TaxonNameBase","TaxonNameBase_AUD",
764 "SynonymRelationship","SynonymRelationship_AUD",
765 "HomotypicalGroup","HomotypicalGroup_AUD"};
766
767 int nSynonyms = service.count(Synonym.class);
768 Assert.assertEquals("There should be 2 synonyms in the database", 2, nSynonyms);
769 int nNames = nameService.count(TaxonNameBase.class);
770 Assert.assertEquals("There should be 4 names in the database", 4, nNames);
771
772 UUID uuidTaxon1=UUID.fromString("c47fdb72-f32c-452e-8305-4b44f01179d0");
773 UUID uuidTaxon2=UUID.fromString("2d9a642d-5a82-442d-8fec-95efa978e8f8");
774 UUID uuidSynonym1=UUID.fromString("7da85381-ad9d-4886-9d4d-0eeef40e3d88");
775 UUID uuidSynonym2=UUID.fromString("f8d86dc9-5f18-4877-be46-fbb9412465e4");
776 UUID uuidSynonymName2=UUID.fromString("613f3c93-013e-4ffc-aadc-1c98d71c335e");
777
778 Synonym synonym1 = (Synonym)service.load(uuidSynonym1);
779 TaxonNameBase name2 = nameService.load(uuidSynonymName2);
780 UUID name3Uuid = synonym1.getName().getUuid();
781 TaxonNameBase name3 = nameService.load(name3Uuid);
782 name3.addRelationshipFromName(name2, NameRelationshipType.LATER_HOMONYM(), null);
783
784 service.saveOrUpdate(synonym1);
785
786 int nRelations = nameService.getAllRelationships(1000, 0).size();
787 logger.info("number of name relations: " + nRelations);
788 Assert.assertEquals("There should be 1 name relationship left in the database", 1, nRelations);
789 SynonymDeletionConfigurator config = new SynonymDeletionConfigurator();
790
791 service.deleteSynonym(synonym1, config);
792
793 this.commitAndStartNewTransaction(tableNames);
794 //synonym is deleted, but the name can not be deleted because of a name relationship
795 nSynonyms = service.count(Synonym.class);
796 Assert.assertEquals("There should still be 1 synonyms left in the database", 1, nSynonyms);
797 nNames = nameService.count(TaxonNameBase.class);
798 Assert.assertEquals("There should be 4 names left in the database (name is related to synonymName2)", 4, nNames);
799 nRelations = service.countAllRelationships();
800 //may change with better implementation of countAllRelationships (see #2653)
801 nRelations = nameService.getAllRelationships(1000, 0).size();
802 logger.info("number of name relations: " + nRelations);
803 Assert.assertEquals("There should be 1 name relationship left in the database", 1, nRelations);
804
805
806 //clean up database
807 name2 = nameService.load(uuidSynonymName2);
808 NameRelationship rel = CdmBase.deproxy(name2.getNameRelations().iterator().next(), NameRelationship.class);
809 name2.removeNameRelationship(rel);
810 nameService.save(name2);
811 this.setComplete();
812 this.endTransaction();
813
814 }
815 @Test
816 @DataSet("TaxonServiceImplTest.testDeleteSynonym.xml")
817 public final void testDeleteSynonymSynonymTaxonBooleanWithRelatedNameDeleteAllNameRelations(){
818 final String[]tableNames = {"TaxonBase","TaxonBase_AUD", "TaxonNameBase","TaxonNameBase_AUD",
819 "SynonymRelationship","SynonymRelationship_AUD",
820 "HomotypicalGroup","HomotypicalGroup_AUD"};
821
822 int nSynonyms = service.count(Synonym.class);
823 Assert.assertEquals("There should be 2 synonyms in the database", 2, nSynonyms);
824 int nNames = nameService.count(TaxonNameBase.class);
825 Assert.assertEquals("There should be 4 names in the database", 4, nNames);
826
827 UUID uuidTaxon1=UUID.fromString("c47fdb72-f32c-452e-8305-4b44f01179d0");
828 UUID uuidTaxon2=UUID.fromString("2d9a642d-5a82-442d-8fec-95efa978e8f8");
829 UUID uuidSynonym1=UUID.fromString("7da85381-ad9d-4886-9d4d-0eeef40e3d88");
830 UUID uuidSynonym2=UUID.fromString("f8d86dc9-5f18-4877-be46-fbb9412465e4");
831 UUID uuidSynonymName2=UUID.fromString("613f3c93-013e-4ffc-aadc-1c98d71c335e");
832
833 Synonym synonym1 = (Synonym)service.load(uuidSynonym1);
834 TaxonNameBase name2 = nameService.load(uuidSynonymName2);
835 UUID name3Uuid = synonym1.getName().getUuid();
836 TaxonNameBase name3 = nameService.load(name3Uuid);
837 name3.addRelationshipFromName(name2, NameRelationshipType.LATER_HOMONYM(), null);
838
839 service.saveOrUpdate(synonym1);
840
841 int nRelations = nameService.getAllRelationships(1000, 0).size();
842 logger.info("number of name relations: " + nRelations);
843 Assert.assertEquals("There should be 1 name relationship left in the database", 1, nRelations);
844 SynonymDeletionConfigurator config = new SynonymDeletionConfigurator();
845 NameDeletionConfigurator nameDeletionConfig = new NameDeletionConfigurator();
846 nameDeletionConfig.setRemoveAllNameRelationships(true);
847 config.setNameDeletionConfig(nameDeletionConfig);
848
849 service.deleteSynonym(synonym1, config);
850
851 this.commitAndStartNewTransaction(tableNames);
852
853 nSynonyms = service.count(Synonym.class);
854 Assert.assertEquals("There should still be 1 synonyms left in the database", 1, nSynonyms);
855 nNames = nameService.count(TaxonNameBase.class);
856 Assert.assertEquals("There should be 3 names left in the database ", 3, nNames);
857 nRelations = service.countAllRelationships();
858 //may change with better implementation of countAllRelationships (see #2653)
859 nRelations = nameService.getAllRelationships(1000, 0).size();
860 logger.info("number of name relations: " + nRelations);
861 Assert.assertEquals("There should be no name relationship left in the database", 0, nRelations);
862 }
863
864 @Test
865 @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="TaxonServiceImplTest.testDeleteSynonym.xml")
866 public final void testDeleteSynonymSynonymTaxonBooleanWithRelatedNameIgnoreIsBasionym(){
867 final String[]tableNames = {"TaxonBase","TaxonBase_AUD", "TaxonNameBase","TaxonNameBase_AUD",
868 "SynonymRelationship","SynonymRelationship_AUD",
869 "HomotypicalGroup","HomotypicalGroup_AUD"};
870
871 int nSynonyms = service.count(Synonym.class);
872 Assert.assertEquals("There should be 2 synonyms in the database", 2, nSynonyms);
873 int nNames = nameService.count(TaxonNameBase.class);
874 Assert.assertEquals("There should be 4 names in the database", 4, nNames);
875
876 UUID uuidTaxon1=UUID.fromString("c47fdb72-f32c-452e-8305-4b44f01179d0");
877 UUID uuidTaxon2=UUID.fromString("2d9a642d-5a82-442d-8fec-95efa978e8f8");
878 UUID uuidSynonym1=UUID.fromString("7da85381-ad9d-4886-9d4d-0eeef40e3d88");
879 UUID uuidSynonym2=UUID.fromString("f8d86dc9-5f18-4877-be46-fbb9412465e4");
880 UUID uuidSynonymName2=UUID.fromString("613f3c93-013e-4ffc-aadc-1c98d71c335e");
881
882 Synonym synonym1 = (Synonym)service.load(uuidSynonym1);
883 TaxonNameBase synName2 = nameService.load(uuidSynonymName2);
884 UUID name3Uuid = synonym1.getName().getUuid();
885 TaxonNameBase synName1 = nameService.load(name3Uuid);
886 synName1.addRelationshipFromName(synName2, NameRelationshipType.BASIONYM(), null);
887
888 service.saveOrUpdate(synonym1);
889
890 int nRelations = nameService.getAllRelationships(1000, 0).size();
891 logger.info("number of name relations: " + nRelations);
892 Assert.assertEquals("There should be 1 name relationship left in the database", 1, nRelations);
893 SynonymDeletionConfigurator config = new SynonymDeletionConfigurator();
894 NameDeletionConfigurator nameDeletionConfig = new NameDeletionConfigurator();
895 nameDeletionConfig.setIgnoreIsBasionymFor(true);
896 config.setNameDeletionConfig(nameDeletionConfig);
897
898 DeleteResult result =service.deleteSynonym(synonym1, config);
899 if (!result.isOk()){
900 Assert.fail();
901 }
902
903
904 logger.debug(result);
905 this.commitAndStartNewTransaction(tableNames);
906
907 nSynonyms = service.count(Synonym.class);
908 Assert.assertEquals("There should still be 1 synonyms left in the database", 1, nSynonyms);
909 nNames = nameService.count(TaxonNameBase.class);
910 Assert.assertEquals("There should be 3 names left in the database ", 3, nNames);
911 nRelations = service.countAllRelationships();
912 //may change with better implementation of countAllRelationships (see #2653)
913 nRelations = nameService.getAllRelationships(1000, 0).size();
914 logger.info("number of name relations: " + nRelations);
915 Assert.assertEquals("There should be no name relationship left in the database", 0, nRelations);
916 }
917
918
919 @Test
920 @DataSet("TaxonServiceImplTest.testDeleteSynonym.xml")
921 public final void testDeleteSynonymSynonymTaxonBooleanWithRollback(){
922 final String[]tableNames = {"TaxonBase","TaxonBase_AUD", "TaxonNameBase","TaxonNameBase_AUD",
923 "SynonymRelationship","SynonymRelationship_AUD",
924 "HomotypicalGroup","HomotypicalGroup_AUD"};
925
926 int nSynonyms = service.count(Synonym.class);
927 Assert.assertEquals("There should be 2 synonyms in the database", 2, nSynonyms);
928 int nNames = nameService.count(TaxonNameBase.class);
929 Assert.assertEquals("There should be 4 names in the database", 4, nNames);
930 int nRelations = service.countAllRelationships();
931
932
933 //may change with better implementation of countAllRelationships (see #2653)
934
935 logger.debug("");
936 Assert.assertEquals("There should be 2 relationships in the database (the 2 synonym relationship) but no name relationship", 2, nRelations);
937
938 UUID uuidSynonym1=UUID.fromString("7da85381-ad9d-4886-9d4d-0eeef40e3d88");
939 UUID uuidSynonymName2=UUID.fromString("613f3c93-013e-4ffc-aadc-1c98d71c335e");
940
941 Synonym synonym1 = (Synonym)service.load(uuidSynonym1);
942 TaxonNameBase name2 = nameService.load(uuidSynonymName2);
943 synonym1.getName().addRelationshipFromName(name2, NameRelationshipType.LATER_HOMONYM(), null);
944
945 service.deleteSynonym(synonym1, new SynonymDeletionConfigurator());
946
947 this.rollback();
948 // printDataSet(System.out, tableNames);
949 this.startNewTransaction();
950
951 nSynonyms = service.count(Synonym.class);
952 Assert.assertEquals("There should still be 2 synonyms left in the database", 2, nSynonyms);
953 nNames = nameService.count(TaxonNameBase.class);
954 Assert.assertEquals("There should be 4 names left in the database", 4, nNames);
955 nRelations = service.countAllRelationships();
956 //may change with better implementation of countAllRelationships (see #2653)
957 Assert.assertEquals("There should be 2 relationship in the database (the 2 synonym relationship) but no name relationship", 2, nRelations);
958
959 }
960
961 @Test
962 @DataSet("TaxonServiceImplTest.testDeleteSynonym.xml")
963 public final void testDeleteSynonymSynonymTaxonBooleanWithoutTransaction(){
964 final String[]tableNames = {"TaxonBase","TaxonBase_AUD", "TaxonNameBase","TaxonNameBase_AUD",
965 "SynonymRelationship","SynonymRelationship_AUD",
966 "HomotypicalGroup","HomotypicalGroup_AUD"};
967
968 int nSynonyms = service.count(Synonym.class);
969 Assert.assertEquals("There should be 2 synonyms in the database", 2, nSynonyms);
970 int nNames = nameService.count(TaxonNameBase.class);
971 Assert.assertEquals("There should be 4 names in the database", 4, nNames);
972 int nRelations = service.countAllRelationships();
973 //may change with better implementation of countAllRelationships (see #2653)
974 Assert.assertEquals("There should be 2 relationship in the database (the 2 synonym relationships) but no name relationship", 2, nRelations);
975
976 UUID uuidSynonym1=UUID.fromString("7da85381-ad9d-4886-9d4d-0eeef40e3d88");
977 UUID uuidSynonymName2=UUID.fromString("613f3c93-013e-4ffc-aadc-1c98d71c335e");
978
979 Synonym synonym1 = (Synonym)service.load(uuidSynonym1);
980 TaxonNameBase name2 = nameService.load(uuidSynonymName2);
981 synonym1.getName().addRelationshipFromName(name2, NameRelationshipType.LATER_HOMONYM(), null);
982
983 service.saveOrUpdate(synonym1);
984 nRelations = service.countAllRelationships();
985 Assert.assertEquals("There should be two relationships in the database", 2, nRelations);
986 this.setComplete();
987 this.endTransaction();
988
989 // printDataSet(System.out, tableNames);
990
991 //out of wrapping transaction
992 service.deleteSynonym(synonym1, new SynonymDeletionConfigurator());
993
994 this.startNewTransaction();
995
996 nSynonyms = service.count(Synonym.class);
997 Assert.assertEquals("There should still be 1 synonyms left in the database. The rollback on name delete should not lead to rollback in synonym delete.", 1, nSynonyms);
998 nNames = nameService.count(TaxonNameBase.class);
999 Assert.assertEquals("There should be 4 names left in the database", 4, nNames);
1000 nRelations = service.countAllRelationships();
1001 Assert.assertEquals("There should be no taxon or synonym relationship in the database", 1, nRelations);
1002 nRelations = nameService.getAllRelationships(1000,0).size();
1003 Assert.assertEquals("There should be one name relationship in the database", 1, nRelations);
1004
1005 }
1006
1007 @Test
1008 @DataSet("TaxonServiceImplTest.testInferredSynonyms.xml")
1009 public void testCreateInferredSynonymy(){
1010
1011 UUID classificationUuid = UUID.fromString("aeee7448-5298-4991-b724-8d5b75a0a7a9");
1012 Classification tree = classificationService.find(classificationUuid);
1013 UUID taxonUuid = UUID.fromString("bc09aca6-06fd-4905-b1e7-cbf7cc65d783");
1014 TaxonBase<?> taxonBase = service.find(taxonUuid);
1015 List <Synonym> synonyms = service.list(Synonym.class, null, null, null, null);
1016 assertEquals("Number of synonyms should be 2",2,synonyms.size());
1017 Taxon taxon = (Taxon)taxonBase;
1018
1019 //synonyms = taxonDao.getAllSynonyms(null, null);
1020 //assertEquals("Number of synonyms should be 2",2,synonyms.size());
1021 List<Synonym> inferredSynonyms = service.createInferredSynonyms(taxon, tree, SynonymRelationshipType.INFERRED_EPITHET_OF(), true);
1022 assertNotNull("there should be a new synonym ", inferredSynonyms);
1023 assertEquals ("the name of inferred epithet should be SynGenus lachesis", "SynGenus lachesis sec. Sp. Pl.", inferredSynonyms.get(0).getTitleCache());
1024
1025 inferredSynonyms = service.createInferredSynonyms(taxon, tree, SynonymRelationshipType.INFERRED_GENUS_OF(), true);
1026 assertNotNull("there should be a new synonym ", inferredSynonyms);
1027 assertEquals ("the name of inferred epithet should be SynGenus lachesis", "Acherontia ciprosus sec. Sp. Pl.", inferredSynonyms.get(0).getTitleCache());
1028
1029 inferredSynonyms = service.createInferredSynonyms(taxon, tree, SynonymRelationshipType.POTENTIAL_COMBINATION_OF(), true);
1030 assertNotNull("there should be a new synonym ", inferredSynonyms);
1031 assertEquals ("the name of inferred epithet should be SynGenus lachesis", "SynGenus ciprosus sec. Sp. Pl.", inferredSynonyms.get(0).getTitleCache());
1032 //assertTrue("set of synonyms should contain an inferred Synonym ", synonyms.contains(arg0))
1033 }
1034
1035 @Test
1036 @DataSet("BlankDataSet.xml")
1037 public final void testTaxonDeletionConfig(){
1038 final String[]tableNames = {
1039 "Classification", "Classification_AUD",
1040 "TaxonBase","TaxonBase_AUD",
1041 "TaxonNode","TaxonNode_AUD",
1042 "TaxonNameBase","TaxonNameBase_AUD",
1043 "SynonymRelationship","SynonymRelationship_AUD",
1044 "TaxonRelationship", "TaxonRelationship_AUD",
1045 "TaxonDescription", "TaxonDescription_AUD",
1046 "HomotypicalGroup","HomotypicalGroup_AUD",
1047 "PolytomousKey","PolytomousKey_AUD",
1048 "PolytomousKeyNode","PolytomousKeyNode_AUD",
1049 "Media","Media_AUD",
1050 "WorkingSet","WorkingSet_AUD",
1051 "DescriptionElementBase","DescriptionElementBase_AUD",
1052 "DeterminationEvent","DeterminationEvent_AUD",
1053 "SpecimenOrObservationBase","SpecimenOrObservationBase_AUD"};
1054
1055 UUID uuidParent=UUID.fromString("b5271d4f-e203-4577-941f-00d76fa9f4ca");
1056 UUID uuidChild1=UUID.fromString("326167f9-0b97-4e7d-b1bf-4ca47b82e21e");
1057 UUID uuidSameAs=UUID.fromString("c2bb0f01-f2dd-43fb-ba12-2a85727ccb8d");
1058 commitAndStartNewTransaction(tableNames);
1059 Taxon testTaxon = TaxonGenerator.getTestTaxon();
1060 service.save(testTaxon);
1061 commitAndStartNewTransaction(tableNames);
1062 int nTaxa = service.count(Taxon.class);
1063
1064 Assert.assertEquals("There should be 4 taxa in the database", 4, nTaxa);
1065 Taxon parent = (Taxon)service.find(TaxonGenerator.GENUS_UUID);
1066 Assert.assertNotNull("Parent taxon should exist", parent);
1067 Taxon child1 = (Taxon)service.find(TaxonGenerator.SPECIES1_UUID);
1068 Assert.assertNotNull("Child taxon should exist", child1);
1069 TaxonDeletionConfigurator config = new TaxonDeletionConfigurator();
1070 config.setDeleteTaxonNodes(false);
1071 config.setDeleteMisappliedNamesAndInvalidDesignations(false);
1072 //try {
1073 //commitAndStartNewTransaction(tableNames);
1074
1075 DeleteResult result = service.deleteTaxon(child1, config, null);
1076 if (result.isOk()){
1077 Assert.fail("Delete should throw an error as long as name is used in classification.");
1078 }
1079
1080 nTaxa = service.count(Taxon.class);
1081 Assert.assertEquals("There should be 4 taxa in the database", 4, nTaxa);
1082 child1 = (Taxon)service.find(TaxonGenerator.SPECIES1_UUID);
1083 Assert.assertNotNull("Child taxon should exist", child1);
1084 Assert.assertEquals("Child should belong to 1 node", 1, child1.getTaxonNodes().size());
1085
1086 TaxonNode node = child1.getTaxonNodes().iterator().next();
1087 child1.addSource(IdentifiableSource.NewInstance(OriginalSourceType.Import));
1088
1089 SpecimenOrObservationBase<IIdentifiableEntityCacheStrategy> identifiedUnit = DerivedUnit.NewInstance(SpecimenOrObservationType.DerivedUnit);
1090 DeterminationEvent determinationEvent = DeterminationEvent.NewInstance(child1, identifiedUnit);
1091 //UUID eventUUID = eventService.save(determinationEvent);
1092 UUID identifiedUnitUUID = occurenceService.save(identifiedUnit);
1093
1094
1095 TaxonNode parentNode = node.getParent();
1096 parentNode =CdmBase.deproxy(parentNode, TaxonNode.class);
1097 parentNode.deleteChildNode(node);
1098 nodeService.save(parentNode);
1099 //commitAndStartNewTransaction(tableNames);
1100
1101 // try {
1102
1103 result = service.deleteTaxon(child1, config, null);
1104 if (result.isOk()){
1105 Assert.fail("Delete should throw an exception because of the determination event");
1106 }
1107
1108
1109
1110 //determinationEvent = (DeterminationEvent)eventService.load(eventUUID);
1111 commitAndStartNewTransaction(tableNames);
1112 identifiedUnit = occurenceService.load(identifiedUnitUUID);
1113
1114 occurenceService.delete(identifiedUnit);
1115
1116 commitAndStartNewTransaction(tableNames);
1117 child1 = (Taxon)service.find(TaxonGenerator.SPECIES1_UUID);
1118
1119 assertEquals(0, child1.getTaxonNodes().size());
1120 // try {
1121
1122 result = service.deleteTaxon(child1, config, null);
1123
1124 if (!result.isOk()){
1125 Assert.fail("Delete should not throw an exception anymore");
1126 }
1127
1128 nTaxa = service.count(Taxon.class);
1129 Assert.assertEquals("There should be 3 taxa in the database", 3, nTaxa);
1130
1131 config.setDeleteTaxonNodes(true);
1132 Taxon child2 =(Taxon) service.find(TaxonGenerator.SPECIES2_UUID);
1133
1134 // try {
1135 result = service.deleteTaxon(child2, config, null);
1136 if (!result.isOk()){
1137 Assert.fail("Delete should not throw an exception");
1138 }
1139
1140
1141 //service.find(uuid);
1142
1143 nTaxa = service.count(Taxon.class);
1144 Assert.assertEquals("There should be 2 taxa in the database",2, nTaxa);
1145 // nNames = nameService.count(TaxonNameBase.class);
1146 // Assert.assertEquals("There should be 3 names left in the database", 3, nNames);
1147 // int nRelations = service.countAllRelationships();
1148 // Assert.assertEquals("There should be no relationship left in the database", 0, nRelations);
1149 }
1150
1151
1152 @Test
1153 @DataSet(value="BlankDataSet.xml")
1154 public final void testDeleteTaxon(){
1155
1156 //create a small classification
1157 Taxon testTaxon = TaxonGenerator.getTestTaxon();
1158
1159 UUID uuid = service.save(testTaxon);
1160
1161 Taxon speciesTaxon = (Taxon)service.find(TaxonGenerator.SPECIES1_UUID);
1162 Iterator<TaxonDescription> descriptionIterator = speciesTaxon.getDescriptions().iterator();
1163 UUID descrUUID = null;
1164 UUID descrElementUUID = null;
1165 if (descriptionIterator.hasNext()){
1166 TaxonDescription descr = descriptionIterator.next();
1167 descrUUID = descr.getUuid();
1168 descrElementUUID = descr.getElements().iterator().next().getUuid();
1169 }
1170 BotanicalName taxonName = (BotanicalName) nameService.find(TaxonGenerator.SPECIES1_NAME_UUID);
1171 assertNotNull(taxonName);
1172
1173 TaxonDeletionConfigurator config = new TaxonDeletionConfigurator();
1174 config.setDeleteNameIfPossible(false);
1175
1176
1177
1178 // try {
1179 DeleteResult result = service.deleteTaxon(speciesTaxon, config, null);
1180 if (!result.isOk()){
1181 Assert.fail();
1182 }
1183 commitAndStartNewTransaction(null);
1184
1185 taxonName = (BotanicalName) nameService.find(TaxonGenerator.SPECIES1_NAME_UUID);
1186 Taxon taxon = (Taxon)service.find(TaxonGenerator.SPECIES1_UUID);
1187
1188 //descriptionService.find(descrUUID);
1189 assertNull(descriptionService.find(descrUUID));
1190 assertNull(descriptionService.getDescriptionElementByUuid(descrElementUUID));
1191 //assertNull(synName);
1192 assertNotNull(taxonName);
1193 assertNull(taxon);
1194 config.setDeleteNameIfPossible(true);
1195 Taxon newTaxon = Taxon.NewInstance(BotanicalName.NewInstance(Rank.SPECIES()), null);
1196 service.save(newTaxon);
1197 result = service.deleteTaxon(newTaxon, config, null);
1198 if (!result.isOk()){
1199 Assert.fail();
1200 }
1201
1202
1203 }
1204
1205 @Test
1206 @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="BlankDataSet.xml")
1207 public final void testDeleteTaxonDeleteSynonymRelations(){
1208
1209 final String[]tableNames = {
1210 "Classification", "Classification_AUD",
1211 "TaxonBase","TaxonBase_AUD",
1212 "TaxonNode","TaxonNode_AUD",
1213 "TaxonNameBase","TaxonNameBase_AUD"};
1214 commitAndStartNewTransaction(tableNames);
1215 //create a small classification
1216 Taxon testTaxon = TaxonGenerator.getTestTaxon();
1217
1218 UUID uuid = service.save(testTaxon);
1219
1220 Taxon speciesTaxon = (Taxon)service.find(TaxonGenerator.SPECIES2_UUID);
1221
1222 SynonymRelationship synRel = speciesTaxon.getSynonymRelations().iterator().next();
1223 UUID synonymRelationUuid = synRel.getUuid();
1224 UUID synonymUuid = synRel.getSynonym().getUuid();
1225 int i = service.getAllRelationships(1000, 0).size();
1226
1227 TaxonDeletionConfigurator config = new TaxonDeletionConfigurator();
1228 config.setDeleteSynonymsIfPossible(false);
1229
1230
1231 DeleteResult result = service.deleteTaxon(speciesTaxon, config, null);
1232 if (!result.isOk()){
1233 Assert.fail();
1234 }
1235 commitAndStartNewTransaction(null);
1236
1237 Taxon taxon = (Taxon)service.find(TaxonGenerator.SPECIES2_UUID);
1238 assertNull("The deleted taxon should no longer exist", taxon);
1239
1240 assertNotNull("The synonym should still exist since DeleteSynonymsIfPossible was false", service.find(synonymUuid));
1241
1242 for(RelationshipBase rel : service.getAllRelationships(1000, 0)){
1243 if(rel instanceof SynonymRelationship && rel.getUuid().equals(synonymRelationUuid)){
1244 Assert.fail("The SynonymRelationship should no longer exist");
1245 }
1246 }
1247 }
1248
1249
1250 @Test
1251 @DataSet(value="BlankDataSet.xml")
1252 public final void testDeleteTaxonNameUsedInOtherContext(){
1253
1254 //create a small classification
1255 Taxon testTaxon = TaxonGenerator.getTestTaxon();
1256
1257 UUID uuid = service.save(testTaxon);
1258
1259 Taxon speciesTaxon = (Taxon)service.find(TaxonGenerator.SPECIES1_UUID);
1260
1261 BotanicalName taxonName = (BotanicalName) nameService.find(TaxonGenerator.SPECIES1_NAME_UUID);
1262 assertNotNull(taxonName);
1263 BotanicalName fromName = BotanicalName.NewInstance(Rank.SPECIES());
1264 taxonName.addRelationshipFromName(fromName, NameRelationshipType.VALIDATED_BY_NAME(), null);
1265
1266 TaxonDeletionConfigurator config = new TaxonDeletionConfigurator();
1267 config.setDeleteNameIfPossible(true);
1268 DeleteResult result = service.deleteTaxon(speciesTaxon, config, null);
1269 if (!result.isOk()){
1270 Assert.fail();
1271 }
1272 commitAndStartNewTransaction(null);
1273
1274 taxonName = (BotanicalName) nameService.find(TaxonGenerator.SPECIES1_NAME_UUID);
1275 Taxon taxon = (Taxon)service.find(TaxonGenerator.SPECIES1_UUID);
1276 //because of the namerelationship the name cannot be deleted
1277 assertNotNull(taxonName);
1278 assertNull(taxon);
1279
1280 }
1281
1282 @Test
1283 @DataSet(value="BlankDataSet.xml")
1284 public final void testDeleteTaxonNameUsedInTwoClassificationsDeleteAllNodes(){
1285 commitAndStartNewTransaction(null);
1286 TaxonDeletionConfigurator config = new TaxonDeletionConfigurator();
1287 //create a small classification
1288 Taxon testTaxon = TaxonGenerator.getTestTaxon();
1289
1290 UUID uuid = service.save(testTaxon);
1291 //BotanicalName name = nameService.find(uuid);
1292 Set<TaxonNode> nodes = testTaxon.getTaxonNodes();
1293 TaxonNode node = nodes.iterator().next();
1294 List<TaxonNode> childNodes = node.getChildNodes();
1295 TaxonNode childNode = childNodes.iterator().next();
1296 UUID childUUID = childNode.getTaxon().getUuid();
1297 Classification secondClassification = TaxonGenerator.getTestClassification("secondClassification");
1298
1299 secondClassification.addChildTaxon(testTaxon, null, null);
1300 //delete the taxon in all classifications
1301 //try {
1302 DeleteResult result = service.deleteTaxon(testTaxon, config, null);
1303 if (!result.isOk()){
1304 Assert.fail();
1305 }
1306 commitAndStartNewTransaction(null);
1307 Taxon tax = (Taxon)service.find(uuid);
1308 assertNull(tax);
1309 Taxon childTaxon = (Taxon)service.find(childUUID);
1310 assertNull(tax);
1311 commitAndStartNewTransaction(null);
1312
1313
1314
1315
1316
1317 }
1318
1319 @Test
1320 @DataSet(value="BlankDataSet.xml")
1321 public final void testDeleteTaxonNameUsedInTwoClassificationsDoNotDeleteAllNodes(){
1322 // delete the taxon only in second classification, this should delete only the nodes, not the taxa
1323 Taxon testTaxon = TaxonGenerator.getTestTaxon();
1324 UUID uuid = service.save(testTaxon);
1325 Classification secondClassification = TaxonGenerator.getTestClassification("secondClassification");
1326 Set<TaxonNode> nodes = testTaxon.getTaxonNodes();
1327 TaxonNode node = nodes.iterator().next();
1328 List<TaxonNode> childNodes = node.getChildNodes();
1329 TaxonNode childNode = childNodes.iterator().next();
1330 UUID childUUID = childNode.getTaxon().getUuid();
1331 childNode = secondClassification.addChildTaxon(testTaxon, null, null);
1332 UUID childNodeUUID = childNode.getUuid();
1333
1334 TaxonDeletionConfigurator config = new TaxonDeletionConfigurator() ;
1335 config.setDeleteInAllClassifications(false);
1336 // try {
1337 DeleteResult result = service.deleteTaxon(testTaxon, config, secondClassification);
1338 /* Assert.fail("The taxon should not be deletable because it is used in a second classification and the configuration is set to deleteInAllClassifications = false");
1339 } catch (DataChangeNoRollbackException e) {
1340 logger.debug(e.getMessage());
1341 }
1342 */
1343
1344 if (result.isOk()){
1345 Assert.fail("The taxon should not be deletable because it is used in a second classification and the configuration is set to deleteInAllClassifications = false");
1346 }
1347
1348 //commitAndStartNewTransaction(null);
1349 Taxon tax = (Taxon)service.find(uuid);
1350 assertNotNull(tax);
1351 Taxon childTaxon = (Taxon)service.find(childUUID);
1352 assertNotNull(tax);
1353 node = nodeService.find(childNodeUUID);
1354 assertNull(node);
1355 }
1356
1357 @Test
1358 @DataSet(value="BlankDataSet.xml")
1359 public final void testTaxonNodeDeletionConfiguratorMoveToParent(){
1360 //test childHandling MOVE_TO_PARENT:
1361 Taxon testTaxon = TaxonGenerator.getTestTaxon();
1362 UUID uuid = service.save(testTaxon);
1363
1364 Taxon topMost = Taxon.NewInstance(BotanicalName.NewInstance(Rank.FAMILY()), null);
1365
1366 Iterator<TaxonNode> nodes = testTaxon.getTaxonNodes().iterator();
1367 TaxonNode node =nodes.next();
1368 Classification classification = node.getClassification();
1369 classification.addParentChild(topMost, testTaxon, null, null);
1370 UUID topMostUUID = service.save(topMost);
1371
1372 TaxonDeletionConfigurator config = new TaxonDeletionConfigurator() ;
1373 config.getTaxonNodeConfig().setChildHandling(ChildHandling.MOVE_TO_PARENT);
1374
1375
1376 DeleteResult result = service.deleteTaxon(testTaxon, config, null);
1377 if(!result.isOk()){
1378 Assert.fail();
1379 }
1380
1381 commitAndStartNewTransaction(null);
1382 Taxon tax = (Taxon)service.find(uuid);
1383 assertNull(tax);
1384 tax = (Taxon)service.find(topMostUUID);
1385 Set<TaxonNode> topMostNodes = tax.getTaxonNodes();
1386 assertNotNull(topMostNodes);
1387 assertEquals("there should be one taxon node", 1, topMostNodes.size());
1388 nodes = topMostNodes.iterator();
1389 TaxonNode topMostNode = nodes.next();
1390 int size = topMostNode.getChildNodes().size();
1391
1392 assertEquals(2, size);
1393 }
1394
1395 @Test
1396 @DataSet(value="BlankDataSet.xml")
1397 public final void testTaxonNodeDeletionConfiguratorDeleteChildren(){
1398 //test childHandling DELETE:
1399 Taxon testTaxon = TaxonGenerator.getTestTaxon();
1400 UUID uuid = service.save(testTaxon);
1401
1402 Taxon topMost = Taxon.NewInstance(BotanicalName.NewInstance(Rank.FAMILY()), null);
1403
1404 Iterator<TaxonNode> nodes = testTaxon.getTaxonNodes().iterator();
1405 TaxonNode node =nodes.next();
1406 UUID taxonNodeUUID = node.getUuid();
1407 Classification classification = node.getClassification();
1408 classification.addParentChild(topMost, testTaxon, null, null);
1409 UUID topMostUUID = service.save(topMost);
1410
1411 TaxonDeletionConfigurator config = new TaxonDeletionConfigurator() ;
1412 config.getTaxonNodeConfig().setChildHandling(ChildHandling.DELETE);
1413
1414 // try {
1415 DeleteResult result = service.deleteTaxon(testTaxon, config, null);
1416 if(!result.isOk()){
1417 Assert.fail();
1418 }
1419 commitAndStartNewTransaction(null);
1420 Taxon tax = (Taxon)service.find(uuid);
1421 assertNull(tax);
1422 tax = (Taxon)service.find(topMostUUID);
1423 Set<TaxonNode> topMostNodes = tax.getTaxonNodes();
1424 assertNotNull(topMostNodes);
1425 assertEquals("there should be one taxon node", 1, topMostNodes.size());
1426 nodes = topMostNodes.iterator();
1427 TaxonNode topMostNode = nodes.next();
1428 int size = topMostNode.getChildNodes().size();
1429 node = nodeService.find(taxonNodeUUID);
1430 assertNull(node);
1431 assertEquals(0, size);
1432 }
1433
1434
1435 @Test
1436 @DataSet(value="BlankDataSet.xml")
1437 public final void testTaxonDeletionConfiguratorDeleteMarker(){
1438 //test childHandling DELETE:
1439 Taxon testTaxon = TaxonGenerator.getTestTaxon();
1440 UUID uuid = service.save(testTaxon);
1441
1442 Taxon topMost = Taxon.NewInstance(BotanicalName.NewInstance(Rank.FAMILY()), null);
1443
1444 Iterator<TaxonNode> nodes = testTaxon.getTaxonNodes().iterator();
1445 TaxonNode node =nodes.next();
1446 Classification classification = node.getClassification();
1447 classification.addParentChild(topMost, testTaxon, null, null);
1448 UUID topMostUUID = service.save(topMost);
1449 Marker marker = Marker.NewInstance(testTaxon, true, MarkerType.IS_DOUBTFUL());
1450 testTaxon.addMarker(marker);
1451 TaxonDeletionConfigurator config = new TaxonDeletionConfigurator() ;
1452 config.getTaxonNodeConfig().setChildHandling(ChildHandling.DELETE);
1453
1454 DeleteResult result = service.deleteTaxon(testTaxon, config, null);
1455
1456 if(!result.isOk()){
1457 Assert.fail();
1458 }
1459 commitAndStartNewTransaction(null);
1460 Taxon tax = (Taxon)service.find(uuid);
1461 assertNull(tax);
1462 tax = (Taxon)service.find(topMostUUID);
1463 Set<TaxonNode> topMostNodes = tax.getTaxonNodes();
1464 assertNotNull(topMostNodes);
1465 assertEquals("there should be one taxon node", 1, topMostNodes.size());
1466 nodes = topMostNodes.iterator();
1467 TaxonNode topMostNode = nodes.next();
1468 int size = topMostNode.getChildNodes().size();
1469
1470 assertEquals(0, size);
1471 }
1472
1473
1474 @Test
1475 @DataSet(value="BlankDataSet.xml")
1476 public final void testTaxonDeletionConfiguratorTaxonWithMisappliedName(){
1477
1478 Taxon testTaxon = TaxonGenerator.getTestTaxon();
1479 UUID uuid = service.save(testTaxon);
1480
1481 Taxon misappliedName = Taxon.NewInstance(BotanicalName.NewInstance(Rank.GENUS()), null);
1482
1483 Iterator<TaxonNode> nodes = testTaxon.getTaxonNodes().iterator();
1484 TaxonNode node =nodes.next();
1485 testTaxon.addMisappliedName(misappliedName, null, null);
1486 UUID misappliedNameUUID = service.save(misappliedName);
1487
1488 TaxonDeletionConfigurator config = new TaxonDeletionConfigurator() ;
1489 config.setDeleteMisappliedNamesAndInvalidDesignations(true);
1490
1491 DeleteResult result = service.deleteTaxon(testTaxon, config, null);
1492 if(!result.isOk()){
1493 Assert.fail();
1494 }
1495 commitAndStartNewTransaction(null);
1496 Taxon tax = (Taxon)service.find(uuid);
1497 assertNull(tax);
1498 tax = (Taxon)service.find(misappliedNameUUID);
1499 //TODO: is that correct or should it be deleted because there is no relation to anything
1500 assertNull(tax);
1501
1502 }
1503 @Test
1504 @DataSet(value="BlankDataSet.xml")
1505 public final void testTaxonDeletionConfiguratorTaxonWithMisappliedNameDoNotDelete(){
1506
1507 Taxon testTaxon = TaxonGenerator.getTestTaxon();
1508 UUID uuid = service.save(testTaxon);
1509
1510 Taxon misappliedName = Taxon.NewInstance(BotanicalName.NewInstance(Rank.GENUS()), null);
1511
1512 Iterator<TaxonNode> nodes = testTaxon.getTaxonNodes().iterator();
1513 TaxonNode node =nodes.next();
1514 testTaxon.addMisappliedName(misappliedName, null, null);
1515 UUID misappliedNameUUID = service.save(misappliedName);
1516
1517 TaxonDeletionConfigurator config = new TaxonDeletionConfigurator() ;
1518 config.setDeleteMisappliedNamesAndInvalidDesignations(false);
1519
1520 DeleteResult result = service.deleteTaxon(testTaxon, config, null);
1521 if(!result.isOk()){
1522 Assert.fail();
1523 }
1524 commitAndStartNewTransaction(null);
1525 Taxon tax = (Taxon)service.find(uuid);
1526 assertNull(tax);
1527 tax = (Taxon)service.find(misappliedNameUUID);
1528 //TODO: is that correct or should it be deleted because there is no relation to anything
1529 assertNotNull(tax);
1530
1531 }
1532
1533 @Test
1534 @DataSet(value="BlankDataSet.xml")
1535 public final void testTaxonDeletionConfiguratorTaxonMisappliedName(){
1536
1537 Taxon testTaxon = TaxonGenerator.getTestTaxon();
1538 UUID uuid = service.save(testTaxon);
1539
1540 Taxon misappliedNameTaxon = Taxon.NewInstance(BotanicalName.NewInstance(Rank.GENUS()), null);
1541
1542 Iterator<TaxonNode> nodes = testTaxon.getTaxonNodes().iterator();
1543 TaxonNode node =nodes.next();
1544 testTaxon.addMisappliedName(misappliedNameTaxon, null, null);
1545 UUID misappliedNameUUID = service.save(misappliedNameTaxon);
1546 misappliedNameTaxon = (Taxon)service.find(misappliedNameUUID);
1547 UUID misNameUUID = misappliedNameTaxon.getName().getUuid();
1548
1549 TaxonDeletionConfigurator config = new TaxonDeletionConfigurator() ;
1550
1551
1552 // try {
1553 service.deleteTaxon(misappliedNameTaxon, config, null);
1554 // } catch (DataChangeNoRollbackException e) {
1555 // e.printStackTrace();
1556
1557 //}
1558
1559 commitAndStartNewTransaction(null);
1560 Taxon tax = (Taxon)service.find(uuid);
1561 assertNotNull(tax);
1562 tax = (Taxon)service.find(misappliedNameUUID);
1563 BotanicalName name = (BotanicalName) nameService.find(misNameUUID);
1564
1565 assertNull(tax);
1566 assertNull(name);
1567
1568 }
1569
1570 @Test
1571 @DataSet(value="BlankDataSet.xml")
1572 public final void testLlistIncludedTaxa(){
1573 Reference<?> citation = null;
1574 String microcitation = null;
1575
1576 //Data
1577 Classification cl1 = Classification.NewInstance("testClassification1");
1578 Classification cl2 = Classification.NewInstance("testClassification2");
1579 Classification cl3 = Classification.NewInstance("testClassification3");
1580
1581 Taxon c1Genus = Taxon.NewInstance(null, null);c1Genus.setUuid(UUID.fromString("daa24f6f-7e38-4668-b385-10c789212e4e"));
1582 Taxon c1Species = Taxon.NewInstance(null, null);c1Species.setUuid(UUID.fromString("1c1d0566-67d0-4806-bf23-ecf55f4b9118"));
1583 Taxon c1SubSpecies1 = Taxon.NewInstance(null, null);c1SubSpecies1.setUuid(UUID.fromString("96ae2fad-76df-429f-b179-42e00838fea4"));
1584 Taxon c1SubSpecies2 = Taxon.NewInstance(null, null);c1SubSpecies2.setUuid(UUID.fromString("5d3f6147-ca72-40e0-be8a-6c835a09a579"));
1585 cl1.addParentChild(c1Genus, c1Species, null, null);
1586 cl1.addParentChild(c1Species, c1SubSpecies1, null, null);
1587 cl1.addParentChild(c1Species, c1SubSpecies2, null, null);
1588
1589 Taxon c2Genus = Taxon.NewInstance(null, null);c2Genus.setUuid(UUID.fromString("ed0ec006-3ac8-4a12-ae13-fdf2a13dedbe"));
1590 Taxon c2Species = Taxon.NewInstance(null, null);c2Species.setUuid(UUID.fromString("1027eb18-1c26-450e-a299-981b775ebc3c"));
1591 Taxon c2SubSpecies1 = Taxon.NewInstance(null, null);c2SubSpecies1.setUuid(UUID.fromString("61f039c8-01f3-4f5d-8e16-1602139774e7"));
1592 Taxon c2SubSpecies2 = Taxon.NewInstance(null, null);c2SubSpecies2.setUuid(UUID.fromString("2ed6b6f8-05f9-459a-a075-2bca57e3013e"));
1593 cl2.addParentChild(c2Genus, c2Species, null, null);
1594 cl2.addParentChild(c2Species, c2SubSpecies1, null, null);
1595 cl2.addParentChild(c2Species, c2SubSpecies2, null, null);
1596
1597 Taxon c3Genus = Taxon.NewInstance(null, null);c3Genus.setUuid(UUID.fromString("407dfc8d-7a4f-4370-ada4-76c1a8279d1f"));
1598 Taxon c3Species = Taxon.NewInstance(null, null);c3Species.setUuid(UUID.fromString("b6d34fc7-4aa7-41e5-b633-86f474edbbd5"));
1599 Taxon c3SubSpecies1 = Taxon.NewInstance(null, null);c3SubSpecies1.setUuid(UUID.fromString("01c07585-a422-40cd-9339-a74c56901d9f"));
1600 Taxon c3SubSpecies2 = Taxon.NewInstance(null, null);c3SubSpecies2.setUuid(UUID.fromString("390c8e23-e05f-4f89-b417-50cf080f4c91"));
1601 cl3.addParentChild(c3Genus, c3Species, null, null);
1602 cl3.addParentChild(c3Species, c3SubSpecies1, null, null);
1603 cl3.addParentChild(c3Species, c3SubSpecies2, null, null);
1604
1605 classificationService.save(cl1);
1606 classificationService.save(cl2);
1607 classificationService.save(cl3);
1608
1609 Taxon c4Genus = Taxon.NewInstance(null, null);c4Genus.setUuid(UUID.fromString("bfd6bbdd-0116-4ab2-a781-9316224aad78"));
1610 Taxon c4Species = Taxon.NewInstance(null, null);c4Species.setUuid(UUID.fromString("9347a3d9-5ece-4d64-9035-e8aaf5d3ee02"));
1611 Taxon c4SubSpecies = Taxon.NewInstance(null, null);c4SubSpecies.setUuid(UUID.fromString("777aabbe-4c3a-449c-ab99-a91f2fec9f07"));
1612
1613 TaxonRelationship rel = c1Species.addTaxonRelation(c2Species, TaxonRelationshipType.CONGRUENT_TO(), citation, microcitation);
1614 rel.setDoubtful(true);
1615 c1Species.addTaxonRelation(c4Species, TaxonRelationshipType.INCLUDES(), citation, microcitation);
1616 c2Species.addTaxonRelation(c1SubSpecies2, TaxonRelationshipType.INCLUDES(), citation, microcitation);
1617
1618 service.saveOrUpdate(c1Species);
1619 service.saveOrUpdate(c2Species);
1620
1621 //Tests
1622 //default starting at species 1
1623 IncludedTaxaDTO dto = service.listIncludedTaxa(c1Species.getUuid(), new IncludedTaxonConfiguration(null, true, false));
1624 Assert.assertNotNull("IncludedTaxaDTO", dto);
1625 Assert.assertEquals("Result should contain 7 taxa: c1Species", 7, dto.getIncludedTaxa().size());
1626 Assert.assertNotNull("date should not be null", dto.getDate());
1627 // Assert.assertTrue(dto.contains(taxonUuid));
1628 //same without doubtful
1629 dto = service.listIncludedTaxa(c1Species.getUuid(), new IncludedTaxonConfiguration(null, false, false));
1630 Assert.assertEquals(4, dto.getIncludedTaxa().size());
1631
1632 //other example starting at Genus2
1633 dto = service.listIncludedTaxa(c2Genus.getUuid(), new IncludedTaxonConfiguration(null, true, false));
1634 Assert.assertEquals(8, dto.getIncludedTaxa().size());
1635 //same without doubtful
1636 dto = service.listIncludedTaxa(c2Genus.getUuid(), new IncludedTaxonConfiguration(null, false, false));
1637 Assert.assertEquals(5, dto.getIncludedTaxa().size());
1638
1639 //only congruent
1640 dto = service.listIncludedTaxa(c1Species.getUuid(), new IncludedTaxonConfiguration(null, true, true));
1641 Assert.assertEquals(2, dto.getIncludedTaxa().size());
1642 //same without doubtful
1643 dto = service.listIncludedTaxa(c1Species.getUuid(), new IncludedTaxonConfiguration(null, false, true));
1644 Assert.assertEquals(1, dto.getIncludedTaxa().size());
1645
1646
1647
1648
1649 }
1650
1651 @Test
1652 public void testDeleteDescriptions(){
1653 try {
1654 createTestDataSet();
1655 } catch (FileNotFoundException e) {
1656 // TODO Auto-generated catch block
1657 e.printStackTrace();
1658 }
1659 TaxonDescription description = TaxonDescription.NewInstance(taxWithoutSyn);
1660 SpecimenOrObservationBase<IIdentifiableEntityCacheStrategy<FieldUnit>> specimen = FieldUnit.NewInstance();
1661 UUID uuid = occurenceService.saveOrUpdate(specimen);
1662 DescriptionElementBase element = IndividualsAssociation.NewInstance(specimen);
1663 description.addElement(element);
1664 service.saveOrUpdate(taxWithoutSyn);
1665 Taxon tax = (Taxon)service.find(uuidTaxWithoutSyn);
1666 Set<TaxonDescription> descr = tax.getDescriptions();
1667 assertEquals(1, descr.size());
1668 description = descr.iterator().next();
1669 UUID uuidDescr = description.getUuid();
1670 UUID uuidDescEl = description.getElements().iterator().next().getUuid();
1671
1672 descriptionService.deleteDescription(description);
1673 service.saveOrUpdate(tax);
1674 description = (TaxonDescription) descriptionService.find(uuidDescr);
1675 specimen = occurenceService.find(uuid);
1676 assertNull(description);
1677 DeleteResult result = occurenceService.delete(specimen);
1678 assertTrue(result.isOk());
1679
1680 }
1681
1682 /* (non-Javadoc)
1683 * @see eu.etaxonomy.cdm.test.integration.CdmIntegrationTest#createTestData()
1684 */
1685 @Override
1686 public void createTestDataSet() throws FileNotFoundException {
1687 Rank rank = Rank.SPECIES();
1688
1689 taxWithoutSyn = Taxon.NewInstance(BotanicalName.NewInstance(rank, "Test1", null, null, null, null, null, null, null), null);
1690 taxWithSyn = Taxon.NewInstance(BotanicalName.NewInstance(rank, "Test3", null, null, null, null, null, null, null), null);
1691 tax2WithSyn = Taxon.NewInstance(BotanicalName.NewInstance(rank, "Test5", null, null, null, null, null, null, null), null);
1692 synonym = Synonym.NewInstance(BotanicalName.NewInstance(rank, "Test2", null, null, null, null, null, null, null), null);
1693 synonym2 = Synonym.NewInstance(BotanicalName.NewInstance(rank, "Test4", null, null, null, null, null, null, null), null);
1694 synonym2.getName().setHomotypicalGroup(synonym.getHomotypicGroup());
1695
1696 taxWithSyn.addSynonym(synonym, SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF());
1697 taxWithSyn.addSynonym(synonym2, SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF());
1698
1699 uuidTaxWithoutSyn = service.save(taxWithoutSyn);
1700 uuidSyn = service.save(synonym);
1701 uuidSyn2 = service.save(synonym2);
1702 uuidTaxWithSyn =service.save(taxWithSyn);
1703
1704 }
1705
1706
1707 }
1708
1709
1710