org.apache.openejb.resource.jdbc.DataSourceFactory.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.openejb.resource.jdbc.DataSourceFactory.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF 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.apache.openejb.resource.jdbc;

import org.apache.commons.dbcp.ConnectionFactory;
import org.apache.commons.dbcp.DataSourceConnectionFactory;
import org.apache.commons.dbcp.managed.DataSourceXAConnectionFactory;
import org.apache.commons.dbcp.managed.LocalXAConnectionFactory;
import org.apache.commons.dbcp.managed.TransactionRegistry;
import org.apache.commons.dbcp.managed.XAConnectionFactory;
import org.apache.openejb.loader.SystemInstance;
import org.apache.openejb.resource.XAResourceWrapper;
import org.apache.openejb.util.LogCategory;
import org.apache.xbean.recipe.ObjectRecipe;
import org.apache.xbean.recipe.Option;

import javax.sql.DataSource;
import javax.sql.XADataSource;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.SQLException;
import java.util.Map;
import java.util.Properties;

/**
 * @version $Rev: 1205747 $ $Date: 2011-11-24 09:53:38 +0200 (Thu, 24 Nov 2011) $
 */
public class DataSourceFactory {

    public static DataSource create(final boolean managed, final Class impl, final String definition)
            throws IllegalAccessException, InstantiationException, IOException {

        final org.apache.commons.dbcp.BasicDataSource ds;

        if (DataSource.class.isAssignableFrom(impl) && !Boolean
                .parseBoolean(System.getProperty("org.apache.openejb.resource.jdbc.hot.deploy", "false"))) {

            final ObjectRecipe recipe = new ObjectRecipe(impl);
            recipe.allow(Option.CASE_INSENSITIVE_PROPERTIES);
            recipe.allow(Option.IGNORE_MISSING_PROPERTIES);
            recipe.allow(Option.NAMED_PARAMETERS);
            recipe.setAllProperties(asProperties(definition));

            DataSource dataSource = (DataSource) recipe.create();

            if (managed) {
                ds = new DbcpManagedDataSource(dataSource);
            } else {
                ds = new DbcpDataSource(dataSource);
            }
        } else {
            ds = (org.apache.commons.dbcp.BasicDataSource) create(managed);
        }

        // force the driver class to be set
        ds.setDriverClassName(impl.getName());

        return ds;
    }

    private static Map<?, ?> asProperties(String definition) throws IOException {
        final ByteArrayInputStream in = new ByteArrayInputStream(definition.getBytes());
        final Properties properties = new Properties();
        properties.load(in);
        trimNotSupportedDataSourceProperties(properties);
        return properties;
    }

    public static void trimNotSupportedDataSourceProperties(Properties properties) {
        properties.remove("LoginTimeout");
    }

    public static DataSource create(boolean managed) {
        org.apache.commons.dbcp.BasicDataSource ds;
        if (managed) {
            XAResourceWrapper xaResourceWrapper = SystemInstance.get().getComponent(XAResourceWrapper.class);
            if (xaResourceWrapper != null) {
                ds = new ManagedDataSourceWithRecovery(xaResourceWrapper);
            } else {
                ds = new BasicManagedDataSource();
            }
        } else {
            ds = new BasicDataSource();
        }
        return ds;
    }

    public static class DbcpDataSource extends BasicDataSource {

        private final DataSource dataSource;

        public DbcpDataSource(DataSource dataSource) {
            this.dataSource = dataSource;
        }

        @Override
        protected ConnectionFactory createConnectionFactory() throws SQLException {
            return new DataSourceConnectionFactory(dataSource, username, password);
        }

        @Override
        public void setJdbcUrl(String url) {
            // TODO This is a big whole and we will need to rework this
            try {
                // only works if hsql is available and datasource is an HSQL jdbcDataSource
                final Class<?> hsql = this.getClass().getClassLoader().loadClass("org.hsqldb.jdbc.JDBCDataSource");
                final Method setDatabase = hsql.getMethod("setDatabase", String.class);
                setDatabase.setAccessible(true);
                setDatabase.invoke(dataSource, url);
            } catch (Throwable e) {
                super.setUrl(url);
            }
        }
    }

    public static class DbcpManagedDataSource extends BasicManagedDataSource {

        private final DataSource dataSource;

        public DbcpManagedDataSource(DataSource dataSource) {
            this.dataSource = dataSource;
        }

        @Override
        public void setJdbcUrl(String url) {
            // TODO This is a big whole and we will need to rework this
            try {
                // only works if hsql is available and datasource is an HSQL jdbcDataSource
                final Class<?> hsql = this.getClass().getClassLoader().loadClass("org.hsqldb.jdbc.JDBCDataSource");
                final Method setDatabase = hsql.getMethod("setDatabase", String.class);
                setDatabase.setAccessible(true);
                setDatabase.invoke(dataSource, url);
            } catch (Throwable e) {
                super.setUrl(url);
            }
        }

        @Override
        protected ConnectionFactory createConnectionFactory() throws SQLException {

            if (dataSource instanceof XADataSource) {

                // Create the XAConectionFactory using the XA data source
                XADataSource xaDataSourceInstance = (XADataSource) dataSource;
                XAConnectionFactory xaConnectionFactory = new DataSourceXAConnectionFactory(getTransactionManager(),
                        xaDataSourceInstance, username, password);
                setTransactionRegistry(xaConnectionFactory.getTransactionRegistry());
                return xaConnectionFactory;

            } else {

                // If xa data source is not specified a DriverConnectionFactory is created and wrapped with a LocalXAConnectionFactory
                ConnectionFactory connectionFactory = new DataSourceConnectionFactory(dataSource, username,
                        password);
                XAConnectionFactory xaConnectionFactory = new LocalXAConnectionFactory(getTransactionManager(),
                        connectionFactory);
                setTransactionRegistry(xaConnectionFactory.getTransactionRegistry());
                return xaConnectionFactory;
            }
        }

        public void setTransactionRegistry(TransactionRegistry registry) {
            try {
                final Field field = org.apache.commons.dbcp.managed.BasicManagedDataSource.class
                        .getDeclaredField("transactionRegistry");
                field.setAccessible(true);
                field.set(this, registry);
            } catch (Throwable e) {
                throw new IllegalStateException(e);
            }
        }
    }
}