package org.olat.upgrade;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.olat.core.helpers.Settings;
import org.olat.core.logging.OLog;
import org.olat.core.logging.StartupException;
import org.olat.core.logging.Tracing;
import org.olat.core.util.WebappHelper;
import org.olat.core.util.xml.XStreamHelper;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;
/**
*
* Description:<br>
* Class to execute upgrade code during system startup. The idea is to
* have a place in the code where you can manage your migration code that is
* necessary because of new code or because of buggy old code that left some dead
* stuff in the database or the fileSystem.
*
*
* <P>
* Initial Date: 11.09.2008 <br>
* @author guido
*/
public abstract class UpgradeManager {
OLog log = Tracing.createLoggerFor(this.getClass());
static final String UPGRADES_FILE = "olat_upgrades.xml";
static final String INSTALLED_UPGRADES_XML = "installed_upgrades.xml";
static final String SYSTEM_DIR = "system";
List<OLATUpgrade> upgrades;
Map<String, UpgradeHistoryData> upgradesHistories;
/**
* Initialize the upgrade manager: get all upgrades from the configuration file and load
* the upgrade history from the olatdata directory
*/
public void init() {
if (Settings.isJUnitTest()) return;
// load upgrades using spring framework
XmlBeanFactory upgradeFactory = new XmlBeanFactory(new FileSystemResource(WebappHelper.getContextRoot() + "/WEB-INF/" + UPGRADES_FILE));
UpgradesDefinitions upgradeDefinitions = (UpgradesDefinitions) upgradeFactory.getBean("olatupgrades");
upgrades = upgradeDefinitions.getUpgrades();
// load history of previous upgrades using xstream
initUpgradesHistories();
}
/**
* Execute alter db sql statements
*/
public abstract void runAlterDbStatements();
/**
* Execute the pre system init code of all upgrades in the order as they were configured
* in the configuration file
*/
public abstract void doPreSystemInitUpgrades();
/**
* Execute the post system init code of all upgrades in the order as they were configured
* in the configuration file
*/
public abstract void doPostSystemInitUpgrades();
/**
* @param version identifyer of UpgradeHistoryData
* @return UpgradeHistoryData of the given version or null if no such history object exists
*/
public UpgradeHistoryData getUpgradesHistory(String version) {
return upgradesHistories.get(version);
}
/**
* Persists the UpgradeHistoryData on the file system
* @param upgradeHistoryData UpgradeHistoryData of the given version
* @param version identifyer of UpgradeHistoryData
*/
public void setUpgradesHistory(UpgradeHistoryData upgradeHistoryData, String version) {
this.upgradesHistories.put(version, upgradeHistoryData);
File upgradesDir = new File(WebappHelper.getUserDataRoot(), SYSTEM_DIR);
upgradesDir.mkdirs(); // create if not exists
File upgradesHistoriesFile = new File(upgradesDir, INSTALLED_UPGRADES_XML);
XStreamHelper.writeObject(upgradesHistoriesFile, this.upgradesHistories);
}
/**
* Load all persisted UpgradeHistoryData objects from the filesystem
*/
@SuppressWarnings("unchecked")
protected void initUpgradesHistories() {
File upgradesDir = new File(WebappHelper.getUserDataRoot(), SYSTEM_DIR);
File upgradesHistoriesFile = new File(upgradesDir, INSTALLED_UPGRADES_XML);
if (upgradesHistoriesFile.exists()) {
this.upgradesHistories = (Map<String, UpgradeHistoryData>) XStreamHelper.readObject(upgradesHistoriesFile);
}
if (this.upgradesHistories == null) {
this.upgradesHistories = new HashMap<String, UpgradeHistoryData>();
}
}
/**
* On any RuntimeExceptions during init. Abort loading of application.
* Modules should throw RuntimeExceptions if they can't live with a the
* given state of configuration.
* @param e
*/
protected void abort(Throwable e) {
if (e instanceof StartupException) {
StartupException se = (StartupException) e;
log.warn("Message: " + se.getLogMsg());
Throwable cause = se.getCause();
log.warn("Cause: " + (cause != null ? cause.getMessage() : "n/a"));
}
throw new RuntimeException("*** CRITICAL ERROR IN UPGRADE MANAGER. Loading aborted.", e);
}
}