Project

General

Profile

Download (53.2 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2007 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.persistence.dao.hibernate.common;
10

    
11
import static org.junit.Assert.assertEquals;
12

    
13
import java.io.FileNotFoundException;
14
import java.util.ArrayList;
15
import java.util.Arrays;
16
import java.util.List;
17
import java.util.Set;
18
import java.util.UUID;
19

    
20
import org.apache.logging.log4j.LogManager;
21
import org.apache.logging.log4j.Logger;
22
import org.junit.Assert;
23
import org.junit.Before;
24
import org.junit.Test;
25
import org.unitils.dbunit.annotation.DataSet;
26
import org.unitils.dbunit.annotation.DataSets;
27
import org.unitils.spring.annotation.SpringBeanByType;
28

    
29
import eu.etaxonomy.cdm.common.URI;
30
import eu.etaxonomy.cdm.model.agent.Address;
31
import eu.etaxonomy.cdm.model.agent.AgentBase;
32
import eu.etaxonomy.cdm.model.agent.Contact;
33
import eu.etaxonomy.cdm.model.agent.Institution;
34
import eu.etaxonomy.cdm.model.agent.InstitutionalMembership;
35
import eu.etaxonomy.cdm.model.agent.Person;
36
import eu.etaxonomy.cdm.model.agent.Team;
37
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
38
import eu.etaxonomy.cdm.model.common.Annotation;
39
import eu.etaxonomy.cdm.model.common.AnnotationType;
40
import eu.etaxonomy.cdm.model.common.CdmBase;
41
import eu.etaxonomy.cdm.model.common.Credit;
42
import eu.etaxonomy.cdm.model.common.Extension;
43
import eu.etaxonomy.cdm.model.common.ExtensionType;
44
import eu.etaxonomy.cdm.model.common.ICdmBase;
45
import eu.etaxonomy.cdm.model.common.IdentifiableSource;
46
import eu.etaxonomy.cdm.model.common.Identifier;
47
import eu.etaxonomy.cdm.model.common.IntextReference;
48
import eu.etaxonomy.cdm.model.common.LSIDAuthority;
49
import eu.etaxonomy.cdm.model.common.Language;
50
import eu.etaxonomy.cdm.model.common.LanguageString;
51
import eu.etaxonomy.cdm.model.common.Marker;
52
import eu.etaxonomy.cdm.model.common.MarkerType;
53
import eu.etaxonomy.cdm.model.common.RelationshipTermBase;
54
import eu.etaxonomy.cdm.model.common.TimePeriod;
55
import eu.etaxonomy.cdm.model.common.VerbatimTimePeriod;
56
import eu.etaxonomy.cdm.model.description.CategoricalData;
57
import eu.etaxonomy.cdm.model.description.CommonTaxonName;
58
import eu.etaxonomy.cdm.model.description.DescriptionBase;
59
import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
60
import eu.etaxonomy.cdm.model.description.Distribution;
61
import eu.etaxonomy.cdm.model.description.Feature;
62
import eu.etaxonomy.cdm.model.description.IndividualsAssociation;
63
import eu.etaxonomy.cdm.model.description.MeasurementUnit;
64
import eu.etaxonomy.cdm.model.description.MediaKey;
65
import eu.etaxonomy.cdm.model.description.PresenceAbsenceTerm;
66
import eu.etaxonomy.cdm.model.description.QuantitativeData;
67
import eu.etaxonomy.cdm.model.description.SpecimenDescription;
68
import eu.etaxonomy.cdm.model.description.State;
69
import eu.etaxonomy.cdm.model.description.StateData;
70
import eu.etaxonomy.cdm.model.description.StatisticalMeasure;
71
import eu.etaxonomy.cdm.model.description.StatisticalMeasurementValue;
72
import eu.etaxonomy.cdm.model.description.TaxonDescription;
73
import eu.etaxonomy.cdm.model.description.TaxonInteraction;
74
import eu.etaxonomy.cdm.model.description.TaxonNameDescription;
75
import eu.etaxonomy.cdm.model.description.TextData;
76
import eu.etaxonomy.cdm.model.description.TextFormat;
77
import eu.etaxonomy.cdm.model.location.Country;
78
import eu.etaxonomy.cdm.model.location.NamedArea;
79
import eu.etaxonomy.cdm.model.location.NamedAreaLevel;
80
import eu.etaxonomy.cdm.model.location.NamedAreaType;
81
import eu.etaxonomy.cdm.model.location.Point;
82
import eu.etaxonomy.cdm.model.location.ReferenceSystem;
83
import eu.etaxonomy.cdm.model.media.AudioFile;
84
import eu.etaxonomy.cdm.model.media.ImageFile;
85
import eu.etaxonomy.cdm.model.media.Media;
86
import eu.etaxonomy.cdm.model.media.MediaRepresentation;
87
import eu.etaxonomy.cdm.model.media.MediaRepresentationPart;
88
import eu.etaxonomy.cdm.model.media.MovieFile;
89
import eu.etaxonomy.cdm.model.media.Rights;
90
import eu.etaxonomy.cdm.model.media.RightsType;
91
import eu.etaxonomy.cdm.model.metadata.CdmPreference;
92
import eu.etaxonomy.cdm.model.molecular.Amplification;
93
import eu.etaxonomy.cdm.model.molecular.DnaSample;
94
import eu.etaxonomy.cdm.model.molecular.PhylogeneticTree;
95
import eu.etaxonomy.cdm.model.molecular.Primer;
96
import eu.etaxonomy.cdm.model.molecular.Sequence;
97
import eu.etaxonomy.cdm.model.molecular.SingleRead;
98
import eu.etaxonomy.cdm.model.molecular.SingleReadAlignment;
99
import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
100
import eu.etaxonomy.cdm.model.name.HybridRelationship;
101
import eu.etaxonomy.cdm.model.name.HybridRelationshipType;
102
import eu.etaxonomy.cdm.model.name.IBotanicalName;
103
import eu.etaxonomy.cdm.model.name.NameRelationship;
104
import eu.etaxonomy.cdm.model.name.NameRelationshipType;
105
import eu.etaxonomy.cdm.model.name.NameTypeDesignation;
106
import eu.etaxonomy.cdm.model.name.NameTypeDesignationStatus;
107
import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
108
import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;
109
import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;
110
import eu.etaxonomy.cdm.model.name.Rank;
111
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
112
import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignationStatus;
113
import eu.etaxonomy.cdm.model.name.TaxonName;
114
import eu.etaxonomy.cdm.model.name.TaxonNameFactory;
115
import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
116
import eu.etaxonomy.cdm.model.occurrence.Collection;
117
import eu.etaxonomy.cdm.model.occurrence.DerivationEvent;
118
import eu.etaxonomy.cdm.model.occurrence.DerivationEventType;
119
import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
120
import eu.etaxonomy.cdm.model.occurrence.DeterminationEvent;
121
import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
122
import eu.etaxonomy.cdm.model.occurrence.GatheringEvent;
123
import eu.etaxonomy.cdm.model.occurrence.PreservationMethod;
124
import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
125
import eu.etaxonomy.cdm.model.permission.GrantedAuthorityImpl;
126
import eu.etaxonomy.cdm.model.permission.Group;
127
import eu.etaxonomy.cdm.model.permission.User;
128
import eu.etaxonomy.cdm.model.reference.IBook;
129
import eu.etaxonomy.cdm.model.reference.IBookSection;
130
import eu.etaxonomy.cdm.model.reference.OriginalSourceBase;
131
import eu.etaxonomy.cdm.model.reference.OriginalSourceType;
132
import eu.etaxonomy.cdm.model.reference.Reference;
133
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
134
import eu.etaxonomy.cdm.model.taxon.Classification;
135
import eu.etaxonomy.cdm.model.taxon.Synonym;
136
import eu.etaxonomy.cdm.model.taxon.SynonymType;
137
import eu.etaxonomy.cdm.model.taxon.Taxon;
138
import eu.etaxonomy.cdm.model.taxon.TaxonBase;
139
import eu.etaxonomy.cdm.model.taxon.TaxonNode;
140
import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
141
import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
142
import eu.etaxonomy.cdm.model.term.DefinedTerm;
143
import eu.etaxonomy.cdm.model.term.DefinedTermBase;
144
import eu.etaxonomy.cdm.model.term.OrderedTermBase;
145
import eu.etaxonomy.cdm.model.term.OrderedTermVocabulary;
146
import eu.etaxonomy.cdm.model.term.Representation;
147
import eu.etaxonomy.cdm.model.term.TermNode;
148
import eu.etaxonomy.cdm.model.term.TermTree;
149
import eu.etaxonomy.cdm.model.term.TermVocabulary;
150
import eu.etaxonomy.cdm.model.view.AuditEvent;
151
import eu.etaxonomy.cdm.persistence.dao.agent.IAgentDao;
152
import eu.etaxonomy.cdm.persistence.dao.name.ITaxonNameDao;
153
import eu.etaxonomy.cdm.persistence.dao.occurrence.IOccurrenceDao;
154
import eu.etaxonomy.cdm.persistence.dao.reference.IReferenceDao;
155
import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao;
156
import eu.etaxonomy.cdm.persistence.dto.ReferencingObjectDto;
157
import eu.etaxonomy.cdm.strategy.match.DefaultMatchStrategy;
158
import eu.etaxonomy.cdm.strategy.match.IMatchStrategy;
159
import eu.etaxonomy.cdm.strategy.match.IMatchStrategyEqual;
160
import eu.etaxonomy.cdm.strategy.match.MatchException;
161
import eu.etaxonomy.cdm.strategy.match.MatchStrategyFactory;
162
import eu.etaxonomy.cdm.strategy.merge.DefaultMergeStrategy;
163
import eu.etaxonomy.cdm.strategy.merge.IMergeStrategy;
164
import eu.etaxonomy.cdm.strategy.merge.MergeException;
165
import eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl;
166
import eu.etaxonomy.cdm.test.integration.CdmTransactionalIntegrationTest;
167
import eu.etaxonomy.cdm.test.unitils.CleanSweepInsertLoadStrategy;
168

    
169
/**
170
 * @author a.mueller
171
 * @since 27.07.2009
172
 */
173
public class CdmGenericDaoImplTest extends CdmTransactionalIntegrationTest {
174

    
175
    private static final Logger logger = LogManager.getLogger(CdmGenericDaoImplTest.class);
176

    
177
	@SpringBeanByType
178
	private CdmGenericDaoImpl cdmGenericDao;
179

    
180
	@SpringBeanByType
181
	private ITaxonDao taxonDao;
182

    
183
	@SpringBeanByType
184
	private IOccurrenceDao occurrenceDao;
185

    
186
	@SpringBeanByType
187
	private ITaxonNameDao nameDao;
188

    
189
	@SpringBeanByType
190
	private IAgentDao agentDao;
191

    
192
    @SpringBeanByType
193
    private IReferenceDao referenceDao;
194

    
195
	@Before
196
	public void setUp() throws Exception {}
197

    
198
// ***************** TESTS **************************************************
199

    
200
	@Test
201
	@DataSets({
202
      @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="/eu/etaxonomy/cdm/database/ClearDB_with_Terms_DataSet.xml"),
203
      @DataSet("/eu/etaxonomy/cdm/database/TermsDataSet-with_auditing_info.xml")}
204
	)
205
	public void testDelete(){
206
		Reference ref1 = ReferenceFactory.newBook();
207
		Reference ref2 = ReferenceFactory.newBook();
208
		Annotation annotation = Annotation.NewInstance("Anno1", null);
209
		ref1.addAnnotation(annotation);
210
		cdmGenericDao.saveOrUpdate(ref1);
211
		cdmGenericDao.saveOrUpdate(ref2);
212
		List<Reference> list = cdmGenericDao.list(Reference.class, 10, 0, null, null);
213

    
214
		try {
215
			cdmGenericDao.merge(ref2, ref1, null);
216

    
217
		} catch (MergeException e) {
218
			Assert.fail();
219
		}
220
		commitAndStartNewTransaction(null);
221
		list = cdmGenericDao.list(Reference.class, 10, 0, null, null);
222
		Assert.assertEquals(1, list.size());
223
	}
224

    
225
	@Test
226
	public void testGetCdmBasesByFieldAndClass() {
227
		logger.warn("Not yet implemented");
228
	}
229

    
230
	@Test
231
	public void testGetCdmBasesWithItemInCollection() {
232
		logger.warn("Not yet implemented");
233
	}
234

    
235
	@Test
236
	public void testGetAllPersistedClasses() {
237
		Class<?>[] existingClassesArray = {
238
				Address.class,
239
				AgentBase.class,
240
				Institution.class,
241
				InstitutionalMembership.class,
242
				Person.class,
243
				Team.class,
244
				TeamOrPersonBase.class,
245
				Annotation.class,
246
				AnnotationType.class,
247
				Credit.class,
248
				DefinedTermBase.class,
249
				Extension.class,
250
				ExtensionType.class,
251
				GrantedAuthorityImpl.class,
252
				Group.class,
253
				IdentifiableSource.class,
254
				Identifier.class,
255
				IntextReference.class,
256
				Language.class,
257
				LanguageString.class,
258
				LSIDAuthority.class,
259
				Marker.class,
260
				MarkerType.class,
261
				OrderedTermBase.class,
262
				OrderedTermVocabulary.class,
263
				OriginalSourceBase.class,
264
				RelationshipTermBase.class,
265
				Representation.class,
266
				TermVocabulary.class,
267
				User.class,
268
				DefinedTerm.class,
269

    
270
				CategoricalData.class,
271
				CommonTaxonName.class,
272
				DescriptionBase.class,
273
				DescriptionElementBase.class,
274
				Distribution.class,
275
				Feature.class,
276
				TermNode.class,
277
				TermTree.class,
278
				MediaKey.class,
279
				IndividualsAssociation.class,
280
				MeasurementUnit.class,
281
				PresenceAbsenceTerm.class,
282
				QuantitativeData.class,
283
				SpecimenDescription.class,
284
				State.class,
285
				StateData.class,
286
				StatisticalMeasure.class,
287
				StatisticalMeasurementValue.class,
288
				TaxonDescription.class,
289
				TaxonInteraction.class,
290
				TaxonNameDescription.class,
291
				TextData.class,
292
				TextFormat.class,
293
				NamedArea.class,
294
				NamedAreaLevel.class,
295
				NamedAreaType.class,
296
				ReferenceSystem.class,
297
				Country.class,
298
				AudioFile.class,
299
				ImageFile.class,
300
				Media.class,
301
				MediaRepresentation.class,
302
				MediaRepresentationPart.class,
303
				MovieFile.class,
304
				Rights.class,
305
				RightsType.class,
306
				Amplification.class,
307
				DnaSample.class,
308
				SingleRead.class,
309
				SingleReadAlignment.class,
310
				Primer.class,
311
				Sequence.class,
312
				PhylogeneticTree.class,
313
				Sequence.class,
314
				HomotypicalGroup.class,
315
				HybridRelationship.class,
316
				HybridRelationshipType.class,
317
				NameRelationship.class,
318
				NameRelationshipType.class,
319
				NameTypeDesignation.class,
320
				NameTypeDesignationStatus.class,
321
				NomenclaturalStatus.class,
322
				NomenclaturalStatusType.class,
323
				Rank.class,
324
				SpecimenTypeDesignation.class,
325
				SpecimenTypeDesignationStatus.class,
326
				TaxonName.class,
327
				TypeDesignationBase.class,
328
				Collection.class,
329
				DerivationEvent.class,
330
				DerivationEventType.class,
331
				DerivedUnit.class,
332
				DeterminationEvent.class,
333
				FieldUnit.class,
334
				GatheringEvent.class,
335
				PreservationMethod.class,
336
				SpecimenOrObservationBase.class,
337
				Reference.class,
338
				Synonym.class,
339
				SynonymType.class,
340
				Taxon.class,
341
				TaxonBase.class,
342
				TaxonNode.class,
343
				Classification.class,
344
				TaxonRelationship.class,
345
				TaxonRelationshipType.class ,
346
				//Contact.class,  //these are embedabble classes
347
				//LSID.class,
348
				//Point.class,
349
				//NomenclaturalCode.class,
350
		}	;
351
		List<Class<?>> existingClassesList = new ArrayList<>();
352
		existingClassesList.addAll(Arrays.asList(existingClassesArray));
353
		boolean includeAbstractClasses = true;
354
		Set<Class<? extends CdmBase>> foundClasses = cdmGenericDao.getAllPersistedClasses(includeAbstractClasses);
355

    
356
		//for debugging only
357
		//		for (Class existingClass : existingClassesList){
358
		//			if (! foundClasses.contains(existingClass)){
359
		//				logger.warn("Class not found: " + existingClass.getCanonicalName());
360
		//			}
361
		//		}
362

    
363
		//All classes must be found
364
		Assert.assertTrue("all classes must be found by getAllCdmClasses() method", foundClasses.containsAll(existingClassesList));
365

    
366
		//No extra classes must be found
367
		for (Class<?> clazz : foundClasses){
368
			if (! CdmBase.class.isAssignableFrom(clazz)&& !( AuditEvent.class == clazz) && !( CdmPreference.class == clazz)  ){ //OLD: && !( LSID.class == clazz)&& !( NomenclaturalCode.class == clazz) && !( Point.class == clazz) && !( Modifier.class == clazz) && !( Contact.class == clazz)
369
				Assert.fail("Class " + clazz.getName() + " is not assignable from CdmBase");
370
			}
371
		}
372

    
373
		includeAbstractClasses = false;
374
		Set<Class<? extends CdmBase>> noAbstractClasses = cdmGenericDao.getAllPersistedClasses(includeAbstractClasses);
375
		Class<?> abstractClassToTest = TaxonBase.class;
376
		Assert.assertFalse("Abstract class " + abstractClassToTest.getName() + " may not be in set ", noAbstractClasses.contains(abstractClassToTest));
377
	}
378

    
379
	@Test
380
	@DataSets({
381
	     @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="/eu/etaxonomy/cdm/database/ClearDB_with_Terms_DataSet.xml"),
382
	     @DataSet("/eu/etaxonomy/cdm/database/TermsDataSet-with_auditing_info.xml")})
383
	public void testGetReferencingObjectsCdmBase() {
384
		IBotanicalName name = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
385
		name.setTitleCache("A name", true);
386
		Reference ref1 = ReferenceFactory.newArticle();
387
		Taxon taxon = Taxon.NewInstance(name, ref1);
388
		Person author = Person.NewInstance();
389
		author.setTitleCache("Author", true);
390
		ref1.addAnnotation(Annotation.NewInstance("A1", Language.DEFAULT()));
391
		ref1.setAuthorship(author);
392
		name.setBasionymAuthorship(author);
393

    
394
		name.setNomenclaturalReference(ref1);
395

    
396
		taxonDao.save(taxon);
397
//		UUID uuid = UUID.fromString("613980ac-9bd5-43b9-a374-d71e1794688f");
398
//		Reference ref1 = referenceService.findByUuid(uuid);
399
		commitAndStartNewTransaction(null);
400

    
401
		Set<CdmBase> referencedObjects = cdmGenericDao.getReferencingObjects(ref1);
402
		String debug = "############## RESULT ###################";
403
		for (CdmBase obj: referencedObjects){
404
			debug += "Object1: " + obj.getClass().getSimpleName() + " - " + obj;
405
		}
406
		//was 3 before bidirectionality was removed for supplemental data
407
		assertEquals(2, referencedObjects.size());
408
		debug += "############## END ###################";
409

    
410
//		UUID uuidAuthor = UUID.fromString("4ce66544-a5a3-4601-ab0b-1f0a1338327b");
411
//		AgentBase author = agentService.findByUuid(uuidAuthor);
412

    
413
		referencedObjects = cdmGenericDao.getReferencingObjects(author);
414
		debug += "############## RESULT ###################";
415
		for (CdmBase obj: referencedObjects){
416
			debug += "Object2: " + obj.getClass().getSimpleName() + " - " + obj;
417
		}
418
		assertEquals(2, referencedObjects.size());
419
		debug += "############## END ###################";
420
		logger.info(debug);
421
	}
422

    
423

    
424
	//similar to testGetReferencingObjectsCdmBase but with DTO
425
	@Test
426
    @DataSets({
427
         @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="/eu/etaxonomy/cdm/database/ClearDB_with_Terms_DataSet.xml"),
428
         @DataSet("/eu/etaxonomy/cdm/database/TermsDataSet-with_auditing_info.xml")})
429
    public void testGetReferencingObjectsDto() {
430

    
431
	    IBotanicalName name = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
432
        name.setTitleCache("A name", true);
433
        Reference ref1 = ReferenceFactory.newArticle();
434
        Taxon taxon = Taxon.NewInstance(name, ref1);
435
        Person author = Person.NewInstance();
436
        author.setTitleCache("Author", true);
437
        ref1.addAnnotation(Annotation.NewInstance("A1", Language.DEFAULT()));
438
        ref1.setAuthorship(author);
439
        name.setCombinationAuthorship(author);
440
        name.setBasionymAuthorship(author);  //to test deduplication
441

    
442
        name.setNomenclaturalReference(ref1);
443

    
444
        taxonDao.save(taxon);
445
//	      UUID uuid = UUID.fromString("613980ac-9bd5-43b9-a374-d71e1794688f");
446
//	      Reference ref1 = referenceService.findByUuid(uuid);
447
        commitAndStartNewTransaction(null);
448

    
449
        int i = 1;
450
        Set<ReferencingObjectDto> referencedObjects = cdmGenericDao.getReferencingObjectsDto(ref1);
451
        String debug = "############## RESULT for ref1 ###################\n";
452
        for (ReferencingObjectDto dto: referencedObjects){
453
            debug += "Object"+ i++ +": " + dto.getType().getSimpleName() + " - " + dto + "\n";
454
        }
455
        //was 3 before bidirectionality was removed for supplemental data
456
        assertEquals(2, referencedObjects.size());
457
        debug += "############## END ###################\n";
458

    
459
//	      UUID uuidAuthor = UUID.fromString("4ce66544-a5a3-4601-ab0b-1f0a1338327b");
460
//	      AgentBase author = agentService.findByUuid(uuidAuthor);
461

    
462
        referencedObjects = cdmGenericDao.getReferencingObjectsDto(author);
463
        i = 1;
464
        debug += "############## RESULT for author ###################\n";
465
        for (ReferencingObjectDto dto: referencedObjects){
466
            debug += "Object"+ i++ +": " + dto.getType().getSimpleName() + " - " + dto + "\n";
467
        }
468
        assertEquals("The both taxon names should be dedulicated", 2, referencedObjects.size());
469
        debug += "############## END ###################\n";
470
        logger.warn(debug);
471
    }
472

    
473
	/**
474
	 * 2nd test method for {@link eu.etaxonomy.cdm.persistence.dao.hibernate.common.CdmGenericDaoImpl#getReferencingObjects(CdmBase)}.
475
	 */
476
	@Test
477
	@DataSet
478
	public final void testGetReferencingObjects2() {
479
//		SpecimenDescription desc1 = SpecimenDescription.NewInstance();
480
//		desc1.setTitleCache("desc1");
481
//		SpecimenDescription desc2 = SpecimenDescription.NewInstance();
482
//		desc2.setTitleCache("desc2");
483
//
484
//		SpecimenOrObservationBase spec1 = Specimen.NewInstance();
485
//
486
//		desc1.addDescribedSpecimenOrObservation(spec1);
487
//		//Taxon taxon = Taxon.NewInstance(taxonName, sec)
488
//		spec1.addDescription(desc2);
489
//
490
//		occurrenceService.save(spec1);
491

    
492
		UUID uuidSpec = UUID.fromString("41539e9c-3764-4f14-9712-2d07d00c8e4c");
493
		SpecimenOrObservationBase<?> spec1 = occurrenceDao.findByUuid(uuidSpec);
494

    
495
		Set<CdmBase> referencingObjects = cdmGenericDao.getReferencingObjects(spec1);
496
//		System.out.println("############## RESULT ###################");
497
//		for (CdmBase obj: referencingObjects){
498
//			System.out.println("Object: " + obj.getClass().getSimpleName() + " - " + obj);
499
//		}
500
//		System.out.println("############## END ###################");
501
		assertEquals("Number of referencing objects must be 2.", 2, referencingObjects.size());
502
	}
503

    
504
	/**
505
	 * Test method for {@link eu.etaxonomy.cdm.persistence.dao.hibernate.common.CdmGenericDaoImpl#merge(CdmBase, CdmBase)}.
506
	 * @throws MergeException
507
	 */
508
	@Test
509
	public void testMergeCdmBaseReferenceAndIdentifiable() throws MergeException {
510

    
511
		TaxonName name1 = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
512
		name1.setTitleCache("BotanicalName1", true);
513

    
514
		TaxonName name2 = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
515
		name2.setTitleCache("BotanicalName2", true);
516

    
517
		TaxonName zooName1 = TaxonNameFactory.NewZoologicalInstance(Rank.SPECIES());
518
		name1.setTitleCache("ZoologicalName1", true);
519

    
520
		Reference article1 = ReferenceFactory.newArticle();
521
		Reference article2 = ReferenceFactory.newArticle();
522

    
523
		name1.setNomenclaturalReference(article1);
524
		name2.setNomenclaturalReference(article2);
525

    
526
		Taxon taxon1 = Taxon.NewInstance(name1, article1);
527
		Taxon taxon2 = Taxon.NewInstance(name2, article2);
528

    
529
//		Person author = Person.NewInstance();
530
//		author.setTitleCache("Author");
531
		Annotation annotation1 = Annotation.NewInstance("A1", Language.DEFAULT());
532
		Annotation annotation2 = Annotation.NewInstance("A2", Language.DEFAULT());
533

    
534
		article1.addAnnotation(annotation1);
535
		article2.addAnnotation(annotation2);
536

    
537
		Marker marker1 = Marker.NewInstance(MarkerType.COMPLETE(), false);
538
		Marker marker2 = Marker.NewInstance(MarkerType.IMPORTED(), false);
539

    
540
		article1.addMarker(marker1);
541
		article2.addMarker(marker2);
542

    
543
		Rights rights1 = Rights.NewInstance();
544
		Rights rights2 = Rights.NewInstance();
545

    
546
		article1.addRights(rights1);
547
		article2.addRights(rights2);
548

    
549
		Credit credit1 = Credit.NewInstance(Team.NewInstance(), TimePeriod.NewInstance(2002), "credit1");
550
		Credit credit2 = Credit.NewInstance(Team.NewInstance(), TimePeriod.NewInstance(2015), "credit2");
551

    
552
		article1.addCredit(credit1);
553
		article2.addCredit(credit2);
554

    
555
		Extension extension1 = Extension.NewInstance();
556
		Extension extension2 = Extension.NewInstance();
557

    
558
		article1.addExtension(extension1);
559
		article2.addExtension(extension2);
560

    
561
		IdentifiableSource source1 = IdentifiableSource.NewInstance(OriginalSourceType.Unknown);
562
		IdentifiableSource source2 = IdentifiableSource.NewInstance(OriginalSourceType.Unknown);
563

    
564
		article1.addSource(source1);
565
		article2.addSource(source2);
566

    
567
		Media media1 = Media.NewInstance();
568
		Media media2 = Media.NewInstance();
569

    
570
		article1.addMedia(media1);
571
		article2.addMedia(media2);
572

    
573
//		ref1.setAuthorship(author);
574
//		name1.setBasionymAuthorship(author);
575

    
576
		name1.setNomenclaturalReference(article1);
577

    
578
		nameDao.save(name1);
579
		nameDao.save(name2);
580
		nameDao.save(zooName1);
581

    
582
		TaxonDescription taxDesc = TaxonDescription.NewInstance(taxon1);
583
		taxDesc.setTitleCache("taxDesc", true);
584
		taxDesc.addSource(OriginalSourceType.Unknown, null, null, article2, null);
585

    
586
		taxonDao.save(taxon1);
587

    
588
		//unidircetional reference to the merged object should be redirected
589
		cdmGenericDao.merge(article1, article2, null);
590
		Assert.assertEquals("Name2 must have article 1 as new nomRef", article1 ,name2.getNomenclaturalReference());
591
		//TODO microCitations!! -> warning
592

    
593
		//Annotations
594
		Assert.assertEquals("Annotation number should be 2 (1 from each of the merged objects)", 2, article1.getAnnotations().size());
595

    
596
		//Marker
597
		Assert.assertEquals("Marker number should be 2 (1 from each of the merged objects)", 2, article1.getMarkers().size());
598

    
599
		//Rights
600
		Assert.assertEquals("Rights number should be 2 (1 from each of the merged objects)", 2, article1.getRights().size());
601

    
602
		//Credits
603
		Assert.assertEquals("Credits number should be 2 (1 from each of the merged objects)", 2, article1.getCredits().size());
604

    
605
		//Extensions
606
		Assert.assertEquals("Extensions number should be 2 (1 from each of the merged objects)", 2, article1.getExtensions().size());
607

    
608
		//Sources
609
		Assert.assertEquals("Sources number should be 2 (1 from each of the merged objects)", 2, article1.getSources().size());
610

    
611
		//Media
612
		Assert.assertEquals("Media number should be 2 (1 from each of the merged objects)", 2, article1.getMedia().size());
613

    
614
		//Description sources
615
		Assert.assertEquals("Number of sources for taxon description must be 1", 1, taxDesc.getSources().size());
616
		Assert.assertEquals("Taxon description must have article1 as source", taxDesc.getSources().iterator().next().getCitation(),article1);
617

    
618
		//test exceptions
619

    
620
		testMergeExceptions(name1, name2, taxon1, zooName1);
621

    
622
		//FIXME TO BE IMPLEMENTED
623
		//current defalt implementation for rights, credits and media is ADD_CLONE and therefore the below tests don't work
624
		//TODO is this the wanted default behaviour?
625
//		Assert.assertTrue("Rights2 must be contained in the rights", article1.getRights().contains(rights2));
626
//		Assert.assertTrue("Credits2 must be contained in the credits", article1.getCredits().contains(credit2));
627
//		Assert.assertTrue("Media2 must be contained in the media", article1.getMedia().contains(media2));
628

    
629
	}
630

    
631
	@Test
632
	public void testMergeTaxonNameAndTaxon() throws MergeException {
633
	    TaxonName name1 = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
634
		name1.setTitleCache("BotanicalName1", true);
635

    
636
		TaxonName name2 = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
637
		name2.setTitleCache("BotanicalName2", true);
638

    
639
		IBotanicalName name3 = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
640
		name3.setTitleCache("BotanicalName3", true);
641

    
642
		Reference database = ReferenceFactory.newDatabase();
643

    
644
		Taxon taxon1 = Taxon.NewInstance(name1, database);
645
		Taxon taxon2 = Taxon.NewInstance(name2, database);
646
		Taxon taxon3 = Taxon.NewInstance(name3, database);
647

    
648
		taxonDao.save(taxon1);
649
		taxonDao.save(taxon2);
650
		taxonDao.save(taxon3);
651

    
652
		cdmGenericDao.merge(name1, name2, null);
653
		Assert.assertEquals("Name1 must have 2 taxa attached now.", 2 ,name1.getTaxonBases().size());
654
		Assert.assertEquals("Taxon2 must have name1 as new name.", name1 ,taxon2.getName());
655

    
656
//TODO
657
//		cdmGenericDao.merge(taxon1, taxon3, null);
658
//		Assert.assertEquals("Name1 must have 3 taxa attached now.", 3 ,name1.getTaxonBases().size());
659
	}
660

    
661
	@Test
662
	public void testMergeAuthors() throws MergeException {
663

    
664
		IBotanicalName name1 = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
665
		name1.setTitleCache("BotanicalName1", true);
666

    
667
		IBotanicalName name2 = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
668
		name2.setTitleCache("BotanicalName2", true);
669

    
670
		IBook book1 = ReferenceFactory.newBook();
671
		IBook book2 = ReferenceFactory.newBook();
672

    
673
		Team team1 = Team.NewInstance();
674
		Team team2 = Team.NewInstance();
675
		Team team3 = Team.NewInstance();
676
		team1.setTitleCache("team1", true);
677
		team2.setTitleCache("team2", true);
678
		team3.setTitleCache("team3", true);
679

    
680
		Person person1 = Person.NewTitledInstance("person1");
681
		Person person2 = Person.NewTitledInstance("person2");
682
		Person person3 = Person.NewTitledInstance("person3");
683

    
684
		team1.setNomenclaturalTitleCache("T.1", true);
685
		String street1 = "Strasse1";
686
		team1.setContact(Contact.NewInstance(street1, "12345", "Berlin", Country.ARGENTINAARGENTINEREPUBLIC(),"pobox" , "Region", "a@b.de", "f12345", "+49-30-123456", URI.create("www.abc.de"), Point.NewInstance(2.4, 3.2, ReferenceSystem.WGS84(), 3)));
687
		team2.setContact(Contact.NewInstance("Street2", null, "London", null, null, null, null, "874599873", null, null, null));
688
		String street3 = "Street3";
689
		team2.addAddress(street3, null, null, null, null, null, Point.NewInstance(1.1, 2.2, null, 4));
690
		String emailAddress1 = "Email1";
691
		team1.addEmailAddress(emailAddress1);
692

    
693
		team2.addTeamMember(person1);
694
		team2.addTeamMember(person2);
695
		String emailAddress2 = "Email2";
696
		team2.addEmailAddress(emailAddress2);
697

    
698
		team3.addTeamMember(person3);
699
		team3.addEmailAddress("emailAddress3");
700

    
701
		book1.setAuthorship(team2);
702
		book2.setAuthorship(team3);
703

    
704
		Credit credit1 = Credit.NewInstance(team3, TimePeriod.NewInstance(1955), "credit1");
705
		book2.addCredit(credit1);
706

    
707
		agentDao.save(team1);
708
		agentDao.save(team2);
709
		agentDao.save(team3);
710
		cdmGenericDao.save((Reference)book1);
711
		cdmGenericDao.save((Reference)book2);
712

    
713
		cdmGenericDao.merge(team2, team3, null);
714

    
715
		Assert.assertSame("Author of book1 must be team2.", team2, book1.getAuthorship());
716
		Assert.assertSame("Author of book2 must be team2.", team2, book2.getAuthorship());
717
		Assert.assertSame("Agent of credit1 must be team2.", team2, credit1.getAgent());
718

    
719
		Assert.assertEquals("Team2 must have 3 persons as members.",3, team2.getTeamMembers().size());
720
		Assert.assertTrue("Team2 must have person3 as new member.", team2.getTeamMembers().contains(person3));
721
		Assert.assertSame("Team2 must have person3 as third member.",person3, team2.getTeamMembers().get(2));
722

    
723
		//Contact
724
		cdmGenericDao.merge(team2, team1, null);
725
		Contact team2Contact = team2.getContact();
726
		Assert.assertNotNull("team2Contact must not be null", team2Contact);
727
		Assert.assertNotNull("Addresses must not be null", team2Contact.getAddresses());
728
		Assert.assertEquals("Number of addresses must be 3", 3, team2Contact.getAddresses().size());
729
		Assert.assertEquals("Number of email addresses must be 4", 4, team2Contact.getEmailAddresses().size());
730

    
731
		boolean street1Exists = false;
732
		boolean street3Exists = false;
733
		boolean country1Exists = false;
734
		for  (Address address : team2Contact.getAddresses()){
735
			if (street1.equals(address.getStreet())){
736
				street1Exists = true;
737
			}
738
			if (street3.equals(address.getStreet())){
739
				street3Exists = true;
740
			}
741
			if (Country.ARGENTINAARGENTINEREPUBLIC() == address.getCountry()){
742
				country1Exists = true;
743
			}
744
		}
745
		Assert.assertTrue("Street1 must be one of the streets in team2's addresses", street1Exists);
746
		Assert.assertTrue("Street3 must be one of the streets in team2's addressesss", street3Exists);
747
		Assert.assertTrue("Argentina must be one of the countries in team2's addresses", country1Exists);
748

    
749
		//Person
750
		Institution institution1 = Institution.NewInstance();
751
		institution1.setTitleCache("inst1", true);
752
		Institution institution2 = Institution.NewInstance();
753
		institution2.setTitleCache("inst2", true);
754

    
755
		TimePeriod period1 = TimePeriod.NewInstance(2002, 2004);
756
		TimePeriod period2 = TimePeriod.NewInstance(2004, 2006);
757

    
758
		person1.addInstitutionalMembership(institution1, period1, "departement1", "role1");
759
		person2.addInstitutionalMembership(institution2, period2, "departement2", "role2");
760

    
761
		IMergeStrategy personMergeStrategy = DefaultMergeStrategy.NewInstance(Person.class);
762
		personMergeStrategy.invoke(person1, person2);
763

    
764
		Assert.assertEquals("Number of institutional memberships must be 2", 2, person1.getInstitutionalMemberships().size());
765
		for (InstitutionalMembership institutionalMembership : person1.getInstitutionalMemberships()){
766
			Assert.assertSame("Person of institutional memebership must be person1", person1, institutionalMembership.getPerson());
767
		}
768
	}
769

    
770
	/**
771
     * Test method for {@link eu.etaxonomy.cdm.persistence.dao.hibernate.common.CdmGenericDaoImpl#merge(CdmBase, CdmBase)}.
772
     *
773
     * Test for https://dev.e-taxonomy.eu/redmine/issues/5652
774
     *
775
     * @throws MergeException
776
     */
777
    @Test
778
    public void testMergePersons() throws MergeException {
779
        Team team1 = Team.NewInstance();
780
        Team team2 = Team.NewInstance();
781
        Team team3 = Team.NewInstance();
782
        team1.setTitleCache("team1", true);
783
        team2.setTitleCache("team2", true);
784
        team3.setTitleCache("team3", true);
785

    
786
        Person person1a = Person.NewTitledInstance("person1a");
787
        Person person1b = Person.NewTitledInstance("person1b");
788
        Person person2 = Person.NewTitledInstance("person2");
789
        Person person3 = Person.NewTitledInstance("person3");
790

    
791
        team1.addTeamMember(person1a);
792
        team1.addTeamMember(person2);
793

    
794
        team2.addTeamMember(person2);
795
        team2.addTeamMember(person1a);
796
        team2.addTeamMember(person3);
797

    
798
        team3.addTeamMember(person3);
799

    
800
        agentDao.save(team1);
801
        agentDao.save(team2);
802
        agentDao.save(team3);
803
        agentDao.save(person1b);
804
        commitAndStartNewTransaction(null);
805

    
806
        IMergeStrategy personMergeStrategy = DefaultMergeStrategy.NewInstance(Person.class);
807
        cdmGenericDao.merge(person1b, person1a, personMergeStrategy);
808

    
809
        team1 = (Team)agentDao.load(team1.getUuid());
810
        team2 = (Team)agentDao.load(team2.getUuid());
811

    
812
        //order should not change and 1a should be replaced by 1b
813
        Assert.assertEquals("person1b", team1.getTeamMembers().get(0).getTitleCache());
814
        Assert.assertEquals("person2", team1.getTeamMembers().get(1).getTitleCache());
815

    
816
        Assert.assertEquals("person2", team2.getTeamMembers().get(0).getTitleCache());
817
        Assert.assertEquals("person1b", team2.getTeamMembers().get(1).getTitleCache());
818
        Assert.assertEquals("person3", team2.getTeamMembers().get(2).getTitleCache());
819
    }
820

    
821
    @Test
822
    public void testReallocateIntextReferenceForReferenceAndLanguageString() throws MergeException {
823
        UUID uuidRef1 = UUID.fromString("41743cec-b893-4e8b-b06c-91f9b9ba8fee");
824
        UUID uuidRef2 = UUID.fromString("8fd56b43-7cca-4c3b-bb90-7576da81c072");
825

    
826
        // CREATE DATA
827

    
828
        Reference ref1 = ReferenceFactory.newGeneric();
829
        ref1.setTitle("Reference1");
830
        ref1.setUuid(uuidRef1);
831
        Reference ref2 = ReferenceFactory.newGeneric();
832
        ref2.setTitle("Reference2");
833
        ref2.setUuid(uuidRef2);
834
        referenceDao.save(ref2);
835
        Taxon taxon = Taxon.NewInstance(null, null);
836

    
837
        TaxonDescription desc = TaxonDescription.NewInstance(taxon);
838
        Language language = Language.DEFAULT();
839
        TextData textData = TextData.NewInstance(Feature.DESCRIPTION(), "And here is a citation" , language, null);
840
        LanguageString languageString = textData.getLanguageText(language);
841
        IntextReference intextRefRef = languageString.addIntextReference(ref1, 4, 8);
842
        String uuidIntextRefRef = intextRefRef.getUuid().toString();
843
        desc.addElement(textData);
844
        Assert.assertEquals("And <cdm:reference cdmId='"+uuidRef1+"' intextId='"+uuidIntextRefRef+"'>here</cdm:reference> is a citation",
845
                    languageString.getText());
846

    
847
        //SAVE AND COMMIT
848
        taxonDao.save(taxon);
849
        commitAndStartNewTransaction(null);
850

    
851
        //MERGE
852
        DefaultMergeStrategy strategy = DefaultMergeStrategy.NewInstance(Reference.class);
853
        ref1 = referenceDao.findByUuid(uuidRef1);
854
        ref2 = referenceDao.findByUuid(uuidRef2);
855
        cdmGenericDao.merge(ref2, ref1, strategy);
856

    
857
        taxon = (Taxon)taxonDao.findByUuid(taxon.getUuid());
858
        textData = (TextData)taxon.getDescriptions().iterator().next().getElements().iterator().next();
859
        languageString = textData.getLanguageText(language);
860
        Assert.assertEquals("And <cdm:reference cdmId='"+uuidRef2+"' intextId='"+uuidIntextRefRef+"'>here</cdm:reference> is a citation",
861
                languageString.getText());
862
    }
863

    
864
    @Test
865
    public void testReallocateIntextReferenceForNameAndAnnotation() throws MergeException {
866
        UUID uuidPinusAlba = UUID.fromString("52743cec-b893-4e8b-b06c-91f9b9ba8fee");
867
        UUID uuidAbiesAlba = UUID.fromString("6ed56b43-7cca-4c3b-bb90-7576da81c072");
868

    
869
        // CREATE DATA
870
        TaxonName pinusAlba = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
871
        pinusAlba.setTitleCache("BotanicalName1", true);
872
        pinusAlba.setUuid(uuidPinusAlba);
873

    
874
        TaxonName abiesAlba = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
875
        abiesAlba.setTitleCache("Abies alba", true);
876
        abiesAlba.setUuid(uuidAbiesAlba);
877

    
878
        Taxon taxon = Taxon.NewInstance(null, null);
879

    
880
        Annotation annotation = Annotation.NewDefaultLanguageInstance("My annotation on Abies alba and its habit.");
881
        taxon.addAnnotation(annotation);
882
        IntextReference intextRefName = annotation.addIntextReference(abiesAlba, "My annotation on ", "Abies alba", " and its habit.");
883
        String uuidIntextRefName = intextRefName.getUuid().toString();
884
        Assert.assertEquals("My annotation on <cdm:name cdmId='"+uuidAbiesAlba+"' intextId='"+uuidIntextRefName+"'>Abies alba</cdm:name> and its habit.",
885
                annotation.getText());
886

    
887
        //SAVE AND COMMIT
888
        taxonDao.save(taxon);
889
        nameDao.save(abiesAlba);
890
        nameDao.save(pinusAlba);
891
        commitAndStartNewTransaction(null);
892

    
893
        //MERGE
894
        DefaultMergeStrategy strategy = DefaultMergeStrategy.NewInstance(TaxonName.class);
895
        abiesAlba = nameDao.findByUuid(uuidAbiesAlba);
896
        pinusAlba = nameDao.findByUuid(uuidPinusAlba);
897
        cdmGenericDao.merge(pinusAlba, abiesAlba, strategy);
898

    
899
        taxon = (Taxon)taxonDao.findByUuid(taxon.getUuid());
900
        annotation = taxon.getAnnotations().iterator().next();
901

    
902
        Assert.assertEquals("My annotation on <cdm:name cdmId='"+uuidPinusAlba+"' intextId='"+uuidIntextRefName+"'>Abies alba</cdm:name> and its habit.",
903
                annotation.getText());
904
    }
905

    
906
	@Test
907
	public void testReallocatePersonTeam() throws MergeException {
908

    
909
	    TaxonName name1 = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
910
		name1.setTitleCache("BotanicalName1", true);
911

    
912
		IBook book1 = ReferenceFactory.newBook();
913

    
914
		Team team1 = Team.NewInstance();
915
		Team team2 = Team.NewInstance();
916
		team1.setTitleCache("team1", true);
917
		team2.setTitleCache("team2", true);
918

    
919
		Person person1 = Person.NewTitledInstance("person1");
920
		Person person2 = Person.NewTitledInstance("person2");
921

    
922
		team1.setNomenclaturalTitleCache("T.1", true);
923
		String street1 = "Strasse1";
924
		person1.setContact(Contact.NewInstance(street1, "12345", "Berlin", Country.ARGENTINAARGENTINEREPUBLIC(),"pobox" , "Region", "a@b.de", "f12345", "+49-30-123456", URI.create("www.abc.de"), Point.NewInstance(2.4, 3.2, ReferenceSystem.WGS84(), 3)));
925
		team2.setContact(Contact.NewInstance("Street2", null, "London", null, null, null, null, "874599873", null, null, null));
926
		String street3 = "Street3";
927
		team2.addAddress(street3, null, null, null, null, null, Point.NewInstance(1.1, 2.2, null, 4));
928
		String emailAddress1 = "Email1";
929
		team1.addEmailAddress(emailAddress1);
930

    
931
		//FIXME
932
//		team2.addTeamMember(person1);
933
		team2.addTeamMember(person2);
934
		String emailAddress2 = "Email2";
935
		team2.addEmailAddress(emailAddress2);
936

    
937
		Credit credit1 = Credit.NewInstance(team2, TimePeriod.NewInstance(2008), "credit1");
938
		book1.addCredit(credit1);
939

    
940
		agentDao.save(team1);
941
		agentDao.save(team2);
942
		agentDao.save(person1);
943
		agentDao.save(person2);
944

    
945
		cdmGenericDao.save((Reference)book1);
946

    
947
		//starting condition
948
		name1.setCombinationAuthorship(person1);
949
		Assert.assertEquals("Name1 should have person1 as combination author", person1, name1.getCombinationAuthorship());
950

    
951
		DefaultMergeStrategy strategy = DefaultMergeStrategy.NewInstance(TeamOrPersonBase.class);
952
//		strategy.setOnlyReallocateLinks(true);
953

    
954
		FieldUnit fieldUnit1 = FieldUnit.NewInstance();
955
		fieldUnit1.setPrimaryCollector(person1);
956
		cdmGenericDao.save(fieldUnit1);
957
		try {
958
			cdmGenericDao.merge(team2, person1, strategy);
959
			Assert.fail("We expect exception because fieldunit.primaryCollector is of type person");
960
		} catch (MergeException e) {
961
			if (! e.getMessage().contains("Object can not be merged into new object as it is referenced in a way that does not allow merging")){
962
				Assert.fail("The exception should be the one thrown by DeduplicationHelper.reallocateByHolder(...)");
963
			}
964
			fieldUnit1.setPrimaryCollector(null);  //clean up for next test
965
		} catch (Exception e) {
966
			Assert.fail("Unhandled exception during merge");
967
		}
968
		Assert.assertEquals("Name1 should still have person1 as combination author", person1, name1.getCombinationAuthorship());
969

    
970
		//test collections
971
		team1.addTeamMember(person1);
972
		try {
973
			cdmGenericDao.merge(team2, person1, strategy);
974
			Assert.fail("We expect exception because fieldunit.primaryCollector is of type person");
975
		} catch (MergeException e) {
976
			if (! e.getMessage().contains("Object can not be merged into new object as it is referenced in a way that does not allow merging")){
977
				Assert.fail("The exception should be the one thrown by DeduplicationHelper.reallocateByHolder(...)");
978
			}
979
			team1.removeTeamMember(person1); //clean up for next test
980
		} catch (Exception e) {
981
			Assert.fail("Unhandled exception during merge");
982
		}
983
		Assert.assertEquals("Name1 should still have person1 as combination author", person1, name1.getCombinationAuthorship());
984

    
985
		//test successful merge
986
		cdmGenericDao.save(name1);
987
		cdmGenericDao.merge(team2, person1, strategy);
988
		Assert.assertEquals("Name1 should have team2 as combination author now", team2, name1.getCombinationAuthorship());
989
	}
990

    
991
	private void testMergeExceptions(CdmBase name1, CdmBase name2, CdmBase taxon, ICdmBase zooName1) throws MergeException{
992
		//
993
		try {
994
			cdmGenericDao.merge(name1, null, null);
995
			Assert.fail("Merging of 2 objects one or both of them null must throw an exception");
996
		} catch (NullPointerException e) {
997
			Assert.assertTrue("Merging of 2 objects of different types must throw an exception", true);
998
		}
999
		//
1000
		try {
1001
			cdmGenericDao.merge(null, name1, null);
1002
			Assert.fail("Merging of 2 objects one or both of them null must throw an exception");
1003
		} catch (NullPointerException e) {
1004
			Assert.assertTrue("Merging of 2 objects of different types must throw an exception", true);
1005
		}
1006
		//exceptions to be thrown
1007
		try {
1008
			cdmGenericDao.merge(name1, taxon, null);
1009
			//this is not fully true anymore !! In certain cases merging of objects of different classes is allowed
1010
			Assert.fail("Merging of 2 objects of different types must throw an exception");
1011
		} catch (MergeException e) {
1012
			Assert.assertTrue("Merging of 2 objects of different types must throw an exception", true);
1013
		}
1014
		//next exception
1015
		//for names this is not the case anymore
1016
//		try {
1017
//			cdmGenericDao.merge(name1, zooName1, null);
1018
//			Assert.fail("Merging of 2 objects of different types must throw an exception");
1019
//		} catch (MergeException e) {
1020
//			Assert.assertTrue("Merging of 2 objects of different types must throw an exception", true);
1021
//		}
1022
	}
1023

    
1024
	@Test
1025
	public void findMatching(){
1026
		IBook book1 = ReferenceFactory.newBook();
1027
		IBook book2 = ReferenceFactory.newBook();
1028
		IBook book3 = ReferenceFactory.newBook();
1029

    
1030
		String title1 = "title1";
1031
		String title2 = "title2";
1032
		book1.setTitle(title1);
1033
		book2.setTitle(title2);
1034
		book3.setTitle(title1);
1035

    
1036
		cdmGenericDao.saveOrUpdate((Reference)book1);
1037
		cdmGenericDao.saveOrUpdate((Reference)book2);
1038
		cdmGenericDao.saveOrUpdate((Reference)book3);
1039

    
1040
		IMatchStrategyEqual matchStrategy = DefaultMatchStrategy.NewInstance(Reference.class);
1041
		try {
1042
		    List<IBook> matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1043
			Assert.assertNotNull("Resultlist must not be null", matchResult);
1044
			Assert.assertEquals("Resultlist must have 1 entries", 1, matchResult.size());
1045
			Assert.assertSame("Resultlist entry must be book 1", book1, matchResult.get(0));
1046

    
1047
			book1.setDatePublished(VerbatimTimePeriod.NewVerbatimInstance(1999, 2002));
1048
			matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1049
			Assert.assertTrue("Resultlist must have no entries", matchResult.isEmpty());
1050

    
1051
			book3.setDatePublished(VerbatimTimePeriod.NewVerbatimInstance(1999));
1052
			matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1053
			Assert.assertTrue("Resultlist must have no entries", matchResult.isEmpty());
1054

    
1055
			book3.setDatePublished(VerbatimTimePeriod.NewVerbatimInstance(1999,2002));
1056
			matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1057
			Assert.assertEquals("Resultlist must have 1 entries", 1, matchResult.size());
1058
			Assert.assertSame("Resultlist entry must be book 1", book1, matchResult.get(0));
1059

    
1060
			//BookSection
1061
			IBookSection section1 = ReferenceFactory.newBookSection();
1062
			section1.setInBook(book1);
1063
			section1.setTitle("SecTitle");
1064
			section1.setPages("22-33");
1065
			IBookSection section2 = ReferenceFactory.newBookSection();
1066
			section2.setInBook(book2);
1067
			section2.setTitle("SecTitle");
1068
			section2.setPages("22-33");
1069
			IBookSection section3 = ReferenceFactory.newBookSection();
1070
			section3.setInBook(book1);
1071
			section3.setTitle("SecTitle");
1072
			section3.setPages("22-33");
1073
			cdmGenericDao.saveOrUpdate((Reference)section1);
1074
			cdmGenericDao.saveOrUpdate((Reference)section2);
1075
			cdmGenericDao.saveOrUpdate((Reference)section3);
1076

    
1077
			List<IBookSection> sectionResult = cdmGenericDao.findMatching(section3, null);
1078
			Assert.assertEquals("Resultlist must have 1 entries", 1, sectionResult.size());
1079
			Assert.assertSame("Resultlist entry must be section1", section1, sectionResult.get(0));
1080

    
1081
			section2.setInBook(book2 = (IBook)book1.clone());
1082
			cdmGenericDao.saveOrUpdate((Reference)book2);
1083
			cdmGenericDao.saveOrUpdate((Reference)book1);
1084
			matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1085
			Assert.assertEquals("Resultlist must have 2 entries", 2, matchResult.size());
1086
			sectionResult = cdmGenericDao.findMatching(section3, null);
1087
			Assert.assertEquals("Resultlist must have 1 entries", 2, sectionResult.size());
1088

    
1089
			Person person1 = Person.NewTitledInstance("person");
1090
			Person person2 = Person.NewTitledInstance("person");
1091
			Person person3 = Person.NewTitledInstance("person");
1092

    
1093
			person1.setPrefix("pre1");
1094
			person2.setPrefix("pre2");
1095
			person3.setPrefix("pre3");
1096

    
1097
//			matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1098
//			Assert.assertEquals("Resultlist must have 2 entries", 2, matchResult.size());
1099

    
1100
			book1.setAuthorship(person1);
1101
			book2.setAuthorship(person1);
1102
			book3.setAuthorship(person1);
1103

    
1104
			boolean m = matchStrategy.invoke(book1, book3).isSuccessful();
1105
			boolean m2 = matchStrategy.invoke(book2, book3).isSuccessful();
1106

    
1107
			matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1108
			Assert.assertEquals("Resultlist must have 2 entries", 2, matchResult.size());
1109

    
1110
			book2.setAuthorship(person2);
1111
			book3.setAuthorship(person3);
1112
			matchResult = cdmGenericDao.findMatching(book3, null);
1113
			Assert.assertEquals("Resultlist must have no entries", 0, matchResult.size());
1114

    
1115
			person3.setPrefix("pre1");
1116
			matchResult = cdmGenericDao.findMatching(book3, null);
1117
			Assert.assertEquals("Resultlist must have 1 entry", 1, matchResult.size());
1118
			Assert.assertSame("Resultlist entry must be book 1", book1, matchResult.get(0));
1119

    
1120
		} catch (MatchException e) {
1121
			Assert.fail("Find match must not throw Exception: " + e.getMessage());
1122
			e.printStackTrace();
1123
		}
1124
	}
1125

    
1126
	@Test
1127
	public void findMatchingCache(){
1128
		IBook book1 = ReferenceFactory.newBook();
1129
		Team team1 = Team.NewInstance();
1130
		Team team2 = Team.NewInstance();
1131
		team1.setTitleCache("Team1", true);
1132
		team2.setTitleCache("Team1", true);
1133

    
1134
		book1.setTitle("Title1");
1135
		book1.setEdition("Edition1");
1136
		book1.setAuthorship(team1);
1137

    
1138

    
1139
		IBook book2 = ((Reference)book1).clone();
1140
		IBook book3 = ((Reference)book1).clone();
1141

    
1142
//		Assert.assertTrue("Cloned book should match", matchStrategy.invoke(book1, bookClone));
1143
//		book1.setTitleCache("cache1");
1144
//		Assert.assertFalse("Cached book should not match", matchStrategy.invoke(book1, bookClone));
1145
//
1146
//		bookClone.setTitleCache("cache1");
1147
//		Assert.assertTrue("Cached book with same cache should match", matchStrategy.invoke(book1, bookClone));
1148
//
1149
//		bookClone.setTitleCache("cache2");
1150
//		Assert.assertFalse("Cached book with differings caches should not match", matchStrategy.invoke(book1, bookClone));
1151
//		bookClone.setTitleCache("cache1"); //restore
1152
//
1153
//		bookClone.setEdition(null);
1154
//		Assert.assertTrue("Cached book with a defined and a null edition should match", matchStrategy.invoke(book1, bookClone));
1155

    
1156
		cdmGenericDao.saveOrUpdate((Reference)book1);
1157
		cdmGenericDao.saveOrUpdate((Reference)book2);
1158
		cdmGenericDao.saveOrUpdate((Reference)book3);
1159
		cdmGenericDao.saveOrUpdate(team1);
1160
		cdmGenericDao.saveOrUpdate(team2);
1161

    
1162
		IMatchStrategyEqual matchStrategy = DefaultMatchStrategy.NewInstance(Reference.class);
1163

    
1164
		try {
1165
			List<IBook> matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1166
			Assert.assertNotNull("Resultlist must not be null", matchResult);
1167
			Assert.assertEquals("Resultlist must have 2 entries", 2, matchResult.size());
1168
			Assert.assertTrue("Resultlist must contain book 1", matchResult.contains(book1));
1169
			Assert.assertTrue("Resultlist must contain book 2", matchResult.contains(book2));
1170

    
1171
			book1.setTitleCache("cache1", true);
1172
			matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1173
			Assert.assertEquals("Resultlist must have 1 entries", 1, matchResult.size());
1174
			Assert.assertTrue("Resultlist must contain book 2", matchResult.contains(book2));
1175

    
1176
			book2.setTitleCache("cache2", false);
1177
			matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1178
			Assert.assertEquals("Resultlist must have 1 entries", 1, matchResult.size());
1179
			Assert.assertTrue("Resultlist must contain book 2", matchResult.contains(book2));
1180

    
1181
			book2.setEdition(null);
1182
			matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1183
			Assert.assertEquals("Resultlist must have 0 entries", 0, matchResult.size());
1184

    
1185
			book3.setTitleCache("cache1", true);
1186
			matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1187
			Assert.assertEquals("Resultlist must have 1 entries", 1, matchResult.size());
1188
			Assert.assertTrue("Resultlist must contain book 1", matchResult.contains(book1));
1189

    
1190
			IMatchStrategyEqual teamMatcher = DefaultMatchStrategy.NewInstance(Team.class);
1191
			boolean teamsMatch = teamMatcher.invoke(team1, team2).isSuccessful();
1192
			Assert.assertTrue("Team1 and team2 should match" ,teamsMatch);
1193

    
1194
			book3.setAuthorship(team2);
1195
			matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1196
			Assert.assertEquals("Resultlist must have 1 entries", 1, matchResult.size());
1197
			Assert.assertTrue("Resultlist must contain book 1", matchResult.contains(book1));
1198

    
1199
			book3.setAuthorship(null);
1200
			matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1201
			Assert.assertEquals("Resultlist must have 1 entries", 1, matchResult.size());
1202
			Assert.assertTrue("Resultlist must contain book 1", matchResult.contains(book1));
1203

    
1204
			book2.setTitleCache(book3.getTitleCache(), true);
1205
			matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1206
			Assert.assertEquals("Resultlist must have 2 entries", 2, matchResult.size());
1207
			Assert.assertTrue("Resultlist must contain book 1", matchResult.contains(book1));
1208
			Assert.assertTrue("Resultlist must contain book 2", matchResult.contains(book2));
1209

    
1210
			team2.setTitleCache("team2", true);
1211
			teamsMatch = teamMatcher.invoke(team1, team2).isSuccessful();
1212
			Assert.assertFalse("Team1 and team2 should not match" ,teamsMatch);
1213

    
1214
			book3.setAuthorship(team1);
1215
			book2.setAuthorship(team2);
1216
			matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1217
			Assert.assertEquals("Resultlist must have 1 entries", 1, matchResult.size());
1218
			Assert.assertTrue("Resultlist must contain book 1", matchResult.contains(book1));
1219

    
1220
		} catch (MatchException e) {
1221
			Assert.fail("Find match must not throw Exception: " + e.getMessage());
1222
			e.printStackTrace();
1223
		}
1224
	}
1225

    
1226
    @Test  //#9905 test find matching candidates
1227
    public void testFindMatchingWithSubMatching() {
1228
        Person person1 = Person.NewInstance();
1229
        Person person2 = Person.NewInstance();
1230
        Person person3 = Person.NewInstance();
1231
        person1.setFamilyName("FamName1");
1232
        person1.setNomenclaturalTitle("NomTitle1");
1233
        person2.setFamilyName("FamName2");
1234
        person2.setNomenclaturalTitle("NomTitle2");
1235
        person3.setFamilyName("FamName3");
1236
        person3.setNomenclaturalTitle("NomTitle3");
1237

    
1238
        Team team1 = Team.NewInstance();
1239
        Team team2 = Team.NewInstance();
1240
        Team team3 = Team.NewInstance();
1241

    
1242
        team1.addTeamMember(person1);
1243
        team1.addTeamMember(person2);
1244

    
1245
        team2.addTeamMember(person2);
1246
        team2.addTeamMember(person3);
1247

    
1248
        team3.setTitleCache("ProtectedTeam", true);
1249

    
1250
        cdmGenericDao.saveOrUpdate(team1);
1251
        cdmGenericDao.saveOrUpdate(team2);
1252
        commitAndStartNewTransaction();
1253

    
1254
        IMatchStrategyEqual matchStrategy = DefaultMatchStrategy.NewInstance(Team.class);
1255
        try {
1256
            Team teamAs1 = Team.NewInstance();
1257
            teamAs1.addTeamMember(person1);
1258
            teamAs1.addTeamMember(person2);
1259
            //match with single instance comparison after hql query
1260
            List<Team> matchResult = cdmGenericDao.findMatching(teamAs1, matchStrategy, false);
1261
            Assert.assertEquals(1, matchResult.size());
1262

    
1263
            //test without single instance comparison after hql query
1264
            List<Team> candidateMatchResult = cdmGenericDao.findMatching(teamAs1, matchStrategy, true);
1265
            //FIXME #9905
1266
            Assert.assertEquals(1, candidateMatchResult.size());
1267

    
1268
            person1.setNomenclaturalTitle("NomTitle1b");
1269
            candidateMatchResult = cdmGenericDao.findMatching(teamAs1, matchStrategy, true);
1270
            Assert.assertEquals(0, candidateMatchResult.size());
1271
            person1.setNomenclaturalTitle("NomTitle1");  //set back
1272

    
1273
            Team teamDifferentOrder = Team.NewInstance();
1274
            teamDifferentOrder.addTeamMember(person2);
1275
            teamDifferentOrder.addTeamMember(person1);
1276
            candidateMatchResult = cdmGenericDao.findMatching(teamAs1, matchStrategy, true);
1277
            //TODO improve, should be 0 in best implementation
1278
            Assert.assertEquals(1, candidateMatchResult.size());
1279

    
1280
            //test that reference.authorTeam.* still works without throwing exceptions
1281
            TaxonName name = NonViralNameParserImpl.NewInstance().parseReferencedName("Abies alba Nyffeler & Eggli in Taxon 59: 232. 2010", NomenclaturalCode.ICNAFP, Rank.SPECIES());
1282
            Reference nomRef = name.getNomenclaturalReference();
1283
            IMatchStrategy referenceMatcher = MatchStrategyFactory.NewParsedReferenceInstance(nomRef);
1284
            List<Reference> matching = cdmGenericDao.findMatching(nomRef, referenceMatcher);
1285
            Assert.assertEquals("We don't expect matchings, only tested that no exceptions are thrown", 0, matching.size());
1286

    
1287
        } catch (IllegalArgumentException | MatchException e) {
1288
            Assert.fail("No exception should be thrown");
1289
            e.printStackTrace();
1290
        }
1291
    }
1292

    
1293
	@Test
1294
	public void testGetHqlResult() {
1295
		logger.warn("testGetHqlResult not yet implemented");
1296
	}
1297

    
1298
    @Override
1299
    public void createTestDataSet() throws FileNotFoundException {}
1300
}
(4-4/7)