org.eclipse.emf.teneo.hibernate.test.stores.HibernateTestStore.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.emf.teneo.hibernate.test.stores.HibernateTestStore.java

Source

/**
 * <copyright> Copyright (c) 2005, 2006, 2007, 2008 Springsite BV (The Netherlands) and others All rights
 * reserved. This program and the accompanying materials are made available under the terms of the
 * Eclipse Public License v1.0 which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html Contributors: Martin Taal </copyright> $Id:
 * HibernateTestStore.java,v 1.16 2007/03/29 15:00:21 mtaal Exp $
 */

package org.eclipse.emf.teneo.hibernate.test.stores;

import java.io.Serializable;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import javax.persistence.EntityManager;

import junit.framework.TestCase;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.teneo.DataStore;
import org.eclipse.emf.teneo.PackageRegistryProvider;
import org.eclipse.emf.teneo.PersistenceOptions;
import org.eclipse.emf.teneo.annotations.pannotation.InheritanceType;
import org.eclipse.emf.teneo.ecore.EModelResolver;
import org.eclipse.emf.teneo.extension.ExtensionManager;
import org.eclipse.emf.teneo.hibernate.HbDataStore;
import org.eclipse.emf.teneo.hibernate.HbEntityDataStore;
import org.eclipse.emf.teneo.hibernate.HbHelper;
import org.eclipse.emf.teneo.hibernate.HbSessionDataStore;
import org.eclipse.emf.teneo.hibernate.SessionWrapper;
import org.eclipse.emf.teneo.hibernate.resource.HbResource;
import org.eclipse.emf.teneo.hibernate.resource.HibernateResource;
import org.eclipse.emf.teneo.hibernate.test.stores.adapters.HibernateTestDBAdapter;
import org.eclipse.emf.teneo.mapping.strategy.EntityNameStrategy;
import org.eclipse.emf.teneo.test.stores.AbstractTestStore;
import org.eclipse.emf.teneo.test.stores.HsqldbTestDatabaseAdapter;
import org.eclipse.emf.teneo.util.AssertUtil;
import org.eclipse.emf.teneo.util.EcoreDataTypes;
import org.hibernate.FlushMode;
import org.hibernate.Session;
import org.hibernate.cfg.Environment;

/**
 * The hibernate test store encapsulates the datastore actions to a hibernate
 * store.
 * 
 * @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
 * @version $Revision: 1.42 $
 */
public class HibernateTestStore extends AbstractTestStore {
    /** The logger */
    private static Log log = LogFactory.getLog(HibernateTestStore.class);

    public static final String USE_DATASTORE_REGISTRY = "useDataStoreRegistry";
    public static final String EPACKAGE_INIT_MODE = "epackageinitmode";
    public static final String EPACKAGE_INIT_MODE_SPECIFIED = "specified";
    public static final String SPECIFIED_EPACKAGES = "specified_epackages";
    public static final String EPACKAGE_INIT_MODE_CLASS = "class";
    public static final String EPACKAGE_INIT_MODE_ECORE = "ecore";
    public static final String EPACKAGE_INIT_MODE_ECORE_VALUE = "ecorefile";

    /** The emf resource set used during the test */
    protected ResourceSet resourceSet;

    /** The EMFDatastore */
    private HbDataStore emfDataStore;

    /** The persistence manager for this test store */
    private SessionWrapper sessionWrapper;

    /** The props used to create it all */
    private final Properties props;

    /** the used epackages */
    private EPackage[] epackages;

    /** The inheritance logic followed */
    private final InheritanceType inheritanceType;

    /** Do ejb3 */
    private final boolean ejb3;

    /** The extensionManager */
    private final ExtensionManager extensionManager;

    /**
     * Constructor for emf test cases
     */
    public HibernateTestStore(HibernateTestDBAdapter adapter, EPackage[] epackages, Properties props,
            InheritanceType inheritanceType, boolean ejb3, ExtensionManager extensionManager) {
        super(adapter);
        this.props = props;
        this.epackages = epackages;
        this.inheritanceType = inheritanceType;
        this.ejb3 = ejb3;
        this.extensionManager = extensionManager;
        init();
    }

    /** Creates/sets the persistence manager */
    private void init() {
        final HibernateTestDBAdapter adapter = (HibernateTestDBAdapter) getDatabaseAdapter();

        props.setProperty(PersistenceOptions.INHERITANCE_MAPPING, inheritanceType.getName());

        for (EPackage element : epackages) {
            log.debug("Creating HibernateTeststore for " + element.getName() + " adapter "
                    + adapter.getClass().getName());
        }

        setDataStore();

        log.debug("HibernateTestStore initialized");
        resourceSet = new ResourceSetImpl();
    }

    /** Creates a Hibernate property set from the databaseadapter */
    private Properties getHibernateProperties(HibernateTestDBAdapter dbadapter) {
        final Properties props = new Properties();
        props.setProperty(Environment.DRIVER, dbadapter.getDbDriver());
        props.setProperty(Environment.USER, dbadapter.getDbUser());
        props.setProperty(Environment.URL, dbadapter.getDbUrl());
        props.setProperty(Environment.PASS, dbadapter.getDbPwd());
        props.setProperty(Environment.DIALECT, dbadapter.getDialect());
        props.setProperty(Environment.BYTECODE_PROVIDER, "cglib");
        return props;
    }

    /** Sets the emfDataStore */
    private void setDataStore() {
        // currentTimeMillis is added to make it unique
        if (ejb3) {
            emfDataStore = new HbEntityDataStore(); // (HbDataStore)HbHelper.INSTANCE.
            // createRegisterDataStore
            // (getDatabaseAdapter().getDbName());
        } else {
            emfDataStore = HbHelper.INSTANCE.createRegisterDataStore(getDatabaseAdapter().getDbName());
        }
        emfDataStore.setExtensionManager(extensionManager);
        emfDataStore.setName(getDatabaseAdapter().getDbName());
        if (props.getProperty(EPACKAGE_INIT_MODE) != null) {
            if (props.getProperty(EPACKAGE_INIT_MODE).compareTo(EPACKAGE_INIT_MODE_SPECIFIED) == 0) {
                final List<String> clss = Collections.singletonList(props.getProperty(SPECIFIED_EPACKAGES));
                emfDataStore.setEPackageClasses(clss);
            } else if (props.getProperty(EPACKAGE_INIT_MODE).compareTo(EPACKAGE_INIT_MODE_CLASS) == 0) {
                final List<String> clss = new ArrayList<String>();
                for (EPackage epackage : epackages) {
                    clss.add(epackage.getClass().getName());
                }
                emfDataStore.setEPackageClasses(clss);
            } else if (props.getProperty(EPACKAGE_INIT_MODE).compareTo(EPACKAGE_INIT_MODE_ECORE) == 0) {
                final List<String> ecores = new ArrayList<String>();
                ecores.add(props.getProperty(EPACKAGE_INIT_MODE_ECORE_VALUE));
                emfDataStore.setEPackageFiles(ecores);
            }
        } else {
            emfDataStore.setEPackages(epackages);
        }
        // any value is fine
        if (props.getProperty(USE_DATASTORE_REGISTRY) != null) {
            PackageRegistryProvider.getInstance().setPackageRegistry(null);
            emfDataStore.setPackageRegistry(EPackage.Registry.INSTANCE);
        } else {
            PackageRegistryProvider.getInstance().setPackageRegistry(EPackage.Registry.INSTANCE);
        }

        // set both hibernate and persistence props as we do not know the
        // difference right now
        props.putAll(getHibernateProperties((HibernateTestDBAdapter) getDatabaseAdapter()));

        if (!props.containsKey(PersistenceOptions.JOIN_TABLE_FOR_NON_CONTAINED_ASSOCIATIONS)) {
            props.setProperty(PersistenceOptions.JOIN_TABLE_FOR_NON_CONTAINED_ASSOCIATIONS, "false");
        }

        // do a special trick for hsqldb, because hsqldb expects all identifiers
        // to be
        // escaped or otherwise uppercases them, so uppercase everything
        // automatically
        if (getDatabaseAdapter() instanceof HsqldbTestDatabaseAdapter
                && !props.containsKey(PersistenceOptions.SQL_CASE_STRATEGY)) {
            props.setProperty(PersistenceOptions.SQL_CASE_STRATEGY, "uppercase");
        }

        if (isEntityManagerStore()) {
            props.setProperty(PersistenceOptions.ALSO_MAP_AS_CLASS, "true");
        }

        emfDataStore.setDataStoreProperties(props);
        emfDataStore.initialize();
        if (sessionWrapper != null) {
            refresh();
        } else {
            sessionWrapper = emfDataStore.createSessionWrapper();
            sessionWrapper.getHibernateSession().setFlushMode(FlushMode.COMMIT);
        }
    }

    /** Returns the mapping xml */
    @Override
    public String getMappingXML() {
        return emfDataStore.getMappingXML();
    }

    /** Add an epackage to the list of epackages */
    public void addEPackage(EPackage epackage) {
        EPackage[] newEPacks = new EPackage[epackages.length + 1];
        newEPacks[0] = epackage;
        for (int i = 0; i < epackages.length; i++) {
            newEPacks[i + 1] = epackages[i];
        }
        epackages = newEPacks;
    }

    /** Update the database schema */
    public void updateSchema() {
        // clear the configuration
        if (emfDataStore instanceof HbSessionDataStore) {
            ((HbSessionDataStore) emfDataStore).setConfiguration(null);
        } else {
            ((HbEntityDataStore) emfDataStore).setConfiguration(null);
        }
        emfDataStore.setEPackages(epackages);
        emfDataStore.initialize();
        refresh();
    }

    /** Creates a new persistence manager, actually to clear the cache */
    public void refresh() {

        if (sessionWrapper.isTransactionActive()) {
            sessionWrapper.rollbackTransaction();
        }
        sessionWrapper.close();
        sessionWrapper = emfDataStore.createSessionWrapper();
        sessionWrapper.getHibernateSession().setFlushMode(FlushMode.COMMIT);
    }

    /** Returns session */
    public Session getSession() {
        final Object obj = sessionWrapper.getSession();
        if (obj instanceof Session) {
            return (Session) obj;
        } else {
            return (Session) ((EntityManager) obj).getDelegate();
        }
    }

    /** Return the sessionwrapper */
    public SessionWrapper getSessionWrapper() {
        return sessionWrapper;
    }

    /** Return the entityManager */
    public EntityManager getEntityManager() {
        return (EntityManager) sessionWrapper.getSession();
    }

    /** Returns a new session */
    public Session getNewSession() {
        return emfDataStore.getSessionFactory().openSession();
    }

    /** Begin transaction */
    public void beginTransaction() {
        sessionWrapper.beginTransaction();
    }

    /** Commit transaction */
    public void commitTransaction() {
        sessionWrapper.commitTransaction();
        refresh();
    }

    /** Rollback transaction */
    public void rollbackTransaction() {
        if (sessionWrapper.isTransactionActive()) {
            sessionWrapper.rollbackTransaction();
        }
        refresh();
    }

    /** Store/Makepersistent */
    public void store(Object object) {
        sessionWrapper.saveOrUpdate(object);
    }

    /** Deletes an object */
    public void deleteObject(Object obj) {
        sessionWrapper.delete(obj);
    }

    /** Test if a delete fails */
    public void checkDeleteFails(Class<?> clazz) {
        checkDelete(clazz, false); // replace class is called in
        // checkDelete/getObjects
    }

    /** Test if a delete fails */
    public void checkDeleteSucceeds(Class<?> clazz) {
        checkDelete(clazz, true); // replace class is called in
        // CheckDelete/getObjects
    }

    /** Query for a class using a field and value pair */
    public List<?> query(Class<?> clazz, String field, String value, int checkCount) {
        // final Class interf = replaceClass(clazz);
        if (sessionWrapper.isEJB3EntityManager()) {
            return query("select o from " + getEntityName(clazz) + " o where o." + field + "=\'" + value + "\'",
                    checkCount);
        } else {
            return query("from " + getEntityName(clazz) + " where " + field + "=\'" + value + "\'", checkCount);
        }
    }

    /** Queries for an object */
    @Override
    public List<?> query(Object query) {
        return query(query, -1);
    }

    /** Queries for an object and checks the number */
    public List<?> query(Object query, int checkCount) {
        final String qryStr = (String) query;
        final List<?> result = sessionWrapper.executeQuery(qryStr);

        if (checkCount > 0) {
            TestCase.assertTrue("Expected " + checkCount + " object(s) for this query but there are "
                    + result.size() + " object(s) for the query " + qryStr, result.size() == checkCount);
        }
        return result;
    }

    /** Test if a delete fails */
    private void checkDelete(Class<?> clazz, boolean shouldSucceed) {
        beginTransaction();
        final List<?> l = getObjects(clazz); // replace class is called in
        // getObjects
        try {
            for (int i = 0; i < l.size(); i++) {
                sessionWrapper.delete(l.get(i));
            }
            commitTransaction();
            TestCase.assertTrue(
                    "The objects of class: " + clazz.getName() + " was deleted while this should not be possible",
                    shouldSucceed);
        } catch (Exception e) {
            TestCase.assertTrue(
                    "The objects of class: " + clazz.getName() + " was not deleted while this should be possible",
                    !shouldSucceed);
            if (sessionWrapper.isTransactionActive()) {
                rollbackTransaction();
            }
            refresh();
        }
    }

    /**
     * Return an object of a certain class, there should only be one in the
     * databases
     */
    @Override
    @SuppressWarnings("unchecked")
    public <T> T getObject(Class<T> clazz) {
        List<?> l = getObjects(clazz); // replace class is called in getObjects
        TestCase.assertTrue("There are " + l.size()
                + " object(s) of this class in the datastore, 1 was expected, class: " + clazz.getName(),
                l.size() == 1);
        return (T) l.get(0);
    }

    public Object getObject(String entityName, Serializable id) {
        return sessionWrapper.get(entityName, id);
    }

    /** Returns a list of object of a certain class */
    @SuppressWarnings("unchecked")
    public <T> List<T> getObjects(Class<T> clazz) {
        // final Class concrete = replaceClass(clazz);
        if (sessionWrapper.isEJB3EntityManager()) {
            return (List<T>) sessionWrapper.executeQuery("select o from " + getEntityName(clazz) + " o");
        } else {
            return (List<T>) sessionWrapper.executeQuery("FROM " + getEntityName(clazz));
        }
    }

    /** Test the amount of objects of a certain class in the db */
    @Override
    public void checkNumber(Class<?> clazz, int count) {
        final List<?> list = getObjects(clazz);
        TestCase.assertTrue("Expected " + count + " object(s) but there are " + list.size()
                + " object(s) of this class in the datastore: " + clazz.getName(), list.size() == count);
    }

    /** Flushes all updates to the underlying datastore */
    public void flush() {
        sessionWrapper.flush();
    }

    /** Is called just before the test */
    @Override
    public void setUp() {

    }

    /**
     * Is called just after the test, the dropStore parameter can be used to
     * prevent dropping the database when an error
     */
    @Override
    public void doTearDown() {
        AssertUtil.assertTrue("Transaction is still active at end of test", !sessionWrapper.isTransactionActive());

        if (sessionWrapper.isTransactionActive()) {
            rollbackTransaction();
        }

        sessionWrapper.close();

        HbHelper.INSTANCE.closeAll();

        if (!donotDrop) {
            dropDatabase();
        }
    }

    /** Returns true if the transaction is still active */
    public boolean transactionActive() {
        return sessionWrapper.isTransactionActive();
    }

    /** Base method to get a resource belonging to the pmf of this test case */
    @Override
    public Resource getResource() {
        return getResource(null);
    }

    /** Base method to get a resource belonging to the session of this test case */
    public Resource getResource(String extraParam) {
        String uriStr = "hibernate://?" + HibernateResource.DS_NAME_PARAM + "=" + emfDataStore.getName();

        if (extraParam != null) {
            uriStr += "&" + extraParam;
        }
        final URI uri = URI.createURI(uriStr);
        log.debug("Getting resource using uri: " + uri.toString());
        final Resource res = resourceSet.createResource(uri);
        assert (res instanceof HbResource);
        return res;
    }

    /**
     * Replaces a passed EMF Interface by its concrete class private Class
     * replaceClass(Class interfaze) { if (!interfaze.isInterface()) return
     * interfaze; if (!EObject.class.isAssignableFrom(interfaze)) return
     * interfaze; return HibernateHelper.INSTANCE.getInstanceClass(interfaze); }
     */

    /** Gets the referedto list */
    public Object[] getCrossReferencers(EObject obj, boolean container) {
        if (container) {
            return new Object[] { obj.eContainer() };
            // final EObject eobj =
            // ((HbDataStore)emfDataStore).getContainer(session, obj);
            // if (eobj == null)
            // {
            // return new EObject[0];
            // }
            // return new EObject[] {eobj};
        } else {
            return emfDataStore.getCrossReferencers(sessionWrapper, obj);
        }
    }

    /** Gets the container list */
    @Override
    public boolean setContainer(EObject obj) {
        return true;
    }

    /** Refreshes the object from the datastore */
    public void refresh(Object obj) {
        sessionWrapper.refresh(obj);
    }

    public Object merge(Object object) {
        return sessionWrapper.merge(object);
    }

    /** Check inheritance strategy */
    public boolean isInheritanceStrategy(Class<?> cls, InheritanceType strategy) {
        return sessionWrapper.isInheritanceStrategy(cls, strategy);
    }

    /** Gets a database connection using the adapters connection info */
    public Connection getConnection() {
        return getDatabaseAdapter().getConnection();
    }

    /** Returns the query name to use for the instance */
    private String getEntityName(Class<?> clazz) {
        final EModelResolver emodelResolver = EModelResolver.instance();
        final EClass eclass = emodelResolver.getEClass(clazz);
        return getDataStore().getExtensionManager().getExtension(EntityNameStrategy.class).toEntityName(eclass);
    }

    /**
     * @return the emfDataStore
     */
    public HbDataStore getEmfDataStore() {
        return emfDataStore;
    }

    /** Return the datastore */
    public DataStore getDataStore() {
        return getEmfDataStore();
    }

    /**
     * @return the inheritanceType
     */
    public InheritanceType getInheritanceType() {
        return inheritanceType;
    }

    /** Is this a hibernate test store */
    @Override
    public boolean isHibernateTestStore() {
        return true;
    }

    public boolean isEntityManagerStore() {
        return ejb3;
    }

    /** Set the xmlgregoriancalendar date */
    public Object getDate(Date date) {
        return EcoreDataTypes.INSTANCE.getXMLGregorianCalendar(date);
    }
}