/* * 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 org.easyrec.model.core.web.RemoteTenant; import org.easyrec.plugin.Plugin.LifecyclePhase; import org.easyrec.plugin.configuration.ConfigurationHelper; import org.easyrec.plugin.container.PluginRegistry; import org.easyrec.plugin.generator.Generator; import org.easyrec.plugin.generator.GeneratorConfiguration; import org.easyrec.plugin.model.PluginId; import org.easyrec.plugin.stats.GeneratorStatistics; import org.easyrec.service.core.TenantService; import org.easyrec.store.dao.impl.BasicDAOMysqlImpl; import org.easyrec.store.dao.web.RemoteTenantDAO; import org.easyrec.util.core.Security; import org.easyrec.utils.servlet.ServletUtils; import org.easyrec.utils.spring.cache.annotation.InvalidatesCache; import org.easyrec.utils.spring.store.dao.DaoUtils; import org.springframework.jdbc.core.RowMapper; import javax.servlet.http.HttpServletRequest; import javax.sql.DataSource; import java.io.ByteArrayInputStream; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Properties; /** * The Class is the Implementation of the RemoteTenant DAO * <p/> * <p> * <b>Company: </b> SAT, Research Studios Austria * </p> * <p/> * <p> * <b>Copyright: </b> (c) 2007 * <p/> * <b>last modified:</b><br/> $Author: fsalcher $<br/> $Date: 2008-07-17 * 20:00:46 +0200 (Do, 17 Jul 2008) $<br/> $Revision: 18781 $ * </p> * * @author <AUTHOR> */ public class RemoteTenantDAOMysqlImpl extends BasicDAOMysqlImpl implements RemoteTenantDAO { private static final String FK_OPERATORID = "operatorId"; private static final String SQL_GET_REMOTE_TENANT; private static final String SQL_GET_REMOTE_TENANT_BY_ID; private static final String SQL_DELETE_TENANT; private static final String SQL_UPDATE_TENANT; private static final String SQL_GET_TENANTS; private static final String SQL_GET_TENANTS_FROM_OPERATOR; private static final String SQL_GET_ALL_TENANTS; private static final int[] ARGTYPES_KEY = {Types.VARCHAR, Types.VARCHAR}; static { SQL_GET_REMOTE_TENANT = new StringBuilder() .append("SELECT ID, STRINGID, OPERATORID, URL, DESCRIPTION, CREATIONDATE, TENANTCONFIG, TENANTSTATISTIC FROM ") .append(DEFAULT_TABLE_NAME).append(" WHERE OPERATORID = ? AND STRINGID = ? ").toString(); SQL_GET_REMOTE_TENANT_BY_ID = new StringBuilder() .append("SELECT ID, STRINGID, OPERATORID, URL, DESCRIPTION, CREATIONDATE, TENANTCONFIG, TENANTSTATISTIC FROM ") .append(DEFAULT_TABLE_NAME).append(" WHERE ID = ?").toString(); SQL_DELETE_TENANT = new StringBuilder().append("DELETE FROM ").append(DEFAULT_TABLE_NAME).append(" WHERE ") .append(DEFAULT_STRINGID_COLUMN_NAME).append(" = ? AND ").append(FK_OPERATORID).append(" = ? ") .toString(); SQL_UPDATE_TENANT = new StringBuilder().append(" UPDATE ").append(DEFAULT_TABLE_NAME) .append(" SET URL = ?, DESCRIPTION = ?, OPERATORID = ?, CREATIONDATE = ? WHERE ").append(DEFAULT_ID_COLUMN_NAME) .append(" = ? ").toString(); SQL_GET_TENANTS = new StringBuilder().append(" SELECT ").append(DEFAULT_TABLE_KEY).append(", ") .append(DEFAULT_STRINGID_COLUMN_NAME) .append(", OPERATORID, URL, DESCRIPTION, CREATIONDATE, TENANTCONFIG, TENANTSTATISTIC ").append(" FROM ") .append(DEFAULT_TABLE_NAME).append(" WHERE STRINGID != ? ").append(" ORDER BY CREATIONDATE DESC LIMIT ?,?").toString(); SQL_GET_ALL_TENANTS = new StringBuilder().append(" SELECT ").append(DEFAULT_TABLE_KEY).append(", ") .append(DEFAULT_STRINGID_COLUMN_NAME).append(", OPERATORID, URL, DESCRIPTION, CREATIONDATE, TENANTCONFIG, TENANTSTATISTIC FROM ") .append(DEFAULT_TABLE_NAME).append(" ORDER BY CREATIONDATE DESC ").toString(); SQL_GET_TENANTS_FROM_OPERATOR = new StringBuilder().append(" SELECT ").append(DEFAULT_TABLE_KEY).append(", ") .append(DEFAULT_STRINGID_COLUMN_NAME) .append(", OPERATORID, URL, DESCRIPTION, CREATIONDATE, TENANTCONFIG, TENANTSTATISTIC ").append(" FROM ") .append(DEFAULT_TABLE_NAME).append(" WHERE ").append(" OPERATORID = ? ").append(" ORDER BY ") .append(" CREATIONDATE ").toString(); } private RemoteTenantRowMapper remoteTenantRowMapper = new RemoteTenantRowMapper(); private HashMap<String, RemoteTenant> remoteTenantCache = new HashMap<String, RemoteTenant>(); private HashMap<Integer, RemoteTenant> remoteTenantIntCache = new HashMap<Integer, RemoteTenant>(); private PluginRegistry pluginRegistry; private TenantService tenantService; public RemoteTenantDAOMysqlImpl(DataSource dataSource) { super(dataSource); this.setTableId(DEFAULT_TABLE_KEY); this.setTableStringId(DEFAULT_STRINGID_COLUMN_NAME); this.setTableName(DEFAULT_TABLE_NAME); } public void setPluginRegistry(PluginRegistry pluginRegistry) { this.pluginRegistry = pluginRegistry; } public void setTenantService(TenantService tenantService) { this.tenantService = tenantService; } /* * (non-Javadoc) * @see at.researchstudio.sat.recommender.remote.store.dao.ItemDAO#tenantExists(java.lang.String) */ public boolean exists(String operatorId, String tenantId) { return (get(operatorId, tenantId) != null); } /* * (non-Javadoc) * @see at.researchstudio.sat.recommender.remote.store.dao.OperatorDAO#removeOperator(java.lang.String) */ public void remove(String operatorId, String tenantId) { RemoteTenant r = get(operatorId, tenantId); if (r != null) { try { getJdbcTemplate().update(SQL_DELETE_TENANT, new Object[]{tenantId, operatorId}, ARGTYPES_KEY); removeTenantDependencies(r.getId()); remoteTenantIntCache.remove(r.getId()); remoteTenantCache.remove(tenantId + ":::" + operatorId); } catch (Exception e) { logger.debug(e); } } } /* * (non-Javadoc) * @see at.researchstudio.sat.recommender.remote.store.dao.OperatorDAO#get(java.lang.String) */ public RemoteTenant get(String operatorId, String tenantId) { String coreTenantId = tenantId + ":::" + operatorId; RemoteTenant r = remoteTenantCache.get(coreTenantId); if (r != null) { return r; } else { try { Object[] args = {operatorId, tenantId}; r = getJdbcTemplate().queryForObject(SQL_GET_REMOTE_TENANT, args, ARGTYPES_KEY, remoteTenantRowMapper); remoteTenantCache.put(coreTenantId, r); remoteTenantIntCache.put(r.getId(), r); return r; } catch (Exception e) { return null; } } } public RemoteTenant get(Integer tenantId) { RemoteTenant r = remoteTenantIntCache.get(tenantId); if (r != null) { return r; } else { Object[] args = {tenantId}; int[] argTypes = {Types.INTEGER}; try { r = getJdbcTemplate() .queryForObject(SQL_GET_REMOTE_TENANT_BY_ID, args, argTypes, remoteTenantRowMapper); remoteTenantCache.put(r.getStringId() + ":::" + r.getOperatorId(), r); remoteTenantIntCache.put(tenantId, r); return r; } catch (Exception e) { return r; } } } /** * This function returns a tenant for a given tenantid that is retrieved * from the given request Object that contains the parameters tenantId and * operatorId if signed in as administrator. If signed in as operator the * operatorId of the signed in operator is used to query for the tenant. */ public RemoteTenant get(HttpServletRequest request) { return get(Security.getOperatorId(request), ServletUtils.getSafeParameter(request, "tenantId", "")); } /* * (non-Javadoc) * @see at.researchstudio.sat.recommender.remote.store.dao.RemoteTenantDAO#update(java.lang.String, java.lang.String) */ public void update(String operatorId, Integer tenantId, String url, String description) { try { getJdbcTemplate() .update(SQL_UPDATE_TENANT, new Object[]{url, description, operatorId, new Date(), tenantId}, new int[]{Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.TIMESTAMP, Types.INTEGER}); remoteTenantCache.remove(get(tenantId).getStringId() + ":::" + operatorId); remoteTenantIntCache.remove(tenantId); } catch (Exception e) { logger.debug(e); } } /* * (non-Javadoc) * @see at.researchstudio.sat.recommender.remote.store.dao.RemoteTenantDAO#getTenantsFromOperator(java.lang.String) */ public List<RemoteTenant> getTenantsFromOperator(String operatorId) { Object[] args = {operatorId}; int[] argTypes = {Types.VARCHAR}; try { return getJdbcTemplate() .query(SQL_GET_TENANTS_FROM_OPERATOR.replace("{0}", operatorId), args, argTypes, remoteTenantRowMapper); } catch (Exception e) { return null; } } /* * (non-Javadoc) * @see at.researchstudio.sat.recommender.remote.store.dao.RemoteTenantDAO#getTenantsFromOperator(java.lang.String) */ public List<RemoteTenant> getAllTenants() { try { return getJdbcTemplate().query(SQL_GET_ALL_TENANTS, remoteTenantRowMapper); } catch (Exception e) { return null; } } /* * (non-Javadoc) * @see at.researchstudio.sat.recommender.remote.store.dao.RemoteTenantDAO */ public List<RemoteTenant> getTenants(int offset, int limit) { return getTenants(offset,limit,false) ; } /* * (non-Javadoc) * @see at.researchstudio.sat.recommender.remote.store.dao.RemoteTenantDAO */ public List<RemoteTenant> getTenants(int offset, int limit, boolean filterDemoTenants) { try { String filter = ""; if(filterDemoTenants){ filter = "EASYREC_DEMO"; } Object[] args = {filter,offset,limit}; int[] argTypes = {Types.VARCHAR,Types.INTEGER,Types.INTEGER}; return getJdbcTemplate() .query(SQL_GET_TENANTS, args, argTypes, remoteTenantRowMapper); } catch (Exception e) { return null; } } /* * (non-Javadoc) * @see at.researchstudio.sat.recommender.remote.store.dao.OperatorDAO#removeOperator(java.lang.String) */ @InvalidatesCache public boolean removeTenantDependencies(int tenantId) { try { Object[] argsDelete = {tenantId}; int[] argTypesDelete = {Types.INTEGER}; execute("DELETE FROM action WHERE tenantId = ?", argsDelete, argTypesDelete); execute("DELETE FROM aggregatetype WHERE tenantId = ?", argsDelete, argTypesDelete); execute("DELETE FROM actiontype WHERE tenantId = ?", argsDelete, argTypesDelete); execute("DELETE FROM assoctype WHERE tenantId = ?", argsDelete, argTypesDelete); execute("DELETE FROM authentication WHERE tenantId = ?", argsDelete, argTypesDelete); execute("DELETE FROM itemtype WHERE tenantId = ?", argsDelete, argTypesDelete); execute("DELETE FROM itemassoc WHERE tenantId = ?", argsDelete, argTypesDelete); execute("DELETE FROM sourcetype WHERE tenantId = ?", argsDelete, argTypesDelete); execute("DELETE FROM viewtype WHERE tenantId = ?", argsDelete, argTypesDelete); execute("DELETE FROM plugin_log WHERE tenantId = ?", argsDelete, argTypesDelete); execute("DELETE FROM plugin_configuration WHERE tenantId = ?", argsDelete, argTypesDelete); } catch (Exception e) { logger.debug(e); return false; } return true; } /** * updates Tenant from Cache */ public void updateTenantInCache(RemoteTenant r) { remoteTenantCache.remove(r.getStringId() + ":::" + r.getOperatorId()); remoteTenantIntCache.remove(r.getId()); get(r.getId()); } /** * Execute a given sql string with the given parameters */ private void execute(String sql, Object[] args, int[] argTypes) throws Exception { try { getJdbcTemplate().update(sql, args, argTypes); } catch (Exception e) { throw new Exception(); } } /** * Clears the statistic properties */ public void reset(Integer tenantId) { getJdbcTemplate().update("UPDATE tenant SET tenantStatistic='' WHERE id=" + tenantId); } /******************************************************************************************/ /************************************** Rowmappers ****************************************/ /** * ************************************************************************************** */ private class RemoteTenantRowMapper implements RowMapper<RemoteTenant> { public RemoteTenant mapRow(ResultSet rs, int rowNum) throws SQLException { String sTenantConfig = DaoUtils.getStringIfPresent(rs, DEFAULT_TENANT_CONFIG_COLUMN_NAME); Properties tenantConfig = new Properties(); try { tenantConfig.load(new ByteArrayInputStream(new StringBuffer(sTenantConfig).toString().getBytes())); } catch (Exception ignored) { } // no tenantConfig available String sTenantStatistic = DaoUtils.getStringIfPresent(rs, DEFAULT_TENANT_STATISTIC_COLUMN_NAME); Properties tenantStatistic = new Properties(); try { tenantStatistic .load(new ByteArrayInputStream(new StringBuffer(sTenantStatistic).toString().getBytes())); } catch (Exception ignored) { } // no tenantStatistic available RemoteTenant remoteTenant = new RemoteTenant(DaoUtils.getIntegerIfPresent(rs, DEFAULT_ID_COLUMN_NAME), DaoUtils.getStringIfPresent(rs, DEFAULT_STRINGID_COLUMN_NAME), DaoUtils.getStringIfPresent(rs, DEFAULT_OPERATORID_COLUMN_NAME), DaoUtils.getStringIfPresent(rs, DEFAULT_URL_COLUMN_NAME), DaoUtils.getStringIfPresent(rs, DEFAULT_DESCRIPTION_COLUMN_NAME), DaoUtils.getStringIfPresent(rs, DEFAULT_CREATIONDATE_COLUMN_NAME), tenantConfig, tenantStatistic, tenantService.getDefaultTenantConfig().getAssocTypes() //typeMappingService.getAssocTypes(DaoUtils.getIntegerIfPresent(rs,DEFAULT_ID_COLUMN_NAME)) ); try { if (remoteTenant.getPluginsEnabled() && (remoteTenant.getTenantConfigProperties().containsKey(PluginRegistry.GENERATOR_PROP))) { String pluginIdStr = remoteTenant.getTenantConfigProperties().getProperty(PluginRegistry .GENERATOR_PROP); PluginId pluginId = PluginId.parsePluginId(pluginIdStr); Generator<GeneratorConfiguration, GeneratorStatistics> generator = pluginRegistry.getGenerators() .get(pluginId); if ((generator == null) || (LifecyclePhase.NOT_INSTALLED.equals(generator.getLifecyclePhase()))) { remoteTenant.setPlugins(RemoteTenant.DISABLED); tenantService.updateConfigProperty(remoteTenant.getId(), PluginRegistry.PLUGINS_ENABLED_PROP, RemoteTenant.DISABLED); } else { GeneratorConfiguration conf = generator.newConfiguration(); ConfigurationHelper confhelper = new ConfigurationHelper(conf); confhelper.setValues(remoteTenant.getTenantConfigProperties(), pluginId.toString()); remoteTenant.setGeneratorConfig(conf); remoteTenant.updatePluginAssocType(conf.getAssociationType()); } } } catch (Exception ex) { logger.warn("Failed to initialize plugins!", ex); } return remoteTenant; } } }