Project

General

Profile

Download (49.9 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

    
10
package eu.etaxonomy.cdm.persistence.dao.hibernate.common;
11

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

    
14
import java.io.FileNotFoundException;
15
import java.net.URI;
16
import java.util.ArrayList;
17
import java.util.Arrays;
18
import java.util.List;
19
import java.util.Map;
20
import java.util.Set;
21
import java.util.UUID;
22

    
23
import org.apache.log4j.Logger;
24
import org.hibernate.MappingException;
25
import org.hibernate.internal.SessionFactoryImpl;
26
import org.hibernate.persister.collection.CollectionPersister;
27
import org.hibernate.stat.Statistics;
28
import org.hibernate.type.Type;
29
import org.junit.Assert;
30
import org.junit.Before;
31
import org.junit.Test;
32
import org.unitils.dbunit.annotation.DataSet;
33
import org.unitils.dbunit.annotation.DataSets;
34
import org.unitils.spring.annotation.SpringBeanByType;
35

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

    
170
/**
171
 * @author a.mueller
172
 * @since 27.07.2009
173
 */
174
public class CdmGenericDaoImplTest extends CdmTransactionalIntegrationTest {
175
	private static final Logger logger = Logger.getLogger(CdmGenericDaoImplTest.class);
176

    
177
	@SpringBeanByType
178
	private ICdmGenericDao 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
	public void testDelete(){
205
		Reference ref1 = ReferenceFactory.newBook();
206
		Reference ref2 = ReferenceFactory.newBook();
207
		Annotation annotation = Annotation.NewInstance("Anno1", null);
208
		ref1.addAnnotation(annotation);
209
		UUID ref1Uuid = cdmGenericDao.saveOrUpdate(ref1);
210
		UUID ref2Uuid = cdmGenericDao.saveOrUpdate(ref2);
211
		List<Reference> list = cdmGenericDao.list(Reference.class, 10, 0, null, null);
212
//        System.out.println("ref1: " + ref1Uuid + " ref2: " + ref2Uuid);
213
        for (Reference ref: list){
214
            System.out.println("reference: " + ref.getUuid());
215
        }
216
		try {
217
			cdmGenericDao.merge(ref2, ref1, null);
218

    
219
		} catch (MergeException e) {
220
			Assert.fail();
221
		}
222
		commitAndStartNewTransaction(null);
223
		list = cdmGenericDao.list(Reference.class, 10, 0, null, null);
224
//		System.out.println("ref1: " + ref1Uuid + " ref2: " + ref2Uuid);
225
//        for (Reference ref: list){
226
//            System.out.println("reference: " + ref.getUuid());
227
//        }
228
		Assert.assertEquals(1, list.size());
229

    
230
	}
231

    
232

    
233
	/**
234
	 * Test method for {@link eu.etaxonomy.cdm.persistence.dao.hibernate.common.CdmGenericDaoImpl#getCdmBasesByFieldAndClass(java.lang.Class, java.lang.String, eu.etaxonomy.cdm.model.common.CdmBase)}.
235
	 */
236
	@Test
237
	public void testGetCdmBasesByFieldAndClass() {
238
		logger.warn("Not yet implemented");
239
	}
240

    
241
	/**
242
	 * Test method for {@link eu.etaxonomy.cdm.persistence.dao.hibernate.common.CdmGenericDaoImpl#getCdmBasesWithItemInCollection(java.lang.Class, java.lang.Class, java.lang.String, eu.etaxonomy.cdm.model.common.CdmBase)}.
243
	 */
244
	@Test
245
	public void testGetCdmBasesWithItemInCollection() {
246
		logger.warn("Not yet implemented");
247
	}
248

    
249
	/**
250
	 * Test method for {@link eu.etaxonomy.cdm.persistence.dao.hibernate.common.CdmGenericDaoImpl#getAllPersistedClasses(boolean)}.
251
	 */
252
	@Test
253
	public void testGetAllPersistedClasses() {
254
		Class<?>[] existingClassesArray = {
255
				Address.class,
256
				AgentBase.class,
257
				Institution.class,
258
				InstitutionalMembership.class,
259
				Person.class,
260
				Team.class,
261
				TeamOrPersonBase.class,
262
				Annotation.class,
263
				AnnotationType.class,
264
				Credit.class,
265
				DefinedTermBase.class,
266
				Extension.class,
267
				ExtensionType.class,
268
				GrantedAuthorityImpl.class,
269
				Group.class,
270
				IdentifiableSource.class,
271
				Identifier.class,
272
				IntextReference.class,
273
				Language.class,
274
				LanguageString.class,
275
				LSIDAuthority.class,
276
				Marker.class,
277
				MarkerType.class,
278
				OrderedTermBase.class,
279
				OrderedTermVocabulary.class,
280
				OriginalSourceBase.class,
281
				RelationshipTermBase.class,
282
				Representation.class,
283
				TermVocabulary.class,
284
				User.class,
285
				DefinedTerm.class,
286

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

    
373
		//for debugging only
374
		//		for (Class existingClass : existingClassesList){
375
		//			if (! foundClasses.contains(existingClass)){
376
		//				logger.warn("Class not found: " + existingClass.getCanonicalName());
377
		//			}
378
		//		}
379

    
380
		//All classes must be found
381
		Assert.assertTrue("all classes must be found by getAllCdmClasses() method", foundClasses.containsAll(existingClassesList));
382

    
383

    
384
		//No extra classes must be found
385
		for (Class<?> clazz : foundClasses){
386
			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)
387
				Assert.fail("Class " + clazz.getName() + " is not assignable from CdmBase");
388
			}
389
		}
390

    
391
		includeAbstractClasses = false;
392
		Set<Class<? extends CdmBase>> noAbstractClasses = cdmGenericDao.getAllPersistedClasses(includeAbstractClasses);
393
		Class<?> abstractClassToTest = TaxonBase.class;
394
		Assert.assertFalse("Abstract class " + abstractClassToTest.getName() + " may not be in set ", noAbstractClasses.contains(abstractClassToTest));
395
	}
396

    
397
	/**
398
	 * Test method for {@link eu.etaxonomy.cdm.persistence.dao.hibernate.common.CdmGenericDaoImpl#getReferencingObjects(CdmBase)}.
399
	 */
400
	@Test
401
	@DataSets({
402
	     @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="/eu/etaxonomy/cdm/database/ClearDB_with_Terms_DataSet.xml"),
403
	     @DataSet("/eu/etaxonomy/cdm/database/TermsDataSet-with_auditing_info.xml")})
404
	public void testGetReferencingObjectsCdmBase() {
405
		IBotanicalName name = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
406
		name.setTitleCache("A name", true);
407
		Reference ref1 = ReferenceFactory.newArticle();
408
		Taxon taxon = Taxon.NewInstance(name, ref1);
409
		Person author = Person.NewInstance();
410
		author.setTitleCache("Author", true);
411
		ref1.addAnnotation(Annotation.NewInstance("A1", Language.DEFAULT()));
412
		ref1.setAuthorship(author);
413
		name.setBasionymAuthorship(author);
414

    
415
		name.setNomenclaturalReference(ref1);
416

    
417
		taxonDao.save(taxon);
418
//		UUID uuid = UUID.fromString("613980ac-9bd5-43b9-a374-d71e1794688f");
419
//		Reference ref1 = referenceService.findByUuid(uuid);
420
		commitAndStartNewTransaction(null);
421

    
422
		Set<CdmBase> referencedObjects = cdmGenericDao.getReferencingObjects(ref1);
423
		String debug = "############## RESULT ###################";
424
		for (CdmBase obj: referencedObjects){
425
			debug += "Object1: " + obj.getClass().getSimpleName() + " - " + obj;
426
		}
427
		//was 3 before bidirectionality was removed for supplemental data
428
		assertEquals(2, referencedObjects.size());
429
		debug += "############## ENDE ###################";
430

    
431
//		UUID uuidAuthor = UUID.fromString("4ce66544-a5a3-4601-ab0b-1f0a1338327b");
432
//		AgentBase author = agentService.findByUuid(uuidAuthor);
433

    
434
		referencedObjects = cdmGenericDao.getReferencingObjects(author);
435
		debug += "############## RESULT ###################";
436
		for (CdmBase obj: referencedObjects){
437
			debug += "Object2: " + obj.getClass().getSimpleName() + " - " + obj;
438
		}
439
		assertEquals(2, referencedObjects.size());
440
		debug += "############## ENDE ###################";
441
		logger.info(debug);
442
	}
443

    
444
	/**
445
	 * 2nd test method for {@link eu.etaxonomy.cdm.persistence.dao.hibernate.common.CdmGenericDaoImpl#getReferencingObjects(CdmBase)}.
446
	 *
447
	 */
448
	@Test
449
	@DataSet
450
	public final void testGetReferencingObjects2() {
451
//		SpecimenDescription desc1 = SpecimenDescription.NewInstance();
452
//		desc1.setTitleCache("desc1");
453
//		SpecimenDescription desc2 = SpecimenDescription.NewInstance();
454
//		desc2.setTitleCache("desc2");
455
//
456
//		SpecimenOrObservationBase spec1 = Specimen.NewInstance();
457
//
458
//		desc1.addDescribedSpecimenOrObservation(spec1);
459
//		//Taxon taxon = Taxon.NewInstance(taxonName, sec)
460
//		spec1.addDescription(desc2);
461
//
462
//		occurrenceService.save(spec1);
463

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

    
467

    
468
		Set<CdmBase> referencingObjects = cdmGenericDao.getReferencingObjects(spec1);
469
//		System.out.println("############## RESULT ###################");
470
//		for (CdmBase obj: referencingObjects){
471
//			System.out.println("Object: " + obj.getClass().getSimpleName() + " - " + obj);
472
//		}
473
//		System.out.println("############## ENDE ###################");
474
		assertEquals("Number of referencing objects must be 2.", 2, referencingObjects.size());
475

    
476
	}
477

    
478
	/**
479
	 * Test method for {@link eu.etaxonomy.cdm.persistence.dao.hibernate.common.CdmGenericDaoImpl#merge(CdmBase, CdmBase)}.
480
	 * @throws MergeException
481
	 */
482
	@Test
483
//	@Ignore
484
	public void testMergeCdmBaseReferenceAndIdentifiable() throws MergeException {
485

    
486
		TaxonName name1 = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
487
		name1.setTitleCache("BotanicalName1", true);
488

    
489
		TaxonName name2 = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
490
		name2.setTitleCache("BotanicalName2", true);
491

    
492
		TaxonName zooName1 = TaxonNameFactory.NewZoologicalInstance(Rank.SPECIES());
493
		name1.setTitleCache("ZoologicalName1", true);
494

    
495
		Reference article1 = ReferenceFactory.newArticle();
496
		Reference article2 = ReferenceFactory.newArticle();
497

    
498

    
499
		name1.setNomenclaturalReference(article1);
500
		name2.setNomenclaturalReference(article2);
501

    
502

    
503
		Taxon taxon1 = Taxon.NewInstance(name1, article1);
504
		Taxon taxon2 = Taxon.NewInstance(name2, article2);
505

    
506

    
507
//		Person author = Person.NewInstance();
508
//		author.setTitleCache("Author");
509
		Annotation annotation1 = Annotation.NewInstance("A1", Language.DEFAULT());
510
		Annotation annotation2 = Annotation.NewInstance("A2", Language.DEFAULT());
511

    
512
		article1.addAnnotation(annotation1);
513
		article2.addAnnotation(annotation2);
514

    
515
		Marker marker1 = Marker.NewInstance(MarkerType.COMPLETE(), false);
516
		Marker marker2 = Marker.NewInstance(MarkerType.IMPORTED(), false);
517

    
518
		article1.addMarker(marker1);
519
		article2.addMarker(marker2);
520

    
521
		Rights rights1 = Rights.NewInstance();
522
		Rights rights2 = Rights.NewInstance();
523

    
524
		article1.addRights(rights1);
525
		article2.addRights(rights2);
526

    
527
		Credit credit1 = Credit.NewInstance(Team.NewInstance(), "credit1");
528
		Credit credit2 = Credit.NewInstance(Team.NewInstance(), "credit2");
529

    
530
		article1.addCredit(credit1);
531
		article2.addCredit(credit2);
532

    
533
		Extension extension1 = Extension.NewInstance();
534
		Extension extension2 = Extension.NewInstance();
535

    
536
		article1.addExtension(extension1);
537
		article2.addExtension(extension2);
538

    
539
		IdentifiableSource source1 = IdentifiableSource.NewInstance(OriginalSourceType.Unknown);
540
		IdentifiableSource source2 = IdentifiableSource.NewInstance(OriginalSourceType.Unknown);
541

    
542
		article1.addSource(source1);
543
		article2.addSource(source2);
544

    
545
		Media media1 = Media.NewInstance();
546
		Media media2 = Media.NewInstance();
547

    
548
		article1.addMedia(media1);
549
		article2.addMedia(media2);
550

    
551
//		ref1.setAuthorship(author);
552
//		name1.setBasionymAuthorship(author);
553

    
554
		name1.setNomenclaturalReference(article1);
555

    
556
		nameDao.save(name1);
557
		nameDao.save(name2);
558
		nameDao.save(zooName1);
559

    
560
		TaxonDescription taxDesc = TaxonDescription.NewInstance(taxon1);
561
		taxDesc.setTitleCache("taxDesc", true);
562
		taxDesc.addSource(OriginalSourceType.Unknown, null, null, article2, null);
563

    
564
		taxonDao.save(taxon1);
565

    
566
		//unidircetional reference to the merged object should be redirected
567
		cdmGenericDao.merge(article1, article2, null);
568
		Assert.assertEquals("Name2 must have article 1 as new nomRef", article1 ,name2.getNomenclaturalReference());
569
		//TODO microCitations!! -> warning
570

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

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

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

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

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

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

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

    
592
		//Description sources
593
		Assert.assertEquals("Number of sources for taxon description must be 1", 1, taxDesc.getSources().size());
594
		Assert.assertEquals("Taxon description must have article1 as source", taxDesc.getSources().iterator().next().getCitation(),article1);
595

    
596
		//test exceptions
597

    
598
		testMergeExceptions(name1, name2, taxon1, zooName1);
599

    
600

    
601

    
602

    
603
		//FIXME TO BE IMPLEMENTED
604
		//current defalt implementation for rights, credits and media is ADD_CLONE and therefore the below tests don't work
605
		//TODO is this the wanted default behaviour?
606
//		Assert.assertTrue("Rights2 must be contained in the rights", article1.getRights().contains(rights2));
607
//		Assert.assertTrue("Credits2 must be contained in the credits", article1.getCredits().contains(credit2));
608
//		Assert.assertTrue("Media2 must be contained in the media", article1.getMedia().contains(media2));
609

    
610
	}
611

    
612
	/**
613
	 * Test method for {@link eu.etaxonomy.cdm.persistence.dao.hibernate.common.CdmGenericDaoImpl#merge(CdmBase, CdmBase)}.
614
	 * @throws MergeException
615
	 */
616
	@Test
617
//	@Ignore
618
	public void testMergeTaxonNameAndTaxon() throws MergeException {
619
	    TaxonName name1 = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
620
		name1.setTitleCache("BotanicalName1", true);
621

    
622
		TaxonName name2 = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
623
		name2.setTitleCache("BotanicalName2", true);
624

    
625
		IBotanicalName name3 = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
626
		name3.setTitleCache("BotanicalName3", true);
627

    
628
		Reference database = ReferenceFactory.newDatabase();
629

    
630
		Taxon taxon1 = Taxon.NewInstance(name1, database);
631
		Taxon taxon2 = Taxon.NewInstance(name2, database);
632
		Taxon taxon3 = Taxon.NewInstance(name3, database);
633

    
634
		taxonDao.save(taxon1);
635
		taxonDao.save(taxon2);
636
		taxonDao.save(taxon3);
637

    
638
		cdmGenericDao.merge(name1, name2, null);
639
		Assert.assertEquals("Name1 must have 2 taxa attached now.", 2 ,name1.getTaxonBases().size());
640
		Assert.assertEquals("Taxon2 must have name1 as new name.", name1 ,taxon2.getName());
641

    
642
//TODO
643
//		cdmGenericDao.merge(taxon1, taxon3, null);
644
//		Assert.assertEquals("Name1 must have 3 taxa attached now.", 3 ,name1.getTaxonBases().size());
645

    
646

    
647
	}
648

    
649
	/**
650
	 * Test method for {@link eu.etaxonomy.cdm.persistence.dao.hibernate.common.CdmGenericDaoImpl#merge(CdmBase, CdmBase)}.
651
	 * @throws MergeException
652
	 */
653
	@Test
654
	public void testMergeAuthors() throws MergeException {
655

    
656
		IBotanicalName name1 = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
657
		name1.setTitleCache("BotanicalName1", true);
658

    
659
		IBotanicalName name2 = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
660
		name2.setTitleCache("BotanicalName2", true);
661

    
662
		IBook book1 = ReferenceFactory.newBook();
663
		IBook book2 = ReferenceFactory.newBook();
664

    
665
		Team team1 = Team.NewInstance();
666
		Team team2 = Team.NewInstance();
667
		Team team3 = Team.NewInstance();
668
		team1.setTitleCache("team1", true);
669
		team2.setTitleCache("team2", true);
670
		team3.setTitleCache("team3", true);
671

    
672
		Person person1 = Person.NewTitledInstance("person1");
673
		Person person2 = Person.NewTitledInstance("person2");
674
		Person person3 = Person.NewTitledInstance("person3");
675

    
676
		team1.setNomenclaturalTitle("T.1");
677
		String street1 = "Strasse1";
678
		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)));
679
		team2.setContact(Contact.NewInstance("Street2", null, "London", null, null, null, null, "874599873", null, null, null));
680
		String street3 = "Street3";
681
		team2.addAddress(street3, null, null, null, null, null, Point.NewInstance(1.1, 2.2, null, 4));
682
		String emailAddress1 = "Email1";
683
		team1.addEmailAddress(emailAddress1);
684

    
685
		team2.addTeamMember(person1);
686
		team2.addTeamMember(person2);
687
		String emailAddress2 = "Email2";
688
		team2.addEmailAddress(emailAddress2);
689

    
690
		team3.addTeamMember(person3);
691
		team3.addEmailAddress("emailAddress3");
692

    
693
		book1.setAuthorship(team2);
694
		book2.setAuthorship(team3);
695

    
696
		Credit credit1 = Credit.NewInstance(team3, "credit1");
697
		book2.addCredit(credit1);
698

    
699
		agentDao.save(team1);
700
		agentDao.save(team2);
701
		agentDao.save(team3);
702
		cdmGenericDao.save((Reference)book1);
703
		cdmGenericDao.save((Reference)book2);
704

    
705
		cdmGenericDao.merge(team2, team3, null);
706

    
707
		Assert.assertSame("Author of book1 must be team2.", team2, book1.getAuthorship());
708
		Assert.assertSame("Author of book2 must be team2.", team2, book2.getAuthorship());
709
		Assert.assertSame("Agent of credit1 must be team2.", team2, credit1.getAgent());
710

    
711
		Assert.assertEquals("Team2 must have 3 persons as members.",3, team2.getTeamMembers().size());
712
		Assert.assertTrue("Team2 must have person3 as new member.", team2.getTeamMembers().contains(person3));
713
		Assert.assertSame("Team2 must have person3 as third member.",person3, team2.getTeamMembers().get(2));
714

    
715

    
716
		//Contact
717
		cdmGenericDao.merge(team2, team1, null);
718
		Contact team2Contact = team2.getContact();
719
		Assert.assertNotNull("team2Contact must not be null", team2Contact);
720
		Assert.assertNotNull("Addresses must not be null", team2Contact.getAddresses());
721
		Assert.assertEquals("Number of addresses must be 3", 3, team2Contact.getAddresses().size());
722
		Assert.assertEquals("Number of email addresses must be 4", 4, team2Contact.getEmailAddresses().size());
723

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

    
742
		//Person
743
		Institution institution1 = Institution.NewInstance();
744
		institution1.setTitleCache("inst1", true);
745
		Institution institution2 = Institution.NewInstance();
746
		institution2.setTitleCache("inst2", true);
747

    
748
		TimePeriod period1 = TimePeriod.NewInstance(2002, 2004);
749
		TimePeriod period2 = TimePeriod.NewInstance(2004, 2006);
750

    
751
		person1.addInstitutionalMembership(institution1, period1, "departement1", "role1");
752
		person2.addInstitutionalMembership(institution2, period2, "departement2", "role2");
753

    
754
		IMergeStrategy personMergeStrategy = DefaultMergeStrategy.NewInstance(Person.class);
755
		personMergeStrategy.invoke(person1, person2);
756

    
757
		Assert.assertEquals("Number of institutional memberships must be 2", 2, person1.getInstitutionalMemberships().size());
758
		for (InstitutionalMembership institutionalMembership : person1.getInstitutionalMemberships()){
759
			Assert.assertSame("Person of institutional memebership must be person1", person1, institutionalMembership.getPerson());
760
		}
761
	}
762

    
763
	/**
764
     * Test method for {@link eu.etaxonomy.cdm.persistence.dao.hibernate.common.CdmGenericDaoImpl#merge(CdmBase, CdmBase)}.
765
     *
766
     * Test for  http://dev.e-taxonomy.eu/trac/ticket/5652
767
     *
768
     * @throws MergeException
769
     */
770
    @Test
771
    public void testMergePersons() throws MergeException {
772
        Team team1 = Team.NewInstance();
773
        Team team2 = Team.NewInstance();
774
        Team team3 = Team.NewInstance();
775
        team1.setTitleCache("team1", true);
776
        team2.setTitleCache("team2", true);
777
        team3.setTitleCache("team3", true);
778

    
779
        Person person1a = Person.NewTitledInstance("person1a");
780
        Person person1b = Person.NewTitledInstance("person1b");
781
        Person person2 = Person.NewTitledInstance("person2");
782
        Person person3 = Person.NewTitledInstance("person3");
783

    
784
        team1.addTeamMember(person1a);
785
        team1.addTeamMember(person2);
786

    
787

    
788
        team2.addTeamMember(person2);
789
        team2.addTeamMember(person1a);
790
        team2.addTeamMember(person3);
791

    
792
        team3.addTeamMember(person3);
793

    
794
        agentDao.save(team1);
795
        agentDao.save(team2);
796
        agentDao.save(team3);
797
        agentDao.save(person1b);
798
        commitAndStartNewTransaction(null);
799

    
800
        IMergeStrategy personMergeStrategy = DefaultMergeStrategy.NewInstance(Person.class);
801
        cdmGenericDao.merge(person1b, person1a, personMergeStrategy);
802

    
803
        team1 = (Team)agentDao.load(team1.getUuid());
804
        team2 = (Team)agentDao.load(team2.getUuid());
805

    
806
        //order should not change and 1a should be replaced by 1b
807
        Assert.assertEquals("person1b", team1.getTeamMembers().get(0).getTitleCache());
808
        Assert.assertEquals("person2", team1.getTeamMembers().get(1).getTitleCache());
809

    
810
        Assert.assertEquals("person2", team2.getTeamMembers().get(0).getTitleCache());
811
        Assert.assertEquals("person1b", team2.getTeamMembers().get(1).getTitleCache());
812
        Assert.assertEquals("person3", team2.getTeamMembers().get(2).getTitleCache());
813

    
814
    }
815

    
816
    @Test
817
    public void testReallocateIntextReferenceForReferenceAndLanguageString() throws MergeException {
818
        UUID uuidRef1 = UUID.fromString("41743cec-b893-4e8b-b06c-91f9b9ba8fee");
819
        UUID uuidRef2 = UUID.fromString("8fd56b43-7cca-4c3b-bb90-7576da81c072");
820

    
821
        // CREATE DATA
822

    
823
        Reference ref1 = ReferenceFactory.newGeneric();
824
        ref1.setTitle("Reference1");
825
        ref1.setUuid(uuidRef1);
826
        Reference ref2 = ReferenceFactory.newGeneric();
827
        ref2.setTitle("Reference2");
828
        ref2.setUuid(uuidRef2);
829
        referenceDao.save(ref2);
830
        Taxon taxon = Taxon.NewInstance(null, null);
831

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

    
842
        //SAVE AND COMMIT
843
        taxonDao.save(taxon);
844
        commitAndStartNewTransaction(null);
845

    
846
        //MERGE
847
        DefaultMergeStrategy strategy = DefaultMergeStrategy.NewInstance(Reference.class);
848
        ref1 = referenceDao.findByUuid(uuidRef1);
849
        ref2 = referenceDao.findByUuid(uuidRef2);
850
        cdmGenericDao.merge(ref2, ref1, strategy);
851

    
852
        taxon = (Taxon)taxonDao.findByUuid(taxon.getUuid());
853
        textData = (TextData)taxon.getDescriptions().iterator().next().getElements().iterator().next();
854
        languageString = textData.getLanguageText(language);
855
        Assert.assertEquals("And <cdm:reference cdmId='"+uuidRef2+"' intextId='"+uuidIntextRefRef+"'>here</cdm:reference> is a citation",
856
                languageString.getText());
857

    
858
    }
859

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

    
865
        // CREATE DATA
866
        TaxonName pinusAlba = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
867
        pinusAlba.setTitleCache("BotanicalName1", true);
868
        pinusAlba.setUuid(uuidPinusAlba);
869

    
870
        TaxonName abiesAlba = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
871
        abiesAlba.setTitleCache("Abies alba", true);
872
        abiesAlba.setUuid(uuidAbiesAlba);
873

    
874
        Taxon taxon = Taxon.NewInstance(null, null);
875

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

    
883
        //SAVE AND COMMIT
884
        taxonDao.save(taxon);
885
        nameDao.save(abiesAlba);
886
        nameDao.save(pinusAlba);
887
        commitAndStartNewTransaction(null);
888

    
889
        //MERGE
890
        DefaultMergeStrategy strategy = DefaultMergeStrategy.NewInstance(TaxonName.class);
891
        abiesAlba = nameDao.findByUuid(uuidAbiesAlba);
892
        pinusAlba = nameDao.findByUuid(uuidPinusAlba);
893
        cdmGenericDao.merge(pinusAlba, abiesAlba, strategy);
894

    
895
        taxon = (Taxon)taxonDao.findByUuid(taxon.getUuid());
896
        annotation = taxon.getAnnotations().iterator().next();
897

    
898
        Assert.assertEquals("My annotation on <cdm:name cdmId='"+uuidPinusAlba+"' intextId='"+uuidIntextRefName+"'>Abies alba</cdm:name> and its habit.",
899
                annotation.getText());
900
    }
901

    
902
	/**
903
	 * Test method for {@link eu.etaxonomy.cdm.persistence.dao.hibernate.common.CdmGenericDaoImpl#merge(CdmBase, CdmBase)}.
904
	 * @throws MergeException
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.setNomenclaturalTitle("T.1");
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

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

    
938
		Credit credit1 = Credit.NewInstance(team2, "credit1");
939
		book1.addCredit(credit1);
940

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

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

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

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

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

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

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

    
991
	}
992

    
993

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

    
1027
	@Test
1028
	public void findMatching(){
1029
		IBook book1 = ReferenceFactory.newBook();
1030
		IBook book2 = ReferenceFactory.newBook();
1031
		IBook book3 = ReferenceFactory.newBook();
1032

    
1033
		String title1 = "title1";
1034
		String title2 = "title2";
1035
		book1.setTitle(title1);
1036
		book2.setTitle(title2);
1037
		book3.setTitle(title1);
1038

    
1039
		cdmGenericDao.saveOrUpdate((Reference)book1);
1040
		cdmGenericDao.saveOrUpdate((Reference)book2);
1041
		cdmGenericDao.saveOrUpdate((Reference)book3);
1042

    
1043
		IMatchStrategy matchStrategy = DefaultMatchStrategy.NewInstance(Reference.class);
1044

    
1045
		try {
1046
			List<IBook> matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1047
			Assert.assertNotNull("Resultlist must not be null", matchResult);
1048
			Assert.assertEquals("Resultlist must have 1 entries", 1, matchResult.size());
1049
			Assert.assertSame("Resultlist entry must be book 1", book1, matchResult.get(0));
1050

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

    
1055
			book3.setDatePublished(TimePeriod.NewInstance(1999));
1056
			matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1057
			Assert.assertTrue("Resultlist must have no entries", matchResult.isEmpty());
1058

    
1059
			book3.setDatePublished(TimePeriod.NewInstance(1999,2002));
1060
			matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1061
			Assert.assertEquals("Resultlist must have 1 entries", 1, matchResult.size());
1062
			Assert.assertSame("Resultlist entry must be book 1", book1, matchResult.get(0));
1063

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

    
1081
			List<IBookSection> sectionResult = cdmGenericDao.findMatching(section3, null);
1082
			Assert.assertEquals("Resultlist must have 1 entries", 1, sectionResult.size());
1083
			Assert.assertSame("Resultlist entry must be section1", section1, sectionResult.get(0));
1084

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

    
1093

    
1094
			Person person1 = Person.NewTitledInstance("person");
1095
			Person person2 = Person.NewTitledInstance("person");
1096
			Person person3 = Person.NewTitledInstance("person");
1097

    
1098
			person1.setPrefix("pre1");
1099
			person2.setPrefix("pre2");
1100
			person3.setPrefix("pre3");
1101

    
1102
//			matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1103
//			Assert.assertEquals("Resultlist must have 2 entries", 2, matchResult.size());
1104

    
1105
			book1.setAuthorship(person1);
1106
			book2.setAuthorship(person1);
1107
			book3.setAuthorship(person1);
1108

    
1109
			boolean m = matchStrategy.invoke(book1, book3);
1110
			boolean m2 = matchStrategy.invoke(book2, book3);
1111

    
1112
			matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1113
			Assert.assertEquals("Resultlist must have 2 entries", 2, matchResult.size());
1114

    
1115
			book2.setAuthorship(person2);
1116
			book3.setAuthorship(person3);
1117
			matchResult = cdmGenericDao.findMatching(book3, null);
1118
			Assert.assertEquals("Resultlist must have no entries", 0, matchResult.size());
1119

    
1120
			person3.setPrefix("pre1");
1121
			matchResult = cdmGenericDao.findMatching(book3, null);
1122
			Assert.assertEquals("Resultlist must have 1 entry", 1, matchResult.size());
1123
			Assert.assertSame("Resultlist entry must be book 1", book1, matchResult.get(0));
1124

    
1125
		} catch (MatchException e) {
1126
			Assert.fail("Find match must not throw Exception: " + e.getMessage());
1127
			e.printStackTrace();
1128
		}
1129

    
1130
	}
1131

    
1132

    
1133
	@Test
1134
	public void findMatchingCache(){
1135
		IBook book1 = ReferenceFactory.newBook();
1136
		Team team1 = Team.NewInstance();
1137
		Team team2 = Team.NewInstance();
1138
		team1.setTitleCache("Team1", true);
1139
		team2.setTitleCache("Team1", true);
1140

    
1141
		book1.setTitle("Title1");
1142
		book1.setEdition("Edition1");
1143
		book1.setAuthorship(team1);
1144

    
1145

    
1146
		IBook book2 = (IBook) ((Reference)book1).clone();
1147
		IBook book3 = (IBook) ((Reference)book1).clone();
1148

    
1149
//		Assert.assertTrue("Cloned book should match", matchStrategy.invoke(book1, bookClone));
1150
//		book1.setTitleCache("cache1");
1151
//		Assert.assertFalse("Cached book should not match", matchStrategy.invoke(book1, bookClone));
1152
//
1153
//		bookClone.setTitleCache("cache1");
1154
//		Assert.assertTrue("Cached book with same cache should match", matchStrategy.invoke(book1, bookClone));
1155
//
1156
//		bookClone.setTitleCache("cache2");
1157
//		Assert.assertFalse("Cached book with differings caches should not match", matchStrategy.invoke(book1, bookClone));
1158
//		bookClone.setTitleCache("cache1"); //restore
1159
//
1160
//		bookClone.setEdition(null);
1161
//		Assert.assertTrue("Cached book with a defined and a null edition should match", matchStrategy.invoke(book1, bookClone));
1162

    
1163
		cdmGenericDao.saveOrUpdate((Reference)book1);
1164
		cdmGenericDao.saveOrUpdate((Reference)book2);
1165
		cdmGenericDao.saveOrUpdate((Reference)book3);
1166
		cdmGenericDao.saveOrUpdate(team1);
1167
		cdmGenericDao.saveOrUpdate(team2);
1168

    
1169

    
1170
		IMatchStrategy matchStrategy = DefaultMatchStrategy.NewInstance(Reference.class);
1171

    
1172
		try {
1173
			List<IBook> matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1174
			Assert.assertNotNull("Resultlist must not be null", matchResult);
1175
			Assert.assertEquals("Resultlist must have 2 entries", 2, matchResult.size());
1176
			Assert.assertTrue("Resultlist must contain book 1", matchResult.contains(book1));
1177
			Assert.assertTrue("Resultlist must contain book 2", matchResult.contains(book2));
1178

    
1179
			book1.setTitleCache("cache1", true);
1180
			matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1181
			Assert.assertEquals("Resultlist must have 1 entries", 1, matchResult.size());
1182
			Assert.assertTrue("Resultlist must contain book 2", matchResult.contains(book2));
1183

    
1184
			book2.setTitleCache("cache2", false);
1185
			matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1186
			Assert.assertEquals("Resultlist must have 1 entries", 1, matchResult.size());
1187
			Assert.assertTrue("Resultlist must contain book 2", matchResult.contains(book2));
1188

    
1189
			book2.setEdition(null);
1190
			matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1191
			Assert.assertEquals("Resultlist must have 0 entries", 0, matchResult.size());
1192

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

    
1198
			IMatchStrategy teamMatcher = DefaultMatchStrategy.NewInstance(Team.class);
1199
			boolean teamsMatch = teamMatcher.invoke(team1, team2);
1200
			Assert.assertTrue("Team1 and team2 should match" ,teamsMatch);
1201

    
1202
			book3.setAuthorship(team2);
1203
			matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1204
			Assert.assertEquals("Resultlist must have 1 entries", 1, matchResult.size());
1205
			Assert.assertTrue("Resultlist must contain book 1", matchResult.contains(book1));
1206

    
1207
			book3.setAuthorship(null);
1208
			matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1209
			Assert.assertEquals("Resultlist must have 1 entries", 1, matchResult.size());
1210
			Assert.assertTrue("Resultlist must contain book 1", matchResult.contains(book1));
1211

    
1212
			book2.setTitleCache(book3.getTitleCache(), true);
1213
			matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1214
			Assert.assertEquals("Resultlist must have 2 entries", 2, matchResult.size());
1215
			Assert.assertTrue("Resultlist must contain book 1", matchResult.contains(book1));
1216
			Assert.assertTrue("Resultlist must contain book 2", matchResult.contains(book2));
1217

    
1218
			team2.setTitleCache("team2", true);
1219
			teamsMatch = teamMatcher.invoke(team1, team2);
1220
			Assert.assertFalse("Team1 and team2 should not match" ,teamsMatch);
1221

    
1222
			book3.setAuthorship(team1);
1223
			book2.setAuthorship(team2);
1224
			matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1225
			Assert.assertEquals("Resultlist must have 1 entries", 1, matchResult.size());
1226
			Assert.assertTrue("Resultlist must contain book 1", matchResult.contains(book1));
1227

    
1228

    
1229
		} catch (MatchException e) {
1230
			Assert.fail("Find match must not throw Exception: " + e.getMessage());
1231
			e.printStackTrace();
1232
		}
1233
	}
1234

    
1235
	//from original testing within class, can be removed if not needed anymore
1236
	private void test() {
1237
		SessionFactoryImpl factory = (SessionFactoryImpl)((CdmGenericDaoImpl)cdmGenericDao).getSession().getSessionFactory();
1238
		Type propType = factory.getReferencedPropertyType(TaxonName.class.getCanonicalName(), "titleCache");
1239
		Map<?,?> collMetadata = factory.getAllCollectionMetadata();
1240
		Object roles = factory.getCollectionRolesByEntityParticipant("eu.etaxonomy.cdm.model.name.BotanicalName");
1241
		CollectionPersister collPersister;
1242
		try {
1243
			collPersister = factory.getCollectionPersister(TaxonName.class.getCanonicalName()+".annotations");
1244
		} catch (MappingException e) {
1245
			// TODO Auto-generated catch block
1246
			e.printStackTrace();
1247
		}
1248
		Statistics statistics = factory.getStatistics();
1249
		Map<?,?> allClassMetadata = factory.getAllClassMetadata();
1250
		logger.debug("");
1251

    
1252
	}
1253

    
1254
	/**
1255
	 * Test method for {@link eu.etaxonomy.cdm.persistence.dao.hibernate.common.CdmGenericDaoImpl#getHqlResult(java.lang.String)}.
1256
	 */
1257
	@Test
1258
	public void testGetHqlResult() {
1259
		logger.warn("Not yet implemented");
1260
	}
1261

    
1262
    @Override
1263
    public void createTestDataSet() throws FileNotFoundException {}
1264
}
(4-4/11)