001    /**
002     * Copyright (c) 2000-2013 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
038            extends 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            @Override
067            public void setDataSource(DataSource dataSource) {
068                    Database database = DatabaseDetector.determineDatabase(dataSource);
069    
070                    AbstractJpaVendorAdapter jpaVendorAdapter = null;
071    
072                    String provider = PropsValues.JPA_PROVIDER;
073    
074                    try {
075                            Class<?> providerClass = getProviderClass(provider);
076    
077                            if (_log.isInfoEnabled()) {
078                                    _log.info("Using provider class " + providerClass.getName());
079                            }
080    
081                            jpaVendorAdapter =
082                                    (AbstractJpaVendorAdapter)providerClass.newInstance();
083                    }
084                    catch (Exception e) {
085                            _log.error(e, e);
086    
087                            return;
088                    }
089    
090                    String databasePlatform = PropsValues.JPA_DATABASE_PLATFORM;
091    
092                    if (provider.equalsIgnoreCase("eclipselink") ||
093                            provider.equalsIgnoreCase("toplink")) {
094    
095                            if (databasePlatform == null) {
096                                    databasePlatform = getDatabasePlatform(database);
097                            }
098    
099                            if (_log.isInfoEnabled()) {
100                                    _log.info("Using database platform " + databasePlatform);
101                            }
102    
103                            jpaVendorAdapter.setDatabasePlatform(databasePlatform);
104                    }
105                    else {
106                            if (databasePlatform == null) {
107                                    jpaVendorAdapter.setDatabase(database);
108    
109                                    if (_log.isInfoEnabled()) {
110                                            _log.info("Using database name " + database.toString());
111                                    }
112                            }
113                            else {
114                                    jpaVendorAdapter.setDatabase(
115                                            Database.valueOf(databasePlatform));
116    
117                                    if (_log.isInfoEnabled()) {
118                                            _log.info("Using database name " + databasePlatform);
119                                    }
120                            }
121                    }
122    
123                    setJpaVendorAdapter(jpaVendorAdapter);
124    
125                    super.setDataSource(dataSource);
126            }
127    
128            protected String getDatabasePlatform(Database database) {
129                    String databasePlatform = null;
130    
131                    String packageName = null;
132    
133                    boolean eclipseLink = false;
134    
135                    if (PropsValues.JPA_PROVIDER.equalsIgnoreCase("eclipselink")) {
136                            packageName = "org.eclipse.persistence.platform.database.";
137    
138                            eclipseLink = true;
139                    }
140                    else {
141                            packageName = "oracle.toplink.essentials.platform.database.";
142                    }
143    
144                    if (database.equals(Database.DB2)) {
145                            databasePlatform = packageName + "DB2Platform";
146                    }
147                    else if (database.equals(Database.DERBY)) {
148                            databasePlatform = packageName + "DerbyPlatform";
149                    }
150                    else if (database.equals(Database.HSQL)) {
151                            databasePlatform = packageName + "HSQLPlatform";
152                    }
153                    else if (database.equals(Database.INFORMIX)) {
154                            databasePlatform = packageName + "InformixPlatform";
155                    }
156                    else if (database.equals(Database.MYSQL)) {
157                            if (eclipseLink) {
158                                    databasePlatform = packageName + "MySQLPlatform";
159                            }
160                            else {
161                                    databasePlatform = packageName + "MySQL4Platform";
162                            }
163                    }
164                    else if (database.equals(Database.ORACLE)) {
165                            if (eclipseLink) {
166                                    databasePlatform = packageName + "OraclePlatform";
167                            }
168                            else {
169                                    databasePlatform = packageName + "oracle.OraclePlatform";
170                            }
171                    }
172                    else if (database.equals(Database.POSTGRESQL)) {
173                            databasePlatform = packageName + "PostgreSQLPlatform";
174                    }
175                    else if (database.equals(Database.SQL_SERVER)) {
176                            databasePlatform = packageName + "SQLServerPlatform";
177                    }
178                    else if (database.equals(Database.SYBASE)) {
179                            databasePlatform = packageName + "SybasePlatform";
180                    }
181                    else {
182                            _log.error(
183                                    "Unable to detect database platform for \"" +
184                                            database.toString() + "\". Override by configuring the " +
185                                                    "\"jpa.database.platform\" property.");
186                    }
187    
188                    return databasePlatform;
189            }
190    
191            protected Class<?> getProviderClass(String provider) throws Exception {
192                    if (provider.equalsIgnoreCase("eclipselink")) {
193                            return EclipseLinkJpaVendorAdapter.class;
194                    }
195                    else if (provider.equalsIgnoreCase("hibernate")) {
196                            return HibernateJpaVendorAdapter.class;
197                    }
198                    else if (provider.equalsIgnoreCase("openjpa")) {
199                            return OpenJpaVendorAdapter.class;
200                    }
201                    else if (provider.equalsIgnoreCase("toplink")) {
202                            return TopLinkJpaVendorAdapter.class;
203                    }
204    
205                    return null;
206            }
207    
208            private static Log _log = LogFactoryUtil.getLog(
209                    LocalContainerEntityManagerFactoryBean.class);
210    
211    }