KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > opencms > setup > CmsSetupDb


1 /*
2  * File : $Source: /usr/local/cvs/opencms/src/org/opencms/setup/CmsSetupDb.java,v $
3  * Date : $Date: 2006/04/28 15:20:52 $
4  * Version: $Revision: 1.26 $
5  *
6  * This library is part of OpenCms -
7  * the Open Source Content Mananagement System
8  *
9  * Copyright (c) 2005 Alkacon Software GmbH (http://www.alkacon.com)
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * Lesser General Public License for more details.
20  *
21  * For further information about Alkacon Software GmbH, please see the
22  * company website: http://www.alkacon.com
23  *
24  * For further information about OpenCms, please see the
25  * project website: http://www.opencms.org
26  *
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30  */

31
32 package org.opencms.setup;
33
34 import org.opencms.main.CmsException;
35 import org.opencms.util.CmsStringUtil;
36
37 import java.io.File JavaDoc;
38 import java.io.FileNotFoundException JavaDoc;
39 import java.io.FileReader JavaDoc;
40 import java.io.InputStreamReader JavaDoc;
41 import java.io.LineNumberReader JavaDoc;
42 import java.io.Reader JavaDoc;
43 import java.io.StringReader JavaDoc;
44 import java.sql.Connection JavaDoc;
45 import java.sql.DriverManager JavaDoc;
46 import java.sql.ResultSet JavaDoc;
47 import java.sql.SQLException JavaDoc;
48 import java.sql.Statement JavaDoc;
49 import java.util.Iterator JavaDoc;
50 import java.util.Map JavaDoc;
51 import java.util.StringTokenizer JavaDoc;
52 import java.util.Vector JavaDoc;
53
54 /**
55  * Helper class to call database setup scripts.<p>
56  *
57  * @author Thomas Weckert
58  * @author Carsten Weinholz
59  *
60  * @version $Revision: 1.26 $
61  *
62  * @since 6.0.0
63  */

64 public class CmsSetupDb extends Object JavaDoc {
65
66     /** The folder where to read the setup data from. */
67     public static final String JavaDoc SETUP_DATA_FOLDER = "WEB-INF/setupdata/";
68
69     /** The folder where the setup wizard is located. */
70     public static final String JavaDoc SETUP_FOLDER = "setup/";
71
72     private String JavaDoc m_basePath;
73     private Connection JavaDoc m_con;
74     private boolean m_errorLogging;
75     private Vector JavaDoc m_errors;
76
77     /**
78      * Creates a new CmsSetupDb object.<p>
79      *
80      * @param basePath the location of the setup scripts
81      */

82     public CmsSetupDb(String JavaDoc basePath) {
83
84         m_errors = new Vector JavaDoc();
85         m_basePath = basePath;
86         m_errorLogging = true;
87     }
88
89     /**
90      * Clears the error messages stored internally.<p>
91      */

92     public void clearErrors() {
93
94         m_errors.clear();
95     }
96
97     /**
98      * Closes the internal connection to the database.<p>
99      */

100     public void closeConnection() {
101
102         try {
103             m_con.close();
104         } catch (Exception JavaDoc e) {
105             // ignore
106
}
107     }
108
109     /**
110      * Calls the create database script for the given database.<p>
111      *
112      * @param database the name of the database
113      * @param replacer the replacements to perform in the drop script
114      */

115     public void createDatabase(String JavaDoc database, Map JavaDoc replacer) {
116
117         m_errorLogging = true;
118         executeSql(database, "create_db.sql", replacer, true);
119     }
120
121     /**
122      * Calls the create database script for the given database.<p>
123      *
124      * @param database the name of the database
125      * @param replacer the replacements to perform in the drop script
126      * @param abortOnError indicates if the script is aborted if an error occurs
127      */

128     public void createDatabase(String JavaDoc database, Map JavaDoc replacer, boolean abortOnError) {
129
130         m_errorLogging = true;
131         executeSql(database, "create_db.sql", replacer, abortOnError);
132     }
133
134     /**
135      * Calls the create tables script for the given database.<p>
136      *
137      * @param database the name of the database
138      * @param replacer the replacements to perform in the drop script
139      */

140     public void createTables(String JavaDoc database, Map JavaDoc replacer) {
141
142         m_errorLogging = true;
143         executeSql(database, "create_tables.sql", replacer, true);
144     }
145
146     /**
147      * Calls the create tables script for the given database.<p>
148      *
149      * @param database the name of the database
150      * @param replacer the replacements to perform in the drop script
151      * @param abortOnError indicates if the script is aborted if an error occurs
152      */

153     public void createTables(String JavaDoc database, Map JavaDoc replacer, boolean abortOnError) {
154
155         m_errorLogging = true;
156         executeSql(database, "create_tables.sql", replacer, abortOnError);
157     }
158
159     /**
160      * Calls the drop script for the given database.
161      *
162      * @param database the name of the database
163      * @param replacer the replacements to perform in the drop script
164      */

165     public void dropDatabase(String JavaDoc database, Map JavaDoc replacer) {
166
167         m_errorLogging = true;
168         executeSql(database, "drop_db.sql", replacer, false);
169     }
170
171     /**
172      * Calls the drop script for the given database.
173      *
174      * @param database the name of the database
175      * @param replacer the replacements to perform in the drop script
176      * @param abortOnError indicates if the script is aborted if an error occurs
177      */

178     public void dropDatabase(String JavaDoc database, Map JavaDoc replacer, boolean abortOnError) {
179
180         m_errorLogging = true;
181         executeSql(database, "drop_db.sql", replacer, abortOnError);
182     }
183
184     /**
185      * Calls the drop tables script for the given database.<p>
186      *
187      * @param database the name of the database
188      */

189     public void dropTables(String JavaDoc database) {
190
191         m_errorLogging = true;
192         executeSql(database, "drop_tables.sql", null, false);
193     }
194
195     /**
196      * Calls the drop tables script for the given database.<p>
197      *
198      * @param database the name of the database
199      * @param replacer the replacements to perform in the drop script
200      */

201     public void dropTables(String JavaDoc database, Map JavaDoc replacer) {
202
203         m_errorLogging = true;
204         executeSql(database, "drop_tables.sql", replacer, false);
205     }
206
207     /**
208      * Calls the drop tables script for the given database.<p>
209      *
210      * @param database the name of the database
211      * @param replacer the replacements to perform in the drop script
212      * @param abortOnError indicates if the script is aborted if an error occurs
213      */

214     public void dropTables(String JavaDoc database, Map JavaDoc replacer, boolean abortOnError) {
215
216         m_errorLogging = true;
217         executeSql(database, "drop_tables.sql", replacer, abortOnError);
218     }
219
220     /**
221      * Returns a Vector of Error messages.<p>
222      *
223      * @return all error messages collected internally
224      */

225     public Vector JavaDoc getErrors() {
226
227         return m_errors;
228     }
229
230     /**
231      * Checks if internal errors occured.<p>
232      *
233      * @return true if internal errors occured
234      */

235     public boolean noErrors() {
236
237         return m_errors.isEmpty();
238     }
239
240     /**
241      * Sets a new internal connection to teh database.<p>
242      *
243      * @param conn the connection to use
244      */

245     public void setConnection(Connection JavaDoc conn) {
246
247         m_con = conn;
248     }
249
250     /**
251      * Creates a new internal connection to the database.<p>
252      *
253      * @param DbDriver JDBC driver class name
254      * @param DbConStr JDBC connect URL
255      * @param DbConStrParams JDBC connect URL params, or null
256      * @param DbUser JDBC database user
257      * @param DbPwd JDBC database password
258      */

259     public void setConnection(String JavaDoc DbDriver, String JavaDoc DbConStr, String JavaDoc DbConStrParams, String JavaDoc DbUser, String JavaDoc DbPwd) {
260
261         String JavaDoc jdbcUrl = DbConStr;
262         try {
263             if (DbConStrParams != null) {
264                 jdbcUrl += DbConStrParams;
265             }
266             Class.forName(DbDriver).newInstance();
267             m_con = DriverManager.getConnection(jdbcUrl, DbUser, DbPwd);
268         } catch (ClassNotFoundException JavaDoc e) {
269             m_errors.addElement(Messages.get().getBundle().key(Messages.ERR_LOAD_JDBC_DRIVER_1, DbDriver));
270             m_errors.addElement(CmsException.getStackTraceAsString(e));
271         } catch (Exception JavaDoc e) {
272             m_errors.addElement(Messages.get().getBundle().key(Messages.ERR_DB_CONNECT_1, DbConStr));
273             m_errors.addElement(CmsException.getStackTraceAsString(e));
274         }
275     }
276
277     /**
278      * Returns an optional warning message if needed, <code>null</code> if not.<p>
279      *
280      * @param db the selected database key
281      *
282      * @return html warning, or <code>null</code> if no warning
283      */

284     public String JavaDoc checkVariables(String JavaDoc db) {
285
286         StringBuffer JavaDoc html = new StringBuffer JavaDoc(512);
287         if (m_con == null) {
288             return null; // prior error, trying to get a connection
289
}
290         SQLException JavaDoc exception = null;
291         if (db.equals("mysql")) { // just for 4.0, > is not needed, < is not supported.
292
String JavaDoc statement = "SELECT @@max_allowed_packet;";
293             Statement JavaDoc stmt = null;
294             ResultSet JavaDoc rs = null;
295             long map = 0;
296             try {
297                 stmt = m_con.createStatement();
298                 rs = stmt.executeQuery(statement);
299                 if (rs.next()) {
300                     map = rs.getLong(1);
301                 }
302             } catch (SQLException JavaDoc e) {
303                 exception = e;
304             } finally {
305                 if (stmt != null) {
306                     try {
307                         stmt.close();
308                     } catch (SQLException JavaDoc e) {
309                         // ignore
310
}
311                 }
312             }
313             if (exception == null) {
314                 if (map > 0) {
315                     html.append("MySQL system variable <code>'max_allowed_packet'</code> is set to ");
316                     html.append(map);
317                     html.append(" Bytes.<p>\n");
318                 }
319                 html.append("Please, note that it will not be possible for OpenCms to handle files bigger than this value.<p>\n");
320                 if (map < 15 * 1024 * 1024) {
321                     m_errors.addElement("<b>Your <code>'max_allowed_packet'</code> variable is set to less than 16Mb ("
322                         + map
323                         + ").</b>\n"
324                         + "The recommended value for running OpenCms is 16Mb."
325                         + "Please change your MySQL configuration (in your <code>mi.ini</code> or <code>my.cnf</code> file).\n");
326                 }
327             }
328         }
329         if (exception != null || db.equals("mysql_3")) {
330             html.append("<i>OpenCms was not able to detect the value of your <code>'max_allowed_packet'</code> variable.</i><p>\n");
331             html.append("Please, note that it will not be possible for OpenCms to handle files bigger than this value.<p>\n");
332             html.append("<b>The recommended value for running OpenCms is 16Mb, please set it in your MySQL configuration (in your <code>mi.ini</code> or <code>my.cnf</code> file).</b>\n");
333             if (exception != null) {
334                 html.append(CmsException.getStackTraceAsString(exception));
335             }
336         }
337         if (html.length() == 0) {
338             return null;
339         }
340         return html.toString();
341     }
342
343     /**
344      * Calls an update script.<p>
345      *
346      * @param updateScript the update script code
347      * @param replacers the replacers to use in the script code
348      */

349     public void updateDatabase(String JavaDoc updateScript, Map JavaDoc replacers) {
350
351         StringReader JavaDoc reader = new StringReader JavaDoc(updateScript);
352         executeSql(reader, replacers, true);
353     }
354
355     /**
356      * Calls an update script.<p>
357      *
358      * @param updateScript the update script code
359      * @param replacers the replacers to use in the script code
360      * @param abortOnError indicates if the script is aborted if an error occurs
361      */

362     public void updateDatabase(String JavaDoc updateScript, Map JavaDoc replacers, boolean abortOnError) {
363
364         StringReader JavaDoc reader = new StringReader JavaDoc(updateScript);
365         executeSql(reader, replacers, abortOnError);
366     }
367
368     /**
369      * @see java.lang.Object#finalize()
370      */

371     protected void finalize() throws Throwable JavaDoc {
372
373         try {
374             closeConnection();
375         } catch (Throwable JavaDoc t) {
376             // ignore
377
}
378         super.finalize();
379     }
380
381     /**
382      * Internal method to parse and execute a setup script.<p>
383      *
384      * @param inputReader an input stream reader on the setup script
385      * @param replacers the replacements to perform in the script
386      * @param abortOnError if a error occurs this flag indicates if to continue or to abort
387      */

388     private void executeSql(Reader JavaDoc inputReader, Map JavaDoc replacers, boolean abortOnError) {
389
390         String JavaDoc statement = "";
391         LineNumberReader JavaDoc reader = null;
392         String JavaDoc line = null;
393
394         // parse the setup script
395
try {
396             reader = new LineNumberReader JavaDoc(inputReader);
397             line = null;
398
399             while (true) {
400                 line = reader.readLine();
401                 if (line == null) {
402                     break;
403                 }
404                 StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(line);
405
406                 while (st.hasMoreTokens()) {
407                     String JavaDoc currentToken = st.nextToken();
408
409                     // comment! Skip rest of the line
410
if (currentToken.startsWith("#")) {
411                         break;
412                     }
413
414                     // not to be executed
415
if (currentToken.startsWith("prompt")) {
416                         break;
417                     }
418
419                     // add token to query
420
statement += " " + currentToken;
421
422                     // query complete (terminated by ';')
423
if (currentToken.endsWith(";")) {
424                         // cut of ';' at the end
425
statement = statement.substring(0, (statement.length() - 1));
426
427                         // normal statement, execute it
428
try {
429                             if (replacers != null) {
430                                 statement = replaceTokens(statement, replacers);
431                                 executeStatement(statement);
432                             } else {
433                                 executeStatement(statement);
434                             }
435                         } catch (SQLException JavaDoc e) {
436                             if (!abortOnError) {
437                                 if (m_errorLogging) {
438                                     m_errors.addElement("Error executing SQL statement: " + statement);
439                                     m_errors.addElement(CmsException.getStackTraceAsString(e));
440                                 }
441                             } else {
442                                 throw e;
443                             }
444                         }
445
446                         // reset
447
statement = "";
448                     }
449                 }
450
451                 statement += " \n";
452             }
453         } catch (SQLException JavaDoc e) {
454             if (m_errorLogging) {
455                 m_errors.addElement("Error executing SQL statement: " + statement);
456                 m_errors.addElement(CmsException.getStackTraceAsString(e));
457             }
458         } catch (Exception JavaDoc e) {
459             if (m_errorLogging) {
460                 m_errors.addElement("Error parsing database setup SQL script in line: " + line);
461                 m_errors.addElement(CmsException.getStackTraceAsString(e));
462             }
463         } finally {
464             try {
465                 if (reader != null) {
466                     reader.close();
467                 }
468             } catch (Exception JavaDoc e) {
469                 // noop
470
}
471         }
472     }
473
474     /**
475      * Internal method to parse and execute a setup script.<p>
476      *
477      * @param databaseKey the database variant of the script
478      * @param sqlScript the name of the script
479      * @param replacers the replacements to perform in the script
480      * @param abortOnError if a error occurs this flag indicates if to continue or to abort
481      */

482     private void executeSql(String JavaDoc databaseKey, String JavaDoc sqlScript, Map JavaDoc replacers, boolean abortOnError) {
483
484         String JavaDoc filename = null;
485         InputStreamReader JavaDoc reader = null;
486         try {
487             filename = m_basePath
488                 + "setup"
489                 + File.separator
490                 + "database"
491                 + File.separator
492                 + databaseKey
493                 + File.separator
494                 + sqlScript;
495             executeSql(new FileReader JavaDoc(filename), replacers, abortOnError);
496         } catch (FileNotFoundException JavaDoc e) {
497             if (m_errorLogging) {
498                 m_errors.addElement("Database setup SQL script not found: " + filename);
499                 m_errors.addElement(CmsException.getStackTraceAsString(e));
500             }
501         } finally {
502             try {
503                 if (reader != null) {
504                     reader.close();
505                 }
506             } catch (Exception JavaDoc e) {
507                 // noop
508
}
509         }
510     }
511
512     /**
513      * Creates and executes a database statment from a String.<p>
514      *
515      * @param statement the database statement
516      *
517      * @throws SQLException if something goes wrong
518      */

519     private void executeStatement(String JavaDoc statement) throws SQLException JavaDoc {
520
521         Statement JavaDoc stmt = null;
522
523         try {
524             stmt = m_con.createStatement();
525             stmt.execute(statement);
526         } finally {
527             if (stmt != null) {
528                 stmt.close();
529             }
530         }
531     }
532
533     /**
534      * Replaces tokens "${xxx}" in a specified SQL query.<p>
535      *
536      * @param sql a SQL query
537      * @param replacers a Map with values keyed by "${xxx}" tokens
538      * @return the SQl query with all "${xxx}" tokens replaced
539      */

540     private String JavaDoc replaceTokens(String JavaDoc sql, Map JavaDoc replacers) {
541
542         Iterator JavaDoc keys = replacers.keySet().iterator();
543         while (keys.hasNext()) {
544
545             String JavaDoc key = (String JavaDoc)keys.next();
546             String JavaDoc value = (String JavaDoc)replacers.get(key);
547
548             sql = CmsStringUtil.substitute(sql, key, value);
549         }
550
551         return sql;
552     }
553 }
Popular Tags