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.StringUtil;
020    import com.liferay.portal.kernel.util.Validator;
021    import com.liferay.portal.util.PropsValues;
022    
023    import javax.sql.DataSource;
024    
025    import org.springframework.instrument.classloading.LoadTimeWeaver;
026    import org.springframework.orm.jpa.persistenceunit.PersistenceUnitPostProcessor;
027    import org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter;
028    import org.springframework.orm.jpa.vendor.Database;
029    import org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter;
030    import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
031    import org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter;
032    import org.springframework.orm.jpa.vendor.TopLinkJpaVendorAdapter;
033    
034    /**
035     * @author Prashant Dighe
036     * @author Brian Wing Shun Chan
037     */
038    public class LocalContainerEntityManagerFactoryBean
039            extends org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean {
040    
041            public LocalContainerEntityManagerFactoryBean() {
042                    try {
043                            if (Validator.isNotNull(PropsValues.JPA_LOAD_TIME_WEAVER)) {
044                                    Class<?> loadTimeWeaverClass = Class.forName(
045                                            PropsValues.JPA_LOAD_TIME_WEAVER);
046    
047                                    LoadTimeWeaver loadTimeWeaver =
048                                            (LoadTimeWeaver)loadTimeWeaverClass.newInstance();
049    
050                                    setLoadTimeWeaver(loadTimeWeaver);
051                            }
052                    }
053                    catch (Exception e) {
054                            _log.error(e, e);
055    
056                            throw new RuntimeException(e);
057                    }
058    
059                    setPersistenceXmlLocation("classpath*:META-INF/persistence-custom.xml");
060    
061                    PersistenceUnitPostProcessor[] persistenceUnitPostProcessors =
062                            {new LiferayPersistenceUnitPostProcessor()};
063    
064                    setPersistenceUnitPostProcessors(persistenceUnitPostProcessors);
065            }
066    
067            @Override
068            public void setDataSource(DataSource dataSource) {
069                    Database database = DatabaseDetector.determineDatabase(dataSource);
070    
071                    AbstractJpaVendorAdapter jpaVendorAdapter = null;
072    
073                    String provider = PropsValues.JPA_PROVIDER;
074    
075                    try {
076                            Class<?> providerClass = getProviderClass(provider);
077    
078                            if (_log.isInfoEnabled()) {
079                                    _log.info("Using provider class " + providerClass.getName());
080                            }
081    
082                            jpaVendorAdapter =
083                                    (AbstractJpaVendorAdapter)providerClass.newInstance();
084                    }
085                    catch (Exception e) {
086                            _log.error(e, e);
087    
088                            return;
089                    }
090    
091                    String databasePlatform = PropsValues.JPA_DATABASE_PLATFORM;
092    
093                    if (StringUtil.equalsIgnoreCase(provider, "eclipselink") ||
094                            StringUtil.equalsIgnoreCase(provider, "toplink")) {
095    
096                            if (databasePlatform == null) {
097                                    databasePlatform = getDatabasePlatform(database);
098                            }
099    
100                            if (_log.isInfoEnabled()) {
101                                    _log.info("Using database platform " + databasePlatform);
102                            }
103    
104                            jpaVendorAdapter.setDatabasePlatform(databasePlatform);
105                    }
106                    else {
107                            if (databasePlatform == null) {
108                                    jpaVendorAdapter.setDatabase(database);
109    
110                                    if (_log.isInfoEnabled()) {
111                                            _log.info("Using database name " + database.toString());
112                                    }
113                            }
114                            else {
115                                    jpaVendorAdapter.setDatabase(
116                                            Database.valueOf(databasePlatform));
117    
118                                    if (_log.isInfoEnabled()) {
119                                            _log.info("Using database name " + databasePlatform);
120                                    }
121                            }
122                    }
123    
124                    setJpaVendorAdapter(jpaVendorAdapter);
125    
126                    super.setDataSource(dataSource);
127            }
128    
129            protected String getDatabasePlatform(Database database) {
130                    String databasePlatform = null;
131    
132                    String packageName = null;
133    
134                    boolean eclipseLink = false;
135    
136                    if (StringUtil.equalsIgnoreCase(
137                                    PropsValues.JPA_PROVIDER, "eclipselink")) {
138    
139                            packageName = "org.eclipse.persistence.platform.database.";
140    
141                            eclipseLink = true;
142                    }
143                    else {
144                            packageName = "oracle.toplink.essentials.platform.database.";
145                    }
146    
147                    if (database.equals(Database.DB2)) {
148                            databasePlatform = packageName + "DB2Platform";
149                    }
150                    else if (database.equals(Database.DERBY)) {
151                            databasePlatform = packageName + "DerbyPlatform";
152                    }
153                    else if (database.equals(Database.HSQL)) {
154                            databasePlatform = packageName + "HSQLPlatform";
155                    }
156                    else if (database.equals(Database.INFORMIX)) {
157                            databasePlatform = packageName + "InformixPlatform";
158                    }
159                    else if (database.equals(Database.MYSQL)) {
160                            if (eclipseLink) {
161                                    databasePlatform = packageName + "MySQLPlatform";
162                            }
163                            else {
164                                    databasePlatform = packageName + "MySQL4Platform";
165                            }
166                    }
167                    else if (database.equals(Database.ORACLE)) {
168                            if (eclipseLink) {
169                                    databasePlatform = packageName + "OraclePlatform";
170                            }
171                            else {
172                                    databasePlatform = packageName + "oracle.OraclePlatform";
173                            }
174                    }
175                    else if (database.equals(Database.POSTGRESQL)) {
176                            databasePlatform = packageName + "PostgreSQLPlatform";
177                    }
178                    else if (database.equals(Database.SQL_SERVER)) {
179                            databasePlatform = packageName + "SQLServerPlatform";
180                    }
181                    else if (database.equals(Database.SYBASE)) {
182                            databasePlatform = packageName + "SybasePlatform";
183                    }
184                    else {
185                            _log.error(
186                                    "Unable to detect database platform for \"" +
187                                            database.toString() + "\". Override by configuring the " +
188                                                    "\"jpa.database.platform\" property.");
189                    }
190    
191                    return databasePlatform;
192            }
193    
194            protected Class<?> getProviderClass(String provider) throws Exception {
195                    if (StringUtil.equalsIgnoreCase(provider, "eclipselink")) {
196                            return EclipseLinkJpaVendorAdapter.class;
197                    }
198                    else if (StringUtil.equalsIgnoreCase(provider, "hibernate")) {
199                            return HibernateJpaVendorAdapter.class;
200                    }
201                    else if (StringUtil.equalsIgnoreCase(provider, "openjpa")) {
202                            return OpenJpaVendorAdapter.class;
203                    }
204                    else if (StringUtil.equalsIgnoreCase(provider, "toplink")) {
205                            return TopLinkJpaVendorAdapter.class;
206                    }
207    
208                    return null;
209            }
210    
211            private static Log _log = LogFactoryUtil.getLog(
212                    LocalContainerEntityManagerFactoryBean.class);
213    
214    }