org.deegree.db.datasource.DataSourceInitializer.java Source code

Java tutorial

Introduction

Here is the source code for org.deegree.db.datasource.DataSourceInitializer.java

Source

/*----------------------------------------------------------------------------
 This file is part of deegree, http://deegree.org/
 Copyright (C) 2001-2014 by:
 - Department of Geography, University of Bonn -
 and
 - lat/lon GmbH -
 and
 - Occam Labs UG (haftungsbeschrnkt) -
    
 This library 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 2.1 of the License, or (at your option)
 any later version.
 This library 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 this library; if not, write to the Free Software Foundation, Inc.,
 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    
 Contact information:
    
 lat/lon GmbH
 Aennchenstr. 19, 53177 Bonn
 Germany
 http://lat-lon.de/
    
 Department of Geography, University of Bonn
 Prof. Dr. Klaus Greve
 Postfach 1147, 53001 Bonn
 Germany
 http://www.geographie.uni-bonn.de/deegree/
    
 Occam Labs UG (haftungsbeschrnkt)
 Godesberger Allee 139, 53175 Bonn
 Germany
    
 e-mail: info@deegree.org
 ----------------------------------------------------------------------------*/
package org.deegree.db.datasource;

import static org.slf4j.LoggerFactory.getLogger;

import java.lang.reflect.InvocationTargetException;
import java.util.List;

import javax.sql.DataSource;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConstructorUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.MethodUtils;
import org.deegree.db.datasource.jaxb.DataSourceConnectionProvider;
import org.deegree.db.datasource.jaxb.DataSourceConnectionProvider.DataSource.Argument;
import org.slf4j.Logger;

/**
 * Creates/retrieves {@link DataSource} instances and applies configuration properties via setters.
 * 
 * @author <a href="mailto:schneider@occamlabs.de">Markus Schneider</a>
 * 
 * @since 3.4
 */
class DataSourceInitializer {

    private static final Logger LOG = getLogger(DataSourceInitializer.class);

    private final ClassLoader classLoader;

    /**
     * Creates a new {@link DataSourceInitializer} instance.
     * 
     * @param classLoader
     *            class loader to be used, can be <code>null</code> (use default class loader)
     */
    DataSourceInitializer(final ClassLoader classLoader) {
        this.classLoader = classLoader;
    }

    /**
     * Creates/retrieves a {@link DataSource} instance and applies configuration properties via setters.
     * 
     * @param config
     *            JAXB configuration, must not be <code>null</code>
     * @return configured DataSource instance, can be <code>null</code> (initialization failed)
     * @throws InstantiationException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     * @throws NoSuchMethodException
     * @throws ClassNotFoundException
     */
    DataSource getConfiguredDataSource(DataSourceConnectionProvider config) throws ClassNotFoundException,
            NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        DataSource ds = getDataSourceInstance(config.getDataSource());
        for (DataSourceConnectionProvider.Property property : config.getProperty()) {
            setProperty(ds, property);
        }
        return ds;
    }

    @SuppressWarnings("unchecked")
    DataSource getDataSourceInstance(DataSourceConnectionProvider.DataSource config) throws ClassNotFoundException,
            NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        DataSource ds = null;
        final Class<?> klass = getClass(config.getJavaClass());
        if (config.getFactoryMethod() != null) {
            ds = invokeStaticFactoryMethod(klass, config.getFactoryMethod(), config.getArgument());
        } else {
            ds = invokeDataSourceConstructor((Class<DataSource>) klass, config.getArgument());
        }
        return ds;
    }

    private DataSource invokeDataSourceConstructor(Class<DataSource> dsClass,
            List<DataSourceConnectionProvider.DataSource.Argument> arguments) throws NoSuchMethodException,
            IllegalAccessException, InvocationTargetException, InstantiationException, ClassNotFoundException {
        final Object[] javaArgs = getJavaArgs(arguments);
        return (DataSource) ConstructorUtils.invokeConstructor(dsClass, javaArgs);
    }

    private DataSource invokeStaticFactoryMethod(Class<?> factoryClass, String methodName,
            List<DataSourceConnectionProvider.DataSource.Argument> arguments) throws NoSuchMethodException,
            IllegalAccessException, InvocationTargetException, ClassNotFoundException {
        final Object[] javaArgs = getJavaArgs(arguments);
        return (DataSource) MethodUtils.invokeStaticMethod(factoryClass, methodName, javaArgs);
    }

    private Object[] getJavaArgs(List<Argument> arguments) throws ClassNotFoundException {
        final Object[] args = new Object[arguments.size()];
        for (int i = 0; i < args.length; i++) {
            if (arguments.get(i) != null) {
                args[i] = getJavaArg(arguments.get(i));
            }
        }
        return args;
    }

    Object getJavaArg(Argument argument) throws ClassNotFoundException {
        Class<?> parameterClass = null;
        try {
            parameterClass = getClass(argument.getJavaClass());
            final Class<?> primitiveClass = MethodUtils.getPrimitiveType(parameterClass);
            if (primitiveClass != null) {
                parameterClass = primitiveClass;
            }
        } catch (ClassNotFoundException e) {
            throw e;
        }
        return ConvertUtils.convert(argument.getValue(), parameterClass);
    }

    void setProperty(final DataSource ds, final DataSourceConnectionProvider.Property property) {
        final String name = property.getName();
        final String value = property.getValue();
        try {
            BeanUtils.setProperty(ds, name, value);
        } catch (Exception e) {
            String msg = "Error setting DataSource property '" + name + "': " + e.getLocalizedMessage();
            LOG.warn(msg);
        }
    }

    private Class<?> getClass(String javaClass) throws ClassNotFoundException {
        if (classLoader == null) {
            return Class.forName(javaClass);
        }
        return classLoader.loadClass(javaClass);
    }
}