org.everit.osgi.jdbc.commons.dbcp.internal.Util.java Source code

Java tutorial

Introduction

Here is the source code for org.everit.osgi.jdbc.commons.dbcp.internal.Util.java

Source

/**
 * This file is part of Everit - Commons DBCP Components.
 *
 * Everit - Commons DBCP Components is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Everit - Commons DBCP Components is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Everit - Commons DBCP Components.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.everit.osgi.jdbc.commons.dbcp.internal;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.util.Collection;
import java.util.Dictionary;
import java.util.Map;

import org.apache.commons.dbcp2.BasicDataSource;
import org.everit.osgi.jdbc.commons.dbcp.DSFConstants;

public final class Util {

    public static void addReferenceIdsToServiceProperties(String prefix, Map<String, Object> referenceProps,
            Dictionary<String, Object> serviceProps) {

        Object serviceId = referenceProps.get("service.id");
        if (serviceId != null) {
            serviceProps.put(prefix + ".service.id", serviceId);
        }

        Object servicedPid = referenceProps.get("service.pid");
        if (servicedPid != null) {
            serviceProps.put(prefix + ".service.pid", servicedPid);
        }
    }

    public static void applyPropertiesOnBasicDataSource(final BasicDataSource basicDataSource,
            final Map<String, Object> componentProperties) {

        setPropertyIfNotNull(basicDataSource, componentProperties,
                DSFConstants.PROP_ACCESS_TO_UNDERLYING_CONNECTION_ALLOWED, boolean.class);

        setPropertyIfNotNull(basicDataSource, componentProperties, DSFConstants.PROP_DEFAULT_AUTO_COMMIT,
                Boolean.class);

        setPropertyIfNotNull(basicDataSource, componentProperties, DSFConstants.PROP_DEFAULT_CATALOG, String.class);

        setPropertyIfNotNull(basicDataSource, componentProperties, DSFConstants.PROP_DEFAULT_READ_ONLY,
                Boolean.class);

        setPropertyIfNotNull(basicDataSource, componentProperties, DSFConstants.PROP_DEFAULT_QUERY_TIMEOUT,
                Integer.class);

        setPropertyIfNotNull(basicDataSource, componentProperties, DSFConstants.PROP_INITIAL_SIZE, int.class);

        setPropertyIfNotNull(basicDataSource, componentProperties, DSFConstants.PROP_LOG_ABANDONED, boolean.class);

        setPropertyIfNotNull(basicDataSource, componentProperties, DSFConstants.PROP_MAX_TOTAL, int.class);

        setPropertyIfNotNull(basicDataSource, componentProperties, DSFConstants.PROP_MAX_IDLE, int.class);

        setPropertyIfNotNull(basicDataSource, componentProperties, DSFConstants.PROP_MAX_OPEN_PREPARED_STATEMENTS,
                int.class);

        setPropertyIfNotNull(basicDataSource, componentProperties, DSFConstants.PROP_MAX_WAIT_MILLIS, long.class);

        setPropertyIfNotNull(basicDataSource, componentProperties, DSFConstants.PROP_MIN_EVICTABLE_IDLE_TIME_MILLIS,
                long.class);

        setPropertyIfNotNull(basicDataSource, componentProperties, DSFConstants.PROP_MIN_IDLE, int.class);

        setPropertyIfNotNull(basicDataSource, componentProperties, DSFConstants.PROP_NUM_TESTS_PER_EVICTION_RUN,
                int.class);

        setPropertyIfNotNull(basicDataSource, componentProperties, DSFConstants.PROP_POOL_PREPARED_STATEMENTS,
                boolean.class);

        setPropertyIfNotNull(basicDataSource, componentProperties, DSFConstants.PROP_REMOVE_ABANDONED_ON_BORROW,
                boolean.class);

        setPropertyIfNotNull(basicDataSource, componentProperties,
                DSFConstants.PROP_REMOVE_ABANDONED_ON_MAINTENANCE, boolean.class);

        setPropertyIfNotNull(basicDataSource, componentProperties, DSFConstants.PROP_REMOVE_ABANDONED_TIMEOUT,
                int.class);

        setPropertyIfNotNull(basicDataSource, componentProperties, DSFConstants.PROP_TEST_ON_BORROW, boolean.class);

        setPropertyIfNotNull(basicDataSource, componentProperties, DSFConstants.PROP_TEST_ON_RETURN, boolean.class);

        setPropertyIfNotNull(basicDataSource, componentProperties, DSFConstants.PROP_TEST_WHILE_IDLE,
                boolean.class);

        setPropertyIfNotNull(basicDataSource, componentProperties,
                DSFConstants.PROP_TIME_BETWEEN_EVICTION_RUNS_MILLIS, long.class);

        setPropertyIfNotNull(basicDataSource, componentProperties, DSFConstants.PROP_VALIDATION_QUERY,
                String.class);

        setPropertyIfNotNull(basicDataSource, componentProperties, DSFConstants.PROP_VALIDATION_QUERY_TIMEOUT,
                int.class);

        setPropertyIfNotNull(basicDataSource, componentProperties, DSFConstants.PROP_LIFO, boolean.class);

        setPropertyIfNotNull(basicDataSource, componentProperties, DSFConstants.PROP_CACHE_STATE, boolean.class);

        setPropertyIfNotNull(basicDataSource, componentProperties, DSFConstants.PROP_TEST_ON_CREATE, boolean.class);

        setPropertyIfNotNull(basicDataSource, componentProperties,
                DSFConstants.PROP_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS, long.class);

        setPropertyIfNotNull(basicDataSource, componentProperties, DSFConstants.PROP_MAX_CONN_LIFETIME_MILLIS,
                long.class);

        setPropertyIfNotNull(basicDataSource, componentProperties, DSFConstants.PROP_JMX_NAME, String.class);

        setPropertyIfNotNull(basicDataSource, componentProperties, DSFConstants.PROP_ENABLE_AUTO_COMMIT_ON_RETURN,
                boolean.class);

        setPropertyIfNotNull(basicDataSource, componentProperties, DSFConstants.PROP_ROLLBACK_ON_RETURN,
                boolean.class);

        setPropertyIfNotNull(basicDataSource, componentProperties, DSFConstants.PROP_ABANDONED_USAGE_TRACKING,
                boolean.class);

        Object connectionInitSqlsObject = componentProperties.get(DSFConstants.PROP_CONNECTION_INIT_SQLS);
        if (connectionInitSqlsObject != null) {
            if (!(connectionInitSqlsObject instanceof Collection)) {
                throw new RuntimeException("Expected type of " + DSFConstants.PROP_CONNECTION_INIT_SQLS
                        + "' is Collection but " + connectionInitSqlsObject.getClass() + " provided");
            }

            @SuppressWarnings("unchecked")
            Collection<String> connectionInitSqls = (Collection<String>) connectionInitSqlsObject;
            basicDataSource.setConnectionInitSqls(connectionInitSqls);
        }

        Object transactionIsolationObject = componentProperties
                .get(DSFConstants.PROP_DEFAULT_TRANSACTION_ISOLATION);
        if (transactionIsolationObject != null) {
            if (DSFConstants.VALUE_READ_COMMITED.equals(transactionIsolationObject)) {
                basicDataSource.setDefaultTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
            } else if (DSFConstants.VALUE_READ_UNCOMMITTED.equals(transactionIsolationObject)) {
                basicDataSource.setDefaultTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
            } else if (DSFConstants.VALUE_REPEATABLE_READ.equals(transactionIsolationObject)) {
                basicDataSource.setDefaultTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
            } else if (DSFConstants.VALUE_SERIALIZABLE.equals(transactionIsolationObject)) {
                basicDataSource.setDefaultTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
            } else if (DSFConstants.VALUE_TRANSACTION_NONE.equals(transactionIsolationObject)) {
                basicDataSource.setDefaultTransactionIsolation(Connection.TRANSACTION_NONE);
            } else {
                throw new RuntimeException("Unknown value '" + transactionIsolationObject
                        + "' for the property key '" + DSFConstants.PROP_DEFAULT_TRANSACTION_ISOLATION
                        + " during datasource configuration.");
            }

        }
    }

    private static String convertPropNameToMethodName(final String propName) {
        return "set" + Character.toUpperCase(propName.charAt(0)) + propName.substring(1);
    }

    private static Class<?> convertToConfigValueType(Class<?> originalType) {
        if (boolean.class.isAssignableFrom(originalType)) {
            return Boolean.class;
        }
        if (int.class.isAssignableFrom(originalType)) {
            return Integer.class;
        }
        if (long.class.isAssignableFrom(originalType)) {
            return Long.class;
        }
        return originalType;
    }

    private static final <T> void setPropertyIfNotNull(final BasicDataSource dataSource,
            final Map<String, Object> properties, String propKey, Class<T> paramType) {

        Object propValueObject = properties.get(propKey);
        propValueObject = convertConfigurationValueIfNecessary(paramType, propValueObject);
        if (propValueObject == null) {
            return;
        }

        Class<?> propType = convertToConfigValueType(paramType);
        if (!propType.isAssignableFrom(propValueObject.getClass())) {
            throw new RuntimeException("Expected type of property '" + propKey + "' is '" + propType
                    + "' while the component property has the type '" + propValueObject.getClass() + "'");
        }

        String methodName = convertPropNameToMethodName(propKey);
        try {
            Method method = dataSource.getClass().getMethod(methodName, paramType);
            method.invoke(dataSource, propValueObject);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException("Error during setting property '" + propKey + "' of datasource", e);
        } catch (SecurityException e) {
            throw new RuntimeException("Error during setting property '" + propKey + "' of datasource", e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException("Error during setting property '" + propKey + "' of datasource", e);
        } catch (IllegalArgumentException e) {
            throw new RuntimeException("Error during setting property '" + propKey + "' of datasource", e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException("Error during setting property '" + propKey + "' of datasource", e);
        }
    }

    private static Object convertConfigurationValueIfNecessary(Class<?> paramType, Object configValue) {
        if (configValue == null || (configValue instanceof String && ((String) configValue).trim().equals(""))) {
            return null;
        }
        if (paramType.isAssignableFrom(Integer.class)) {
            if (configValue instanceof String) {
                return Integer.valueOf((String) configValue);
            }
        } else if (paramType.isAssignableFrom(Long.class)) {
            if (configValue instanceof String) {
                return Long.valueOf((String) configValue);
            }
        } else if (paramType.isAssignableFrom(Boolean.class)) {
            if (configValue instanceof String) {
                if (configValue.equals(DSFConstants.BOOLEAN_OPT_DEFAULT)) {
                    return null;
                }
                return Boolean.valueOf((String) configValue);
            }
        }
        return configValue;
    }

    private Util() {
    }
}