/* vim: set ts=2 et sw=2 cindent fo=qroca: */ package com.globant.katari.user; import java.sql.Connection; import java.sql.SQLException; import javax.servlet.ServletContext; import javax.sql.DataSource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; import org.springframework.core.io.FileSystemResourceLoader; import org.springframework.mock.web.MockServletContext; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.DefaultTransactionDefinition; import org.springframework.web.context.support.XmlWebApplicationContext; /** Utility class to give support to test cases. */ public final class SpringTestUtils { /** The class logger. */ private static Logger log = LoggerFactory.getLogger(SpringTestUtils.class); /** a data source. */ private static DataSource dataSource = null; /** Bean factory. */ private static ApplicationContext beanFactory; /** User module Bean factory. */ private static ApplicationContext servletBeanFactory; /** The katari transaction manager for the application context. */ private static PlatformTransactionManager transactionManager; /** The current transaction status. */ private static TransactionStatus transactionStatus; /** A private constructor so no instances are created. */ private SpringTestUtils() { } /** Gets the configured data source. * * @return a DataSource. */ public static synchronized DataSource getDataSource() { if (dataSource == null) { beanFactory = getBeanFactory(); dataSource = (DataSource) beanFactory.getBean("dataSource"); } return dataSource; } /** Gets the connection to the database. * * @return a Connection. * * @exception SQLException if a database access error occurs */ public static synchronized Connection getConnection() throws SQLException { if (dataSource == null) { beanFactory = getBeanFactory(); dataSource = (DataSource) beanFactory.getBean("dataSource"); } Connection connection = dataSource.getConnection(); return connection; } /** This method returns a BeanFactory. * * @return a BeanFactory */ private static synchronized ApplicationContext getBeanFactory() { if (beanFactory == null) { log.info("Creating a beanFactory"); ServletContext sc = new MockServletContext("./src/main/webapp", new FileSystemResourceLoader()); XmlWebApplicationContext appContext = new XmlWebApplicationContext(); appContext.setServletContext(sc); appContext.setConfigLocations(new String[] { "classpath:/com/globant/katari/user/applicationContext.xml"}); appContext.refresh(); beanFactory = appContext; } return beanFactory; } /** This method returns a BeanFactory. * * @return a BeanFactory */ private static synchronized ApplicationContext getServletBeanFactory() { if (servletBeanFactory == null) { log.info("Creating a beanFactory"); servletBeanFactory = new FileSystemXmlApplicationContext( new String[] {"classpath:/com/globant/katari/user/view/spring-servlet.xml"}, getBeanFactory()); } return servletBeanFactory; } /** Obtains a bean from the application bean factory. * * @param beanName the name of the bean to search for in the bean factory. * It cannot be null. * * @return the bean named beanName, or null if not found. */ public static Object getBean(final String beanName) { return getBeanFactory().getBean(beanName); } /** Obtains a bean from the spring dispatcher servlet bean factory or its * parent. * * @param beanName the name of the bean to search for in the bean factory. * It cannot be null. * * @return the bean named beanName, or null if not found. */ public static Object getServletBean(final String beanName) { return getServletBeanFactory().getBean(beanName); } /** Obtains the transactionManager from the application context. * * @return a transaction manager. */ private static synchronized PlatformTransactionManager getTransactionManager() { if (transactionManager == null) { log.info("Creating a transactionManager"); transactionManager = (PlatformTransactionManager) getBeanFactory().getBean("katari.transactionManager"); } return transactionManager; } /** Begins a global transaction. * * This is used to guarantee that each unit tests use a single hibernate * session. Only one transaction can be active at any given time. Calling * this operation implicitely commits the pending transaction, if any. * * This is intended to be called in a @Before operation. */ public static synchronized void beginTransaction() { endTransaction(); transactionStatus = getTransactionManager().getTransaction( new DefaultTransactionDefinition()); } /** Commits the pending transaction, if any. */ public static synchronized void endTransaction() { if (transactionStatus != null && !transactionStatus.isCompleted()) { if (transactionStatus.isRollbackOnly()) { transactionManager.rollback(transactionStatus); } else { transactionManager.commit(transactionStatus); } } transactionStatus = null; } }