com.excilys.ebi.spring.dbunit.test.TestConfigurationProcessor.java Source code

Java tutorial

Introduction

Here is the source code for com.excilys.ebi.spring.dbunit.test.TestConfigurationProcessor.java

Source

/**
 * Copyright 2011-2012 eBusiness Information, Groupe Excilys (www.excilys.com)
 *
 * Licensed 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 com.excilys.ebi.spring.dbunit.test;

import static com.excilys.ebi.spring.dbunit.config.DataSetConfiguration.newDataSetConfiguration;
import static com.excilys.ebi.spring.dbunit.config.DataSetFormatOptions.newFormatOptions;
import static com.excilys.ebi.spring.dbunit.config.ExpectedDataSetConfiguration.newExpectedDataSetConfiguration;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.Map;

import org.dbunit.DatabaseUnitException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.test.context.TestContext;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import com.excilys.ebi.spring.dbunit.ConfigurationProcessor;
import com.excilys.ebi.spring.dbunit.config.DataSetConfiguration;
import com.excilys.ebi.spring.dbunit.config.ExpectedDataSetConfiguration;
import com.excilys.ebi.spring.dbunit.test.conventions.ConfigurationConventions;
import com.excilys.ebi.spring.dbunit.test.conventions.DefaultConfigurationConventions;

/**
 * @author <a href="mailto:slandelle@excilys.com">Stephane LANDELLE</a>
 */
public class TestConfigurationProcessor implements ConfigurationProcessor<TestContext> {

    /**
     * The logger
     */
    protected final Logger LOGGER = LoggerFactory.getLogger(getClass());

    private final ConfigurationConventions conventions;

    private boolean hasWarnedAboutNoDataSet;

    private boolean hasWarnedAboutNoExpectedDataSet;

    /**
     * A configuration cache used between setup and teardown
     */
    protected final Map<Method, DataSetConfiguration> configurationCache = Collections
            .synchronizedMap(new IdentityHashMap<Method, DataSetConfiguration>());

    protected final Map<Method, ExpectedDataSetConfiguration> expectedConfigurationCache = Collections
            .synchronizedMap(new IdentityHashMap<Method, ExpectedDataSetConfiguration>());

    /**
     * Configure with default conventions
     */
    public TestConfigurationProcessor() {
        conventions = new DefaultConfigurationConventions();
    }

    /**
     * Configure with custom conventions
     * 
     * @param conventions
     */
    public TestConfigurationProcessor(ConfigurationConventions conventions) {
        this.conventions = conventions;
    }

    /**
     * @param testContext the context
     * @return the configuration
     * @throws IOException I/O failureDataSet
     * @throws DatabaseUnitException DBUnit failure
     */
    @Override
    public DataSetConfiguration getConfiguration(TestContext testContext) {

        DataSetConfiguration configuration = configurationCache.get(testContext.getTestMethod());

        if (configuration == null) {
            // no cached configuration --> instancing it
            DataSet dataSetAnnotation = findAnnotation(testContext.getTestMethod(), testContext.getTestClass(),
                    DataSet.class);

            if (dataSetAnnotation != null) {
                configuration = buildConfiguration(dataSetAnnotation, testContext);
                configurationCache.put(testContext.getTestMethod(), configuration);

            } else {
                if (!hasWarnedAboutNoDataSet) {
                    LOGGER.info(
                            "DataSetTestExecutionListener was configured but without any DataSet or DataSets! DataSet features are disabled");
                    hasWarnedAboutNoDataSet = true;
                }
            }
        }

        return configuration;
    }

    /**
     * @param testContext the context
     * @return the configuration
     * @throws IOException I/O failureDataSet
     * @throws DatabaseUnitException DBUnit failure
     */
    @Override
    public ExpectedDataSetConfiguration getExpectedConfiguration(TestContext testContext) {

        ExpectedDataSetConfiguration configuration = expectedConfigurationCache.get(testContext.getTestMethod());

        if (configuration == null) {
            // no cached configuration --> instancing it
            ExpectedDataSet expectedDataSetAnnotation = findAnnotation(testContext.getTestMethod(),
                    testContext.getTestClass(), ExpectedDataSet.class);

            if (expectedDataSetAnnotation != null) {
                configuration = buildExpectedConfiguration(expectedDataSetAnnotation, testContext);
                expectedConfigurationCache.put(testContext.getTestMethod(), configuration);

            } else {
                if (!hasWarnedAboutNoExpectedDataSet) {
                    LOGGER.info(
                            "DataSetTestExecutionListener was configured but without any ExpectedDataSet or ExpectedDataSets! ExpectedDataSet features are disabled");
                    hasWarnedAboutNoExpectedDataSet = true;
                }
            }
        }

        return configuration;
    }

    protected final DataSetConfiguration buildConfiguration(DataSet annotation, TestContext testContext) {

        String[] dataSetResourceLocations = getResourceLocationsByConventions(annotation, testContext);

        return newDataSetConfiguration()/**/
                .withBatchedStatements(annotation.batchedStatements())/**/
                .withBatchSize(annotation.batchSize())/**/
                .withDataSetResourceLocations(dataSetResourceLocations)/**/
                .withDataSourceSpringName(
                        StringUtils.hasText(annotation.dataSourceSpringName()) ? annotation.dataSourceSpringName()
                                : null)/**/
                .withDbType(annotation.dbType())/**/
                .withEscapePattern(annotation.escapePattern())/**/
                .withFetchSize(annotation.fetchSize())/**/
                .withFormat(annotation.format())/**/
                .withFormatOptions(newFormatOptions()//
                        .withColumnSensing(annotation.columnSensing())//
                        .withDtdLocation(
                                StringUtils.hasText(annotation.dtdLocation()) ? annotation.dtdLocation() : null)//
                        .withDtdMetadata(annotation.dtdMetadata())//
                        .withCaseSensitiveTableNames(annotation.caseSensitiveTableNames())//
                        .build())/**/
                .withSetUpOp(annotation.setUpOperation())/**/
                .withSkipOracleRecycleBinTables(annotation.skipOracleRecycleBinTables())/**/
                .withTearDownOp(annotation.tearDownOperation())/**/
                .withTableType(annotation.tableType())/**/
                .withQualifiedTableNames(annotation.qualifiedTableNames())/**/
                .withSchema(annotation.schema())/**/
                .withDecorators(annotation.decorators()).build();
    }

    protected final ExpectedDataSetConfiguration buildExpectedConfiguration(ExpectedDataSet annotation,
            TestContext testContext) {

        String[] dataSetResourceLocations = getExpectedResourceLocationsByConventions(annotation, testContext);

        return newExpectedDataSetConfiguration()/**/
                .withDataSetResourceLocations(dataSetResourceLocations)/**/
                .withColumnsToIgnore(annotation.columnsToIgnore())/**/
                .withDataSourceSpringName(
                        StringUtils.hasText(annotation.dataSourceSpringName()) ? annotation.dataSourceSpringName()
                                : null)/**/
                .withDbType(annotation.dbType())/**/
                .withEscapePattern(annotation.escapePattern())/**/
                .withFormat(annotation.format())/**/
                .withFormatOptions(newFormatOptions()//
                        .withColumnSensing(annotation.columnSensing())//
                        .withDtdLocation(
                                StringUtils.hasText(annotation.dtdLocation()) ? annotation.dtdLocation() : null)//
                        .withDtdMetadata(annotation.dtdMetadata())//
                        .withCaseSensitiveTableNames(annotation.caseSensitiveTableNames())//
                        .build())/**/
                .withTableType(annotation.tableType())/**/
                .withQualifiedTableNames(annotation.qualifiedTableNames())/**/
                .withSchema(annotation.schema())/**/
                .build();
    }

    /**
     * @param annotation the DataSet annotation
     * @param testContext the context
     * @return an String array, containing the locations of resources
     * @throws IOException I/O failure
     */
    private String[] getResourceLocationsByConventions(DataSet annotation, TestContext testContext) {

        String[] valueLocations = annotation.value();
        String[] locations = annotation.locations();
        if (!ObjectUtils.isEmpty(valueLocations)) {
            locations = valueLocations;
        }

        return conventions.getDataSetResourcesLocations(testContext.getTestClass(), locations);
    }

    /**
     * @param annotation the ExpectedDataSet annotation
     * @param testContext the context
     * @return an String array, containing the locations of resources
     * @throws IOException I/O failure
     */
    private String[] getExpectedResourceLocationsByConventions(ExpectedDataSet annotation,
            TestContext testContext) {

        String[] valueLocations = annotation.value();
        String[] locations = annotation.locations();
        if (!ObjectUtils.isEmpty(valueLocations)) {
            locations = valueLocations;
        }

        return conventions.getExpectedDataSetResourcesLocations(testContext.getTestClass(), locations);
    }

    /**
     * @param method the test method
     * @param clazz the test class
     * @return the {@link DataSet} at method level if found, otherwise at class level
     */
    private <A extends Annotation> A findAnnotation(Method method, Class<?> clazz, Class<A> annotationType) {
        A annotation = AnnotationUtils.findAnnotation(method, annotationType);
        return annotation == null ? annotation = AnnotationUtils.findAnnotation(clazz, annotationType) : annotation;
    }
}