001    /**
002     * Copyright (c) 2000-present 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.dao.db;
016    
017    import com.liferay.portal.dao.orm.hibernate.DialectImpl;
018    import com.liferay.portal.kernel.dao.db.DB;
019    import com.liferay.portal.kernel.dao.db.DBFactory;
020    import com.liferay.portal.kernel.log.Log;
021    import com.liferay.portal.kernel.log.LogFactoryUtil;
022    import com.liferay.portal.kernel.security.pacl.DoPrivileged;
023    import com.liferay.portal.kernel.util.InfrastructureUtil;
024    import com.liferay.portal.kernel.util.InstanceFactory;
025    import com.liferay.portal.kernel.util.ReflectionUtil;
026    import com.liferay.portal.util.PropsValues;
027    
028    import java.sql.Connection;
029    import java.sql.DatabaseMetaData;
030    import java.sql.SQLException;
031    
032    import javax.sql.DataSource;
033    
034    import org.hibernate.dialect.DB2Dialect;
035    import org.hibernate.dialect.Dialect;
036    import org.hibernate.dialect.HSQLDialect;
037    import org.hibernate.dialect.MySQLDialect;
038    import org.hibernate.dialect.Oracle8iDialect;
039    import org.hibernate.dialect.Oracle9Dialect;
040    import org.hibernate.dialect.PostgreSQLDialect;
041    import org.hibernate.dialect.SQLServerDialect;
042    import org.hibernate.dialect.Sybase11Dialect;
043    import org.hibernate.dialect.SybaseASE15Dialect;
044    import org.hibernate.dialect.SybaseAnywhereDialect;
045    import org.hibernate.dialect.SybaseDialect;
046    
047    /**
048     * @author Alexander Chow
049     * @author Brian Wing Shun Chan
050     */
051    @DoPrivileged
052    @SuppressWarnings("deprecation")
053    public class DBFactoryImpl implements DBFactory {
054    
055            @Override
056            public DB getDB() {
057                    if (_db == null) {
058                            try {
059                                    if (_log.isInfoEnabled()) {
060                                            _log.info("Using dialect " + PropsValues.HIBERNATE_DIALECT);
061                                    }
062    
063                                    Dialect dialect = (Dialect)InstanceFactory.newInstance(
064                                            PropsValues.HIBERNATE_DIALECT);
065    
066                                    setDB(dialect, InfrastructureUtil.getDataSource());
067                            }
068                            catch (Exception e) {
069                                    _log.error(e, e);
070                            }
071                    }
072    
073                    return _db;
074            }
075    
076            @Override
077            public DB getDB(Object dialect, DataSource dataSource) {
078                    if (dialect instanceof DialectImpl) {
079                            DialectImpl dialectImpl = (DialectImpl)dialect;
080    
081                            dialect = dialectImpl.getWrappedDialect();
082                    }
083    
084                    if (dialect instanceof DB2Dialect) {
085                            return getDB(DB.TYPE_DB2, dataSource);
086                    }
087    
088                    if (dialect instanceof HSQLDialect) {
089                            return getDB(DB.TYPE_HYPERSONIC, dataSource);
090                    }
091    
092                    if (dialect instanceof MySQLDialect) {
093                            return getDB(DB.TYPE_MYSQL, dataSource);
094                    }
095    
096                    if (dialect instanceof Oracle8iDialect ||
097                            dialect instanceof Oracle9Dialect) {
098    
099                            return getDB(DB.TYPE_ORACLE, dataSource);
100                    }
101    
102                    if (dialect instanceof PostgreSQLDialect) {
103                            return getDB(DB.TYPE_POSTGRESQL, dataSource);
104                    }
105    
106                    if (dialect instanceof SQLServerDialect) {
107                            return getDB(DB.TYPE_SQLSERVER, dataSource);
108                    }
109    
110                    if (dialect instanceof SybaseDialect ||
111                            dialect instanceof Sybase11Dialect ||
112                            dialect instanceof SybaseAnywhereDialect ||
113                            dialect instanceof SybaseASE15Dialect) {
114    
115                            return getDB(DB.TYPE_SYBASE, dataSource);
116                    }
117    
118                    throw new IllegalArgumentException("Unknown dialect type " + dialect);
119            }
120    
121            @Override
122            public DB getDB(String type, DataSource dataSource) {
123                    int dbMajorVersion = 0;
124                    int dbMinorVersion = 0;
125    
126                    if (dataSource != null) {
127                            try (Connection connection = dataSource.getConnection()) {
128                                    DatabaseMetaData databaseMetaData = connection.getMetaData();
129    
130                                    dbMajorVersion = databaseMetaData.getDatabaseMajorVersion();
131                                    dbMinorVersion = databaseMetaData.getDatabaseMinorVersion();
132                            }
133                            catch (SQLException sqle) {
134                                    return ReflectionUtil.throwException(sqle);
135                            }
136                    }
137    
138                    if (type.equals(DB.TYPE_DB2)) {
139                            return new DB2DB(dbMajorVersion, dbMinorVersion);
140                    }
141    
142                    if (type.equals(DB.TYPE_HYPERSONIC)) {
143                            return new HypersonicDB(dbMajorVersion, dbMinorVersion);
144                    }
145    
146                    if (type.equals(DB.TYPE_MYSQL)) {
147                            return new MySQLDB(dbMajorVersion, dbMinorVersion);
148                    }
149    
150                    if (type.equals(DB.TYPE_ORACLE)) {
151                            return new OracleDB(dbMajorVersion, dbMinorVersion);
152                    }
153    
154                    if (type.equals(DB.TYPE_POSTGRESQL)) {
155                            return new PostgreSQLDB(dbMajorVersion, dbMinorVersion);
156                    }
157    
158                    if (type.equals(DB.TYPE_SQLSERVER)) {
159                            return new SQLServerDB(dbMajorVersion, dbMinorVersion);
160                    }
161    
162                    if (type.equals(DB.TYPE_SYBASE)) {
163                            return new SybaseDB(dbMajorVersion, dbMinorVersion);
164                    }
165    
166                    throw new IllegalArgumentException("Unknown database type " + type);
167            }
168    
169            @Override
170            public void setDB(Object dialect, DataSource dataSource) {
171                    _db = getDB(dialect, dataSource);
172    
173                    if (_log.isDebugEnabled()) {
174                            Class<?> dbClazz = _db.getClass();
175                            Class<?> dialectClazz = dialect.getClass();
176    
177                            _log.debug(
178                                    "Using DB implementation " + dbClazz.getName() + " for " +
179                                            dialectClazz.getName());
180                    }
181            }
182    
183            @Override
184            public void setDB(String type, DataSource dataSource) {
185                    _db = getDB(type, dataSource);
186    
187                    if (_log.isDebugEnabled()) {
188                            Class<?> clazz = _db.getClass();
189    
190                            _log.debug(
191                                    "Using DB implementation " + clazz.getName() + " for " + type);
192                    }
193            }
194    
195            private static final Log _log = LogFactoryUtil.getLog(DBFactoryImpl.class);
196    
197            private static DB _db;
198    
199    }