/////////////////////////////////////////////////////////////////////////////
//
// Project ProjectForge Community Edition
// www.projectforge.org
//
// Copyright (C) 2001-2014 Kai Reinhard (k.reinhard@micromata.de)
//
// ProjectForge is dual-licensed.
//
// This community edition is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation; version 3 of the License.
//
// This community edition is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
// Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, see http://www.gnu.org/licenses/.
//
/////////////////////////////////////////////////////////////////////////////
package org.projectforge.test;
import java.io.File;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.Validate;
import org.apache.log4j.Logger;
import org.projectforge.common.StringHelper;
import org.projectforge.core.ConfigXmlTest;
import org.projectforge.core.Configuration;
import org.projectforge.database.HibernateUtils;
import org.projectforge.jdbc.PropertyDataSource;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.hibernate3.LocalSessionFactoryBean;
/**
* Only needed for test configuration
*/
public class TestConfiguration
{
private static final String WORK_DIR = "work";
private static final Logger log = Logger.getLogger(TestConfiguration.class);
private static final String[] TEST_CONTEXT_FILES = new String[] { "test-applicationContext-main.xml", "applicationContext-hibernate.xml",
"applicationContext-business.xml", "applicationContext-web.xml", "applicationContext-ldap.xml",
"org/projectforge/plugins/memo/pluginContext.xml", "org/projectforge/plugins/todo/pluginContext.xml"};
private static final String[] CMD_CONTEXT_FILES = new String[] { "cmd-applicationContext-main.xml", "applicationContext-hibernate.xml",
"applicationContext-business.xml", "applicationContext-ldap.xml"};
protected ClassPathXmlApplicationContext ctx = null;
protected String[] contextFiles;
protected String databaseUrl;
protected boolean isInitialized = false;
public static TestConfiguration testConfiguration = null;
public static synchronized void initAsTestConfiguration()
{
initAsTestConfiguration((String[]) null);
}
public static synchronized void initAsTestConfiguration(final String... additionalContextFiles)
{
System.setProperty("base.dir", new File("./tmp").getAbsoluteFile().toString());
ConfigXmlTest.createTestConfiguration();
final String[] contextFiles;
if (additionalContextFiles != null && additionalContextFiles.length > 0) {
contextFiles = (String[]) ArrayUtils.addAll(TEST_CONTEXT_FILES, additionalContextFiles);
} else {
contextFiles = TEST_CONTEXT_FILES;
}
init(contextFiles);
}
public static synchronized void initAsCmdLineConfiguration()
{
init(CMD_CONTEXT_FILES);
}
/**
* Get the file from the working directory. If the working directory doesn't exist then it'll be created.
* @param filename
* @return
*/
public static File getWorkFile(final String filename)
{
final File workDir = new File(WORK_DIR);
if (workDir.exists() == false) {
log.info("Create working directory: " + workDir.getAbsolutePath());
workDir.mkdir();
}
return new File(workDir, filename);
}
private static synchronized void init(final String[] contextFiles)
{
if (testConfiguration == null) {
testConfiguration = new TestConfiguration(contextFiles);
} else if (ArrayUtils.isEquals(testConfiguration.contextFiles, contextFiles) == false) {
final String msg = "Already initialized with incompatible context files: "
+ StringHelper.listToString(", ",
testConfiguration.contextFiles
+ ". New context files: "
+ StringHelper.listToString(",", contextFiles)
+ ". This is OK if the test case is started in fork-mode.");
log.warn(msg);
testConfiguration = new TestConfiguration(contextFiles);
}
}
public static TestConfiguration getConfiguration()
{
if (testConfiguration == null) {
final String msg = "Not initialized.";
log.fatal(msg);
throw new RuntimeException(msg);
}
return testConfiguration;
}
public ConfigurableListableBeanFactory getBeanFactory()
{
return ctx.getBeanFactory();
}
public boolean isInitialized()
{
return isInitialized;
}
public void setInitialized(final boolean isInitialized)
{
this.isInitialized = isInitialized;
}
public ClassPathXmlApplicationContext getApplicationContext()
{
return this.ctx;
}
public <T> T getBean(final String name, final Class<T> requiredType)
{
final T obj = ctx.getBean(name, requiredType);
return obj;
}
public <T> T getAndAutowireBean(final String name, final Class<T> requiredType)
{
final T obj = getBean(name, requiredType);
autowire(obj, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME);
return obj;
}
public String getDatabaseUrl()
{
return databaseUrl;
}
/**
* Convenience. Bean-Properties "spring-like" setzen.
* @param existingBean .
* @param autowireMode Analog <code>AutowireCapableBeanFactory.AUTOWIRE_BY_NAME</code> etc.
*/
public void autowire(final Object existingBean, final int autowireMode)
{
Validate.notNull(existingBean, "Bean to wire is null");
ctx.getBeanFactory().autowireBeanProperties(existingBean, autowireMode, false);
}
/**
* Init and reinitialise context for each run
*/
protected TestConfiguration(final String[] contextFiles) throws BeansException
{
this.contextFiles = contextFiles;
initCtx();
}
/**
* Init and reinitialise context for each run
*/
protected void initCtx() throws BeansException
{
if (ctx == null) {
log.info("Initializing context: " + org.projectforge.common.StringHelper.listToString(", ", contextFiles));
try {
// Build spring context
ctx = new ClassPathXmlApplicationContext(contextFiles);
ctx.getBeanFactory().autowireBeanProperties(this, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, false);
final PropertyDataSource ds = ctx.getBean("dataSource", PropertyDataSource.class);
this.databaseUrl = ds.getUrl();
final JdbcTemplate jdbc = new JdbcTemplate(ds);
try {
jdbc.execute("CHECKPOINT DEFRAG");
} catch (final org.springframework.jdbc.BadSqlGrammarException ex) {
// ignore
}
final LocalSessionFactoryBean localSessionFactoryBean = (LocalSessionFactoryBean) ctx.getBean("&sessionFactory");
HibernateUtils.setConfiguration(localSessionFactoryBean.getConfiguration());
} catch (final Throwable ex) {
log.error(ex.getMessage(), ex);
throw new RuntimeException(ex);
}
} else {
// Get a new HibernateTemplate each time
ctx.getBeanFactory().autowireBeanProperties(this, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, false);
}
final Configuration cfg = ctx.getBean("configuration", Configuration.class);
cfg.setBeanFactory(ctx.getBeanFactory()); // Bean factory need to be set.
}
}