/* * Copyright (c) JForum Team * All rights reserved. * * Redistribution and use in source and binary forms, * with or without modification, are permitted provided * that the following conditions are met: * * 1) Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * 2) Redistributions in binary form must reproduce the * above copyright notice, this list of conditions and * the following disclaimer in the documentation and/or * other materials provided with the distribution. * 3) Neither the name of "Rafael Steil" nor * the names of its contributors may be used to endorse * or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE * * Created on 29/11/2005 13:25:55 * The JForum Project * http://www.jforum.net */ package net.jforum.dao; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.OutputStream; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.util.Properties; import net.jforum.ConfigLoader; import net.jforum.util.preferences.ConfigKeys; import net.jforum.util.preferences.SystemGlobals; import org.apache.log4j.Logger; /** * Try to fix some database configuration problems. * This class will much likely do some checks only for mysql. * @author Rafael Steil * @version $Id: MySQLVersionWorkarounder.java,v 1.1 2007/09/12 14:43:13 rafaelsteil Exp $ */ public class MySQLVersionWorkarounder { private static Logger logger = Logger.getLogger(MySQLVersionWorkarounder.class); private static final String MYSQL_323_DATA_ACCESS_DRIVER = net.jforum.dao.mysql.MySQL323DataAccessDriver.class.getName(); private static final String MYSQL_DATA_ACCESS_DRIVER = net.jforum.dao.mysql.MysqlDataAccessDriver.class.getName(); public void handleWorkarounds(Connection c) { if (c == null) { logger.warn("Cannot work with a null connection"); return; } if (!"mysql".equals(SystemGlobals.getValue(ConfigKeys.DATABASE_DRIVER_NAME))) { return; } try { DatabaseMetaData meta = c.getMetaData(); logger.debug("MySQL Version: " + meta.getDatabaseProductVersion()); int major = meta.getDatabaseMajorVersion(); int minor = meta.getDatabaseMinorVersion(); if (major == 3 && minor == 23) { this.handleMySql323(); } else if (major == 4 && minor == 0) { this.handleMySql40x(); } else if (major > 4 || (major == 4 && minor > 0)) { this.handleMySql41xPlus(); } } catch (Exception e) { logger.error(e.toString(), e); } } private void handleMySql323() throws Exception { this.ensureDaoClassIsCorrect(MYSQL_323_DATA_ACCESS_DRIVER); Properties p = this.loadSqlQueries(); if (p != null) { String[] necessaryKeys = { "PermissionControl.deleteRoleValuesByRoleId", "PermissionControl.getRoleIdsByGroup", "PermissionControl.getRoles", "PermissionControl.getRoleValues" }; boolean shouldUpdate = false; if (p.size() == 0) { shouldUpdate = true; } else { for (int i = 0; i < necessaryKeys.length; i++) { String key = necessaryKeys[i]; if (p.getProperty(key) == null) { shouldUpdate = true; break; } } } if (shouldUpdate) { String path = this.buildPath("mysql_323.sql"); FileInputStream fis = new FileInputStream(path); try { p.load(fis); this.saveSqlQueries(p); } finally { fis.close(); } } } } private void handleMySql40x() throws Exception { this.ensureDaoClassIsCorrect(MYSQL_DATA_ACCESS_DRIVER); Properties p = this.loadSqlQueries(); if (p != null) { if (p.size() == 0 || p.getProperty("PermissionControl.deleteAllRoleValues") == null) { String path = this.buildPath("mysql_40.sql"); FileInputStream fis = new FileInputStream(path); try { p.load(fis); this.saveSqlQueries(p); } finally { fis.close(); } } } } private void handleMySql41xPlus() throws Exception { this.ensureDaoClassIsCorrect(MYSQL_DATA_ACCESS_DRIVER); Properties p = this.loadSqlQueries(); if (p != null && p.size() > 0) { this.saveSqlQueries(new Properties()); } this.fixEncoding(); } private void fixEncoding() throws Exception { FileInputStream fis = null; OutputStream os = null; try { Properties p = new Properties(); File f = new File(SystemGlobals.getValue(ConfigKeys.DATABASE_DRIVER_CONFIG)); if (f.canWrite()) { fis = new FileInputStream(f); p.load(fis); p.setProperty(ConfigKeys.DATABASE_MYSQL_ENCODING, ""); p.setProperty(ConfigKeys.DATABASE_MYSQL_UNICODE, ""); os = new FileOutputStream(f); p.store(os, null); } } finally { if (fis != null) { fis.close(); } if (os != null) { os.close(); } } } private void ensureDaoClassIsCorrect(String shouldBe) throws Exception { if (!shouldBe.equals(SystemGlobals.getValue(ConfigKeys.DAO_DRIVER))) { logger.info("MySQL DAO class is incorrect. Setting it to " + shouldBe); this.fixDAODriver(shouldBe); SystemGlobals.setValue(ConfigKeys.DAO_DRIVER, shouldBe); ConfigLoader.loadDaoImplementation(); } } private Properties loadSqlQueries() throws Exception { // First, check if we really have a problem String sqlQueries = SystemGlobals.getValue(ConfigKeys.SQL_QUERIES_DRIVER); File f = new File(sqlQueries); Properties p = new Properties(); FileInputStream fis = new FileInputStream(f); try { p.load(fis); if (f.canWrite()) { return p; } } finally { try { fis.close(); } catch (Exception e) {} } logger.warn("Cannot overwrite" + sqlQueries + " file. Insuficient privileges"); return null; } private void saveSqlQueries(Properties p) throws Exception { FileOutputStream fos = new FileOutputStream(SystemGlobals.getValue(ConfigKeys.SQL_QUERIES_DRIVER)); try { p.store(fos, null); } finally { fos.close(); } SystemGlobals.loadQueries(SystemGlobals.getValue(ConfigKeys.SQL_QUERIES_DRIVER)); } private void fixDAODriver(String daoClassName) throws Exception { String driverConfigPath = SystemGlobals.getValue(ConfigKeys.DATABASE_DRIVER_CONFIG); File f = new File(driverConfigPath); if (f.canWrite()) { // Fix the DAO class Properties p = new Properties(); FileInputStream fis = new FileInputStream(driverConfigPath); FileOutputStream fos = null; try { p.load(fis); p.setProperty(ConfigKeys.DAO_DRIVER, daoClassName); fos = new FileOutputStream(driverConfigPath); p.store(fos, null); } finally { if (fos != null) { fos.close(); } fis.close(); } } else { logger.warn("Cannot overwrite" + driverConfigPath + ". Insuficient privileges"); } } private String buildPath(String concat) { return new StringBuffer(256) .append(SystemGlobals.getValue(ConfigKeys.CONFIG_DIR)) .append('/') .append("database/mysql/") .append(concat) .toString(); } }