/*
* Copyright 2010 Research Studios Austria Forschungsgesellschaft mBH
*
* This file is part of easyrec.
*
* easyrec 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, either version 3 of the License, or
* (at your option) any later version.
*
* easyrec 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 easyrec. If not, see <http://www.gnu.org/licenses/>.
*/
package org.easyrec.store.dao.web.impl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.easyrec.model.core.web.Operator;
import org.easyrec.store.dao.web.LoaderDAO;
import org.easyrec.store.dao.web.OperatorDAO;
import org.easyrec.utils.spring.store.service.sqlscript.SqlScriptService;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.jdbc.support.DatabaseMetaDataCallback;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.jdbc.support.MetaDataAccessException;
import org.springframework.web.context.ConfigurableWebApplicationContext;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.sql.*;
import java.util.*;
import java.util.Date;
/**
* @author szavrel
*/
public class LoaderDAOMysqlImpl extends JdbcDaoSupport
implements LoaderDAO, ApplicationListener, ApplicationContextAware {
private final Log logger = LogFactory.getLog(LoaderDAOMysqlImpl.class);
private SqlScriptService sqlScriptService;
private Properties properties;
private Resource overrideFolder;
private Resource dbCreationFile;
private Resource dbMigrateFolder;
private List<String> migrateFiles;
private ApplicationContext applicationContext;
private HashMap<String, String> configLocations;
private String currentVersion;
private static final String SQL_ADD_OPERATOR;
static {
SQL_ADD_OPERATOR = new StringBuilder().append(" INSERT INTO ").append(OperatorDAO.DEFAULT_TABLE_NAME)
.append(" (").append(OperatorDAO.DEFAULT_TABLE_KEY).append(", PASSWORD, FIRSTNAME, LASTNAME, ")
.append(" EMAIL, PHONE, COMPANY, ADDRESS, APIKEY, IP, CREATIONDATE, ACTIVE, ACCESSLEVEL) VALUES ")
.append(" (?,PASSWORD(?),?,?,?,?,?,?,?,?,?,?,?) ").toString();
}
public LoaderDAOMysqlImpl(BasicDataSource dataSource, SqlScriptService sqlScriptService, Resource dbCreationFile,
Resource dbMigrateFolder) {
setDataSource(dataSource);
this.sqlScriptService = sqlScriptService;
this.dbCreationFile = dbCreationFile;
this.dbMigrateFolder = dbMigrateFolder;
}
@Override
public void testConnection(String url, String username, String password) throws Exception {
BasicDataSource bds = (BasicDataSource) getDataSource();
bds.setUrl(url);
bds.setUsername(username);
bds.setPassword(password);
boolean tablesOk = false;
DatabaseMetaDataCallback callback = new DatabaseMetaDataCallback() {
public Object processMetaData(DatabaseMetaData dbmd) throws SQLException, MetaDataAccessException {
ResultSet rs = dbmd.getTables(null, null, "operator", null);
return rs.next();
}
};
tablesOk = (Boolean) JdbcUtils.extractDatabaseMetaData(bds, callback);
}
@Override
public void createDB() throws Exception {
BasicDataSource bds = (BasicDataSource) getDataSource();
boolean tablesOk = false;
DatabaseMetaDataCallback callback = new DatabaseMetaDataCallback() {
public Object processMetaData(DatabaseMetaData dbmd) throws SQLException, MetaDataAccessException {
ResultSet rs = dbmd.getTables(null, null, "operator", null);
return rs.next();
}
};
tablesOk = (Boolean) JdbcUtils.extractDatabaseMetaData(bds, callback);
sqlScriptService.executeSqlScript(dbCreationFile.getInputStream());
}
@Override
public void migrateDB() throws Exception {
BasicDataSource bds = (BasicDataSource) getDataSource();
boolean tablesOk = false;
DatabaseMetaDataCallback callback = new DatabaseMetaDataCallback() {
public Object processMetaData(DatabaseMetaData dbmd) throws SQLException, MetaDataAccessException {
ResultSet rs = dbmd.getTables(null, null, "operator", null);
return rs.next();
}
};
tablesOk = (Boolean) JdbcUtils.extractDatabaseMetaData(bds, callback);
Float installedVersion = checkVersion();
for (String migrateFile : migrateFiles) {
logger.info("migrate File: " + migrateFile);
Float scriptVersion = Float.parseFloat(migrateFile.substring(migrateFile.lastIndexOf("_") + 1));
logger.info("scriptVersion: " + scriptVersion);
if (installedVersion < scriptVersion) {
File f = new File(dbMigrateFolder.getFile(), migrateFile + ".sql");
if (f.exists()) {
logger.info("Executing migrate script: " + f.getName());
sqlScriptService.executeSqlScript(new FileSystemResource(f).getInputStream());
}
}
}
if (installedVersion < 0.96f) {
update_0_96f();
// logs are not converted from ruleminerlog -> plugin_log
}
if (installedVersion < 0.98) {
update_0_98();
}
//updateVersion(); // done in migrate script!
}
/*
* Items now have a profile field so the profile table moved to the item table
* this function will move the items from the profile table to the items table and
* remove the profile table from the database.
*/
private void update_0_98() {
logger.info("executing 'update_0_98()'...");
final String profileTableName = "profile";
final String itemTableName = "item";
final String itemTypeTableName = "itemtype";
final String assocTypeTableName = "assoctype";
final String sourceTypeTableName = "sourcetype";
final String itemColumnTenantID = "tenantId";
final String itemColumnItemID = "itemid";
final String itemColumnItemType = "itemtype";
final String itemColumnProfileData = "profileData";
final String itemColumnChangeDate = "changedate";
final String itemColumnActive = "active";
final String profileColumnTenantID = "tenantId";
final String profileColumnItemID = "itemId";
final String profileColumnItemTypeID = "itemTypeId";
final String profileColumnProfileData = "profileData";
final String profileColumnChangeData = "changeDate";
final String profileColumnActive = "active";
final String itemTypeColumnTenantID = "tenantId";
final String itemTypeColumnName = "name";
final String itemTypeColumnID = "id";
final String assocTypeTenantID = "tenantId";
final String assocTypeName = "name";
final String assocTypeID = "id";
final String assocTypeVisible = "visible";
final String sourceTypeColumnId = "id";
final String sourceTypeColumnTenantId = "tenantId";
final String sourceTypeColumnName = "name";
/* Create a hashmap with the itemTypeNames as values and the
* tenantId and itemTypeId as key.
*/
logger.info("creating a hashmap with itemTypeNames...");
final HashMap<String, String> itemTypeList = new HashMap<String, String>();
getJdbcTemplate().query("SELECT * FROM " + itemTypeTableName, new RowCallbackHandler() {
public void processRow(ResultSet resultSet) throws SQLException {
int tenantId = resultSet.getInt(itemTypeColumnTenantID);
int itemTypeId = resultSet.getInt(itemTypeColumnID);
String itemTypeName = resultSet.getString(itemTypeColumnName);
itemTypeList.put(String.valueOf(tenantId) + "," + String.valueOf(itemTypeId), itemTypeName);
}
});
/*
* For each entry in the profile table look for an entry with the same key in the
* item table. If the item table has no entry, create it else update the entry with
* the values from the profile table.
*/
logger.info("executing 'update_0_98()'...");
getJdbcTemplate().query("SELECT * FROM " + profileTableName, new RowCallbackHandler() {
public void processRow(ResultSet resultSet) throws SQLException {
final int tenantId = resultSet.getInt(profileColumnTenantID);
final int itemId = resultSet.getInt(profileColumnItemID);
int itemTypeId = resultSet.getInt(profileColumnItemTypeID);
String tempProfileData = resultSet.getString(profileColumnProfileData);
if (tempProfileData == null) {
tempProfileData = "null";
} else {
tempProfileData = "'" + tempProfileData + "'";
}
final String profileData = tempProfileData;
final String itemTypeName = "'" + itemTypeList.get(
String.valueOf(tenantId) + "," + String.valueOf(itemTypeId)) + "'";
/*
* A "0000-00-00 00:00:00" value in the table is returned as null and
* must therefore a null value must be changed back to "0000-00-00 00:00:00"
* before updating the table.
*/
String tempChangeDate = resultSet.getString(profileColumnChangeData);
if (tempChangeDate == null) {
tempChangeDate = "0000-00-00 00:00:00";
}
final String changeDate = "'" + tempChangeDate + "'";
final boolean active = resultSet.getBoolean(profileColumnActive);
final String sqlItemUpdate = " WHERE " +
itemColumnItemID + " = " + itemId + " AND " +
itemColumnTenantID + " = " + tenantId + " AND " +
itemColumnItemType + " like " + itemTypeName;
final String sqlItemToUpdate = "FROM " + itemTableName + sqlItemUpdate;
getJdbcTemplate().query("SELECT COUNT(*) " + sqlItemToUpdate, new RowCallbackHandler() {
public void processRow(ResultSet resultSet) throws SQLException {
if (resultSet.getInt(1) == 0) { // The profile is not in the item table -> create one.
String sqlInsertStatement = "INSERT INTO " + itemTableName + " SET " +
itemColumnItemID + " = " + String.valueOf(itemId) + ", " +
itemColumnTenantID + " = " + String.valueOf(tenantId) + ", " +
itemColumnItemType + " = " + itemTypeName + ", " +
itemColumnProfileData + " = " + profileData + ", " +
itemColumnChangeDate + " = " + changeDate + ", " +
itemColumnActive + " = " + String.valueOf(active);
logger.info("executing: " + sqlInsertStatement);
getJdbcTemplate().execute(sqlInsertStatement);
} else { // The profile has already an entry in the item table -> just updating.
getJdbcTemplate().query("SELECT * " + sqlItemToUpdate, new RowCallbackHandler() {
public void processRow(ResultSet resultSet) throws SQLException {
logger.info("updating item: " + resultSet.getString(itemColumnItemID));
getJdbcTemplate().execute("UPDATE " + itemTableName + " SET " +
itemColumnProfileData + " = " + profileData + ", " +
itemColumnChangeDate + " = " + changeDate + " " +
sqlItemUpdate);
}
}
);
}
}
}
);
}
});
getJdbcTemplate().execute("DROP TABLE " + profileTableName);
/**
* create association type PROFILE_SIMILARITY for the profileDuke plugin
*/
// get list of tenantIDs in the assoctype table
logger.info("inserting PROFILE_SIMILARITY assoc Type");
String sql = "SELECT DISTINCT " + assocTypeTenantID + " FROM " + assocTypeTableName;
logger.info("fireing: " + sql);
final List<Integer> tenantIDList = new ArrayList<Integer>();
getJdbcTemplate().query(sql,
new RowCallbackHandler() {
public void processRow(ResultSet resultSet) throws SQLException {
int tenantIdx = resultSet.getInt(assocTypeTenantID);
logger.info("found tenant " + tenantIdx);
logger.info("found " + resultSet.getFetchSize() + " results");
int tenantId = resultSet.getInt(assocTypeTenantID);
logger.info("found tenant " + tenantId);
tenantIDList.add(tenantId);
}
});
// get the max id of each tenant and add a PROFILE_SIMILARITY association type and
// a sourceType for the plugins with the new versions.
Integer maxAssocTypeId;
Integer maxSourceTypeId;
for (final Integer tenantId : tenantIDList) {
// association type
maxAssocTypeId = getJdbcTemplate().queryForInt("SELECT MAX(id) FROM " + assocTypeTableName +
" WHERE " + assocTypeTableName + "." + assocTypeTenantID + " = " + tenantId);
sql = "INSERT INTO " + assocTypeTableName + " (" +
assocTypeTenantID + ", " + assocTypeName + ", " + assocTypeID + ", " + assocTypeVisible +
") VALUES (" + tenantId + ", \"PROFILE_SIMILARITY\", " + (maxAssocTypeId + 1) + ", 1)";
getJdbcTemplate().execute(sql);
// sourceType
maxSourceTypeId = getJdbcTemplate().queryForInt("SELECT MAX(" + sourceTypeColumnId + ") FROM " +
sourceTypeTableName +
" WHERE " + sourceTypeTableName + "." + sourceTypeColumnTenantId + " = " + tenantId);
sql = "INSERT INTO " + sourceTypeTableName + " (" +
sourceTypeColumnTenantId + ", " + sourceTypeColumnName + ", " + sourceTypeColumnId +
") VALUES (" + tenantId + ", \"http://www.easyrec.org/plugins/slopeone/0.98\", " + (maxSourceTypeId + 1) + ")";
getJdbcTemplate().execute(sql);
sql = "INSERT INTO " + sourceTypeTableName + " (" +
sourceTypeColumnTenantId + ", " + sourceTypeColumnName + ", " + sourceTypeColumnId +
") VALUES (" + tenantId + ", \"http://www.easyrec.org/plugins/ARM/0.98\", " + (maxSourceTypeId + 2) + ")";
getJdbcTemplate().execute(sql);
}
// update the pluginVersion on the plugin_configuration table
sql = "UPDATE plugin_configuration SET pluginVersion = '0.98'\n" +
"WHERE pluginId = 'http://www.easyrec.org/plugins/ARM' OR pluginId = 'http://www.easyrec.org/plugins/slopeone'";
getJdbcTemplate().execute(sql);
}
/**
* easyrec pre 0.96 stored settings for plugins in the tenantConfig column of the tenantsTable from 0.96
* onwards they are stored as XML serialized GeneratorConfigurations in the plugin_configuration table
* this snippet converts the existing ARM configurations (and only ARM configurations) to the new XML
* version.
*
* @throws IOException
*/
private void update_0_96f() throws IOException {
//
final String RENAME_SOURCETYPE_QUERY =
"UPDATE sourcetype SET name=? WHERE name=?";
getJdbcTemplate().update(RENAME_SOURCETYPE_QUERY, "http://www.easyrec.org/plugins/ARM/0.96", "ARM");
getJdbcTemplate().update(RENAME_SOURCETYPE_QUERY, "http://www.easyrec.org/plugins/slopeone/0.96", "http://www.easyrec.org/plugins/slopeone/0.95");
ResultSetExtractor<Map<Integer, String>> rse = new ResultSetExtractor<Map<Integer, String>>() {
public Map<Integer, String> extractData(ResultSet rs) throws SQLException, DataAccessException {
Map<Integer, String> result = Maps.newHashMap();
while (rs.next()) {
int id = rs.getInt("id");
String config = rs.getString("tenantConfig");
result.put(id, config);
}
return result;
}
};
Map<Integer, String> tenantConfigs = getJdbcTemplate().query("SELECT id, tenantConfig FROM tenant", rse);
for (Map.Entry<Integer, String> tenantConfig : tenantConfigs.entrySet()) {
String tenantConfigString = tenantConfig.getValue();
if (tenantConfigString == null)
tenantConfigString = "";
int tenantId = tenantConfig.getKey();
StringReader reader = new StringReader(tenantConfigString);
Properties propertiesConfig = new Properties();
propertiesConfig.load(reader);
String configViewedTogether =
generateXmlConfigurationFromProperties(propertiesConfig, "VIEWED_TOGETHER", "VIEW");
String configGoodRatedTogether =
generateXmlConfigurationFromProperties(propertiesConfig, "GOOD_RATED_TOGETHER", "RATE");
String configBoughtTogether =
generateXmlConfigurationFromProperties(propertiesConfig, "BOUGHT_TOGETHER", "BUY");
// write back config with arm settings removed
// getJdbcTemplate().update("UPDATE tenant SET tenantConfig = ? WHERE id = ?",
// propertiesConfig.toString(), tenantConfig.getKey());
final String CONFIG_QUERY =
"INSERT INTO plugin_configuration(tenantId, assocTypeId, pluginId, pluginVersion, name, configuration, active) VALUES " +
"(?, ?, 'http://www.easyrec.org/plugins/ARM', ?, 'Default Configuration', ?, b'1')";
// generate configuration entries
getJdbcTemplate().update(CONFIG_QUERY, tenantId, 1, currentVersion, configViewedTogether);
getJdbcTemplate().update(CONFIG_QUERY, tenantId, 2, currentVersion, configGoodRatedTogether);
getJdbcTemplate().update(CONFIG_QUERY, tenantId, 3, currentVersion, configBoughtTogether);
final String slopeOneXmlConfig =
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" +
"<slopeOneConfiguration>" +
"<configurationName>Default Configuration</configurationName>" +
"<associationType>IS_RELATED</associationType>" +
"<maxRecsPerItem>10</maxRecsPerItem>" +
"<minRatedCount xsi:nil=\"true\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"/>" +
"<nonPersonalizedSourceInfo>slopeone-nonpersonalized</nonPersonalizedSourceInfo>" +
"<actionType>RATE</actionType><itemTypes/>" +
"<viewType>COMMUNITY</viewType>" +
"</slopeOneConfiguration>";
final String GET_ISRELATED_ASSOCTYPE_QUERY =
"SELECT id FROM assoctype WHERE name = 'IS_RELATED' AND tenantId = ?";
int isRelatedAssocType = 0;
// for tenants without a type 'IS_RELATED' this throws an exception - so catch!!
try {
isRelatedAssocType = getJdbcTemplate().queryForInt(GET_ISRELATED_ASSOCTYPE_QUERY, tenantId);
} catch (EmptyResultDataAccessException erdar) {
isRelatedAssocType = 0;
}
if (isRelatedAssocType == 0) {
final String GET_MAX_ASSOCTYPE_QUERY =
"SELECT MAX(id) FROM assoctype WHERE tenantId = ?";
isRelatedAssocType = getJdbcTemplate().queryForInt(GET_MAX_ASSOCTYPE_QUERY, tenantId) + 1;
final String INSERT_ASSOCTYPE_QUERY =
"INSERT INTO assoctype(tenantId, name, id, visible) VALUES (?, 'IS_RELATED', ?, b'1')";
getJdbcTemplate().update(INSERT_ASSOCTYPE_QUERY, tenantId, isRelatedAssocType);
}
// add sourcetype for slopeone where missing
final String GET_SLOPEONE_SOURCETYPE_QUERY =
"SELECT id FROM sourcetype WHERE name = 'http://www.easyrec.org/plugins/slopeone/0.96' AND tenantId = ?";
int slopeOneSourceType = 0;
// for tenants without a type 'http://www.easyrec.org/plugins/slopeone/0.96' this throws an exception - so catch!!
try {
slopeOneSourceType = getJdbcTemplate().queryForInt(GET_SLOPEONE_SOURCETYPE_QUERY, tenantId);
} catch (EmptyResultDataAccessException erdar) {
slopeOneSourceType = 0;
}
if (slopeOneSourceType == 0) { // this means sourcetype not found, so update
final String GET_MAX_SOURCETYPE_QUERY =
"SELECT MAX(id) FROM sourcetype WHERE tenantId = ?";
slopeOneSourceType = getJdbcTemplate().queryForInt(GET_MAX_SOURCETYPE_QUERY, tenantId) + 1;
final String INSERT_SOURCETYPE_QUERY =
"INSERT INTO sourcetype(tenantId, name, id) VALUES (?, 'http://www.easyrec.org/plugins/slopeone/0.96', ?)";
getJdbcTemplate().update(INSERT_SOURCETYPE_QUERY, tenantId, slopeOneSourceType);
}
final String SLOPEONE_CONFIG_QUERY =
"INSERT INTO plugin_configuration(tenantId, assocTypeId, pluginId, pluginVersion, name, configuration, active) VALUES " +
"(?, ?, 'http://www.easyrec.org/plugins/slopeone', ?, 'Default Configuration', ?, b'1')";
getJdbcTemplate().update(SLOPEONE_CONFIG_QUERY, tenantId, isRelatedAssocType, currentVersion,
slopeOneXmlConfig);
}
}
private String generateXmlConfigurationFromProperties(final Properties propertiesConfig, final String assocType,
final String actionType) {
String supportMinAbs = propertiesConfig.getProperty(assocType + ".ARM.supportMinAbs", "2");
String supportPercnt = propertiesConfig.getProperty(assocType + ".ARM.supportPrcnt", "0.0");
String confidencePercnt = propertiesConfig.getProperty(assocType + ".ARM.confidencePrcnt", "0.0");
// no harm to keep the old values - maybe useful as fallback
// propertiesConfig.remove(assocType + ".ARM.supportMinAbs");
// propertiesConfig.remove(assocType + ".ARM.supportPrcnt");
// propertiesConfig.remove(assocType + ".ARM.confidencePrcnt");
final String xmlConfigurationTemplate =
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" +
"<armConfiguration>" +
"<configurationName>Default Configuration</configurationName>" +
"<associationType>%s</associationType>" +
"<actionType>%s</actionType>" +
"<confidencePrcnt>%s</confidencePrcnt>" +
"<doDeltaUpdate>false</doDeltaUpdate>" +
"<excludeSingleItemBaskests>false</excludeSingleItemBaskests>" +
"<itemTypes>ITEM</itemTypes>" +
"<maxRulesPerItem>50</maxRulesPerItem>" +
"<maxSizeL1>5000</maxSizeL1>" +
"<metricType>CONFIDENCE</metricType>" +
"<ratingNeutral>5.5</ratingNeutral>" +
"<supportMinAbs>%s</supportMinAbs>" +
"<supportPrcnt>%s</supportPrcnt>" +
"</armConfiguration>";
return String.format(xmlConfigurationTemplate, assocType, actionType, confidencePercnt, supportMinAbs,
supportPercnt);
}
/**
* This function returns the current version of easyrec,
* depending on the presence of a version table. If
* no version table is present return the inital version
*
* @return
*/
@Override
public Float checkVersion() throws Exception {
BasicDataSource bds = (BasicDataSource) getDataSource();
float tableCount;
DatabaseMetaDataCallback callback = new DatabaseMetaDataCallback() {
public Object processMetaData(DatabaseMetaData dbmd) throws SQLException, MetaDataAccessException {
ResultSet rs = dbmd.getTables(null, null, "%", null);
float f = 0;
while (rs.next()) {
f++;
}
return f;
}
};
tableCount = (Float) JdbcUtils.extractDatabaseMetaData(bds, callback);
if (tableCount != 0) {
try {
return getJdbcTemplate().queryForObject("SELECT MAX(VERSION) FROM easyrec ", Float.class);
} catch (Exception e) {
// else return initial version 0.9
return INITIAL_VERSION;
}
} else {
return tableCount;
}
}
public void updateVersion() {
try {
getJdbcTemplate().update("INSERT INTO easyrec(version) VALUES (?)", currentVersion);
} catch (Exception e) {
logger.warn("unable to update version", e);
}
}
@Override
public Operator addOperator(String id, String password, String firstName, String lastName, String email,
String phone, String company, String address, String apiKey, String ip) {
Object[] args = {id, password, firstName, lastName, email, phone, company, address, apiKey, ip, new Date(),
true, 1};
int[] argTypes = {Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR,
Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.TIMESTAMP, Types.BOOLEAN,
Types.INTEGER};
try {
getJdbcTemplate().update(SQL_ADD_OPERATOR, args, argTypes);
return new Operator(id, password, firstName, lastName, email, phone, company, address, apiKey, ip, true,
// active
new Date().toString(), // creation date
1, // acceslevel
0, // login count
null // last login date
);
} catch (Exception e) {
logger.debug(e);
e.printStackTrace();
return null;
}
}
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ContextRefreshedEvent) {
// after context start, check if properties file in folder /override exists
try {
File f = new File(overrideFolder.getFile(), "easyrec.database.properties");
// if file exists, config was already written, so boot application as normal
if (f.exists()) {
reloadContext();
}
} catch (IOException ex) {
logger.error("Error looking for config file! Running in installer mode as fallback!");
}
}
}
@Override
public void reloadContext() {
reloadBackend();
reloadFrontend();
}
@Override
public void reloadBackend() {
List<String> configLocs = Lists.newArrayList("classpath:spring/web/commonContext.xml");
if ("on".equals(properties.getProperty("easyrec.rest"))) {
configLocs.add(configLocations.get("easyrec.rest"));
}
// if no config found use default
if (configLocs.size() == 1) {
configLocs.add(configLocations.get("easyrec.rest"));
}
if ("on".equals(properties.getProperty("easyrec.dev"))) {
configLocs.add(configLocations.get("easyrec.dev"));
}
ApplicationContext webctx = applicationContext;
ApplicationContext parent = webctx.getParent();
if (parent instanceof ConfigurableWebApplicationContext) {
((ConfigurableWebApplicationContext) parent).setConfigLocations(
configLocs.toArray(new String[configLocs.size()]));
((ConfigurableWebApplicationContext) parent).refresh();
}
}
@Override
public void reloadFrontend() {
ApplicationContext webctx = applicationContext;
if (webctx instanceof ConfigurableWebApplicationContext) {
((ConfigurableWebApplicationContext) webctx)
.setConfigLocation("classpath:spring/web/easyrecContext.xml");
((ConfigurableWebApplicationContext) webctx).refresh();
}
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public void setDriver(String driver) {
BasicDataSource bds = (BasicDataSource) getDataSource();
bds.setDriverClassName(driver);
}
public void setProperties(Properties properties) {
this.properties = properties;
}
public Properties getProperties() {
return properties;
}
public void setOverrideFolder(Resource resource) {
this.overrideFolder = resource;
}
public void setConfigLocations(HashMap<String, String> configLocations) {
this.configLocations = configLocations;
}
public List<String> getMigrateFiles() {
return migrateFiles;
}
public void setMigrateFiles(List<String> migrateFiles) {
this.migrateFiles = migrateFiles;
}
public void setCurrentVersion(String currentVersion) {
this.currentVersion = currentVersion;
}
}