All Downloads are FREE. Search and download functionalities are using the official Maven repository.

au.net.causal.maven.plugins.boxdb.db.DataSourceBuilder Maven / Gradle / Ivy

There is a newer version: 3.3
Show newest version
package au.net.causal.maven.plugins.boxdb.db;

import au.net.causal.maven.plugins.boxdb.JavaRunner;
import org.eclipse.aether.resolution.DependencyResolutionException;

import javax.sql.DataSource;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * Construct and configure a data source.
 */
public class DataSourceBuilder 
{
    private final BoxContext context;
    
    private final List dependencies = new ArrayList<>();
    private final Map dataSourceMethodSetup = new LinkedHashMap<>(); 
    
    private String dataSourceClassName;

    public DataSourceBuilder(BoxContext context)
    {
        this.context = context;
    }

    /**
     * Configures the class name of the data source.
     * 
     * @param dataSourceClassName the fully qualified class name of the data source.
     * 
     * @return this builder.
     */
    public DataSourceBuilder dataSourceClassName(String dataSourceClassName) 
    {
        this.dataSourceClassName = dataSourceClassName;
        return this;
    }

    /**
     * Configures JAR dependencies of the data source.
     * 
     * @param dependencies the dependencies to set.
     *                     
     * @return this builder.
     */
    public DataSourceBuilder dependencies(Collection dependencies)
    {
        this.dependencies.clear();
        this.dependencies.addAll(dependencies);
        return this;
    }
    
    private void configureDataSourceObject(DataSource dataSource, String methodName, Class valueType, Object value)
    throws NoSuchMethodException, InvocationTargetException, IllegalAccessException
    {
        if (value != null)
            dataSource.getClass().getMethod(methodName, valueType).invoke(dataSource, value);
    }

    /**
     * Configures how the data source object will be configured after construction through a method
     * call.
     * 
     * @param methodName the name of the method on the data source to call.  e.g. 'setUrl'.  Must take a single parameter.
     * @param parameterType the parameter type of the method.
     * @param value the value to use when calling the method.
     *              
     * @return this builder.
     */
    public DataSourceBuilder configureDataSource(String methodName, Class parameterType, Object value)
    {
        dataSourceMethodSetup.put(methodName, new DataSourceConfigurationEntry(methodName, parameterType, value));
        return this;
    }

    /**
     * Creates a data source using the builder configuration.
     * 
     * @return the created data source, configured for use.
     * 
     * @throws IOException if an I/O error occurs.
     * @throws BoxDatabaseException if another error occurs creating the data source.
     */
    public DataSource create()
    throws IOException, BoxDatabaseException
    {
        try
        {
            JavaRunner javaRunner = context.createJavaRunner(dataSourceClassName, dependencies);
            Class clientDataSourceClass = javaRunner.makeClass();
            DataSource dataSource = (DataSource)clientDataSourceClass.getConstructor().newInstance();

            for (DataSourceConfigurationEntry entry : dataSourceMethodSetup.values())
            {
                configureDataSourceObject(dataSource, entry.getMethodName(), entry.getParameterType(), entry.getValue());
            }
            
            return dataSource;
        }
        catch (DependencyResolutionException e)
        {
            throw new BoxDatabaseException("Failed to resolve database dependency: " + e, e);
        }
        catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e)
        {
            throw new BoxDatabaseException("Failed to create database data source: " + e, e);
        }
    }

    /**
     * Holds configuration for a single data source method call.
     */
    private static class DataSourceConfigurationEntry
    {
        private final String methodName;
        private final Class parameterType;
        private final Object value;

        public DataSourceConfigurationEntry(String methodName, Class parameterType, Object value) 
        {
            this.methodName = methodName;
            this.parameterType = parameterType;
            this.value = value;
        }

        public String getMethodName() 
        {
            return methodName;
        }

        public Class getParameterType() 
        {
            return parameterType;
        }

        public Object getValue() 
        {
            return value;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy