/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 org.apache.openjpa.persistence.test; import java.util.List; import javax.persistence.EntityManager; import org.apache.openjpa.jdbc.conf.JDBCConfiguration; import org.apache.openjpa.jdbc.meta.ClassMapping; import org.apache.openjpa.jdbc.sql.DBDictionary; import org.apache.openjpa.lib.log.Log; import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI; /** * Base class for OpenJPA-specific Test Case. * Provides utilities for configuration setup and persistent entity * registration during setUp() method and EMF cleanup in tearDown(). * Derived classes can access protected EntityManagerFactory to create * EntityManager. The protected EntityManagerFactory is declared to be * OpenJPA-extended SPI interface <code>OpenJPAEntityManagerFactorySPI</code> * so that derived classes can access internal mapping/metadata/configuration * and other structures. * Extends AbstractCachedEMFTestCase, which extends AbstractPersistenceTestCase. * Cleans up the EMF it provides and any EMs created from it in tearDown(). * */ public abstract class SingleEMFTestCase extends AbstractCachedEMFTestCase { protected OpenJPAEntityManagerFactorySPI emf; /** * Call {@link #setUp(Object... props)} with no arguments so that the emf * set-up happens even if <code>setUp()</code> is not called from the * subclass. */ public void setUp() throws Exception { super.setUp(); setUp(new Object[0]); } /** * Initialize entity manager factory. Put {@link #CLEAR_TABLES} in * this list to tell the test framework to delete all table contents * before running the tests. * NOTE: The EMF and any EMs will be closed in tearDown(), * but any user created EMFs need to be manually closed. * * @param props list of persistent types used in testing and/or * configuration values in the form key,value,key,value... */ protected void setUp(Object... props) { emf = createEMF(props); } /** * Closes the entity manager factory. */ public void tearDown() throws Exception { super.tearDown(); if (emf == null) return; try { clear(emf); } catch (Exception e) { // if a test failed, swallow any exceptions that happen // during tear-down, as these just mask the original problem. if (testResult.wasSuccessful()) throw e; } finally { closeEMF(emf); emf = null; } } /** * Get the class mapping for a given entity * * @param name The Entity's name. * * @return If the entity is a known type the ClassMapping for the Entity * will be returned. Otherwise null */ protected ClassMapping getMapping(String name) { return (ClassMapping) emf.getConfiguration() .getMetaDataRepositoryInstance().getMetaData(name, getClass().getClassLoader(), true); } /** * Get the class mapping for a given entity * * @param entityClass an entity class. * * @return If the entity is a known type the ClassMapping for the Entity * will be returned. Otherwise null */ protected ClassMapping getMapping(Class<?> entityClass) { return (ClassMapping) emf.getConfiguration() .getMetaDataRepositoryInstance().getMetaData(entityClass, getClass().getClassLoader(), true); } /** * Get number of instances by an aggregate query with the given alias. */ public int count(String alias) { return ((Number)emf.createEntityManager().createQuery( "SELECT COUNT(p) FROM " + alias + " p") .getSingleResult()).intValue(); } /** * Count number of instances of the given class assuming that the alias * for the class is its simple name. */ public int count(Class<?> c) { return count(getAlias(c)); } /** * Get all the instances of given type. * The returned instances are obtained without a persistence context. */ @SuppressWarnings("unchecked") public <T> List<T> getAll(Class<T> t) { return (List<T>)emf.createEntityManager().createQuery( "SELECT p FROM " + getAlias(t) + " p").getResultList(); } /** * Get all the instances of given type. * The returned instances are obtained within the given persistence context. */ @SuppressWarnings("unchecked") public <T> List<T> getAll(EntityManager em, Class<T> t) { return (List<T>)em.createQuery("SELECT p FROM " + getAlias(t) + " p") .getResultList(); } public String getAlias(Class<?> t) { return emf.getConfiguration().getMetaDataRepositoryInstance() .getMetaData(t, null, true).getTypeAlias(); } protected ClassMapping [] getMappings() { return (ClassMapping [] ) emf.getConfiguration().getMetaDataRepositoryInstance().getMetaDatas(); } protected void setUnsupportedDatabases(Class<?> ... dbs) { OpenJPAEntityManagerFactorySPI tempEMF = emf; if (tempEMF == null) { tempEMF = createEMF(); } DBDictionary dict = ((JDBCConfiguration)tempEMF.getConfiguration()).getDBDictionaryInstance(); for (Class<?> db : dbs) { if (dict.getClass().getCanonicalName().equalsIgnoreCase(db.getCanonicalName())) { setTestsDisabled(true); break; } } if (emf == null) { closeEMF(tempEMF); } } protected void setSupportedDatabases(Class<?> ... dbs) { OpenJPAEntityManagerFactorySPI tempEMF = emf; if (tempEMF == null) { tempEMF = createEMF(); } DBDictionary dict = ((JDBCConfiguration)tempEMF.getConfiguration()).getDBDictionaryInstance(); boolean supportedDB = false; for (Class<?> db : dbs) { if (dict.getClass().getCanonicalName().equalsIgnoreCase(db.getCanonicalName())) { supportedDB = true; break; } } setTestsDisabled(!supportedDB); if (emf == null) { closeEMF(tempEMF); } } protected Log getLog() { return emf.getConfiguration().getLog("Tests"); } protected String getForUpdateClause() { DBDictionary dict = getDBDictionary(); if (dict.forUpdateClause != null) { return dict.forUpdateClause; } if (dict.tableForUpdateClause != null) { return dict.tableForUpdateClause; } return ""; } protected DBDictionary getDBDictionary() { return ((JDBCConfiguration) emf.getConfiguration()).getDBDictionaryInstance(); } protected String repeatString(String val, int nr) { StringBuilder sb = new StringBuilder(val.length() * nr); for (int i = 0; i < nr; i++) { sb.append(val); } return sb.toString(); } }