001: /*
002: * Copyright (c) JForum Team
003: * All rights reserved.
004: *
005: * Redistribution and use in source and binary forms,
006: * with or without modification, are permitted provided
007: * that the following conditions are met:
008: *
009: * 1) Redistributions of source code must retain the above
010: * copyright notice, this list of conditions and the
011: * following disclaimer.
012: * 2) Redistributions in binary form must reproduce the
013: * above copyright notice, this list of conditions and
014: * the following disclaimer in the documentation and/or
015: * other materials provided with the distribution.
016: * 3) Neither the name of "Rafael Steil" nor
017: * the names of its contributors may be used to endorse
018: * or promote products derived from this software without
019: * specific prior written permission.
020: *
021: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
022: * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
023: * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
024: * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
025: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR
026: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
027: * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
028: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
029: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES
030: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
031: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
032: * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
033: * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
034: * IN CONTRACT, STRICT LIABILITY, OR TORT
035: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
036: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
037: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
038: *
039: * Created on 29/11/2005 13:25:55
040: * The JForum Project
041: * http://www.jforum.net
042: */
043: package net.jforum.dao;
044:
045: import java.io.File;
046: import java.io.FileInputStream;
047: import java.io.FileOutputStream;
048: import java.io.OutputStream;
049: import java.sql.Connection;
050: import java.sql.DatabaseMetaData;
051: import java.util.Properties;
052:
053: import net.jforum.ConfigLoader;
054: import net.jforum.util.preferences.ConfigKeys;
055: import net.jforum.util.preferences.SystemGlobals;
056:
057: import org.apache.log4j.Logger;
058:
059: /**
060: * Try to fix some database configuration problems.
061: * This class will much likely do some checks only for mysql.
062: * @author Rafael Steil
063: * @version $Id: MySQLVersionWorkarounder.java,v 1.1 2007/09/12 14:43:13 rafaelsteil Exp $
064: */
065: public class MySQLVersionWorkarounder {
066: private static Logger logger = Logger
067: .getLogger(MySQLVersionWorkarounder.class);
068: private static final String MYSQL_323_DATA_ACCESS_DRIVER = net.jforum.dao.mysql.MySQL323DataAccessDriver.class
069: .getName();
070: private static final String MYSQL_DATA_ACCESS_DRIVER = net.jforum.dao.mysql.MysqlDataAccessDriver.class
071: .getName();
072:
073: public void handleWorkarounds(Connection c) {
074: if (c == null) {
075: logger.warn("Cannot work with a null connection");
076: return;
077: }
078:
079: if (!"mysql".equals(SystemGlobals
080: .getValue(ConfigKeys.DATABASE_DRIVER_NAME))) {
081: return;
082: }
083:
084: try {
085: DatabaseMetaData meta = c.getMetaData();
086: logger.debug("MySQL Version: "
087: + meta.getDatabaseProductVersion());
088:
089: int major = meta.getDatabaseMajorVersion();
090: int minor = meta.getDatabaseMinorVersion();
091:
092: if (major == 3 && minor == 23) {
093: this .handleMySql323();
094: } else if (major == 4 && minor == 0) {
095: this .handleMySql40x();
096: } else if (major > 4 || (major == 4 && minor > 0)) {
097: this .handleMySql41xPlus();
098: }
099: } catch (Exception e) {
100: logger.error(e.toString(), e);
101: }
102: }
103:
104: private void handleMySql323() throws Exception {
105: this .ensureDaoClassIsCorrect(MYSQL_323_DATA_ACCESS_DRIVER);
106:
107: Properties p = this .loadSqlQueries();
108:
109: if (p != null) {
110: String[] necessaryKeys = {
111: "PermissionControl.deleteRoleValuesByRoleId",
112: "PermissionControl.getRoleIdsByGroup",
113: "PermissionControl.getRoles",
114: "PermissionControl.getRoleValues" };
115:
116: boolean shouldUpdate = false;
117:
118: if (p.size() == 0) {
119: shouldUpdate = true;
120: } else {
121: for (int i = 0; i < necessaryKeys.length; i++) {
122: String key = necessaryKeys[i];
123:
124: if (p.getProperty(key) == null) {
125: shouldUpdate = true;
126: break;
127: }
128: }
129: }
130:
131: if (shouldUpdate) {
132: String path = this .buildPath("mysql_323.sql");
133:
134: FileInputStream fis = new FileInputStream(path);
135:
136: try {
137: p.load(fis);
138: this .saveSqlQueries(p);
139: } finally {
140: fis.close();
141: }
142: }
143: }
144: }
145:
146: private void handleMySql40x() throws Exception {
147: this .ensureDaoClassIsCorrect(MYSQL_DATA_ACCESS_DRIVER);
148:
149: Properties p = this .loadSqlQueries();
150:
151: if (p != null) {
152: if (p.size() == 0
153: || p
154: .getProperty("PermissionControl.deleteAllRoleValues") == null) {
155: String path = this .buildPath("mysql_40.sql");
156:
157: FileInputStream fis = new FileInputStream(path);
158:
159: try {
160: p.load(fis);
161: this .saveSqlQueries(p);
162: } finally {
163: fis.close();
164: }
165: }
166: }
167: }
168:
169: private void handleMySql41xPlus() throws Exception {
170: this .ensureDaoClassIsCorrect(MYSQL_DATA_ACCESS_DRIVER);
171:
172: Properties p = this .loadSqlQueries();
173:
174: if (p != null && p.size() > 0) {
175: this .saveSqlQueries(new Properties());
176: }
177:
178: this .fixEncoding();
179: }
180:
181: private void fixEncoding() throws Exception {
182: FileInputStream fis = null;
183: OutputStream os = null;
184:
185: try {
186: Properties p = new Properties();
187:
188: File f = new File(SystemGlobals
189: .getValue(ConfigKeys.DATABASE_DRIVER_CONFIG));
190:
191: if (f.canWrite()) {
192: fis = new FileInputStream(f);
193:
194: p.load(fis);
195:
196: p.setProperty(ConfigKeys.DATABASE_MYSQL_ENCODING, "");
197: p.setProperty(ConfigKeys.DATABASE_MYSQL_UNICODE, "");
198:
199: os = new FileOutputStream(f);
200: p.store(os, null);
201: }
202: } finally {
203: if (fis != null) {
204: fis.close();
205: }
206: if (os != null) {
207: os.close();
208: }
209: }
210: }
211:
212: private void ensureDaoClassIsCorrect(String shouldBe)
213: throws Exception {
214: if (!shouldBe.equals(SystemGlobals
215: .getValue(ConfigKeys.DAO_DRIVER))) {
216: logger.info("MySQL DAO class is incorrect. Setting it to "
217: + shouldBe);
218:
219: this .fixDAODriver(shouldBe);
220:
221: SystemGlobals.setValue(ConfigKeys.DAO_DRIVER, shouldBe);
222: ConfigLoader.loadDaoImplementation();
223: }
224: }
225:
226: private Properties loadSqlQueries() throws Exception {
227: // First, check if we really have a problem
228: String sqlQueries = SystemGlobals
229: .getValue(ConfigKeys.SQL_QUERIES_DRIVER);
230:
231: File f = new File(sqlQueries);
232:
233: Properties p = new Properties();
234:
235: FileInputStream fis = new FileInputStream(f);
236:
237: try {
238: p.load(fis);
239:
240: if (f.canWrite()) {
241: return p;
242: }
243: } finally {
244: try {
245: fis.close();
246: } catch (Exception e) {
247: }
248: }
249:
250: logger.warn("Cannot overwrite" + sqlQueries
251: + " file. Insuficient privileges");
252: return null;
253: }
254:
255: private void saveSqlQueries(Properties p) throws Exception {
256: FileOutputStream fos = new FileOutputStream(SystemGlobals
257: .getValue(ConfigKeys.SQL_QUERIES_DRIVER));
258:
259: try {
260: p.store(fos, null);
261: } finally {
262: fos.close();
263: }
264:
265: SystemGlobals.loadQueries(SystemGlobals
266: .getValue(ConfigKeys.SQL_QUERIES_DRIVER));
267: }
268:
269: private void fixDAODriver(String daoClassName) throws Exception {
270: String driverConfigPath = SystemGlobals
271: .getValue(ConfigKeys.DATABASE_DRIVER_CONFIG);
272:
273: File f = new File(driverConfigPath);
274:
275: if (f.canWrite()) {
276: // Fix the DAO class
277: Properties p = new Properties();
278:
279: FileInputStream fis = new FileInputStream(driverConfigPath);
280: FileOutputStream fos = null;
281:
282: try {
283: p.load(fis);
284: p.setProperty(ConfigKeys.DAO_DRIVER, daoClassName);
285:
286: fos = new FileOutputStream(driverConfigPath);
287: p.store(fos, null);
288: } finally {
289: if (fos != null) {
290: fos.close();
291: }
292:
293: fis.close();
294: }
295: } else {
296: logger.warn("Cannot overwrite" + driverConfigPath
297: + ". Insuficient privileges");
298: }
299: }
300:
301: private String buildPath(String concat) {
302: return new StringBuffer(256).append(
303: SystemGlobals.getValue(ConfigKeys.CONFIG_DIR)).append(
304: '/').append("database/mysql/").append(concat)
305: .toString();
306: }
307: }
|