Project

General

Profile

Download (16.4 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2015 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.persistence.dao.initializer;
10

    
11
import static org.junit.Assert.assertEquals;
12
import static org.junit.Assert.assertFalse;
13
import static org.junit.Assert.assertTrue;
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.HashMap;
20
import java.util.HashSet;
21
import java.util.List;
22
import java.util.Map;
23
import java.util.Set;
24
import java.util.UUID;
25

    
26
import org.apache.log4j.Level;
27
import org.apache.log4j.Logger;
28
import org.hibernate.FlushMode;
29
import org.hibernate.Hibernate;
30
import org.hibernate.HibernateException;
31
import org.hibernate.SessionFactory;
32
import org.junit.After;
33
import org.junit.Before;
34
import org.junit.Ignore;
35
import org.junit.Test;
36
import org.unitils.dbunit.annotation.DataSet;
37
import org.unitils.spring.annotation.SpringBeanByType;
38

    
39
import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
40
import eu.etaxonomy.cdm.model.agent.Address;
41
import eu.etaxonomy.cdm.model.agent.Contact;
42
import eu.etaxonomy.cdm.model.agent.Person;
43
import eu.etaxonomy.cdm.model.agent.Team;
44
import eu.etaxonomy.cdm.model.common.CdmBase;
45
import eu.etaxonomy.cdm.model.location.Country;
46
import eu.etaxonomy.cdm.model.location.Point;
47
import eu.etaxonomy.cdm.model.location.ReferenceSystem;
48
import eu.etaxonomy.cdm.model.name.Rank;
49
import eu.etaxonomy.cdm.model.name.TaxonName;
50
import eu.etaxonomy.cdm.model.name.TaxonNameFactory;
51
import eu.etaxonomy.cdm.model.reference.Reference;
52
import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
53
import eu.etaxonomy.cdm.model.taxon.Taxon;
54
import eu.etaxonomy.cdm.persistence.dao.agent.IAgentDao;
55
import eu.etaxonomy.cdm.persistence.dao.name.ITaxonNameDao;
56
import eu.etaxonomy.cdm.persistence.dao.reference.IReferenceDao;
57
import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao;
58
import eu.etaxonomy.cdm.test.integration.CdmTransactionalIntegrationTest;
59

    
60
/**
61
 * @author a.mueller
62
 * @since 16.11.2015
63
 */
64
public class AdvancedBeanInitializerTest extends CdmTransactionalIntegrationTest {
65

    
66
    private static final Logger logger = Logger.getLogger(AdvancedBeanInitializerTest.class);
67

    
68
    private static final UUID personUuid = UUID.fromString("d0568bb1-4dc8-40dc-a405-d0b9e714a7a9");
69

    
70
    private static final UUID teamUuid = UUID.fromString("f2ab0cab-f8a4-4db0-9f2d-2f0a1b627597");
71

    
72
    private static final UUID referenceUuid = UUID.fromString("f48196c6-854a-416e-8f2a-67bd39e988dc");
73

    
74
    private static final UUID nameUuid = UUID.fromString("98cbb643-d521-4ca7-86f7-8180bea85d9f");
75

    
76
    private static final UUID taxonUuid = UUID.fromString("07171a4c-f9f0-4459-a7e4-9f75981f7027");
77

    
78
    @SpringBeanByType
79
    private IAgentDao agentDao;
80

    
81
    @SpringBeanByType
82
    private IReferenceDao referenceDao;
83

    
84
    @SpringBeanByType
85
    private ITaxonNameDao nameDao;
86

    
87
    @SpringBeanByType
88
    private ITaxonDao taxonDao;
89

    
90
    @SpringBeanByType
91
    private AdvancedBeanInitializer initializer;
92

    
93
    @SpringBeanByType
94
    private AdvancedBeanInitializer defaultBeanInitializer;
95

    
96
    @SpringBeanByType
97
    private SessionFactory factory;
98

    
99
    private Map<Class<? extends CdmBase>, AutoPropertyInitializer<CdmBase>> deacivatedAutoIntitializers;
100

    
101
    /**
102
     * Checks that the AdvancedBeanInitializer is available and that the expected set of beanAutoInitializers is configured
103
     * in the persitence.xml.
104

    
105
     */
106
    @Before
107
    public void assertAutoinitializers(){
108

    
109
        assert defaultBeanInitializer != null;
110

    
111
        Class[] expectedAutoInitializers = new Class[]{
112
            eu.etaxonomy.cdm.persistence.dao.initializer.TitleAndNameCacheAutoInitializer.class,
113
            eu.etaxonomy.cdm.persistence.dao.initializer.AnnotationTypeAutoInitializer.class,
114
            eu.etaxonomy.cdm.persistence.dao.initializer.MarkerTypeAutoInitializer.class,
115
            eu.etaxonomy.cdm.persistence.dao.initializer.GatheringEventLocationAutoInitializer.class,
116
            eu.etaxonomy.cdm.persistence.dao.initializer.TermBaseAutoInitializer.class,
117
            eu.etaxonomy.cdm.persistence.dao.initializer.MediaAutoInitializer.class,
118
            eu.etaxonomy.cdm.persistence.dao.initializer.TypeDesignationAutoInitializer.class,
119
            eu.etaxonomy.cdm.persistence.dao.initializer.TeamAutoInitializer.class
120
            };
121

    
122
        Set<Class> checkSet = new HashSet<>(Arrays.asList(expectedAutoInitializers));
123

    
124
        for(AutoPropertyInitializer api : defaultBeanInitializer.getBeanAutoInitializers().values()){
125
            assert checkSet.remove(api.getClass()) == true;
126
        }
127
        assert checkSet.size() == 0;
128
    }
129

    
130
    @After
131
    public void restoreAutoinitializers() {
132
        if(deacivatedAutoIntitializers != null){
133
            defaultBeanInitializer.getBeanAutoInitializers().putAll(deacivatedAutoIntitializers);
134
            deacivatedAutoIntitializers = null;
135
        }
136
    }
137

    
138
    @DataSet
139
    @Test
140
    public void testContact() {
141
        Person person = (Person)agentDao.findByUuid(personUuid);
142

    
143
        final List<String> propPath = Arrays.asList(new String[]{
144
            "contact.urls",
145
            "contact.phoneNumbers",
146
            "contact.addresses",
147
            "contact.faxNumbers",
148
            "contact.emailAddresses",
149
        });
150
        initializer.initialize(person, propPath);
151
    }
152

    
153
    @DataSet
154
    @Test
155
    public void testFullNameGraphWithPreloadedReference() {
156
        // find the reference by iD (not load!)
157
        Reference ref = referenceDao.findById(5000);
158
        TaxonName name = nameDao.findById(5000);
159
        assertFalse("for this test to be significant the authorship must be uninitialized", Hibernate.isInitialized(name.getNomenclaturalReference().getAuthorship()));
160
        initializer.initialize(name, Arrays.asList(new String[]{"nomenclaturalReference.authorship.$"}));
161
        assertTrue(Hibernate.isInitialized(name.getNomenclaturalReference().getAuthorship()));
162
    }
163

    
164

    
165
    @DataSet
166
    @Test
167
    public void testToOneWildcard() {
168

    
169
        deacivatedAutoIntitializers = clearAutoinitializers();
170
        assureSessionClear();
171

    
172
        TaxonName name = nameDao.load(nameUuid, Arrays.asList("$"));
173
        assertTrue(Hibernate.isInitialized(name.getNomenclaturalReference()));
174
        assertFalse(Hibernate.isInitialized(name.getAnnotations()));
175

    
176
        name = nameDao.load(nameUuid, Arrays.asList("nomenclaturalReference.$"));
177
        assertTrue(Hibernate.isInitialized(name.getNomenclaturalReference()));
178
        assertTrue(Hibernate.isInitialized(name.getNomenclaturalReference().getAuthorship()));
179
        assertFalse(Hibernate.isInitialized(name.getNomenclaturalReference().getAnnotations()));
180
    }
181

    
182
    @DataSet
183
    @Test
184
    @Ignore // TODO fix #7375
185
    public void testComplexPath() {
186

    
187
        deacivatedAutoIntitializers = clearAutoinitializers();
188
        assureSessionClear();
189

    
190
        TaxonName name = nameDao.load(nameUuid, Arrays.asList("nomenclaturalReference.$.*.contact.faxNumbers"));
191
        assertTrue(Hibernate.isInitialized(name.getNomenclaturalReference())); // nomenclaturalReference
192
        assertTrue(Hibernate.isInitialized(name.getNomenclaturalReference().getAuthorship())); // $
193
        assertFalse("must not be initialized by 'nomenclaturalReference.$'", Hibernate.isInitialized(name.getNomenclaturalReference().getExtensions()));
194
        Team team = HibernateProxyHelper.deproxy(name.getNomenclaturalReference().getAuthorship(), Team.class);
195
        assertTrue(Hibernate.isInitialized(team.getTeamMembers())); // *
196
        Person person1 = HibernateProxyHelper.deproxy(team.getTeamMembers().get(0), Person.class);
197
        assertEquals(personUuid, person1.getUuid());
198
        assertTrue(Hibernate.isInitialized(person1.getContact())); // contact
199
        assertFalse("must not be initialized by 'nomenclaturalReference.$.*.contact'", Hibernate.isInitialized(person1.getAnnotations()));
200
        assertTrue(Hibernate.isInitialized(person1.getContact().getFaxNumbers())); // * // FIXME fails here #7375
201
    }
202

    
203
    @DataSet
204
    @Test
205
    public void testPersonContacts() {
206

    
207
        deacivatedAutoIntitializers = clearAutoinitializers();
208
        assureSessionClear();
209

    
210
        Person person1 = (Person) agentDao.load(personUuid, Arrays.asList("contact.faxNumbers"));
211
        assertTrue(Hibernate.isInitialized(person1.getContact()));
212
        assertTrue(Hibernate.isInitialized(person1.getContact().getFaxNumbers()));
213
    }
214

    
215
    @DataSet
216
    @Test
217
    public void testToOneWildcardDepth1() {
218

    
219
        deacivatedAutoIntitializers = clearAutoinitializers();
220
        assureSessionClear();
221

    
222
        TaxonName name = nameDao.load(nameUuid, Arrays.asList("nomenclaturalReference.$"));
223
        assertTrue(Hibernate.isInitialized(name.getNomenclaturalReference()));
224
        assertTrue(Hibernate.isInitialized(name.getNomenclaturalReference().getAuthorship()));
225
        assertFalse(Hibernate.isInitialized(name.getNomenclaturalReference().getAnnotations()));
226

    
227
    }
228

    
229
    @DataSet
230
    @Test
231
    public void testToManyWildcard() {
232

    
233
        deacivatedAutoIntitializers = clearAutoinitializers();
234
        assureSessionClear();
235

    
236
        TaxonName name = nameDao.load(nameUuid, Arrays.asList("*"));
237
        assertTrue(Hibernate.isInitialized(name.getNomenclaturalReference()));
238
        assertTrue(Hibernate.isInitialized(name.getAnnotations()));
239

    
240
    }
241

    
242
    @DataSet
243
    @Test
244
    public void testToManyWildcardDepth1() {
245

    
246
        deacivatedAutoIntitializers = clearAutoinitializers();
247
        assureSessionClear();
248

    
249
        TaxonName name = nameDao.load(nameUuid, Arrays.asList("nomenclaturalReference.*"));
250
        assertTrue(Hibernate.isInitialized(name.getNomenclaturalReference()));
251
        assertTrue(Hibernate.isInitialized(name.getNomenclaturalReference().getAuthorship()));
252
        assertTrue(Hibernate.isInitialized(name.getNomenclaturalReference().getAnnotations()));
253

    
254
    }
255

    
256
    @DataSet
257
    @Test
258
    public void testTitleAndNameCacheAutoInitializer() {
259

    
260
        assureSessionClear();
261

    
262
        Logger.getLogger(AdvancedBeanInitializer.class).setLevel(Level.TRACE);
263

    
264
        Taxon taxon = (Taxon)taxonDao.load(taxonUuid, Arrays.asList("$"));
265
        assertTrue(Hibernate.isInitialized(taxon.getName()));
266
        TaxonName name = taxon.getName();
267
        // the TitleAndNameCacheAutoInitializer must not intitialize the nomenclaturalReference
268
        // since the authorship is only taken from the combinationAutors field
269
        assertFalse(Hibernate.isInitialized(name.getNomenclaturalReference()));
270
    }
271

    
272
    @DataSet
273
    @Test
274
    public void testTeamAutoInitializer() {
275

    
276
        assureSessionClear();
277

    
278
        Logger.getLogger(AdvancedBeanInitializer.class).setLevel(Level.TRACE);
279

    
280
        deacivatedAutoIntitializers = clearAutoinitializers();
281
        // load bean with autoinitializers deactivated
282
        factory.getCurrentSession().setFlushMode(FlushMode.MANUAL); // TODO this is only needed due to #7377 and should be removed otherwise
283
        Taxon taxon = (Taxon)taxonDao.load(taxonUuid, Arrays.asList("name.nomenclaturalReference.authorship"));
284
        assertTrue(Hibernate.isInitialized(taxon.getName())); // name
285
        TaxonName name = taxon.getName();
286
        assertTrue(Hibernate.isInitialized(name.getNomenclaturalReference())); // nomenclaturalReference
287
        assertTrue(Hibernate.isInitialized(name.getNomenclaturalReference().getAuthorship())); // authorship
288
        Team team = HibernateProxyHelper.deproxy(name.getNomenclaturalReference().getAuthorship(), Team.class);
289

    
290
        // FIXME : the below assertion fail due to #7377 if the session flushmode is AUTO, this is not critical but an inconsistency.
291
        //    In AdvancedBeanInitializer.bulkLoadLazyBeans(BeanInitNode node) the query.list()
292
        //    with "QueryImpl( SELECT c FROM TeamOrPersonBase as c  WHERE c.id IN (:idSet) )" triggers an autoFlush.
293
        //    In turn of the autoflush the team.titleCache is generated which causes the teamMembers to be initialized
294
        //
295
        // members should not initialized since they where not included in the property path
296
        assertFalse("members should not intitialized since they where not included in the property path", Hibernate.isInitialized(team.getTeamMembers()));
297

    
298
        // activate the teamAutoInitializer again
299
        AutoPropertyInitializer<CdmBase> teamAutoInitializer = deacivatedAutoIntitializers.get(Team.class);
300
        deacivatedAutoIntitializers.remove(teamAutoInitializer);
301
        defaultBeanInitializer.getBeanAutoInitializers().put(Team.class, teamAutoInitializer);
302

    
303
        taxon = (Taxon)taxonDao.load(taxonUuid, Arrays.asList("name.nomenclaturalReference.authorship"));
304

    
305
        team = HibernateProxyHelper.deproxy(name.getNomenclaturalReference().getAuthorship(), Team.class);
306
        assertTrue("members should have been intitialized by the ", Hibernate.isInitialized(team.getTeamMembers()));
307

    
308
    }
309

    
310
    // ============================== end of tests ========================= //
311

    
312
    /**
313
     * @return
314
     */
315
    protected Map<Class<? extends CdmBase>, AutoPropertyInitializer<CdmBase>> clearAutoinitializers() {
316
        Map<Class<? extends CdmBase>, AutoPropertyInitializer<CdmBase>> autoIntitializers = new HashMap<>(defaultBeanInitializer.getBeanAutoInitializers());
317
        defaultBeanInitializer.getBeanAutoInitializers().clear();
318
        return autoIntitializers;
319
    }
320

    
321

    
322
    /**
323
     *
324
     */
325
    protected void assureSessionClear() {
326
        try {
327
            factory.getCurrentSession().clear();
328
            logger.debug("session cleared");
329
        } catch (HibernateException e){
330
            logger.debug("no session");
331
            // IGNORE no session
332
        }
333
    }
334

    
335

    
336
    @Override
337
    // @Test
338
    public void createTestDataSet() throws FileNotFoundException {
339
        // 1. create person and a reference
340
        Person person1 = Person.NewTitledInstance("A. Adonis");
341
        Person person2 = Person.NewTitledInstance("B. Belalugosi");
342
        Team team = Team.NewInstance();
343
        team.setUuid(teamUuid);
344
        team.addTeamMember(person1);
345
        team.addTeamMember(person2);
346
        Set<Address> addresses = new HashSet<Address>();
347
        addresses.add(Address.NewInstance(Country.GERMANY(), "locality", "pobox", "postcode", "region", "street", Point.NewInstance(50.02,33.3, ReferenceSystem.GOOGLE_EARTH(), 3)));
348
        List<String> emailAddresses = new ArrayList<String>();
349
        emailAddresses.add("My.email@web.de");
350
        List<String> faxNumbers = new ArrayList<String>();
351
        faxNumbers.add("0049-30-1234545");
352
        List<String> phoneNumbers = new ArrayList<String>();
353
        phoneNumbers.add("0049-30-1234546");
354
        List<URI> urls = new ArrayList<URI>();
355
        urls.add(URI.create("http://www.test.de"));
356
        Contact contact = Contact.NewInstance(addresses, emailAddresses, faxNumbers, phoneNumbers, urls);
357

    
358
        person1.setContact(contact);
359
        person1.setUuid(personUuid);
360
        person1 = (Person)agentDao.save(person1);
361
        person2 = (Person)agentDao.save(person2);
362
        team = (Team)agentDao.save(team);
363

    
364
        Reference ref = ReferenceFactory.newBook();
365
        ref.setUuid(referenceUuid);
366
        ref.setAuthorship(team);
367
        ref.setTitle("The Book");
368
        referenceDao.save(ref);
369

    
370
        TaxonName name = TaxonNameFactory.NewBotanicalInstance(Rank.SPECIES());
371
        name.setUuid(nameUuid);
372
        name.setNomenclaturalReference(ref);
373
        name.setTitleCache("Species testii", true);
374
        nameDao.save(name);
375

    
376
        Taxon taxon = Taxon.NewInstance(name, null);
377
        taxon.setUuid(taxonUuid);
378
        taxonDao.save(taxon);
379

    
380
        // 2. end the transaction so that all data is actually written to the db
381
        setComplete();
382
        endTransaction();
383

    
384
        // use the fileNameAppendix if you are creating a data set file which need to be named differently
385
        // from the standard name. For example if a single test method needs different data then the other
386
        // methods the test class you may want to set the fileNameAppendix when creating the data for this method.
387
        String fileNameAppendix = null;
388

    
389
        // 3.
390
        writeDbUnitDataSetFile(new String[] {
391
            "ADDRESS", "AGENTBASE","AgentBase_contact_emailaddresses",
392
            "AgentBase_contact_faxnumbers","AgentBase_contact_phonenumbers",
393
            "AgentBase_contact_urls","AgentBase_Address", "AgentBase_AgentBase",
394
            "REFERENCE", "TaxonName", "HomotypicalGroup", "TaxonBase",
395
            "",
396
            "HIBERNATE_SEQUENCES" // IMPORTANT!!!
397
            },
398
            fileNameAppendix );
399

    
400
    }
401

    
402
}
    (1-1/1)