merge 3.4.1 into trunk
[cdmlib.git] / cdmlib-persistence / src / test / java / eu / etaxonomy / cdm / persistence / dao / hibernate / common / CdmGenericDaoImplTest.java
1 // $Id$
2 /**
3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10
11 package eu.etaxonomy.cdm.persistence.dao.hibernate.common;
12
13 import static org.junit.Assert.assertEquals;
14
15 import java.io.FileNotFoundException;
16 import java.net.URI;
17 import java.util.ArrayList;
18 import java.util.Arrays;
19 import java.util.List;
20 import java.util.Set;
21 import java.util.UUID;
22
23 import org.apache.log4j.Logger;
24 import org.junit.After;
25 import org.junit.AfterClass;
26 import org.junit.Assert;
27 import org.junit.Before;
28 import org.junit.BeforeClass;
29 import org.junit.Ignore;
30 import org.junit.Test;
31 import org.unitils.dbunit.annotation.DataSet;
32 import org.unitils.spring.annotation.SpringBeanByType;
33
34 import eu.etaxonomy.cdm.model.agent.Address;
35 import eu.etaxonomy.cdm.model.agent.AgentBase;
36 import eu.etaxonomy.cdm.model.agent.Contact;
37 import eu.etaxonomy.cdm.model.agent.Institution;
38 import eu.etaxonomy.cdm.model.agent.InstitutionalMembership;
39 import eu.etaxonomy.cdm.model.agent.Person;
40 import eu.etaxonomy.cdm.model.agent.Team;
41 import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
42 import eu.etaxonomy.cdm.model.common.Annotation;
43 import eu.etaxonomy.cdm.model.common.AnnotationType;
44 import eu.etaxonomy.cdm.model.common.CdmBase;
45 import eu.etaxonomy.cdm.model.common.Credit;
46 import eu.etaxonomy.cdm.model.common.DefinedTerm;
47 import eu.etaxonomy.cdm.model.common.DefinedTermBase;
48 import eu.etaxonomy.cdm.model.common.Extension;
49 import eu.etaxonomy.cdm.model.common.ExtensionType;
50 import eu.etaxonomy.cdm.model.common.GrantedAuthorityImpl;
51 import eu.etaxonomy.cdm.model.common.Group;
52 import eu.etaxonomy.cdm.model.common.IdentifiableSource;
53 import eu.etaxonomy.cdm.model.common.LSIDAuthority;
54 import eu.etaxonomy.cdm.model.common.Language;
55 import eu.etaxonomy.cdm.model.common.LanguageString;
56 import eu.etaxonomy.cdm.model.common.Marker;
57 import eu.etaxonomy.cdm.model.common.MarkerType;
58 import eu.etaxonomy.cdm.model.common.OrderedTermBase;
59 import eu.etaxonomy.cdm.model.common.OrderedTermVocabulary;
60 import eu.etaxonomy.cdm.model.common.OriginalSourceBase;
61 import eu.etaxonomy.cdm.model.common.OriginalSourceType;
62 import eu.etaxonomy.cdm.model.common.RelationshipTermBase;
63 import eu.etaxonomy.cdm.model.common.Representation;
64 import eu.etaxonomy.cdm.model.common.TermVocabulary;
65 import eu.etaxonomy.cdm.model.common.TimePeriod;
66 import eu.etaxonomy.cdm.model.common.User;
67 import eu.etaxonomy.cdm.model.description.CategoricalData;
68 import eu.etaxonomy.cdm.model.description.CommonTaxonName;
69 import eu.etaxonomy.cdm.model.description.DescriptionBase;
70 import eu.etaxonomy.cdm.model.description.DescriptionElementBase;
71 import eu.etaxonomy.cdm.model.description.Distribution;
72 import eu.etaxonomy.cdm.model.description.Feature;
73 import eu.etaxonomy.cdm.model.description.FeatureNode;
74 import eu.etaxonomy.cdm.model.description.FeatureTree;
75 import eu.etaxonomy.cdm.model.description.IndividualsAssociation;
76 import eu.etaxonomy.cdm.model.description.MeasurementUnit;
77 import eu.etaxonomy.cdm.model.description.MediaKey;
78 import eu.etaxonomy.cdm.model.description.PresenceAbsenceTerm;
79 import eu.etaxonomy.cdm.model.description.QuantitativeData;
80 import eu.etaxonomy.cdm.model.description.SpecimenDescription;
81 import eu.etaxonomy.cdm.model.description.State;
82 import eu.etaxonomy.cdm.model.description.StateData;
83 import eu.etaxonomy.cdm.model.description.StatisticalMeasure;
84 import eu.etaxonomy.cdm.model.description.StatisticalMeasurementValue;
85 import eu.etaxonomy.cdm.model.description.TaxonDescription;
86 import eu.etaxonomy.cdm.model.description.TaxonInteraction;
87 import eu.etaxonomy.cdm.model.description.TaxonNameDescription;
88 import eu.etaxonomy.cdm.model.description.TextData;
89 import eu.etaxonomy.cdm.model.description.TextFormat;
90 import eu.etaxonomy.cdm.model.location.Country;
91 import eu.etaxonomy.cdm.model.location.NamedArea;
92 import eu.etaxonomy.cdm.model.location.NamedAreaLevel;
93 import eu.etaxonomy.cdm.model.location.NamedAreaType;
94 import eu.etaxonomy.cdm.model.location.Point;
95 import eu.etaxonomy.cdm.model.location.ReferenceSystem;
96 import eu.etaxonomy.cdm.model.media.AudioFile;
97 import eu.etaxonomy.cdm.model.media.ImageFile;
98 import eu.etaxonomy.cdm.model.media.Media;
99 import eu.etaxonomy.cdm.model.media.MediaRepresentation;
100 import eu.etaxonomy.cdm.model.media.MediaRepresentationPart;
101 import eu.etaxonomy.cdm.model.media.MovieFile;
102 import eu.etaxonomy.cdm.model.media.Rights;
103 import eu.etaxonomy.cdm.model.media.RightsType;
104 import eu.etaxonomy.cdm.model.molecular.DnaSample;
105 import eu.etaxonomy.cdm.model.molecular.PhylogeneticTree;
106 import eu.etaxonomy.cdm.model.molecular.Sequence;
107 import eu.etaxonomy.cdm.model.name.BacterialName;
108 import eu.etaxonomy.cdm.model.name.BotanicalName;
109 import eu.etaxonomy.cdm.model.name.CultivarPlantName;
110 import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
111 import eu.etaxonomy.cdm.model.name.HybridRelationship;
112 import eu.etaxonomy.cdm.model.name.HybridRelationshipType;
113 import eu.etaxonomy.cdm.model.name.NameRelationship;
114 import eu.etaxonomy.cdm.model.name.NameRelationshipType;
115 import eu.etaxonomy.cdm.model.name.NameTypeDesignation;
116 import eu.etaxonomy.cdm.model.name.NameTypeDesignationStatus;
117 import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;
118 import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;
119 import eu.etaxonomy.cdm.model.name.NonViralName;
120 import eu.etaxonomy.cdm.model.name.Rank;
121 import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
122 import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignationStatus;
123 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
124 import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
125 import eu.etaxonomy.cdm.model.name.ViralName;
126 import eu.etaxonomy.cdm.model.name.ZoologicalName;
127 import eu.etaxonomy.cdm.model.occurrence.Collection;
128 import eu.etaxonomy.cdm.model.occurrence.DerivationEvent;
129 import eu.etaxonomy.cdm.model.occurrence.DerivationEventType;
130 import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
131 import eu.etaxonomy.cdm.model.occurrence.DeterminationEvent;
132 import eu.etaxonomy.cdm.model.occurrence.FieldUnit;
133 import eu.etaxonomy.cdm.model.occurrence.GatheringEvent;
134 import eu.etaxonomy.cdm.model.occurrence.PreservationMethod;
135 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
136 import eu.etaxonomy.cdm.model.reference.IBook;
137 import eu.etaxonomy.cdm.model.reference.IBookSection;
138 import eu.etaxonomy.cdm.model.reference.Reference;
139 import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
140 import eu.etaxonomy.cdm.model.taxon.Classification;
141 import eu.etaxonomy.cdm.model.taxon.Synonym;
142 import eu.etaxonomy.cdm.model.taxon.SynonymRelationship;
143 import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;
144 import eu.etaxonomy.cdm.model.taxon.Taxon;
145 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
146 import eu.etaxonomy.cdm.model.taxon.TaxonNode;
147 import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
148 import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
149 import eu.etaxonomy.cdm.model.view.AuditEvent;
150 import eu.etaxonomy.cdm.persistence.dao.agent.IAgentDao;
151 import eu.etaxonomy.cdm.persistence.dao.common.ICdmGenericDao;
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.taxon.ITaxonDao;
155 import eu.etaxonomy.cdm.strategy.match.DefaultMatchStrategy;
156 import eu.etaxonomy.cdm.strategy.match.IMatchStrategy;
157 import eu.etaxonomy.cdm.strategy.match.MatchException;
158 import eu.etaxonomy.cdm.strategy.merge.DefaultMergeStrategy;
159 import eu.etaxonomy.cdm.strategy.merge.IMergeStrategy;
160 import eu.etaxonomy.cdm.strategy.merge.MergeException;
161 import eu.etaxonomy.cdm.test.integration.CdmTransactionalIntegrationTest;
162
163 /**
164 * @author a.mueller
165 * @created 27.07.2009
166 */
167 @Ignore
168 public class CdmGenericDaoImplTest extends CdmTransactionalIntegrationTest{
169 private static final Logger logger = Logger.getLogger(CdmGenericDaoImplTest.class);
170
171 @SpringBeanByType
172 private ICdmGenericDao cdmGenericDao;
173
174 @SpringBeanByType
175 private ITaxonDao taxonDao;
176
177 @SpringBeanByType
178 private IOccurrenceDao occurrenceDao;
179
180
181 @SpringBeanByType
182 private ITaxonNameDao nameDao;
183
184 @SpringBeanByType
185 private IAgentDao agentDao;
186
187
188 /**
189 * @throws java.lang.Exception
190 */
191 @BeforeClass
192 public static void setUpBeforeClass() throws Exception {
193 }
194
195 /**
196 * @throws java.lang.Exception
197 */
198 @AfterClass
199 public static void tearDownAfterClass() throws Exception {
200 }
201
202 /**
203 * @throws java.lang.Exception
204 */
205 @Before
206 public void setUp() throws Exception {
207 }
208
209 /**
210 * @throws java.lang.Exception
211 */
212 @After
213 public void tearDown() throws Exception {
214 }
215
216 // ***************** TESTS **************************************************
217
218 @Test
219 @Ignore
220 public void testDelete(){
221 Reference<?> ref1 = ReferenceFactory.newBook();
222 Reference<?> ref2 = ReferenceFactory.newBook();
223 Annotation annotation = Annotation.NewInstance("Anno1", null);
224 ref1.addAnnotation(annotation);
225 cdmGenericDao.saveOrUpdate(ref1);
226 cdmGenericDao.saveOrUpdate(ref2);
227 taxonDao.flush();
228 try {
229 cdmGenericDao.merge(ref2, ref1, null);
230 taxonDao.flush();
231 } catch (MergeException e) {
232 // TODO Auto-generated catch block
233 e.printStackTrace();
234 }
235 //cdmGenericDao.delete(ref1);
236 taxonDao.flush();
237 System.out.println("OK");
238 //Assert.fail("Failed for testing");
239 }
240
241 /**
242 * Test method for {@link eu.etaxonomy.cdm.persistence.dao.hibernate.common.CdmGenericDaoImpl#merge(CdmBase, CdmBase)}.
243 * @throws MergeException
244 */
245 @Test
246 @Ignore
247 public void testDelete2() throws MergeException {
248 BotanicalName name1 = BotanicalName.NewInstance(Rank.SPECIES());
249 name1.setTitleCache("BotanicalName1", true);
250
251 BotanicalName name2 = BotanicalName.NewInstance(Rank.SPECIES());
252 name2.setTitleCache("BotanicalName2", true);
253
254 Reference article1 = ReferenceFactory.newArticle();
255 Reference article2 = ReferenceFactory.newArticle();
256
257
258 name1.setNomenclaturalReference(article1);
259 name2.setNomenclaturalReference(article2);
260
261
262 Taxon taxon1 = Taxon.NewInstance(name1, article1);
263
264 // Person author = Person.NewInstance();
265 // author.setTitleCache("Author");
266 Annotation annotation1 = Annotation.NewInstance("A1", Language.DEFAULT());
267 Annotation annotation2 = Annotation.NewInstance("A2", Language.DEFAULT());
268
269 article1.addAnnotation(annotation1);
270 article2.addAnnotation(annotation2);
271
272 nameDao.save(name1);
273 nameDao.save(name2);
274 cdmGenericDao.saveOrUpdate(article2);
275
276 taxonDao.save(taxon1);
277
278 //unidircetional reference to the merged object should be redirected
279 cdmGenericDao.merge(article1, article2, null);
280 Assert.assertEquals("Name2 must have article 1 as new nomRef", article1 ,name2.getNomenclaturalReference());
281 //TODO microCitations!! -> warning
282
283 //Annotations
284 Assert.assertEquals("Annotation number should be 2 (1 from each of the merged objects)", 2, article1.getAnnotations().size());
285 }
286
287
288
289
290 /**
291 * Test method for {@link eu.etaxonomy.cdm.persistence.dao.hibernate.common.CdmGenericDaoImpl#CdmGenericDaoImpl()}.
292 */
293 @Test
294 public void testCdmGenericDaoImpl() {
295 logger.warn("Not yet implemented");
296 }
297
298 /**
299 * 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)}.
300 */
301 @Test
302 public void testGetCdmBasesByFieldAndClass() {
303 logger.warn("Not yet implemented");
304 }
305
306 /**
307 * 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)}.
308 */
309 @Test
310 public void testGetCdmBasesWithItemInCollection() {
311 logger.warn("Not yet implemented");
312 }
313
314 /**
315 * Test method for {@link eu.etaxonomy.cdm.persistence.dao.hibernate.common.CdmGenericDaoImpl#getAllCdmClasses(boolean)}.
316 */
317 @Test
318 public void testGetAllCdmClasses() {
319 Class[] existingClassesArray = {
320 Address.class,
321 AgentBase.class,
322 Institution.class,
323 InstitutionalMembership.class,
324 Person.class,
325 Team.class,
326 TeamOrPersonBase.class,
327 Annotation.class,
328 AnnotationType.class,
329 Credit.class,
330 DefinedTermBase.class,
331 Extension.class,
332 ExtensionType.class,
333 GrantedAuthorityImpl.class,
334 Group.class,
335 IdentifiableSource.class,
336 Language.class,
337 LanguageString.class,
338 LSIDAuthority.class,
339 Marker.class,
340 MarkerType.class,
341 OrderedTermBase.class,
342 OrderedTermVocabulary.class,
343 OriginalSourceBase.class,
344 RelationshipTermBase.class,
345 Representation.class,
346 TermVocabulary.class,
347 User.class,
348 DefinedTerm.class,
349
350 CategoricalData.class,
351 CommonTaxonName.class,
352 DescriptionBase.class,
353 DescriptionElementBase.class,
354 Distribution.class,
355 Feature.class,
356 FeatureNode.class,
357 FeatureTree.class,
358 MediaKey.class,
359 IndividualsAssociation.class,
360 MeasurementUnit.class,
361 PresenceAbsenceTerm.class,
362 QuantitativeData.class,
363 SpecimenDescription.class,
364 State.class,
365 StateData.class,
366 StatisticalMeasure.class,
367 StatisticalMeasurementValue.class,
368 TaxonDescription.class,
369 TaxonInteraction.class,
370 TaxonNameDescription.class,
371 TextData.class,
372 TextFormat.class,
373 NamedArea.class,
374 NamedAreaLevel.class,
375 NamedAreaType.class,
376 ReferenceSystem.class,
377 Country.class,
378 AudioFile.class,
379 ImageFile.class,
380 Media.class,
381 MediaRepresentation.class,
382 MediaRepresentationPart.class,
383 MovieFile.class,
384 Rights.class,
385 RightsType.class,
386 DnaSample.class,
387 PhylogeneticTree.class,
388 Sequence.class,
389 BacterialName.class,
390 BotanicalName.class,
391 CultivarPlantName.class,
392 HomotypicalGroup.class,
393 HybridRelationship.class,
394 HybridRelationshipType.class,
395 NameRelationship.class,
396 NameRelationshipType.class,
397 NameTypeDesignation.class,
398 NameTypeDesignationStatus.class,
399 NomenclaturalStatus.class,
400 NomenclaturalStatusType.class,
401 NonViralName.class,
402 Rank.class,
403 SpecimenTypeDesignation.class,
404 SpecimenTypeDesignationStatus.class,
405 TaxonNameBase.class,
406 TypeDesignationBase.class,
407 ViralName.class,
408 ZoologicalName.class,
409 Collection.class,
410 DerivationEvent.class,
411 DerivationEventType.class,
412 DerivedUnit.class,
413 DeterminationEvent.class,
414 FieldUnit.class,
415 GatheringEvent.class,
416 PreservationMethod.class,
417 SpecimenOrObservationBase.class,
418 Reference.class,
419 Synonym.class,
420 SynonymRelationship.class,
421 SynonymRelationshipType.class,
422 Taxon.class,
423 TaxonBase.class,
424 TaxonNode.class,
425 Classification.class,
426 TaxonRelationship.class,
427 TaxonRelationshipType.class
428 //Contact.class,
429 //LSID.class,
430 //Modifier.class,
431 //Point.class,
432 //NomenclaturalCode.class,
433 } ;
434 List<Class> existingClassesList = new ArrayList<Class>();
435 existingClassesList.addAll(Arrays.asList(existingClassesArray));
436 boolean includeAbstractClasses = true;
437 Set<Class<? extends CdmBase>> foundClasses = cdmGenericDao.getAllCdmClasses(includeAbstractClasses);
438
439 //for debugging only
440 // for (Class existingClass : existingClassesList){
441 // if (! foundClasses.contains(existingClass)){
442 // logger.warn("Class not found: " + existingClass.getCanonicalName());
443 // }
444 // }
445
446 //All classes must be found
447 Assert.assertTrue("all classes must be found by getAllCdmClasses() method", foundClasses.containsAll(existingClassesList));
448
449
450 //No extra classes must be found
451 for (Class clazz : foundClasses){
452 if (! CdmBase.class.isAssignableFrom(clazz)&& !( AuditEvent.class == clazz) ){ //OLD: && !( LSID.class == clazz)&& !( NomenclaturalCode.class == clazz) && !( Point.class == clazz) && !( Modifier.class == clazz) && !( Contact.class == clazz)
453 Assert.fail("Class " + clazz.getName() + " is not assignable from CdmBase");
454 }
455 }
456
457 includeAbstractClasses = false;
458 Set<Class<? extends CdmBase>> noAbstractClasses = cdmGenericDao.getAllCdmClasses(includeAbstractClasses);
459 Class abstractClassToTest = TaxonNameBase.class;
460 Assert.assertFalse("Abstract class " + abstractClassToTest.getName() + " may not be in set ", noAbstractClasses.contains(abstractClassToTest));
461 }
462
463 /**
464 * Test method for {@link eu.etaxonomy.cdm.persistence.dao.hibernate.common.CdmGenericDaoImpl#getReferencingObjects(CdmBase)}.
465 */
466 @Test
467 public void testGetReferencingObjectsCdmBase() {
468 BotanicalName name = BotanicalName.NewInstance(Rank.SPECIES());
469 name.setTitleCache("A name", true);
470 Reference ref1 = ReferenceFactory.newArticle();
471 Taxon taxon = Taxon.NewInstance(name, ref1);
472 Person author = Person.NewInstance();
473 author.setTitleCache("Author", true);
474 ref1.addAnnotation(Annotation.NewInstance("A1", Language.DEFAULT()));
475 ref1.setAuthorship(author);
476 name.setBasionymAuthorTeam(author);
477
478 name.setNomenclaturalReference(ref1);
479
480 taxonDao.save(taxon);
481 // UUID uuid = UUID.fromString("613980ac-9bd5-43b9-a374-d71e1794688f");
482 // Reference ref1 = referenceService.findByUuid(uuid);
483
484
485 Set<CdmBase> referencedObjects = cdmGenericDao.getReferencingObjects(ref1);
486 System.out.println("############## RESULT ###################");
487 for (CdmBase obj: referencedObjects){
488 System.out.println("Object1: " + obj.getClass().getSimpleName() + " - " + obj);
489 }
490 assertEquals(3, referencedObjects.size());
491 System.out.println("############## ENDE ###################");
492
493 // UUID uuidAuthor = UUID.fromString("4ce66544-a5a3-4601-ab0b-1f0a1338327b");
494 // AgentBase author = agentService.findByUuid(uuidAuthor);
495
496 referencedObjects = cdmGenericDao.getReferencingObjects(author);
497 System.out.println("############## RESULT ###################");
498 for (CdmBase obj: referencedObjects){
499 System.out.println("Object2: " + obj.getClass().getSimpleName() + " - " + obj);
500 }
501 assertEquals(2, referencedObjects.size());
502 System.out.println("############## ENDE ###################");
503 }
504
505 /**
506 * 2nd test method for {@link eu.etaxonomy.cdm.persistence.dao.hibernate.common.CdmGenericDaoImpl#getReferencingObjects(CdmBase)}.
507 *
508 */
509 @Test
510 @DataSet
511 public final void testGetReferencingObjects2() {
512 // SpecimenDescription desc1 = SpecimenDescription.NewInstance();
513 // desc1.setTitleCache("desc1");
514 // SpecimenDescription desc2 = SpecimenDescription.NewInstance();
515 // desc2.setTitleCache("desc2");
516 //
517 // SpecimenOrObservationBase spec1 = Specimen.NewInstance();
518 //
519 // desc1.addDescribedSpecimenOrObservation(spec1);
520 // //Taxon taxon = Taxon.NewInstance(taxonNameBase, sec)
521 // spec1.addDescription(desc2);
522 //
523 // occurrenceService.save(spec1);
524
525 UUID uuidSpec = UUID.fromString("41539e9c-3764-4f14-9712-2d07d00c8e4c");
526 SpecimenOrObservationBase spec1 = occurrenceDao.findByUuid(uuidSpec);
527
528
529 Set<CdmBase> referencingObjects = cdmGenericDao.getReferencingObjects(spec1);
530 // System.out.println("############## RESULT ###################");
531 // for (CdmBase obj: referencingObjects){
532 // System.out.println("Object: " + obj.getClass().getSimpleName() + " - " + obj);
533 // }
534 // System.out.println("############## ENDE ###################");
535 assertEquals("Number of referencing objects must be 2.", 2, referencingObjects.size());
536
537 }
538
539 /**
540 * Test method for {@link eu.etaxonomy.cdm.persistence.dao.hibernate.common.CdmGenericDaoImpl#merge(CdmBase, CdmBase)}.
541 * @throws MergeException
542 */
543 @Test
544 @Ignore
545 public void testMergeCdmBaseReferenceAndIdentifiable() throws MergeException {
546
547 BotanicalName name1 = BotanicalName.NewInstance(Rank.SPECIES());
548 name1.setTitleCache("BotanicalName1", true);
549
550 BotanicalName name2 = BotanicalName.NewInstance(Rank.SPECIES());
551 name2.setTitleCache("BotanicalName2", true);
552
553 ZoologicalName zooName1 = ZoologicalName.NewInstance(Rank.SPECIES());
554 name1.setTitleCache("ZoologicalName1", true);
555
556 Reference article1 = ReferenceFactory.newArticle();
557 Reference article2 = ReferenceFactory.newArticle();
558
559
560 name1.setNomenclaturalReference(article1);
561 name2.setNomenclaturalReference(article2);
562
563
564 Taxon taxon1 = Taxon.NewInstance(name1, article1);
565 Taxon taxon2 = Taxon.NewInstance(name2, article2);
566
567
568 // Person author = Person.NewInstance();
569 // author.setTitleCache("Author");
570 Annotation annotation1 = Annotation.NewInstance("A1", Language.DEFAULT());
571 Annotation annotation2 = Annotation.NewInstance("A2", Language.DEFAULT());
572
573 article1.addAnnotation(annotation1);
574 article2.addAnnotation(annotation2);
575
576 Marker marker1 = Marker.NewInstance(MarkerType.COMPLETE(), false);
577 Marker marker2 = Marker.NewInstance(MarkerType.IMPORTED(), false);
578
579 article1.addMarker(marker1);
580 article2.addMarker(marker2);
581
582 Rights rights1 = Rights.NewInstance();
583 Rights rights2 = Rights.NewInstance();
584
585 article1.addRights(rights1);
586 article2.addRights(rights2);
587
588
589 Credit credit1 = Credit.NewInstance(Team.NewInstance(), "credit1");
590 Credit credit2 = Credit.NewInstance(Team.NewInstance(), "credit2");
591
592 article1.addCredit(credit1);
593 article2.addCredit(credit2);
594
595 Extension extension1 = Extension.NewInstance();
596 Extension extension2 = Extension.NewInstance();
597
598 article1.addExtension(extension1);
599 article2.addExtension(extension2);
600
601 IdentifiableSource source1 = IdentifiableSource.NewInstance(OriginalSourceType.Unknown);
602 IdentifiableSource source2 = IdentifiableSource.NewInstance(OriginalSourceType.Unknown);
603
604 article1.addSource(source1);
605 article2.addSource(source2);
606
607 Media media1 = Media.NewInstance();
608 Media media2 = Media.NewInstance();
609
610 article1.addMedia(media1);
611 article2.addMedia(media2);
612
613 // ref1.setAuthorship(author);
614 // name1.setBasionymAuthorTeam(author);
615
616 name1.setNomenclaturalReference(article1);
617
618 nameDao.save(name1);
619 nameDao.save(name2);
620 nameDao.save(zooName1);
621
622 TaxonDescription taxDesc = TaxonDescription.NewInstance(taxon1);
623 taxDesc.setTitleCache("taxDesc", true);
624 taxDesc.addSource(OriginalSourceType.Unknown, null, null, article2, null);
625
626 taxonDao.save(taxon1);
627
628 //unidircetional reference to the merged object should be redirected
629 cdmGenericDao.merge(article1, article2, null);
630 Assert.assertEquals("Name2 must have article 1 as new nomRef", article1 ,name2.getNomenclaturalReference());
631 //TODO microCitations!! -> warning
632
633 //Annotations
634 Assert.assertEquals("Annotation number should be 2 (1 from each of the merged objects)", 2, article1.getAnnotations().size());
635
636 //Marker
637 Assert.assertEquals("Marker number should be 2 (1 from each of the merged objects)", 2, article1.getMarkers().size());
638
639 //Rights
640 Assert.assertEquals("Rights number should be 2 (1 from each of the merged objects)", 2, article1.getRights().size());
641
642 //Credits
643 Assert.assertEquals("Credits number should be 2 (1 from each of the merged objects)", 2, article1.getCredits().size());
644
645 //Extensions
646 Assert.assertEquals("Extensions number should be 2 (1 from each of the merged objects)", 2, article1.getExtensions().size());
647
648 //Sources
649 Assert.assertEquals("Sources number should be 2 (1 from each of the merged objects)", 2, article1.getSources().size());
650
651 //Media
652 Assert.assertEquals("Media number should be 2 (1 from each of the merged objects)", 2, article1.getMedia().size());
653
654 //Description sources
655 Assert.assertEquals("Number of sources for taxon description must be 1", 1, taxDesc.getSources().size());
656 Assert.assertEquals("Taxon description must have article1 as source", taxDesc.getSources().iterator().next().getCitation(),article1);
657
658 //test exceptions
659 testMergeExceptions(name1, name2, taxon1, zooName1);
660
661
662 //TO BE IMPLEMENTED
663 Assert.assertTrue("Rights2 must be contained in the rights", article1.getRights().contains(rights2));
664 Assert.assertTrue("Credits2 must be contained in the credits", article1.getCredits().contains(credit2));
665 Assert.assertTrue("Media2 must be contained in the media", article1.getMedia().contains(media2));
666
667 }
668
669 /**
670 * Test method for {@link eu.etaxonomy.cdm.persistence.dao.hibernate.common.CdmGenericDaoImpl#merge(CdmBase, CdmBase)}.
671 * @throws MergeException
672 */
673 @Test
674 @Ignore
675 public void testMergeTaxonNameAndTaxon() throws MergeException {
676 BotanicalName name1 = BotanicalName.NewInstance(Rank.SPECIES());
677 name1.setTitleCache("BotanicalName1", true);
678
679 BotanicalName name2 = BotanicalName.NewInstance(Rank.SPECIES());
680 name2.setTitleCache("BotanicalName2", true);
681
682 BotanicalName name3 = BotanicalName.NewInstance(Rank.SPECIES());
683 name3.setTitleCache("BotanicalName3", true);
684
685 Reference database = ReferenceFactory.newDatabase();
686
687 Taxon taxon1 = Taxon.NewInstance(name1, database);
688 Taxon taxon2 = Taxon.NewInstance(name2, database);
689 Taxon taxon3 = Taxon.NewInstance(name3, database);
690
691 taxonDao.save(taxon1);
692 taxonDao.save(taxon2);
693 taxonDao.save(taxon3);
694
695 cdmGenericDao.merge(name1, name2, null);
696 Assert.assertEquals("Name1 must have 2 taxa attached now.", 2 ,name1.getTaxonBases().size());
697 Assert.assertEquals("Taxon2 must have name1 as new name.", name1 ,taxon2.getName());
698
699 //TODO
700 // cdmGenericDao.merge(taxon1, taxon3, null);
701 // Assert.assertEquals("Name1 must have 3 taxa attached now.", 3 ,name1.getTaxonBases().size());
702
703
704 }
705
706 /**
707 * Test method for {@link eu.etaxonomy.cdm.persistence.dao.hibernate.common.CdmGenericDaoImpl#merge(CdmBase, CdmBase)}.
708 * @throws MergeException
709 */
710 @Test
711 public void testMergeAuthors() throws MergeException {
712
713 BotanicalName name1 = BotanicalName.NewInstance(Rank.SPECIES());
714 name1.setTitleCache("BotanicalName1", true);
715
716 BotanicalName name2 = BotanicalName.NewInstance(Rank.SPECIES());
717 name2.setTitleCache("BotanicalName2", true);
718
719 IBook book1 = ReferenceFactory.newBook();
720 IBook book2 = ReferenceFactory.newBook();
721
722 Team team1 = Team.NewInstance();
723 Team team2 = Team.NewInstance();
724 Team team3 = Team.NewInstance();
725 team1.setTitleCache("team1", true);
726 team2.setTitleCache("team2", true);
727 team3.setTitleCache("team3", true);
728
729 Person person1 = Person.NewTitledInstance("person1");
730 Person person2 = Person.NewTitledInstance("person2");
731 Person person3 = Person.NewTitledInstance("person3");
732
733 team1.setNomenclaturalTitle("T.1");
734 String street1 = "Strasse1";
735 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)));
736 team2.setContact(Contact.NewInstance("Street2", null, "London", null, null, null, null, "874599873", null, null, null));
737 String street3 = "Street3";
738 team2.addAddress(street3, null, null, null, null, null, Point.NewInstance(1.1, 2.2, null, 4));
739 String emailAddress1 = "Email1";
740 team1.addEmailAddress(emailAddress1);
741
742 team2.addTeamMember(person1);
743 team2.addTeamMember(person2);
744 String emailAddress2 = "Email2";
745 team2.addEmailAddress(emailAddress2);
746
747 team3.addTeamMember(person3);
748 team3.addEmailAddress("emailAddress3");
749
750 book1.setAuthorship(team2);
751 book2.setAuthorship(team3);
752
753 Credit credit1 = Credit.NewInstance(team3, "credit1");
754 book2.addCredit(credit1);
755
756 agentDao.save(team1);
757 agentDao.save(team2);
758 agentDao.save(team3);
759 cdmGenericDao.save((Reference)book1);
760 cdmGenericDao.save((Reference)book2);
761
762 cdmGenericDao.merge(team2, team3, null);
763
764 Assert.assertSame("Author of book1 must be team2.", team2, book1.getAuthorship());
765 Assert.assertSame("Author of book2 must be team2.", team2, book2.getAuthorship());
766 Assert.assertSame("Agent of credit1 must be team2.", team2, credit1.getAgent());
767
768 Assert.assertEquals("Team2 must have 3 persons as members.",3, team2.getTeamMembers().size());
769 Assert.assertTrue("Team2 must have person3 as new member.", team2.getTeamMembers().contains(person3));
770 Assert.assertSame("Team2 must have person3 as third member.",person3, team2.getTeamMembers().get(2));
771
772
773 //Contact
774 cdmGenericDao.merge(team2, team1, null);
775 Contact team2Contact = team2.getContact();
776 Assert.assertNotNull("team2Contact must not be null", team2Contact);
777 Assert.assertNotNull("Addresses must not be null", team2Contact.getAddresses());
778 Assert.assertEquals("Number of addresses must be 3", 3, team2Contact.getAddresses().size());
779 Assert.assertEquals("Number of email addresses must be 4", 4, team2Contact.getEmailAddresses().size());
780
781 boolean street1Exists = false;
782 boolean street3Exists = false;
783 boolean country1Exists = false;
784 for (Address address : team2Contact.getAddresses()){
785 if (street1.equals(address.getStreet())){
786 street1Exists = true;
787 }
788 if (street3.equals(address.getStreet())){
789 street3Exists = true;
790 }
791 if (Country.ARGENTINAARGENTINEREPUBLIC() == address.getCountry()){
792 country1Exists = true;
793 }
794 }
795 Assert.assertTrue("Street1 must be one of the streets in team2's addresses", street1Exists);
796 Assert.assertTrue("Street3 must be one of the streets in team2's addressesss", street3Exists);
797 Assert.assertTrue("Argentina must be one of the countries in team2's addresses", country1Exists);
798
799 //Person
800 Institution institution1 = Institution.NewInstance();
801 institution1.setTitleCache("inst1", true);
802 Institution institution2 = Institution.NewInstance();
803 institution2.setTitleCache("inst2", true);
804
805 TimePeriod period1 = TimePeriod.NewInstance(2002, 2004);
806 TimePeriod period2 = TimePeriod.NewInstance(2004, 2006);
807
808 person1.addInstitutionalMembership(institution1, period1, "departement1", "role1");
809 person2.addInstitutionalMembership(institution2, period2, "departement2", "role2");
810
811 IMergeStrategy personMergeStrategy = DefaultMergeStrategy.NewInstance(Person.class);
812 personMergeStrategy.invoke(person1, person2);
813
814 Assert.assertEquals("Number of institutional memberships must be 2", 2, person1.getInstitutionalMemberships().size());
815 for (InstitutionalMembership institutionalMembership : person1.getInstitutionalMemberships()){
816 Assert.assertSame("Person of institutional memebership must be person1", person1, institutionalMembership.getPerson());
817 }
818
819 }
820
821 private void testMergeExceptions(CdmBase name1, CdmBase name2, CdmBase taxon,CdmBase zooName1) throws MergeException{
822 //
823 try {
824 cdmGenericDao.merge(name1, null, null);
825 Assert.fail("Merging of 2 objects one or both of them null must throw an exception");
826 } catch (MergeException e) {
827 Assert.assertTrue("Merging of 2 objects of different types must throw an exception", true);
828 }
829 //
830 try {
831 cdmGenericDao.merge(null, name1, null);
832 Assert.fail("Merging of 2 objects one or both of them null must throw an exception");
833 } catch (NullPointerException e) {
834 Assert.assertTrue("Merging of 2 objects of different types must throw an exception", true);
835 }
836 //exceptions to be thrown
837 try {
838 cdmGenericDao.merge(name1, taxon, null);
839 Assert.fail("Merging of 2 objects of different types must throw an exception");
840 } catch (MergeException e) {
841 Assert.assertTrue("Merging of 2 objects of different types must throw an exception", true);
842 }
843 //next exception
844 try {
845 cdmGenericDao.merge(name1, zooName1, null);
846 Assert.fail("Merging of 2 objects of different types must throw an exception");
847 } catch (MergeException e) {
848 Assert.assertTrue("Merging of 2 objects of different types must throw an exception", true);
849 }
850 }
851
852 @Test
853 public void findMatching(){
854 IBook book1 = ReferenceFactory.newBook();
855 IBook book2 = ReferenceFactory.newBook();
856 IBook book3 = ReferenceFactory.newBook();
857 IBook book4 = ReferenceFactory.newBook();
858
859 String title1 = "title1";
860 String title2 = "title2";
861 book1.setTitle(title1);
862 book2.setTitle(title2);
863 book3.setTitle(title1);
864
865 cdmGenericDao.saveOrUpdate((Reference)book1);
866 cdmGenericDao.saveOrUpdate((Reference)book2);
867 cdmGenericDao.saveOrUpdate((Reference)book3);
868
869 IMatchStrategy matchStrategy = DefaultMatchStrategy.NewInstance(Reference.class);
870
871 try {
872 List<IBook> matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
873 Assert.assertNotNull("Resultlist must not be null", matchResult);
874 Assert.assertEquals("Resultlist must have 1 entries", 1, matchResult.size());
875 Assert.assertSame("Resultlist entry must be book 1", book1, matchResult.get(0));
876
877 book1.setDatePublished(TimePeriod.NewInstance(1999, 2002));
878 matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
879 Assert.assertTrue("Resultlist must have no entries", matchResult.isEmpty());
880
881 book3.setDatePublished(TimePeriod.NewInstance(1999));
882 matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
883 Assert.assertTrue("Resultlist must have no entries", matchResult.isEmpty());
884
885 book3.setDatePublished(TimePeriod.NewInstance(1999,2002));
886 matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
887 Assert.assertEquals("Resultlist must have 1 entries", 1, matchResult.size());
888 Assert.assertSame("Resultlist entry must be book 1", book1, matchResult.get(0));
889
890 //BookSection
891 IBookSection section1 = ReferenceFactory.newBookSection();
892 section1.setInBook(book1);
893 section1.setTitle("SecTitle");
894 section1.setPages("22-33");
895 IBookSection section2 = ReferenceFactory.newBookSection();
896 section2.setInBook(book2);
897 section2.setTitle("SecTitle");
898 section2.setPages("22-33");
899 IBookSection section3 = ReferenceFactory.newBookSection();
900 section3.setInBook(book1);
901 section3.setTitle("SecTitle");
902 section3.setPages("22-33");
903 cdmGenericDao.saveOrUpdate((Reference)section1);
904 cdmGenericDao.saveOrUpdate((Reference)section2);
905 cdmGenericDao.saveOrUpdate((Reference)section3);
906
907 List<IBookSection> sectionResult = cdmGenericDao.findMatching(section3, null);
908 Assert.assertEquals("Resultlist must have 1 entries", 1, sectionResult.size());
909 Assert.assertSame("Resultlist entry must be section1", section1, sectionResult.get(0));
910 section2.setInBook(book2 = (IBook)((Reference) book1).clone());
911 cdmGenericDao.saveOrUpdate((Reference)book2);
912 cdmGenericDao.saveOrUpdate((Reference)book1);
913
914 matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
915 Assert.assertEquals("Resultlist must have 2 entries", 2, matchResult.size());
916 sectionResult = cdmGenericDao.findMatching(section3, null);
917 Assert.assertEquals("Resultlist must have 1 entries", 2, sectionResult.size());
918
919
920 Person person1 = Person.NewTitledInstance("person");
921 Person person2 = Person.NewTitledInstance("person");
922 Person person3 = Person.NewTitledInstance("person");
923
924 person1.setPrefix("pre1");
925 person2.setPrefix("pre2");
926 person3.setPrefix("pre3");
927
928 // matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
929 // Assert.assertEquals("Resultlist must have 2 entries", 2, matchResult.size());
930
931 book1.setAuthorship(person1);
932 book2.setAuthorship(person1);
933 book3.setAuthorship(person1);
934
935 boolean m = matchStrategy.invoke(book1, book3);
936 boolean m2 = matchStrategy.invoke(book2, book3);
937
938 matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
939 Assert.assertEquals("Resultlist must have 2 entries", 2, matchResult.size());
940
941 book2.setAuthorship(person2);
942 book3.setAuthorship(person3);
943 matchResult = cdmGenericDao.findMatching(book3, null);
944 Assert.assertEquals("Resultlist must have no entries", 0, matchResult.size());
945
946 person3.setPrefix("pre1");
947 matchResult = cdmGenericDao.findMatching(book3, null);
948 Assert.assertEquals("Resultlist must have 1 entry", 1, matchResult.size());
949 Assert.assertSame("Resultlist entry must be book 1", book1, matchResult.get(0));
950
951 } catch (MatchException e) {
952 Assert.fail("Find match must not throw Exception: " + e.getMessage());
953 e.printStackTrace();
954 }
955
956 }
957
958
959 @Test
960 public void findMatchingCache(){
961 IBook book1 = ReferenceFactory.newBook();
962 Team team1 = Team.NewInstance();
963 Team team2 = Team.NewInstance();
964 team1.setTitleCache("Team1", true);
965 team2.setTitleCache("Team1", true);
966
967 book1.setTitle("Title1");
968 book1.setEdition("Edition1");
969 book1.setAuthorship(team1);
970
971
972 IBook book2 = (IBook) ((Reference)book1).clone();
973 IBook book3 = (IBook) ((Reference)book1).clone();
974
975 // Assert.assertTrue("Cloned book should match", matchStrategy.invoke(book1, bookClone));
976 // book1.setTitleCache("cache1");
977 // Assert.assertFalse("Cached book should not match", matchStrategy.invoke(book1, bookClone));
978 //
979 // bookClone.setTitleCache("cache1");
980 // Assert.assertTrue("Cached book with same cache should match", matchStrategy.invoke(book1, bookClone));
981 //
982 // bookClone.setTitleCache("cache2");
983 // Assert.assertFalse("Cached book with differings caches should not match", matchStrategy.invoke(book1, bookClone));
984 // bookClone.setTitleCache("cache1"); //restore
985 //
986 // bookClone.setEdition(null);
987 // Assert.assertTrue("Cached book with a defined and a null edition should match", matchStrategy.invoke(book1, bookClone));
988
989 cdmGenericDao.saveOrUpdate((Reference)book1);
990 cdmGenericDao.saveOrUpdate((Reference)book2);
991 cdmGenericDao.saveOrUpdate((Reference)book3);
992 cdmGenericDao.saveOrUpdate(team1);
993 cdmGenericDao.saveOrUpdate(team2);
994
995
996 IMatchStrategy matchStrategy = DefaultMatchStrategy.NewInstance(Reference.class);
997
998 try {
999 List<IBook> matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1000 Assert.assertNotNull("Resultlist must not be null", matchResult);
1001 Assert.assertEquals("Resultlist must have 2 entries", 2, matchResult.size());
1002 Assert.assertTrue("Resultlist must contain book 1", matchResult.contains(book1));
1003 Assert.assertTrue("Resultlist must contain book 2", matchResult.contains(book2));
1004
1005 book1.setTitleCache("cache1", true);
1006 matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1007 Assert.assertEquals("Resultlist must have 1 entries", 1, matchResult.size());
1008 Assert.assertTrue("Resultlist must contain book 2", matchResult.contains(book2));
1009
1010 book2.setTitleCache("cache2", false);
1011 matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1012 Assert.assertEquals("Resultlist must have 1 entries", 1, matchResult.size());
1013 Assert.assertTrue("Resultlist must contain book 2", matchResult.contains(book2));
1014
1015 book2.setEdition(null);
1016 matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1017 Assert.assertEquals("Resultlist must have 0 entries", 0, matchResult.size());
1018
1019 book3.setTitleCache("cache1", true);
1020 matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1021 Assert.assertEquals("Resultlist must have 1 entries", 1, matchResult.size());
1022 Assert.assertTrue("Resultlist must contain book 1", matchResult.contains(book1));
1023
1024 IMatchStrategy teamMatcher = DefaultMatchStrategy.NewInstance(Team.class);
1025 boolean teamsMatch = teamMatcher.invoke(team1, team2);
1026 Assert.assertTrue("Team1 and team2 should match" ,teamsMatch);
1027
1028 book3.setAuthorship(team2);
1029 matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1030 Assert.assertEquals("Resultlist must have 1 entries", 1, matchResult.size());
1031 Assert.assertTrue("Resultlist must contain book 1", matchResult.contains(book1));
1032
1033 book3.setAuthorship(null);
1034 matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1035 Assert.assertEquals("Resultlist must have 1 entries", 1, matchResult.size());
1036 Assert.assertTrue("Resultlist must contain book 1", matchResult.contains(book1));
1037
1038 book2.setTitleCache(book3.getTitleCache(), true);
1039 matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1040 Assert.assertEquals("Resultlist must have 2 entries", 2, matchResult.size());
1041 Assert.assertTrue("Resultlist must contain book 1", matchResult.contains(book1));
1042 Assert.assertTrue("Resultlist must contain book 2", matchResult.contains(book2));
1043
1044 team2.setTitleCache("team2", true);
1045 teamsMatch = teamMatcher.invoke(team1, team2);
1046 Assert.assertFalse("Team1 and team2 should not match" ,teamsMatch);
1047
1048 book3.setAuthorship(team1);
1049 book2.setAuthorship(team2);
1050 matchResult = cdmGenericDao.findMatching(book3, matchStrategy);
1051 Assert.assertEquals("Resultlist must have 1 entries", 1, matchResult.size());
1052 Assert.assertTrue("Resultlist must contain book 1", matchResult.contains(book1));
1053
1054
1055 } catch (MatchException e) {
1056 Assert.fail("Find match must not throw Exception: " + e.getMessage());
1057 e.printStackTrace();
1058 }
1059
1060 }
1061
1062 /**
1063 * Test method for {@link eu.etaxonomy.cdm.persistence.dao.hibernate.common.CdmGenericDaoImpl#getHqlResult(java.lang.String)}.
1064 */
1065 @Test
1066 public void testGetHqlResult() {
1067 logger.warn("Not yet implemented");
1068 }
1069
1070 /* (non-Javadoc)
1071 * @see eu.etaxonomy.cdm.test.integration.CdmIntegrationTest#createTestData()
1072 */
1073 @Override
1074 protected void createTestDataSet() throws FileNotFoundException {
1075 // TODO Auto-generated method stub
1076
1077 }
1078 }