Package junit.rules.jpa.hibernate

Source Code of junit.rules.jpa.hibernate.HibernatePersistenceContext

/**
* junit-rules: JUnit Rules Library
*
* Copyright (c) 2009-2011 by Alistair A. Israel.
* This software is made available under the terms of the MIT License.
*
* Created Oct 16, 2009
*/
package junit.rules.jpa.hibernate;

import static junit.rules.util.Reflection.invoke;
import static junit.rules.util.Reflection.set;

import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceContext;

import junit.rules.TestFixture;
import junit.rules.dbunit.Fixtures;
import junit.rules.util.Reflection;

import org.apache.derby.jdbc.EmbeddedDriver;
import org.dbunit.JdbcDatabaseTester;
import org.dbunit.dataset.CompositeDataSet;
import org.dbunit.dataset.DataSetException;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.xml.XmlDataSet;
import org.hibernate.ejb.Ejb3Configuration;
import org.junit.runner.Description;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* @author Alistair A. Israel
* @since 0.3
*/
public class HibernatePersistenceContext extends TestFixture implements junit.rules.jpa.PersistenceContext {

    private static final Logger logger = LoggerFactory.getLogger(HibernatePersistenceContext.class);

    private final List<String> fixtureNames = new ArrayList<String>();

    private EntityManagerFactory entityManagerFactory;

    private EntityManager entityManager;

    private JdbcDatabaseTester jdbcDatabaseTester;

    /**
     * @param classes
     *        the annotated classes
     */
    public HibernatePersistenceContext(final Class<?>... classes) {
        final Ejb3Configuration cfg = DerbyHibernateUtil.configureDerbyHibernateJpa(classes);
        entityManagerFactory = cfg.buildEntityManagerFactory();
        entityManager = entityManagerFactory.createEntityManager();
    }

    /**
     * @param object
     *        an object to which we will apply EJB 3.0 style @PersistenceContext and @PostConstruct handling
     */
    @Override
    public final void injectAndPostConstruct(final Object object) {
        final Class<? extends Object> clazz = object.getClass();
        for (final Field field : clazz.getDeclaredFields()) {
            if (field.isAnnotationPresent(PersistenceContext.class)) {
                final Class<?> type = field.getType();
                if (type.equals(EntityManager.class)) {
                    set(field).of(object).to(entityManager);
                } else {
                    logger.warn("Found field \"{}\" annotated with @PersistenceContext but is of type {}", field
                            .getName(), type.getName());
                }
            }
        }

        for (final Method method : clazz.getDeclaredMethods()) {
            if (method.isAnnotationPresent(PostConstruct.class)) {
                final int nParameters = method.getParameterTypes().length;
                if (nParameters == 0) {
                    invoke(method).on(object);
                } else {
                    logger.warn("Found method \"{}\" annotated @PostConstruct "
                            + "but don't know how to invoke with {} parameters", method.getName(), nParameters);
                }
            }
        }
    }

    /**
     * {@inheritDoc}
     *
     * @see junit.rules.TestFixture#inspect(org.junit.runner.Description)
     */
    @Override
    protected final void inspect(final Description description) {
        final Class<? extends Object> testClass = description.getTestClass();
        if (testClass.isAnnotationPresent(Fixtures.class)) {
            addFixturesFromAnnotation(testClass.getAnnotation(Fixtures.class));
        }
        final Method method = Reflection.quietlyGetMethod(testClass, description.getMethodName());
        if (method.isAnnotationPresent(Fixtures.class)) {
            addFixturesFromAnnotation(method.getAnnotation(Fixtures.class));
        }
    }

    /**
     * @param annotation
     *        the {@link Fixtures} annotation
     */
    private void addFixturesFromAnnotation(final Fixtures annotation) {
        for (final String fixtureName : annotation.value()) {
            fixtureNames.add(fixtureName);
        }
    }

    /**
     * {@inheritDoc}
     *
     * @see junit.rules.TestFixture#setUp()
     */
    @Override
    protected final void setUp() throws Throwable {
        jdbcDatabaseTester = new JdbcDatabaseTester(EmbeddedDriver.class.getName(), DerbyHibernateUtil.JDBC_DERBY_URL);
        if (fixtureNames.isEmpty()) {
            logger.warn("No fixtures to load! Specify fixtures using @Fixtures.");
        } else {
            loadFixtures();
        }

        jdbcDatabaseTester.onSetup();
    }

    /**
     * @throws DataSetException
     *         on any exception
     */
    private void loadFixtures() throws DataSetException {
        final List<IDataSet> dataSets = new ArrayList<IDataSet>();

        for (final String fixtureName : fixtureNames) {
            logger.trace("Attempting to load database fixture \"" + fixtureName + "\"");
            final IDataSet dataSet = attemptToLoadFixture(fixtureName);
            if (dataSet != null) {
                dataSets.add(dataSet);
            }
        }

        if (dataSets.isEmpty()) {
            logger.warn("Found 0 data sets!");
        } else {
            final CompositeDataSet compositeDataSet = new CompositeDataSet(dataSets.toArray(new IDataSet[dataSets
                    .size()]));
            jdbcDatabaseTester.setDataSet(compositeDataSet);
        }
    }

    /**
     * @param fixtureName
     *        the fixture name
     * @return {@link IDataSet}
     */
    private IDataSet attemptToLoadFixture(final String fixtureName) {
        IDataSet dataSet = null;

        try {
            final InputStream in = ClassLoader.getSystemResourceAsStream(fixtureName);
            try {
                if (in != null) {
                    if (fixtureName.endsWith(".xml")) {
                        dataSet = new XmlDataSet(in);
                    }
                }
            } finally {
                in.close();
            }
        } catch (final Exception e) {
            logger.warn(e.getMessage(), e);
        }
        return dataSet;
    }

    /**
     * {@inheritDoc}
     *
     * @see junit.rules.TestFixture#tearDown()
     */
    @Override
    protected final void tearDown() throws Throwable {
        jdbcDatabaseTester.onTearDown();
        entityManagerFactory.close();
    }

    /**
     * @return {@link EntityManager}
     * @see javax.persistence.EntityManagerFactory#createEntityManager()
     */
    public final EntityManager getEntityManager() {
        return this.entityManager;
    }

}
TOP

Related Classes of junit.rules.jpa.hibernate.HibernatePersistenceContext

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.