1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portal.spring.jpa;
16  
17  import com.liferay.portal.kernel.log.Log;
18  import com.liferay.portal.kernel.log.LogFactoryUtil;
19  import com.liferay.portal.kernel.util.Validator;
20  import com.liferay.portal.util.PropsValues;
21  
22  import javax.sql.DataSource;
23  
24  import org.springframework.instrument.classloading.LoadTimeWeaver;
25  import org.springframework.orm.jpa.persistenceunit.PersistenceUnitPostProcessor;
26  import org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter;
27  import org.springframework.orm.jpa.vendor.Database;
28  import org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter;
29  import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
30  import org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter;
31  import org.springframework.orm.jpa.vendor.TopLinkJpaVendorAdapter;
32  
33  /**
34   * <a href="LocalContainerEntityManagerFactoryBean.java.html"><b><i>View Source
35   * </i></b></a>
36   *
37   * @author Prashant Dighe
38   * @author Brian Wing Shun Chan
39   */
40  public class LocalContainerEntityManagerFactoryBean extends
41       org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean {
42  
43      public LocalContainerEntityManagerFactoryBean() {
44          try {
45              if (Validator.isNotNull(PropsValues.JPA_LOAD_TIME_WEAVER)) {
46                  Class<?> loadTimeWeaverClass = Class.forName(
47                      PropsValues.JPA_LOAD_TIME_WEAVER);
48  
49                  LoadTimeWeaver loadTimeWeaver =
50                      (LoadTimeWeaver)loadTimeWeaverClass.newInstance();
51  
52                  setLoadTimeWeaver(loadTimeWeaver);
53              }
54          }
55          catch(Exception e) {
56              _log.error(e, e);
57  
58              throw new RuntimeException(e);
59          }
60  
61          setPersistenceXmlLocation("classpath*:META-INF/persistence-custom.xml");
62  
63          PersistenceUnitPostProcessor[] persistenceUnitPostProcessors =
64              {new LiferayPersistenceUnitPostProcessor()};
65  
66          setPersistenceUnitPostProcessors(persistenceUnitPostProcessors);
67      }
68  
69      public void setDataSource(DataSource dataSource) {
70          Database database = DatabaseDetector.determineDatabase(dataSource);
71  
72          AbstractJpaVendorAdapter jpaVendorAdapter = null;
73  
74          String provider = PropsValues.JPA_PROVIDER;
75  
76          try {
77              Class<?> providerClass = getProviderClass(provider);
78  
79              if (_log.isInfoEnabled()) {
80                  _log.info("Using provider class " + providerClass.getName());
81              }
82  
83              jpaVendorAdapter =
84                  (AbstractJpaVendorAdapter)providerClass.newInstance();
85          }
86          catch(Exception e) {
87              _log.error(e, e);
88  
89              return;
90          }
91  
92          String databasePlatform = PropsValues.JPA_DATABASE_PLATFORM;
93  
94          if (provider.equalsIgnoreCase("eclipselink") ||
95              provider.equalsIgnoreCase("toplink")) {
96  
97              if (databasePlatform == null) {
98                  databasePlatform = getDatabasePlatform(database);
99              }
100 
101             if (_log.isInfoEnabled()) {
102                 _log.info("Using database platform " + databasePlatform);
103             }
104 
105             jpaVendorAdapter.setDatabasePlatform(databasePlatform);
106         }
107         else {
108             if (databasePlatform == null) {
109                 jpaVendorAdapter.setDatabase(database);
110 
111                 if (_log.isInfoEnabled()) {
112                     _log.info("Using database name " + database.toString());
113                 }
114             }
115             else {
116                 jpaVendorAdapter.setDatabase(
117                     Database.valueOf(databasePlatform));
118 
119                 if (_log.isInfoEnabled()) {
120                     _log.info("Using database name " + databasePlatform);
121                 }
122             }
123         }
124 
125         setJpaVendorAdapter(jpaVendorAdapter);
126 
127         super.setDataSource(dataSource);
128     }
129 
130     protected String getDatabasePlatform(Database database) {
131         String databasePlatform = null;
132 
133         String packageName = null;
134 
135         boolean eclipseLink = false;
136 
137         if (PropsValues.JPA_PROVIDER.equalsIgnoreCase("eclipselink")) {
138             packageName = "org.eclipse.persistence.platform.database.";
139 
140             eclipseLink = true;
141         }
142         else {
143             packageName = "oracle.toplink.essentials.platform.database.";
144         }
145 
146         if (database.equals(Database.DB2)) {
147             databasePlatform = packageName + "DB2Platform";
148         }
149         else if (database.equals(Database.DERBY)) {
150             databasePlatform = packageName + "DerbyPlatform";
151         }
152         else if (database.equals(Database.HSQL)) {
153             databasePlatform = packageName + "HSQLPlatform";
154         }
155         else if (database.equals(Database.INFORMIX)) {
156             databasePlatform = packageName + "InformixPlatform";
157         }
158         else if (database.equals(Database.MYSQL)) {
159             if (eclipseLink) {
160                 databasePlatform = packageName + "MySQLPlatform";
161             }
162             else {
163                 databasePlatform = packageName + "MySQL4Platform";
164             }
165         }
166         else if (database.equals(Database.ORACLE)) {
167             if (eclipseLink) {
168                 databasePlatform = packageName + "OraclePlatform";
169             }
170             else {
171                 databasePlatform = packageName + "oracle.OraclePlatform";
172             }
173         }
174         else if (database.equals(Database.POSTGRESQL)) {
175             databasePlatform = packageName + "PostgreSQLPlatform";
176         }
177         else if (database.equals(Database.SQL_SERVER)) {
178             databasePlatform = packageName + "SQLServerPlatform";
179         }
180         else if (database.equals(Database.SYBASE)) {
181             databasePlatform = packageName + "SybasePlatform";
182         }
183         else {
184             _log.error(
185                 "Unable to detect database platform for \"" +
186                     database.toString() + "\". Override by configuring the " +
187                         "\"jpa.database.platform\" property.");
188         }
189 
190         return databasePlatform;
191     }
192 
193     protected Class<?> getProviderClass(String provider) throws Exception {
194         if (provider.equalsIgnoreCase("eclipselink")) {
195             return EclipseLinkJpaVendorAdapter.class;
196         }
197         else if (provider.equalsIgnoreCase("hibernate")) {
198             return HibernateJpaVendorAdapter.class;
199         }
200         else if (provider.equalsIgnoreCase("openjpa")) {
201             return OpenJpaVendorAdapter.class;
202         }
203         else if (provider.equalsIgnoreCase("toplink")) {
204             return TopLinkJpaVendorAdapter.class;
205         }
206 
207         return null;
208     }
209 
210     private static Log _log = LogFactoryUtil.getLog(
211         LocalContainerEntityManagerFactoryBean.class);
212 
213 }