com.liferay.portal.dao.jdbc.util.DataSourceFactoryBean.java Source code

Java tutorial

Introduction

Here is the source code for com.liferay.portal.dao.jdbc.util.DataSourceFactoryBean.java

Source

/**
 * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package com.liferay.portal.dao.jdbc.util;

import com.liferay.portal.kernel.jndi.JNDIUtil;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.util.SortedProperties;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.util.PropsUtil;

import com.mchange.v2.c3p0.ComboPooledDataSource;

import com.mchange.v2.c3p0.DataSources;
import java.util.Enumeration;
import java.util.Properties;

import javax.naming.InitialContext;

import javax.sql.DataSource;

import org.apache.commons.beanutils.BeanUtils;

import org.springframework.beans.factory.config.AbstractFactoryBean;

/**
 * Changes to this class fixes DB connection leak.<br />
 * <br />
 * Note: This class is the same as the portal's DataSourceFactoryBean.<br />
 * <br />
 * It introduces new method {@link DataSourceFactoryBean#destroyInstance(java.lang.Object) } 
 * which is used to close database connection.
 *
 * @author Brian Wing Shun Chan
 * @author Tom Poleovsk
 */
public class DataSourceFactoryBean extends AbstractFactoryBean {

    public Class<?> getObjectType() {
        return DataSource.class;
    }

    public void setPropertyPrefix(String propertyPrefix) {
        _propertyPrefix = propertyPrefix;
    }

    protected Object createInstance() throws Exception {
        Properties properties = PropsUtil.getProperties(_propertyPrefix, true);

        String jndiName = properties.getProperty("jndi.name");

        if (Validator.isNotNull(jndiName)) {
            try {
                return JNDIUtil.lookup(new InitialContext(), jndiName);
            } catch (Exception e) {
                _log.error("Unable to lookup " + jndiName, e);
            }
        }

        DataSource dataSource = new ComboPooledDataSource();

        Enumeration<String> enu = (Enumeration<String>) properties.propertyNames();

        while (enu.hasMoreElements()) {
            String key = enu.nextElement();

            String value = properties.getProperty(key);

            // Map org.apache.commons.dbcp.BasicDataSource to C3PO

            if (key.equalsIgnoreCase("driverClassName")) {
                key = "driverClass";
            } else if (key.equalsIgnoreCase("url")) {
                key = "jdbcUrl";
            } else if (key.equalsIgnoreCase("username")) {
                key = "user";
            }

            BeanUtils.setProperty(dataSource, key, value);
        }

        if (_log.isDebugEnabled()) {
            SortedProperties sortedProperties = new SortedProperties(properties);

            _log.debug("Properties for prefix " + _propertyPrefix);

            sortedProperties.list(System.out);
        }

        return dataSource;
    }

    protected void destroyInstance(Object instance) throws Exception {
        // instance should be ComboPooledDataSource
        if (instance instanceof ComboPooledDataSource) {
            DataSources.destroy((DataSource) instance);
        } else {
            _log.fatal("Cannot close DB DataSource. [" + instance.getClass().getName() + "] not instance of the ["
                    + ComboPooledDataSource.class.getName() + "]");
        }
    }

    private static Log _log = LogFactoryUtil.getLog(DataSourceFactoryBean.class);

    private String _propertyPrefix;

}