View Javadoc
1   /*
2    * Copyright (c) 2002-2014, Mairie de Paris
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    *
9    *  1. Redistributions of source code must retain the above copyright notice
10   *     and the following disclaimer.
11   *
12   *  2. Redistributions in binary form must reproduce the above copyright notice
13   *     and the following disclaimer in the documentation and/or other materials
14   *     provided with the distribution.
15   *
16   *  3. Neither the name of 'Mairie de Paris' nor 'Lutece' nor the names of its
17   *     contributors may be used to endorse or promote products derived from
18   *     this software without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   * POSSIBILITY OF SUCH DAMAGE.
31   *
32   * License 1.0
33   */
34  package fr.paris.lutece.portal.service.jpa;
35  
36  import fr.paris.lutece.portal.service.database.AppConnectionService;
37  import fr.paris.lutece.portal.service.init.StartUpService;
38  import fr.paris.lutece.portal.service.spring.SpringContextService;
39  import fr.paris.lutece.portal.service.util.AppPropertiesService;
40  import fr.paris.lutece.util.ReferenceItem;
41  import fr.paris.lutece.util.ReferenceList;
42  import fr.paris.lutece.util.jpa.JPAConstants;
43  import fr.paris.lutece.util.jpa.JPAPersistenceUnitPostProcessor;
44  import fr.paris.lutece.util.jpa.transaction.ChainedTransactionManager;
45  
46  import org.apache.commons.lang.StringUtils;
47  
48  import org.apache.log4j.Logger;
49  
50  import org.springframework.orm.jpa.JpaDialect;
51  import org.springframework.orm.jpa.JpaTransactionManager;
52  import org.springframework.orm.jpa.JpaVendorAdapter;
53  import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
54  import org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager;
55  import org.springframework.orm.jpa.persistenceunit.PersistenceUnitPostProcessor;
56  
57  import org.springframework.transaction.PlatformTransactionManager;
58  
59  import java.util.ArrayList;
60  import java.util.HashMap;
61  import java.util.List;
62  import java.util.Map;
63  
64  import javax.persistence.EntityManagerFactory;
65  
66  import javax.sql.DataSource;
67  
68  
69  /**
70   * JPAStartupService
71   */
72  public class JPAStartupService implements StartUpService
73  {
74      /** The name of the property used by the JPA provider to specify the dialect */
75      private static final String JPA_DIALECT_PROPERTY = "jpa.dialect.property";
76      private static Logger _log = Logger.getLogger( JPAConstants.JPA_LOGGER );
77  
78      /**
79       * Initialize JPA objects (Datasource, Persistence Unit Manager, Entity Manager Factory,
80       * Transaction Manager) for each pool.
81       */
82      public void process(  )
83      {
84          ReferenceList list = new ReferenceList(  );
85          AppConnectionService.getPoolList( list );
86  
87          Map<String, EntityManagerFactory> mapFactories = new HashMap<String, EntityManagerFactory>(  );
88          List<PlatformTransactionManager> listTransactionManagers = new ArrayList<PlatformTransactionManager>(  );
89          _log.info( "JPA Startup Service : Initializing JPA objects ..." );
90  
91          String strDialectProperty = AppPropertiesService.getProperty( JPA_DIALECT_PROPERTY );
92  
93          for ( ReferenceItem poolItem : list )
94          {
95              String strPoolname = poolItem.getCode(  );
96  
97              DataSource ds = AppConnectionService.getPoolManager(  ).getDataSource( strPoolname );
98              _log.info( "JPA Startup Service : DataSource retrieved for pool : " + strPoolname );
99              _log.debug( "> DS : " + ds.toString(  ) );
100 
101             DefaultPersistenceUnitManager pum = new DefaultPersistenceUnitManager(  );
102             pum.setDefaultDataSource( ds );
103 
104             PersistenceUnitPostProcessor[] postProcessors = { new JPAPersistenceUnitPostProcessor(  ) };
105             pum.setPersistenceUnitPostProcessors( postProcessors );
106 
107             pum.afterPropertiesSet(  );
108 
109             _log.info( "JPA Startup Service : Persistence Unit Manager for pool : " + strPoolname );
110             _log.debug( "> PUM : " + pum.toString(  ) );
111 
112             LocalContainerEntityManagerFactoryBean lcemfb = new LocalContainerEntityManagerFactoryBean(  );
113             lcemfb.setDataSource( ds );
114             lcemfb.setPersistenceUnitManager( pum );
115             lcemfb.setPersistenceUnitName( "jpaLuteceUnit" );
116 
117             JpaDialect jpaDialect = (JpaDialect) SpringContextService.getBean( "jpaDialect" );
118             lcemfb.setJpaDialect( jpaDialect );
119 
120             Map mapJpaProperties = (Map) SpringContextService.getBean( "jpaPropertiesMap" );
121             lcemfb.setJpaPropertyMap( mapJpaProperties );
122 
123             String strDialect = AppPropertiesService.getProperty( poolItem.getName(  ) + ".dialect" );
124 
125             // replace default dialect if <poolname>.dialect is specified
126             if ( StringUtils.isNotBlank( strDialect ) )
127             {
128                 mapJpaProperties.put( strDialectProperty, strDialect );
129             }
130 
131             _log.debug( "Using dialect " + mapJpaProperties.get( strDialectProperty ) + " for pool " +
132                 poolItem.getName(  ) );
133 
134             JpaVendorAdapter jpaVendorAdapter = (JpaVendorAdapter) SpringContextService.getBean( "jpaVendorAdapter" );
135             lcemfb.setJpaVendorAdapter( jpaVendorAdapter );
136 
137             lcemfb.afterPropertiesSet(  );
138 
139             EntityManagerFactory emf = lcemfb.getNativeEntityManagerFactory(  );
140             _log.info( "JPA Startup Service : EntityManagerFactory created for pool : " + strPoolname );
141             _log.debug( "> EMF : " + emf.toString(  ) );
142 
143             JpaTransactionManager tm = new JpaTransactionManager(  );
144             tm.setEntityManagerFactory( emf );
145             tm.setJpaDialect( jpaDialect );
146             _log.debug( "> JpaDialect " + jpaDialect );
147             tm.afterPropertiesSet(  );
148             _log.info( "JPA Startup Service : JPA TransactionManager created for pool : " + strPoolname );
149             _log.debug( "> TM : " + tm.toString(  ) );
150 
151             mapFactories.put( strPoolname, emf );
152             listTransactionManagers.add( tm );
153         }
154 
155         EntityManagerService ems = (EntityManagerService) SpringContextService.getBean( "entityManagerService" );
156         ems.setMapFactories( mapFactories );
157 
158         ChainedTransactionManager ctm = (ChainedTransactionManager) SpringContextService.getBean( "transactionManager" );
159         ctm.setTransactionManagers( listTransactionManagers );
160         _log.info( "JPA Startup Service : completed successfully" );
161     }
162 
163     /**
164      * {@inheritDoc }
165      * @return
166      */
167     public String getName(  )
168     {
169         return ( "JPA Startup Service" );
170     }
171 }