001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.spring.jpa;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.util.Validator;
020    import com.liferay.portal.util.PropsValues;
021    
022    import javax.sql.DataSource;
023    
024    import org.springframework.instrument.classloading.LoadTimeWeaver;
025    import org.springframework.orm.jpa.persistenceunit.PersistenceUnitPostProcessor;
026    import org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter;
027    import org.springframework.orm.jpa.vendor.Database;
028    import org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter;
029    import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
030    import org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter;
031    import org.springframework.orm.jpa.vendor.TopLinkJpaVendorAdapter;
032    
033    /**
034     * @author Prashant Dighe
035     * @author Brian Wing Shun Chan
036     */
037    public class LocalContainerEntityManagerFactoryBean extends
038             org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean {
039    
040            public LocalContainerEntityManagerFactoryBean() {
041                    try {
042                            if (Validator.isNotNull(PropsValues.JPA_LOAD_TIME_WEAVER)) {
043                                    Class<?> loadTimeWeaverClass = Class.forName(
044                                            PropsValues.JPA_LOAD_TIME_WEAVER);
045    
046                                    LoadTimeWeaver loadTimeWeaver =
047                                            (LoadTimeWeaver)loadTimeWeaverClass.newInstance();
048    
049                                    setLoadTimeWeaver(loadTimeWeaver);
050                            }
051                    }
052                    catch(Exception e) {
053                            _log.error(e, e);
054    
055                            throw new RuntimeException(e);
056                    }
057    
058                    setPersistenceXmlLocation("classpath*:META-INF/persistence-custom.xml");
059    
060                    PersistenceUnitPostProcessor[] persistenceUnitPostProcessors =
061                            {new LiferayPersistenceUnitPostProcessor()};
062    
063                    setPersistenceUnitPostProcessors(persistenceUnitPostProcessors);
064            }
065    
066            public void setDataSource(DataSource dataSource) {
067                    Database database = DatabaseDetector.determineDatabase(dataSource);
068    
069                    AbstractJpaVendorAdapter jpaVendorAdapter = null;
070    
071                    String provider = PropsValues.JPA_PROVIDER;
072    
073                    try {
074                            Class<?> providerClass = getProviderClass(provider);
075    
076                            if (_log.isInfoEnabled()) {
077                                    _log.info("Using provider class " + providerClass.getName());
078                            }
079    
080                            jpaVendorAdapter =
081                                    (AbstractJpaVendorAdapter)providerClass.newInstance();
082                    }
083                    catch(Exception e) {
084                            _log.error(e, e);
085    
086                            return;
087                    }
088    
089                    String databasePlatform = PropsValues.JPA_DATABASE_PLATFORM;
090    
091                    if (provider.equalsIgnoreCase("eclipselink") ||
092                            provider.equalsIgnoreCase("toplink")) {
093    
094                            if (databasePlatform == null) {
095                                    databasePlatform = getDatabasePlatform(database);
096                            }
097    
098                            if (_log.isInfoEnabled()) {
099                                    _log.info("Using database platform " + databasePlatform);
100                            }
101    
102                            jpaVendorAdapter.setDatabasePlatform(databasePlatform);
103                    }
104                    else {
105                            if (databasePlatform == null) {
106                                    jpaVendorAdapter.setDatabase(database);
107    
108                                    if (_log.isInfoEnabled()) {
109                                            _log.info("Using database name " + database.toString());
110                                    }
111                            }
112                            else {
113                                    jpaVendorAdapter.setDatabase(
114                                            Database.valueOf(databasePlatform));
115    
116                                    if (_log.isInfoEnabled()) {
117                                            _log.info("Using database name " + databasePlatform);
118                                    }
119                            }
120                    }
121    
122                    setJpaVendorAdapter(jpaVendorAdapter);
123    
124                    super.setDataSource(dataSource);
125            }
126    
127            protected String getDatabasePlatform(Database database) {
128                    String databasePlatform = null;
129    
130                    String packageName = null;
131    
132                    boolean eclipseLink = false;
133    
134                    if (PropsValues.JPA_PROVIDER.equalsIgnoreCase("eclipselink")) {
135                            packageName = "org.eclipse.persistence.platform.database.";
136    
137                            eclipseLink = true;
138                    }
139                    else {
140                            packageName = "oracle.toplink.essentials.platform.database.";
141                    }
142    
143                    if (database.equals(Database.DB2)) {
144                            databasePlatform = packageName + "DB2Platform";
145                    }
146                    else if (database.equals(Database.DERBY)) {
147                            databasePlatform = packageName + "DerbyPlatform";
148                    }
149                    else if (database.equals(Database.HSQL)) {
150                            databasePlatform = packageName + "HSQLPlatform";
151                    }
152                    else if (database.equals(Database.INFORMIX)) {
153                            databasePlatform = packageName + "InformixPlatform";
154                    }
155                    else if (database.equals(Database.MYSQL)) {
156                            if (eclipseLink) {
157                                    databasePlatform = packageName + "MySQLPlatform";
158                            }
159                            else {
160                                    databasePlatform = packageName + "MySQL4Platform";
161                            }
162                    }
163                    else if (database.equals(Database.ORACLE)) {
164                            if (eclipseLink) {
165                                    databasePlatform = packageName + "OraclePlatform";
166                            }
167                            else {
168                                    databasePlatform = packageName + "oracle.OraclePlatform";
169                            }
170                    }
171                    else if (database.equals(Database.POSTGRESQL)) {
172                            databasePlatform = packageName + "PostgreSQLPlatform";
173                    }
174                    else if (database.equals(Database.SQL_SERVER)) {
175                            databasePlatform = packageName + "SQLServerPlatform";
176                    }
177                    else if (database.equals(Database.SYBASE)) {
178                            databasePlatform = packageName + "SybasePlatform";
179                    }
180                    else {
181                            _log.error(
182                                    "Unable to detect database platform for \"" +
183                                            database.toString() + "\". Override by configuring the " +
184                                                    "\"jpa.database.platform\" property.");
185                    }
186    
187                    return databasePlatform;
188            }
189    
190            protected Class<?> getProviderClass(String provider) throws Exception {
191                    if (provider.equalsIgnoreCase("eclipselink")) {
192                            return EclipseLinkJpaVendorAdapter.class;
193                    }
194                    else if (provider.equalsIgnoreCase("hibernate")) {
195                            return HibernateJpaVendorAdapter.class;
196                    }
197                    else if (provider.equalsIgnoreCase("openjpa")) {
198                            return OpenJpaVendorAdapter.class;
199                    }
200                    else if (provider.equalsIgnoreCase("toplink")) {
201                            return TopLinkJpaVendorAdapter.class;
202                    }
203    
204                    return null;
205            }
206    
207            private static Log _log = LogFactoryUtil.getLog(
208                    LocalContainerEntityManagerFactoryBean.class);
209    
210    }