org.sakaiproject.nakamura.persistence.dbcp.DataSourceServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.sakaiproject.nakamura.persistence.dbcp.DataSourceServiceImpl.java

Source

/**
 * Licensed to the Sakai Foundation (SF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The SF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */
package org.sakaiproject.nakamura.persistence.dbcp;

import org.apache.commons.dbcp.ConnectionFactory;
import org.apache.commons.dbcp.DriverManagerConnectionFactory;
import org.apache.commons.dbcp.PoolableConnectionFactory;
import org.apache.commons.dbcp.PoolingDataSource;
import org.apache.commons.pool.impl.GenericKeyedObjectPool;
import org.apache.commons.pool.impl.GenericKeyedObjectPoolFactory;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.osgi.service.component.ComponentContext;
import org.sakaiproject.nakamura.api.configuration.ConfigurationService;
import org.sakaiproject.nakamura.api.configuration.NakamuraConstants;
import org.sakaiproject.nakamura.api.persistence.DataSourceService;

import java.sql.SQLException;

import javax.sql.DataSource;

/**
 * <p>
 * Service to provide a data source for database connections.
 * </p>
 * The implementation is based on the javadoc from DBCP which reads like the following:<br/>
 * The {@link org.apache.commons.dbcp.PoolingDataSource} uses an underlying
 * {@link org.apache.commons.pool.ObjectPool} to create and store its java.sql.Connection.<br/>
 * To create a {@link org.apache.commons.pool.ObjectPool}, you'll need a
 * {@link org.apache.commons.pool.PoolableObjectFactory} that creates the actual
 * {@link java.sql.Connection}s. That's what
 * {@link org.apache.commons.dbcp.PoolableConnectionFactory} is for.<br/>
 * To create the {@link org.apache.commons.dbcp.PoolableConnectionFactory} , you'll need
 * at least two things:
 * <ol>
 * <li>A {@link org.apache.commons.dbcp.ConnectionFactory} from which the actual database
 * {@link java.sql.Connection}s will be obtained.</li>
 * <li>An empty and factory-less {@link org.apache.commons.pool.ObjectPool} in which the
 * {@link java.sql.Connection}s will be stored.</li>
 * </ol>
 * When you pass an {@link org.apache.commons.pool.ObjectPool} into the
 * {@link org.apache.commons.dbcp.PoolableConnectionFactory} , it will automatically
 * register itself as the {@link org.apache.commons.pool.PoolableObjectFactory} for that
 * pool.<br/>
 * You can optionally provide a {@link org.apache.commons.pool.KeyedObjectPoolFactory}
 * that will be used to create {@link org.apache.commons.pool.KeyedObjectPool}s for
 * pooling {@link java.sql.PreparedStatement}s for each {@link java.sql.Connection}.
 *
 *
 *
 *
 *
 */
@Component(immediate = true)
@Service
public class DataSourceServiceImpl implements DataSourceService {

    private PoolingDataSource dataSource;
    @SuppressWarnings("unused")
    private PoolableConnectionFactory poolableConnectionFactory;

    @Reference
    private ConfigurationService confurationService;

    /**
     * Construct a DBCP data source service.
     *
     * @param driverClassName
     * @param url
     * @param username
     * @param password
     * @param validationQuery
     * @param defaultReadOnly
     * @param defaultAutoCommit
     * @param poolPreparedStatements
     * @throws ClassNotFoundException
     * @throws SQLException
     */
    public DataSourceServiceImpl() {
    }

    @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = { "URF_UNREAD_FIELD",
            "UWF_UNWRITTEN_FIELD" }, justification = "PoolableConnectionFactory injects itself into connectionPool, but we need a reference to it, ConfigurationService is OSgi managed.")
    protected void activate(ComponentContext componentContext) throws ClassNotFoundException {
        String driverClassName = confurationService.getProperty(NakamuraConstants.JDBC_DRIVER_NAME);

        String url = confurationService.getProperty(NakamuraConstants.JDBC_URL);
        String username = confurationService.getProperty(NakamuraConstants.JDBC_USERNAME);
        String password = confurationService.getProperty(NakamuraConstants.JDBC_PASSWORD);
        String validationQuery = confurationService.getProperty(NakamuraConstants.JDBC_VALIDATION_QUERY);
        boolean defaultReadOnly = Boolean
                .valueOf(confurationService.getProperty(NakamuraConstants.JDBC_DEFAULT_READ_ONLY));
        boolean defaultAutoCommit = Boolean
                .valueOf(confurationService.getProperty(NakamuraConstants.JDBC_DEFAULT_AUTO_COMMIT));
        boolean poolPreparedStatements = Boolean
                .valueOf(confurationService.getProperty(NakamuraConstants.JDBC_DEFAULT_PREPARED_STATEMENTS));

        Class.forName(driverClassName);
        GenericObjectPool connectionPool = new GenericObjectPool(null);
        ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(url, username, password);

        // Set up statement pool, if desired
        GenericKeyedObjectPoolFactory statementPoolFactory = null;
        if (poolPreparedStatements) {
            int maxActive = -1;
            byte whenExhaustedAction = GenericKeyedObjectPool.WHEN_EXHAUSTED_FAIL;
            long maxWait = 0L;
            int maxIdlePerKey = 1;
            int maxOpenPreparedStatements = 0;
            statementPoolFactory = new GenericKeyedObjectPoolFactory(null, maxActive, whenExhaustedAction, maxWait,
                    maxIdlePerKey, maxOpenPreparedStatements);
        }

        poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory, connectionPool,
                statementPoolFactory, validationQuery, defaultReadOnly, defaultAutoCommit);
        dataSource = new PoolingDataSource(connectionPool);
    }

    protected void deactivate(ComponentContext componentContext) {
    }

    /**
     * {@inheritDoc}
     *
     * @see org.sakaiproject.nakamura.api.persistence.DataSourceService#getDataSource()
     */
    public DataSource getDataSource() {
        return dataSource;
    }

    /**
     * {@inheritDoc}
     *
     * @see org.sakaiproject.nakamura.api.persistence.DataSourceService#getType()
     */
    public String getType() {
        return DataSourceService.NON_JTA_DATASOURCE;
    }

}