Java tutorial
/** * Copyright 2010 The Kuali Foundation Licensed under the * Educational Community 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.osedu.org/licenses/ECL-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.kuali.student.common.test.spring; import org.apache.commons.lang.StringUtils; import org.junit.Before; import org.junit.runner.RunWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; import org.springframework.core.io.ClassPathResource; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.TestExecutionListeners; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.support.DirtiesContextTestExecutionListener; import org.springframework.test.context.transaction.BeforeTransaction; import org.springframework.test.context.transaction.TransactionConfiguration; import org.springframework.test.context.transaction.TransactionalTestExecutionListener; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.jta.JtaTransactionManager; import org.springframework.transaction.support.DefaultTransactionDefinition; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.lang.reflect.Field; import java.util.List; /** * This test class will load your dao and gives you access to the shared * entityManager em. Also passes the @Dao and @PersistenceFileLocation * to system properties from the annotations. * <p> * Extend this class and set the * <ul> * <li>@PersistenceFileLocation * <li>@Dao * </ul> * <p> * @PersistenceFileLocation defines the persistence.xml location if it is * named something else. * <p> * @Dao defines the Dao implementation class, and an optional application * context that contains a list of beans that should be persisted. The list bean * should be called "persistList". SQL files that should be loaded can also be defined here with the * testSqlFile parameter. This should be an SQL file. * <p> * This test class is @Transactional, so all tests will be rolled back. * That means the data you load will be in the same state for each test. * <p> * Example: * * <pre> * @PersistenceFileLocation("classpath:META-INF/custom-persistence.xml") * public class DaoCommonTest extends AbstractTransactionalDaoTest { * * @Dao(value = "org.kuali.student.MyDaoImpl", * testDataFile = "classpath:META-INF/pretest-data-beans-1.xml,pretest-data-beans-2.xml") * public MyDao myDao; * * @Test * public void test1() { * MyObject a = myDao.foo(); * MyObject b = em.find(MyObject.class,1); * assertEquals(a.id,b.id); * } * } * </pre> * * Example of application context for preloading data: * * <pre> * <?xml version="1.0" encoding="UTF-8"?> * <beans xmlns="http://www.springframework.org/schema/beans" * xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" * xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> * * <bean id="persistList" * class="org.springframework.beans.factory.config.ListFactoryBean"> * <property name="sourceList"> * <list> * <ref bean="value1" /> * <ref bean="value2" /> * </list> * </property> * </bean> * * <bean id="value1" * class="org.kuali.student.Value"> * <property name="value" value="Value Number One" /> * </bean> * * <bean id="value2" * class="org.kuali.student.Value"> * <property name="value" value="Value Number Two" /> * </bean> * * </beans> * </pre> */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:META-INF/default-dao-context-test.xml" }) @TestExecutionListeners({ TransactionalTestExecutionListener.class, DaoTestDependencyInjectorListener.class, DirtiesContextTestExecutionListener.class }) @Transactional @TransactionConfiguration(transactionManager = "JtaTxManager") public abstract class AbstractTransactionalDaoTest { private static final Logger LOG = LoggerFactory.getLogger(AbstractTransactionalDaoTest.class); @PersistenceContext protected EntityManager em; @Autowired private JtaTransactionManager jtaTxManager; private static boolean preloadedData = false; /** * Loads the application context defined in the @Dao testDataFile * attribute. Then uses the EntityManager em to persist the beans in * persistList */ @Before public void preLoadBeans() { for (Field f : this.getClass().getDeclaredFields()) { if (f.isAnnotationPresent(Dao.class)) { Dao dao = f.getAnnotation(Dao.class); if (dao.testDataFile().length() > 0) { ConfigurableApplicationContext ac = new FileSystemXmlApplicationContext(dao.testDataFile()); List<?> persistList = (List<?>) ac.getBean("persistList"); ac.close(); for (Object o : persistList) { em.persist(o); } em.flush(); } } } } @BeforeTransaction public void preLoadData() throws IOException { if (!preloadedData) { preloadedData = true; for (Field f : this.getClass().getDeclaredFields()) { if (f.isAnnotationPresent(Dao.class)) { Dao dao = f.getAnnotation(Dao.class); if (dao.testSqlFile().length() > 0) { if (dao.testSqlFile().startsWith("classpath:")) { String file = dao.testSqlFile().substring("classpath:".length()); String[] files = file.split("\\s*,\\s*"); for (String testFile : files) { File sqlFile = new ClassPathResource(testFile).getFile(); process(sqlFile); } } else { String[] files = dao.testSqlFile().split("\\s*,\\s*"); for (String testFile : files) { File sqlFile = new File(testFile); process(sqlFile); } } } } } } } private void process(File sqlFile) throws FileNotFoundException { BufferedReader in = new BufferedReader(new FileReader(sqlFile)); String ln; //Check if oracle TransactionDefinition txDefinition = new DefaultTransactionDefinition(); TransactionStatus txStatus = jtaTxManager.getTransaction(txDefinition); try { while ((ln = in.readLine()) != null) { if (!ln.startsWith("/") && !ln.startsWith("--") && StringUtils.isNotBlank(ln)) { ln = ln.replaceFirst("[;/]\\s*$", ""); em.createNativeQuery(ln).executeUpdate(); } } jtaTxManager.commit(txStatus); } catch (Exception e) { LOG.error("Exception occurred", e); jtaTxManager.rollback(txStatus); } finally { try { in.close(); } catch (IOException e) { LOG.error("IO Stream closed ", e); } } } /** * Passes some variables so they can be used in the application context */ public AbstractTransactionalDaoTest() { super(); // Grab annotations and pass them as System properties if (this.getClass().isAnnotationPresent(PersistenceFileLocation.class)) { PersistenceFileLocation a = this.getClass().getAnnotation(PersistenceFileLocation.class); System.setProperty("ks.test.persistenceLocation", a.value()); } else { System.setProperty("ks.test.persistenceLocation", "classpath:META-INF/persistence.xml"); } } }