1 package eu
.etaxonomy
.cdm
.remote
.dto
.assembler
.lsid
;
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
;
8 import java
.io
.Serializable
;
9 import java
.lang
.reflect
.Field
;
10 import java
.lang
.reflect
.Method
;
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
;
18 import java
.util
.UUID
;
20 import net
.sf
.cglib
.proxy
.Enhancer
;
21 import net
.sf
.cglib
.proxy
.MethodInterceptor
;
22 import net
.sf
.cglib
.proxy
.MethodProxy
;
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
;
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
;
75 @SpringApplicationContext("file:./target/test-classes/eu/etaxonomy/cdm/applicationContext-test.xml")
76 public class AssemblerTest
extends UnitilsJUnit4
{
78 public static final Logger logger
= Logger
.getLogger(AssemblerTest
.class);
81 private Mapper mapper
;
86 private Reference
<?
> bookSection
;
87 private TeamOrPersonBase
<?
> authorTeam
;
88 private NonViralName
<?
> name
;
90 private TaxonDescription taxonDescription
;
93 public static void onSetUp() {
94 DefaultTermInitializer defaultTermInitializer
= new DefaultTermInitializer();
95 defaultTermInitializer
.initialize();
99 public void setUp() throws Exception
{
100 lsid
= new LSID("urn:lsid:example.org:taxonconcepts:1");
102 authorTeam
= Person
.NewInstance();
103 authorTeam
.setTitleCache("authorTeam.titleCache", true);
104 authorTeam
.setLsid(new LSID("urn:lsid:dagg.org:agents:2"));
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());
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"));
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);
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);
133 taxonDescription
= TaxonDescription
.NewInstance();
134 taxon
.addDescription(taxonDescription
);
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
);
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());
151 taxonDescription
.addElement(distribution
);
153 // ------------------------------------------------------
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"));
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"));
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());
192 if(!UriUtils
.isInternetAvailable(null)){
193 // dozer requires access to dozer.sourceforge.net
194 logger
.info("Internet is not available: Skipping test");
198 TaxonConcept taxonConcept
= mapper
.map(taxon
, TaxonConcept
.class);
200 assertNotNull("map() should return an object", taxonConcept
);
201 assertTrue("map() should return a TaxonConcept",taxonConcept
instanceof TaxonConcept
);
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());
218 public void testLazyInitializationExceptionWithProxy() throws Exception
{
220 if(!UriUtils
.isInternetAvailable(null)){
221 // dozer requires access to dozer.sourceforge.net
222 logger
.info("Internet is not available: Skipping test");
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
);
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());
238 public void testLazyInitializationExceptionWithPersistentCollection() throws Exception
{
240 if(!UriUtils
.isInternetAvailable(null)){
241 // dozer requires access to dozer.sourceforge.net
242 logger
.info("Internet is not available: Skipping test");
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
);
252 TaxonConcept taxonConcept
= mapper
.map(taxon
, TaxonConcept
.class);
253 assertTrue("TaxonBase.relationsToThisTaxon was uninitialized, so TaxonConcept.hasRelationship should be null",taxonConcept
.getHasRelationship().isEmpty());
257 public void testSpeciesProfileModelMapping() {
259 if(!UriUtils
.isInternetAvailable(null)){
260 // dozer requires access to dozer.sourceforge.net
261 logger
.info("Internet is not available: Skipping test");
265 SpeciesProfileModel speciesProfileModel
= mapper
.map(taxonDescription
, SpeciesProfileModel
.class);
266 assertEquals(speciesProfileModel
.getHasInformation().size(),2);
270 public void testSimpleDarwinCoreMapping() {
272 if(!UriUtils
.isInternetAvailable(null)){
273 // dozer requires access to dozer.sourceforge.net
274 logger
.info("Internet is not available: Skipping test");
278 SimpleDarwinRecord simpleDarwinRecord
= mapper
.map(taxon
, SimpleDarwinRecord
.class);
279 mapper
.map(taxon
.getName(), simpleDarwinRecord
);
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());
289 public void testOAIDublinCoreMapping() {
291 if(!UriUtils
.isInternetAvailable(null)){
292 // dozer requires access to dozer.sourceforge.net
293 logger
.info("Internet is not available: Skipping test");
297 OaiDc oaiDcRecordBook
= mapper
.map(book
, OaiDc
.class);
299 assertEquals(book
.getTitle(), book
.getTitle());
301 OaiDc oaiDcRecordBookSection
= mapper
.map(bookSection
, OaiDc
.class);
302 assertNotNull(oaiDcRecordBookSection
.getRelation());
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() {
314 public Object
intercept(Object obj
, Method method
, Object
[] args
, MethodProxy proxy
) throws Throwable
{
315 if("wasInitialized".equals(method
.getName())) {
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())) {
331 throw new LazyInitializationException(null);
337 T proxy
= (T
)enhancer
.create();
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() {
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())) {
366 throw new LazyInitializationException(null);
372 T proxy
= (T
)enhancer
.create();
376 class UninitializedLazyInitializer
implements LazyInitializer
{
379 public boolean isUninitialized() {
384 public String
getEntityName() {
385 // TODO Auto-generated method stub
390 public Serializable
getIdentifier() {
391 // TODO Auto-generated method stub
396 public Object
getImplementation() {
397 // TODO Auto-generated method stub
402 public Class
getPersistentClass() {
403 // TODO Auto-generated method stub
408 public SessionImplementor
getSession() {
409 // TODO Auto-generated method stub
414 public void initialize() throws HibernateException
{
415 // TODO Auto-generated method stub
420 public boolean isUnwrap() {
421 // TODO Auto-generated method stub
426 public void setIdentifier(Serializable arg0
) {
427 // TODO Auto-generated method stub
432 public void setImplementation(Object arg0
) {
433 // TODO Auto-generated method stub
438 public void setUnwrap(boolean arg0
) {
439 // TODO Auto-generated method stub
444 public Object
getImplementation(
445 org
.hibernate
.engine
.spi
.SessionImplementor session
)
446 throws HibernateException
{
447 // TODO Auto-generated method stub
452 public boolean isReadOnlySettingAvailable() {
453 // TODO Auto-generated method stub
458 public boolean isReadOnly() {
459 // TODO Auto-generated method stub
464 public void setReadOnly(boolean readOnly
) {
465 // TODO Auto-generated method stub
470 public void setSession(
471 org
.hibernate
.engine
.spi
.SessionImplementor session
)
472 throws HibernateException
{
473 // TODO Auto-generated method stub
478 public void unsetSession() {
479 // TODO Auto-generated method stub