ef3c76faa967822b77b92696383223cd92f94a20
[cdmlib.git] / cdmlib-remote / src / test / java / eu / etaxonomy / cdm / remote / dto / assembler / lsid / AssemblerTest.java
1 package eu.etaxonomy.cdm.remote.dto.assembler.lsid;
2
3 import static org.junit.Assert.assertEquals;
4 import static org.junit.Assert.assertNotNull;
5 import static org.junit.Assert.assertNull;
6 import static org.junit.Assert.assertTrue;
7
8 import java.io.Serializable;
9 import java.lang.reflect.Field;
10 import java.lang.reflect.Method;
11 import java.net.URI;
12 import java.util.ArrayList;
13 import java.util.Arrays;
14 import java.util.Collection;
15 import java.util.HashSet;
16 import java.util.List;
17 import java.util.Set;
18 import java.util.UUID;
19
20 import net.sf.cglib.proxy.Enhancer;
21 import net.sf.cglib.proxy.MethodInterceptor;
22 import net.sf.cglib.proxy.MethodProxy;
23
24 import org.apache.log4j.Logger;
25 import org.dozer.Mapper;
26 import org.hibernate.Hibernate;
27 import org.hibernate.HibernateException;
28 import org.hibernate.LazyInitializationException;
29 import org.hibernate.collection.spi.PersistentCollection;
30 import org.hibernate.engine.spi.SessionImplementor;
31 import org.hibernate.proxy.HibernateProxy;
32 import org.hibernate.proxy.LazyInitializer;
33 import org.joda.time.DateTime;
34 import org.joda.time.DateTimeFieldType;
35 import org.joda.time.Partial;
36 import org.junit.Before;
37 import org.junit.BeforeClass;
38 import org.junit.Test;
39 import org.unitils.UnitilsJUnit4;
40 import org.unitils.spring.annotation.SpringApplicationContext;
41 import org.unitils.spring.annotation.SpringBeanByType;
42
43 import eu.etaxonomy.cdm.common.UriUtils;
44 import eu.etaxonomy.cdm.model.agent.Person;
45 import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
46 import eu.etaxonomy.cdm.model.common.Credit;
47 import eu.etaxonomy.cdm.model.common.DefaultTermInitializer;
48 import eu.etaxonomy.cdm.model.common.IdentifiableSource;
49 import eu.etaxonomy.cdm.model.common.LSID;
50 import eu.etaxonomy.cdm.model.common.Language;
51 import eu.etaxonomy.cdm.model.common.LanguageString;
52 import eu.etaxonomy.cdm.model.common.TimePeriod;
53 import eu.etaxonomy.cdm.model.description.Distribution;
54 import eu.etaxonomy.cdm.model.description.PresenceTerm;
55 import eu.etaxonomy.cdm.model.description.TaxonDescription;
56 import eu.etaxonomy.cdm.model.description.TextData;
57 import eu.etaxonomy.cdm.model.location.NamedArea;
58 import eu.etaxonomy.cdm.model.name.BotanicalName;
59 import eu.etaxonomy.cdm.model.name.NonViralName;
60 import eu.etaxonomy.cdm.model.name.Rank;
61 import eu.etaxonomy.cdm.model.reference.IBook;
62 import eu.etaxonomy.cdm.model.reference.INomenclaturalReference;
63 import eu.etaxonomy.cdm.model.reference.Reference;
64 import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
65 import eu.etaxonomy.cdm.model.taxon.Synonym;
66 import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;
67 import eu.etaxonomy.cdm.model.taxon.Taxon;
68 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
69 import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;
70 import eu.etaxonomy.cdm.remote.dto.dwc.SimpleDarwinRecord;
71 import eu.etaxonomy.cdm.remote.dto.oaipmh.OaiDc;
72 import eu.etaxonomy.cdm.remote.dto.tdwg.voc.SpeciesProfileModel;
73 import eu.etaxonomy.cdm.remote.dto.tdwg.voc.TaxonConcept;
74
75 @SpringApplicationContext("file:./target/test-classes/eu/etaxonomy/cdm/applicationContext-test.xml")
76 public class AssemblerTest extends UnitilsJUnit4 {
77
78 public static final Logger logger = Logger.getLogger(AssemblerTest.class);
79
80 @SpringBeanByType
81 private Mapper mapper;
82
83 private Taxon taxon;
84 private IBook sec;
85 private IBook book;
86 private Reference<?> bookSection;
87 private TeamOrPersonBase<?> authorTeam;
88 private NonViralName<?> name;
89 private LSID lsid;
90 private TaxonDescription taxonDescription;
91
92 @BeforeClass
93 public static void onSetUp() {
94 DefaultTermInitializer defaultTermInitializer = new DefaultTermInitializer();
95 defaultTermInitializer.initialize();
96 }
97
98 @Before
99 public void setUp() throws Exception {
100 lsid = new LSID("urn:lsid:example.org:taxonconcepts:1");
101
102 authorTeam = Person.NewInstance();
103 authorTeam.setTitleCache("authorTeam.titleCache", true);
104 authorTeam.setLsid(new LSID("urn:lsid:dagg.org:agents:2"));
105
106 name = BotanicalName.NewInstance(null);
107 name.setNameCache("nameCache");
108 INomenclaturalReference nomenclaturalReference = ReferenceFactory.newArticle();
109 nomenclaturalReference.setTitleCache("nomenclaturalReference", true);
110 name.setNomenclaturalReference(nomenclaturalReference);
111 name.setNomenclaturalMicroReference("1");
112 name.setAuthorshipCache("authorshipCache");
113 name.setRank(Rank.SPECIES());
114
115 sec = ReferenceFactory.newBook();
116 sec.setAuthorTeam(authorTeam);
117 sec.setTitleCache("sec.titleCache", true);
118 sec.setLsid(new LSID("urn:lsid:example.org:references:1"));
119
120 taxon = Taxon.NewInstance(name, (Reference)sec);
121 taxon.setCreated(new DateTime(2004, 12, 25, 12, 0, 0, 0));
122 taxon.setUpdated(new DateTime(2005, 12, 25, 12, 0, 0, 0));
123 taxon.setTitleCache("titleCache", true);
124 taxon.setLsid(lsid);
125
126 for(int i = 0; i < 10; i++) {
127 Taxon child = Taxon.NewInstance(name, (Reference)sec);
128 child.setLsid(new LSID("urn:lsid:example.org:taxonconcepts:" + (2 + i )));
129 taxon.addTaxonomicChild(child, null,null);
130 }
131
132
133 taxonDescription = TaxonDescription.NewInstance();
134 taxon.addDescription(taxonDescription);
135
136 TextData textData = TextData.NewInstance();
137 Language english = Language.NewInstance();
138 english.setIso639_1("en");
139 Language french = Language.NewInstance();
140 french.setIso639_1("fr");
141 textData.getMultilanguageText().put(english, LanguageString.NewInstance("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce justo leo, tempus ultricies bibendum eu, interdum sit amet ipsum. Suspendisse eu odio in sem iaculis euismod. Suspendisse sed metus ante, in sodales risus. In sit amet magna sit amet risus elementum dapibus. Nullam in magna at mauris placerat sagittis. Proin urna nisl, porta at venenatis in, tristique tempus nisl. Proin vel arcu blandit velit vestibulum blandit. In at diam libero, vel malesuada mauris. Duis a enim diam. Donec urna dui, dictum at suscipit vel, consectetur quis est. In venenatis bibendum diam nec laoreet. ", english));
142 textData.getMultilanguageText().put(french, LanguageString.NewInstance("Mauris elementum malesuada orci, non eleifend metus placerat ut. Aenean ornare felis sed lectus cursus id cursus nulla consectetur. Mauris magna justo, placerat id pretium posuere, ultrices et libero. Aliquam erat volutpat. Ut libero diam, interdum commodo fringilla sollicitudin, faucibus vel nisl. Fusce mattis justo interdum enim rhoncus eget sollicitudin dolor lobortis. Morbi mauris odio, tempus eget egestas eu, ornare vel ante. In quis placerat mi. Aliquam blandit tristique dictum. Donec pretium dui lacinia magna ornare eu venenatis ante dignissim. Integer ullamcorper tempus nisl et tincidunt. Curabitur vel nulla eu dolor faucibus porta. Mauris pulvinar est at est porta molestie. Nam varius nunc nec ipsum lacinia non egestas turpis congue. In at ipsum augue. Nulla mollis lobortis mauris ac sagittis. Nullam et facilisis lacus. Nam euismod sapien pellentesque lacus hendrerit dapibus. Aenean blandit rhoncus feugiat.", french));
143 taxonDescription.addElement(textData);
144
145 Distribution distribution = Distribution.NewInstance();
146 NamedArea namedArea = NamedArea.NewInstance("Africa", "Africa", "Africa");
147 namedArea.setTitleCache("Africa", true);
148 distribution.setArea(namedArea);
149 distribution.setStatus(PresenceTerm.NATIVE());
150
151 taxonDescription.addElement(distribution);
152
153 // ------------------------------------------------------
154
155 book = ReferenceFactory.newBook();
156 book.setTitle("Book.title");
157 book.setAuthorTeam(authorTeam);
158 book.setCreated(new DateTime(2004, 12, 25, 12, 0, 0, 0));
159 book.setDatePublished(new TimePeriod(new Partial(DateTimeFieldType.year(), 1800)));
160 book.setEdition("1st Edition");
161 book.setEditor("Editor");
162 book.setIsbn("isbn");
163 book.setPlacePublished("placePublished");
164 book.setPublisher("publisher");
165 book.setReferenceAbstract("referenceAbstract");
166 book.setUri(new URI("http://persitent.books.foo/myBook"));
167 book.setUuid(UUID.randomUUID());
168 book.setVolume("Volume 1");
169 book.addSource(IdentifiableSource.NewInstance("http://persitent.IdentifiableSources.foo/1"));
170
171 bookSection = ReferenceFactory.newBookSection();
172 bookSection.setInReference((Reference)book);
173 bookSection.setPages("999 ff.");
174 bookSection.setTitle("BookSection.title");
175 bookSection.setAuthorTeam(authorTeam);
176 bookSection.setCreated(new DateTime(2004, 12, 25, 12, 0, 0, 0));
177 bookSection.setDatePublished(new TimePeriod(new Partial(DateTimeFieldType.year(), 1800)));
178 bookSection.setReferenceAbstract("referenceAbstract");
179 bookSection.setUri(new URI("http://persitent.books.foo/myBookSection"));
180 bookSection.setUuid(UUID.randomUUID());
181 bookSection.addCredit(Credit.NewInstance(authorTeam, "Credits to the authorTeam"));
182 bookSection.addSource(IdentifiableSource.NewInstance("http://persitent.IdentifiableSources.foo/2"));
183 }
184
185 @Test
186 public void testDeepMapping() {
187 for(int i = 0; i < 3; i++) {
188 Synonym synonym = Synonym.NewInstance(name,(Reference)sec);
189 taxon.addSynonym(synonym,new SynonymRelationshipType());
190 }
191
192 if(!UriUtils.isInternetAvailable(null)){
193 // dozer requires access to dozer.sourceforge.net
194 logger.info("Internet is not available: Skipping test");
195 return;
196 }
197
198 TaxonConcept taxonConcept = mapper.map(taxon, TaxonConcept.class);
199
200 assertNotNull("map() should return an object", taxonConcept);
201 assertTrue("map() should return a TaxonConcept",taxonConcept instanceof TaxonConcept);
202
203 assertEquals("IdentifiableEntity.titleCache should be copied into BaseThing.title",taxon.getTitleCache(),taxonConcept.getTitle());
204 assertEquals("IdentifiableEntity.lsid should be copied into BaseThing.identifier",taxon.getLsid().toString(),taxonConcept.getIdentifier().toString());
205 assertEquals("BaseThing.sameAs should refer to the proxy version of the lsid","http://lsid.example.org/" + taxon.getLsid().toString(),taxonConcept.getSameAs());
206 assertEquals("CdmBase.created should be copied into BaseThing.created",new DateTime(2004, 12, 25, 12, 0, 0, 0),taxonConcept.getCreated());
207 assertNotNull("TaxonBase.sec should be mapped into BaseThing.publishedInCitation",taxonConcept.getPublishedInCitation());
208 assertEquals("TaxonBase.sec.titleCache should be mapped into BaseThing.publishedInCitation.title",sec.getTitleCache(),taxonConcept.getPublishedInCitation().getTitle());
209 assertNotNull("TaxonBase.sec.authorTeam should be mapped into TaxonConcept.accordingTo",taxonConcept.getAccordingTo());
210 assertEquals("TaxonBase.sec.authorTeam.titleCache should be mapped into TaxonConcept.accordingTo.title",authorTeam.getTitleCache(),taxonConcept.getAccordingTo().getTitle());
211 assertNotNull("TaxonBase.name should be mapped to TaxonConcept.hasName",taxonConcept.getHasName());
212 assertEquals("NonViralName.nameCache should be mapped to TaxonName.nameComplete",name.getNameCache(),taxonConcept.getHasName().getNameComplete());
213 assertNotNull("Taxon.relationsToThisTaxon should be copied into TaxonConcept.hasRelationship",taxonConcept.getHasRelationship());
214 assertEquals("There should be 13 relations in TaxonConcept.hasRelationship",13,taxonConcept.getHasRelationship().size());
215 }
216
217 @Test
218 public void testLazyInitializationExceptionWithProxy() throws Exception {
219
220 if(!UriUtils.isInternetAvailable(null)){
221 // dozer requires access to dozer.sourceforge.net
222 logger.info("Internet is not available: Skipping test");
223 return;
224 }
225
226 IBook proxy = getUninitializedDetachedProxy(Reference.class,(Reference)sec);
227 assert !Hibernate.isInitialized(proxy);
228 Field secField = TaxonBase.class.getDeclaredField("sec");
229 secField.setAccessible(true);
230 secField.set(taxon, proxy);
231
232 TaxonConcept taxonConcept = mapper.map(taxon, TaxonConcept.class);
233 assertNull("TaxonBase.sec was uninitialized, so TaxonConcept.publishedInCitation should be null",taxonConcept.getPublishedInCitation());
234 assertNull("TaxonBase.sec was uninitialized, so TaxonConcept.accordingTo should be null",taxonConcept.getAccordingTo());
235 }
236
237 @Test
238 public void testLazyInitializationExceptionWithPersistentCollection() throws Exception {
239
240 if(!UriUtils.isInternetAvailable(null)){
241 // dozer requires access to dozer.sourceforge.net
242 logger.info("Internet is not available: Skipping test");
243 return;
244 }
245
246 Set<TaxonRelationship> proxy = getUninitializedPersistentCollection(HashSet.class,(HashSet<TaxonRelationship>)taxon.getRelationsToThisTaxon());
247 assert !Hibernate.isInitialized(proxy);
248 Field relationsToThisTaxonField = Taxon.class.getDeclaredField("relationsToThisTaxon");
249 relationsToThisTaxonField.setAccessible(true);
250 relationsToThisTaxonField.set(taxon, proxy);
251
252 TaxonConcept taxonConcept = mapper.map(taxon, TaxonConcept.class);
253 assertTrue("TaxonBase.relationsToThisTaxon was uninitialized, so TaxonConcept.hasRelationship should be null",taxonConcept.getHasRelationship().isEmpty());
254 }
255
256 @Test
257 public void testSpeciesProfileModelMapping() {
258
259 if(!UriUtils.isInternetAvailable(null)){
260 // dozer requires access to dozer.sourceforge.net
261 logger.info("Internet is not available: Skipping test");
262 return;
263 }
264
265 SpeciesProfileModel speciesProfileModel = mapper.map(taxonDescription, SpeciesProfileModel.class);
266 assertEquals(speciesProfileModel.getHasInformation().size(),2);
267 }
268
269 @Test
270 public void testSimpleDarwinCoreMapping() {
271
272 if(!UriUtils.isInternetAvailable(null)){
273 // dozer requires access to dozer.sourceforge.net
274 logger.info("Internet is not available: Skipping test");
275 return;
276 }
277
278 SimpleDarwinRecord simpleDarwinRecord = mapper.map(taxon, SimpleDarwinRecord.class);
279 mapper.map(taxon.getName(), simpleDarwinRecord);
280
281 assertNotNull(simpleDarwinRecord.getModified());
282 assertEquals(taxon.getName().getTitleCache(), simpleDarwinRecord.getScientificName());
283 assertEquals(((NonViralName)taxon.getName()).getAuthorshipCache(), simpleDarwinRecord.getScientificNameAuthorship());
284 assertEquals(((NonViralName)taxon.getName()).getCitationString(), simpleDarwinRecord.getNamePublishedIn());
285 assertEquals(Rank.SPECIES().getLabel(), simpleDarwinRecord.getTaxonRank());
286 }
287
288 @Test
289 public void testOAIDublinCoreMapping() {
290
291 if(!UriUtils.isInternetAvailable(null)){
292 // dozer requires access to dozer.sourceforge.net
293 logger.info("Internet is not available: Skipping test");
294 return;
295 }
296
297 OaiDc oaiDcRecordBook = mapper.map(book, OaiDc.class);
298
299 assertEquals(book.getTitle(), book.getTitle());
300
301 OaiDc oaiDcRecordBookSection = mapper.map(bookSection, OaiDc.class);
302 assertNotNull(oaiDcRecordBookSection.getRelation());
303 }
304
305 private <T extends Collection> T getUninitializedPersistentCollection(final Class<T> clazz,final T wrappedCollection) {
306 final Enhancer enhancer = new Enhancer();
307 List<Class> interfaces = new ArrayList<Class>();
308 interfaces.addAll(Arrays.asList(clazz.getInterfaces()));
309 interfaces.add(PersistentCollection.class);
310 enhancer.setSuperclass(clazz);
311 enhancer.setInterfaces(interfaces.toArray(new Class[interfaces.size()]));
312 enhancer.setCallback( new MethodInterceptor() {
313 @Override
314 public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
315 if("wasInitialized".equals(method.getName())) {
316 return false;
317 } else if(clazz.getDeclaredConstructor().equals(method)){
318 return proxy.invoke(obj, args);
319 } else if("finalize".equals(method.getName())){
320 return proxy.invoke(obj, args);
321 } else if("toString".equals(method.getName())) {
322 return wrappedCollection.toString();
323 } else if("getClass".equals(method.getName())) {
324 return proxy.invoke(obj, args);
325 } else if("hashCode".equals(method.getName())) {
326 return wrappedCollection.hashCode();
327 }else if("initListener".equals(method.getName())) {
328 return null;
329 } else {
330
331 throw new LazyInitializationException(null);
332 }
333
334 }
335 });
336
337 T proxy = (T)enhancer.create();
338 return proxy;
339 }
340
341 private <T> T getUninitializedDetachedProxy(final Class<T> clazz,final T wrappedClass) {
342 final Enhancer enhancer = new Enhancer();
343 List<Class> interfaces = new ArrayList<Class>();
344 interfaces.addAll(Arrays.asList(clazz.getInterfaces()));
345 interfaces.add(HibernateProxy.class);
346 enhancer.setSuperclass(clazz);
347 enhancer.setInterfaces(interfaces.toArray(new Class[interfaces.size()]));
348 enhancer.setCallback( new MethodInterceptor() {
349 @Override
350 public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
351 if("getHibernateLazyInitializer".equals(method.getName())) {
352 return new UninitializedLazyInitializer();
353 } else if(clazz.getDeclaredConstructor().equals(method)){
354 return proxy.invoke(obj, args);
355 } else if("finalize".equals(method.getName())){
356 return proxy.invoke(obj, args);
357 } else if("toString".equals(method.getName())) {
358 return wrappedClass.toString();
359 } else if("getClass".equals(method.getName())) {
360 return proxy.invoke(obj, args);
361 } else if("hashCode".equals(method.getName())) {
362 return wrappedClass.hashCode();
363 } else if("initListener".equals(method.getName())) {
364 return null;
365 } else {
366 throw new LazyInitializationException(null);
367 }
368
369 }
370 });
371
372 T proxy = (T)enhancer.create();
373 return proxy;
374 }
375
376 class UninitializedLazyInitializer implements LazyInitializer {
377
378 @Override
379 public boolean isUninitialized() {
380 return true;
381 }
382
383 @Override
384 public String getEntityName() {
385 // TODO Auto-generated method stub
386 return null;
387 }
388
389 @Override
390 public Serializable getIdentifier() {
391 // TODO Auto-generated method stub
392 return null;
393 }
394
395 @Override
396 public Object getImplementation() {
397 // TODO Auto-generated method stub
398 return null;
399 }
400
401 @Override
402 public Class getPersistentClass() {
403 // TODO Auto-generated method stub
404 return null;
405 }
406
407 @Override
408 public SessionImplementor getSession() {
409 // TODO Auto-generated method stub
410 return null;
411 }
412
413 @Override
414 public void initialize() throws HibernateException {
415 // TODO Auto-generated method stub
416
417 }
418
419 @Override
420 public boolean isUnwrap() {
421 // TODO Auto-generated method stub
422 return false;
423 }
424
425 @Override
426 public void setIdentifier(Serializable arg0) {
427 // TODO Auto-generated method stub
428
429 }
430
431 @Override
432 public void setImplementation(Object arg0) {
433 // TODO Auto-generated method stub
434
435 }
436
437 @Override
438 public void setUnwrap(boolean arg0) {
439 // TODO Auto-generated method stub
440
441 }
442
443 @Override
444 public Object getImplementation(
445 org.hibernate.engine.spi.SessionImplementor session)
446 throws HibernateException {
447 // TODO Auto-generated method stub
448 return null;
449 }
450
451 @Override
452 public boolean isReadOnlySettingAvailable() {
453 // TODO Auto-generated method stub
454 return false;
455 }
456
457 @Override
458 public boolean isReadOnly() {
459 // TODO Auto-generated method stub
460 return false;
461 }
462
463 @Override
464 public void setReadOnly(boolean readOnly) {
465 // TODO Auto-generated method stub
466
467 }
468
469 @Override
470 public void setSession(
471 org.hibernate.engine.spi.SessionImplementor session)
472 throws HibernateException {
473 // TODO Auto-generated method stub
474
475 }
476
477 @Override
478 public void unsetSession() {
479 // TODO Auto-generated method stub
480
481 }
482
483 }
484
485
486
487
488 }