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: * This file creation date: 27/08/2004 - 18:15:54
040: * The JForum Project
041: * http://www.jforum.net
042: */
043: package net.jforum.view.install;
044:
045: import java.io.File;
046: import java.io.FileInputStream;
047: import java.io.FileOutputStream;
048: import java.io.IOException;
049: import java.sql.Connection;
050: import java.sql.PreparedStatement;
051: import java.sql.SQLException;
052: import java.sql.Statement;
053: import java.util.Date;
054: import java.util.Enumeration;
055: import java.util.Iterator;
056: import java.util.List;
057: import java.util.Locale;
058: import java.util.Properties;
059:
060: import net.jforum.Command;
061: import net.jforum.ConfigLoader;
062: import net.jforum.DBConnection;
063: import net.jforum.DataSourceConnection;
064: import net.jforum.JForumExecutionContext;
065: import net.jforum.SessionFacade;
066: import net.jforum.SimpleConnection;
067: import net.jforum.context.RequestContext;
068: import net.jforum.context.ResponseContext;
069: import net.jforum.dao.DataAccessDriver;
070: import net.jforum.dao.ForumDAO;
071: import net.jforum.dao.PostDAO;
072: import net.jforum.dao.TopicDAO;
073: import net.jforum.entities.Post;
074: import net.jforum.entities.Topic;
075: import net.jforum.entities.User;
076: import net.jforum.entities.UserSession;
077: import net.jforum.exceptions.DatabaseException;
078: import net.jforum.exceptions.ForumException;
079: import net.jforum.util.DbUtils;
080: import net.jforum.util.FileMonitor;
081: import net.jforum.util.I18n;
082: import net.jforum.util.MD5;
083: import net.jforum.util.preferences.ConfigKeys;
084: import net.jforum.util.preferences.SystemGlobals;
085: import net.jforum.util.preferences.SystemGlobalsListener;
086: import net.jforum.util.preferences.TemplateKeys;
087:
088: import org.apache.commons.lang.StringUtils;
089: import org.apache.log4j.Logger;
090:
091: import freemarker.template.SimpleHash;
092: import freemarker.template.Template;
093:
094: /**
095: * JForum Web Installer.
096: *
097: * @author Rafael Steil
098: * @version $Id: InstallAction.java,v 1.79 2007/10/08 17:34:40 rafaelsteil Exp $
099: */
100: public class InstallAction extends Command {
101: private static Logger logger = Logger
102: .getLogger(InstallAction.class);
103:
104: private static final String POOLED_CONNECTION = net.jforum.PooledConnection.class
105: .getName();
106: private static final String SIMPLE_CONNECTION = net.jforum.SimpleConnection.class
107: .getName();
108: private static final String DATASOURCE_CONNECTION = net.jforum.DataSourceConnection.class
109: .getName();
110:
111: public void welcome() {
112: this .checkLanguage();
113:
114: this .context.put("language", this .getFromSession("language"));
115: this .context.put("database", this .getFromSession("database"));
116: this .context.put("dbhost", this .getFromSession("dbHost"));
117: this .context.put("dbuser", this .getFromSession("dbUser"));
118: this .context.put("dbname", this .getFromSession("dbName"));
119: this .context.put("dbport", this .getFromSession("dbPort"));
120: this .context.put("dbpasswd", this .getFromSession("dbPassword"));
121: this .context.put("dbencoding", this
122: .getFromSession("dbEncoding"));
123: this .context.put("use_pool", this .getFromSession("usePool"));
124: this .context.put("forumLink", this .getFromSession("forumLink"));
125: this .context.put("siteLink", this .getFromSession("siteLink"));
126: this .context.put("dbdatasource", this
127: .getFromSession("dbdatasource"));
128:
129: this .setTemplateName(TemplateKeys.INSTALL_WELCOME);
130: }
131:
132: private void checkLanguage() {
133: String lang = this .request.getParameter("l");
134:
135: if (lang == null) {
136: Locale locale = this .request.getLocale();
137: lang = locale.getLanguage() + "_" + locale.getCountry();
138: }
139:
140: if (!I18n.languageExists(lang)) {
141: return;
142: }
143: I18n.load(lang);
144:
145: UserSession us = new UserSession();
146: us.setLang(lang);
147:
148: SessionFacade.add(us);
149: this .addToSessionAndContext("language", lang);
150: }
151:
152: private String getFromSession(String key) {
153: return (String) this .request.getSessionContext().getAttribute(
154: key);
155: }
156:
157: private void error() {
158: this .setTemplateName(TemplateKeys.INSTALL_ERROR);
159: }
160:
161: public void doInstall() {
162: if (!this .checkForWritableDir()) {
163: return;
164: }
165:
166: this .removeUserConfig();
167:
168: Connection conn = null;
169:
170: if (!"passed".equals(this .getFromSession("configureDatabase"))) {
171: logger.info("Going to configure the database...");
172:
173: conn = this .configureDatabase();
174:
175: if (conn == null) {
176: this .context.put("message", I18n
177: .getMessage("Install.databaseError"));
178: this .error();
179: return;
180: }
181: }
182:
183: logger.info("Database configuration ok");
184:
185: // Database Configuration is ok
186: this .addToSessionAndContext("configureDatabase", "passed");
187:
188: DBConnection simpleConnection = new SimpleConnection();
189:
190: if (conn == null) {
191: conn = simpleConnection.getConnection();
192: }
193:
194: boolean dbError = false;
195:
196: try {
197: //this.setupAutoCommit(conn);
198:
199: if (!"passed".equals(this .getFromSession("createTables"))
200: && !this .createTables(conn)) {
201: this .context.put("message", I18n
202: .getMessage("Install.createTablesError"));
203: dbError = true;
204: this .error();
205: return;
206: }
207:
208: // Create tables is ok
209: this .addToSessionAndContext("createTables", "passed");
210: logger.info("Table creation is ok");
211: this .setupAutoCommit(conn);
212: if (!"passed".equals(this
213: .getFromSession("importTablesData"))
214: && !this .importTablesData(conn)) {
215: this .context.put("message", I18n
216: .getMessage("Install.importTablesDataError"));
217: dbError = true;
218: this .error();
219: return;
220: }
221:
222: // Dump is ok
223: this .addToSessionAndContext("importTablesData", "passed");
224:
225: if (!this .updateAdminPassword(conn)) {
226: this .context.put("message", I18n
227: .getMessage("Install.updateAdminError"));
228: dbError = true;
229: this .error();
230: return;
231: }
232:
233: this .storeSupportProjectMessage(conn);
234: } finally {
235: if (conn != null) {
236: try {
237: if (dbError) {
238: conn.rollback();
239: } else {
240: conn.commit();
241: }
242: } catch (SQLException e) {
243: }
244:
245: simpleConnection.releaseConnection(conn);
246: }
247: }
248:
249: JForumExecutionContext.setRedirect(this .request
250: .getContextPath()
251: + "/install/install"
252: + SystemGlobals.getValue(ConfigKeys.SERVLET_EXTENSION)
253: + "?module=install&action=finished");
254: }
255:
256: private void setupAutoCommit(Connection conn) {
257: try {
258: conn.setAutoCommit(false);
259: } catch (SQLException e) {
260: throw new DatabaseException(e);
261: }
262: }
263:
264: private void removeUserConfig() {
265: File f = new File(SystemGlobals
266: .getValue(ConfigKeys.INSTALLATION_CONFIG));
267:
268: if (f.exists() && f.canWrite()) {
269: try {
270: f.delete();
271: } catch (Exception e) {
272: logger.info(e.toString());
273: }
274: }
275: }
276:
277: public void finished() {
278: this .setTemplateName(TemplateKeys.INSTALL_FINISHED);
279:
280: this .context.put("clickHere", I18n
281: .getMessage("Install.clickHere"));
282: this .context.put("forumLink", this .getFromSession("forumLink"));
283:
284: String lang = this .getFromSession("language");
285:
286: if (lang == null) {
287: lang = "en_US";
288: }
289:
290: this .context.put("lang", lang);
291:
292: this .fixModulesMapping();
293: this .configureSystemGlobals();
294:
295: SystemGlobals.loadQueries(SystemGlobals
296: .getValue(ConfigKeys.SQL_QUERIES_GENERIC));
297: SystemGlobals.loadQueries(SystemGlobals
298: .getValue(ConfigKeys.SQL_QUERIES_DRIVER));
299:
300: SessionFacade.remove(this .request.getSessionContext().getId());
301: }
302:
303: private void fixModulesMapping() {
304: FileInputStream fis = null;
305: FileOutputStream fos = null;
306:
307: try {
308: // Modules Mapping
309: String modulesMapping = SystemGlobals
310: .getValue(ConfigKeys.CONFIG_DIR)
311: + "/modulesMapping.properties";
312:
313: if (new File(modulesMapping).canWrite()) {
314: Properties p = new Properties();
315: fis = new FileInputStream(modulesMapping);
316: p.load(fis);
317:
318: if (p.containsKey("install")) {
319: p.remove("install");
320:
321: fos = new FileOutputStream(modulesMapping);
322:
323: p.store(fos, "Modified by JForum Installer");
324: ConfigLoader.loadModulesMapping(SystemGlobals
325: .getValue(ConfigKeys.CONFIG_DIR));
326: }
327:
328: this .addToSessionAndContext("mappingFixed", "true");
329: }
330: } catch (Exception e) {
331: logger
332: .warn("Error while working on modulesMapping.properties: "
333: + e);
334: } finally {
335: if (fis != null) {
336: try {
337: fis.close();
338: } catch (Exception e) {
339: }
340: }
341:
342: if (fos != null) {
343: try {
344: fos.close();
345: } catch (Exception e) {
346: }
347: }
348: }
349: }
350:
351: private void configureSystemGlobals() {
352: SystemGlobals.setValue(ConfigKeys.USER_HASH_SEQUENCE, MD5
353: .crypt(this .getFromSession("dbPassword")
354: + System.currentTimeMillis()));
355:
356: SystemGlobals.setValue(ConfigKeys.FORUM_LINK, this
357: .getFromSession("forumLink"));
358: SystemGlobals.setValue(ConfigKeys.HOMEPAGE_LINK, this
359: .getFromSession("siteLink"));
360: SystemGlobals.setValue(ConfigKeys.I18N_DEFAULT, this
361: .getFromSession("language"));
362: SystemGlobals.setValue(ConfigKeys.INSTALLED, "true");
363:
364: SystemGlobals.saveInstallation();
365:
366: this .restartSystemGlobals();
367: }
368:
369: private boolean importTablesData(Connection conn) {
370: try {
371: boolean status = true;
372: boolean autoCommit = conn.getAutoCommit();
373: conn.setAutoCommit(false);
374:
375: String dbType = this .getFromSession("database");
376:
377: List statements = ParseDBDumpFile.parse(SystemGlobals
378: .getValue(ConfigKeys.CONFIG_DIR)
379: + "/database/"
380: + dbType
381: + "/"
382: + dbType
383: + "_data_dump.sql");
384:
385: for (Iterator iter = statements.iterator(); iter.hasNext();) {
386: String query = (String) iter.next();
387:
388: if (query == null || "".equals(query.trim())) {
389: continue;
390: }
391:
392: query = query.trim();
393:
394: Statement s = conn.createStatement();
395:
396: try {
397: if (query.startsWith("UPDATE")
398: || query.startsWith("INSERT")
399: || query.startsWith("SET")) {
400: s.executeUpdate(query);
401: } else if (query.startsWith("SELECT")) {
402: s.executeQuery(query);
403: } else {
404: throw new SQLException("Invalid query: "
405: + query);
406: }
407: } catch (SQLException ex) {
408: status = false;
409: conn.rollback();
410: logger.error("Error importing data for " + query
411: + ": " + ex, ex);
412: this .context.put("exceptionMessage", ex
413: .getMessage()
414: + "\n" + query);
415: break;
416: } finally {
417: s.close();
418: }
419: }
420:
421: conn.setAutoCommit(autoCommit);
422: return status;
423: } catch (Exception e) {
424: throw new ForumException(e);
425: }
426: }
427:
428: private boolean createTables(Connection conn) {
429:
430: logger.info("Going to create tables...");
431: String dbType = this .getFromSession("database");
432:
433: if ("postgresql".equals(dbType) || "oracle".equals(dbType)) {
434: // This should be in a separate transaction block; otherwise, an empty database will fail.
435: this .dropOracleOrPostgreSQLTables(dbType, conn);
436: }
437: try {
438: boolean status = true;
439: boolean autoCommit = conn.getAutoCommit();
440: conn.setAutoCommit(false);
441:
442: List statements = ParseDBStructFile.parse(SystemGlobals
443: .getValue(ConfigKeys.CONFIG_DIR)
444: + "/database/"
445: + dbType
446: + "/"
447: + dbType
448: + "_db_struct.sql");
449:
450: for (Iterator iter = statements.iterator(); iter.hasNext();) {
451: String query = (String) iter.next();
452:
453: if (query == null || "".equals(query.trim())) {
454: continue;
455: }
456:
457: Statement s = null;
458:
459: try {
460: s = conn.createStatement();
461: s.executeUpdate(query);
462: } catch (SQLException ex) {
463: status = false;
464:
465: logger.error("Error executing query: " + query
466: + ": " + ex, ex);
467: this .context.put("exceptionMessage", ex
468: .getMessage()
469: + "\n" + query);
470:
471: break;
472: } finally {
473: DbUtils.close(s);
474: }
475: }
476: conn.setAutoCommit(autoCommit);
477: return status;
478: } catch (Exception e) {
479: throw new ForumException(e);
480: }
481: }
482:
483: private void dropOracleOrPostgreSQLTables(String dbName,
484: Connection conn) {
485: Statement s = null;
486:
487: try {
488: boolean autoCommit = conn.getAutoCommit();
489: conn.setAutoCommit(false);
490:
491: List statements = ParseDBStructFile.parse(SystemGlobals
492: .getValue(ConfigKeys.CONFIG_DIR)
493: + "/database/"
494: + dbName
495: + "/"
496: + dbName
497: + "_drop_tables.sql");
498:
499: this .setupAutoCommit(conn);
500: for (Iterator iter = statements.iterator(); iter.hasNext();) {
501: try {
502: String query = (String) iter.next();
503:
504: if (query == null || "".equals(query.trim())) {
505: continue;
506: }
507:
508: s = conn.createStatement();
509: s.executeUpdate(query);
510: s.close();
511: } catch (Exception e) {
512: logger.error("IGNORE: " + e.toString());
513: }
514: }
515: conn.setAutoCommit(autoCommit);
516: } catch (Exception e) {
517: logger.error(e.toString(), e);
518: } finally {
519: DbUtils.close(s);
520: }
521: }
522:
523: private boolean checkForWritableDir() {
524: boolean canWriteToWebInf = this .canWriteToWebInf();
525: boolean canWriteToLuceneIndex = this .canWriteToLuceneIndex();
526:
527: if (!canWriteToWebInf || !canWriteToLuceneIndex) {
528: if (!canWriteToWebInf) {
529: this .context.put("message", I18n
530: .getMessage("Install.noWritePermission"));
531: } else if (!canWriteToLuceneIndex) {
532: this .context
533: .put(
534: "message",
535: I18n
536: .getMessage(
537: "Install.noWritePermissionLucene",
538: new Object[] { SystemGlobals
539: .getValue(ConfigKeys.LUCENE_INDEX_WRITE_PATH) }));
540: }
541:
542: this .context.put("tryAgain", true);
543: this .error();
544: return false;
545: }
546:
547: return true;
548: }
549:
550: private boolean canWriteToWebInf() {
551: return new File(SystemGlobals.getValue(ConfigKeys.CONFIG_DIR)
552: + "/modulesMapping.properties").canWrite();
553: }
554:
555: private boolean canWriteToLuceneIndex() {
556: File file = new File(SystemGlobals
557: .getValue(ConfigKeys.LUCENE_INDEX_WRITE_PATH));
558:
559: if (!file.exists()) {
560: return file.mkdir();
561: }
562:
563: return file.canWrite();
564: }
565:
566: private void handleDatabasePort(Properties p, String port) {
567: String portKey = ":${database.connection.port}";
568: String connectionString = p
569: .getProperty(ConfigKeys.DATABASE_CONNECTION_STRING);
570:
571: if (port == null || port.trim().length() == 0) {
572: int index = connectionString.indexOf(portKey);
573:
574: if (index > -1) {
575: if (connectionString.charAt(index - 1) == '\\') {
576: connectionString = connectionString.replaceAll("\\"
577: + portKey, "");
578: } else {
579: connectionString = connectionString.replaceAll(
580: portKey, "");
581: }
582: }
583: } else if (connectionString.indexOf(portKey) == -1) {
584: String hostKey = "${database.connection.host}";
585: connectionString = StringUtils.replace(connectionString,
586: hostKey, hostKey + portKey);
587: }
588:
589: p.setProperty(ConfigKeys.DATABASE_CONNECTION_STRING,
590: connectionString);
591: }
592:
593: private void configureJDBCConnection() {
594: String username = this .getFromSession("dbUser");
595: String password = this .getFromSession("dbPassword");
596: String dbName = this .getFromSession("dbName");
597: String host = this .getFromSession("dbHost");
598: String type = this .getFromSession("database");
599: String encoding = this .getFromSession("dbEncoding");
600: String port = this .getFromSession("dbPort");
601:
602: String dbConfigFilePath = SystemGlobals
603: .getValue(ConfigKeys.CONFIG_DIR)
604: + "/database/" + type + "/" + type + ".properties";
605:
606: Properties p = new Properties();
607: FileInputStream fis = null;
608:
609: try {
610: fis = new FileInputStream(dbConfigFilePath);
611: p.load(fis);
612: } catch (IOException e) {
613: throw new ForumException(e);
614: } finally {
615: if (fis != null) {
616: try {
617: fis.close();
618: } catch (Exception e) {
619: }
620: }
621: }
622:
623: this .handleDatabasePort(p, port);
624:
625: // Write database information to the respective file
626: p.setProperty(ConfigKeys.DATABASE_CONNECTION_HOST, host);
627: p
628: .setProperty(ConfigKeys.DATABASE_CONNECTION_USERNAME,
629: username);
630: p
631: .setProperty(ConfigKeys.DATABASE_CONNECTION_PASSWORD,
632: password);
633: p.setProperty(ConfigKeys.DATABASE_CONNECTION_DBNAME, dbName);
634: p
635: .setProperty(ConfigKeys.DATABASE_CONNECTION_ENCODING,
636: encoding);
637: p.setProperty(ConfigKeys.DATABASE_CONNECTION_PORT, port);
638: p.setProperty(ConfigKeys.DATABASE_DRIVER_NAME, type);
639:
640: FileOutputStream fos = null;
641:
642: try {
643: fos = new FileOutputStream(dbConfigFilePath);
644: p.store(fos, null);
645: } catch (Exception e) {
646: logger.warn("Error while trying to write to " + type
647: + ".properties: " + e);
648: } finally {
649: if (fos != null) {
650: try {
651: fos.close();
652: } catch (IOException e) {
653: }
654: }
655: }
656:
657: // Proceed to SystemGlobals / jforum-custom.conf configuration
658: for (Enumeration e = p.keys(); e.hasMoreElements();) {
659: String key = (String) e.nextElement();
660: String value = p.getProperty(key);
661:
662: SystemGlobals.setValue(key, value);
663:
664: logger.info("Updating key " + key + " with value " + value);
665: }
666: }
667:
668: private Connection configureDatabase() {
669: String database = this .getFromSession("database");
670: String connectionType = this
671: .getFromSession("db_connection_type");
672: String implementation;
673:
674: boolean isDatasource = false;
675:
676: if ("JDBC".equals(connectionType)) {
677: implementation = "yes".equals(this
678: .getFromSession("usePool"))
679: && !"hsqldb".equals(database) ? POOLED_CONNECTION
680: : SIMPLE_CONNECTION;
681:
682: this .configureJDBCConnection();
683: } else {
684: isDatasource = true;
685: implementation = DATASOURCE_CONNECTION;
686: SystemGlobals.setValue(ConfigKeys.DATABASE_DATASOURCE_NAME,
687: this .getFromSession("dbdatasource"));
688: }
689:
690: SystemGlobals.setValue(
691: ConfigKeys.DATABASE_CONNECTION_IMPLEMENTATION,
692: implementation);
693: SystemGlobals.setValue(ConfigKeys.DATABASE_DRIVER_NAME,
694: database);
695:
696: SystemGlobals.saveInstallation();
697: this .restartSystemGlobals();
698:
699: int fileChangesDelay = SystemGlobals
700: .getIntValue(ConfigKeys.FILECHANGES_DELAY);
701:
702: if (fileChangesDelay > 0) {
703: FileMonitor.getInstance().addFileChangeListener(
704: new SystemGlobalsListener(),
705: SystemGlobals
706: .getValue(ConfigKeys.INSTALLATION_CONFIG),
707: fileChangesDelay);
708: }
709:
710: Connection conn;
711: try {
712: DBConnection s;
713:
714: if (!isDatasource) {
715: s = new SimpleConnection();
716: } else {
717: s = new DataSourceConnection();
718: }
719:
720: s.init();
721:
722: conn = s.getConnection();
723: } catch (Exception e) {
724: logger.warn("Error while trying to get a connection: " + e);
725: this .context.put("exceptionMessage", e.getMessage());
726: return null;
727: }
728:
729: return conn;
730: }
731:
732: private void restartSystemGlobals() {
733: String appPath = SystemGlobals.getApplicationPath();
734:
735: SystemGlobals.reset();
736:
737: ConfigLoader.startSystemglobals(appPath);
738: }
739:
740: private boolean updateAdminPassword(Connection conn) {
741: logger.info("Going to update the administrator's password");
742:
743: boolean status = false;
744:
745: PreparedStatement p = null;
746:
747: try {
748: p = conn
749: .prepareStatement("UPDATE jforum_users SET user_password = ? WHERE username = 'Admin'");
750: p.setString(1, MD5.crypt(this
751: .getFromSession("adminPassword")));
752: p.executeUpdate();
753: status = true;
754: } catch (Exception e) {
755: logger
756: .warn("Error while trying to update the administrator's password: "
757: + e);
758: this .context.put("exceptionMessage", e.getMessage());
759: } finally {
760: DbUtils.close(p);
761: }
762:
763: return status;
764: }
765:
766: public void checkInformation() {
767: this .setTemplateName(TemplateKeys.INSTALL_CHECK_INFO);
768:
769: String language = this .request.getParameter("language");
770: String database = this .request.getParameter("database");
771: String dbHost = this .request.getParameter("dbhost");
772: String dbPort = this .request.getParameter("dbport");
773: String dbUser = this .request.getParameter("dbuser");
774: String dbName = this .request.getParameter("dbname");
775: String dbPassword = this .request.getParameter("dbpasswd");
776: String dbEncoding = this .request.getParameter("dbencoding");
777: String dbEncodingOther = this .request
778: .getParameter("dbencoding_other");
779: String usePool = this .request.getParameter("use_pool");
780: String forumLink = this .request.getParameter("forum_link");
781: String adminPassword = this .request.getParameter("admin_pass1");
782:
783: dbHost = this .notNullDefault(dbHost, "localhost");
784: dbEncodingOther = this .notNullDefault(dbEncodingOther, "utf-8");
785: dbEncoding = this .notNullDefault(dbEncoding, dbEncodingOther);
786: forumLink = this .notNullDefault(forumLink, "http://localhost");
787: dbName = this .notNullDefault(dbName, "jforum");
788:
789: if ("hsqldb".equals(database)) {
790: dbUser = this .notNullDefault(dbUser, "sa");
791: }
792:
793: this .addToSessionAndContext("language", language);
794: this .addToSessionAndContext("database", database);
795: this .addToSessionAndContext("dbHost", dbHost);
796: this .addToSessionAndContext("dbPort", dbPort);
797: this .addToSessionAndContext("dbUser", dbUser);
798: this .addToSessionAndContext("dbName", dbName);
799: this .addToSessionAndContext("dbPassword", dbPassword);
800: this .addToSessionAndContext("dbEncoding", dbEncoding);
801: this .addToSessionAndContext("usePool", usePool);
802: this .addToSessionAndContext("forumLink", forumLink);
803: this .addToSessionAndContext("siteLink", this .request
804: .getParameter("site_link"));
805: this .addToSessionAndContext("adminPassword", adminPassword);
806: this .addToSessionAndContext("dbdatasource", this .request
807: .getParameter("dbdatasource"));
808: this .addToSessionAndContext("db_connection_type", this .request
809: .getParameter("db_connection_type"));
810:
811: this .addToSessionAndContext("configureDatabase", null);
812: this .addToSessionAndContext("createTables", null);
813: this .addToSessionAndContext("importTablesData", null);
814:
815: this .context.put("canWriteToWebInf", this .canWriteToWebInf());
816: this .context.put("moduleAction", "install_check_info.htm");
817: }
818:
819: private void addToSessionAndContext(String key, String value) {
820: this .request.getSessionContext().setAttribute(key, value);
821: this .context.put(key, value);
822: }
823:
824: private String notNullDefault(String value, String useDefault) {
825: if (value == null || value.trim().equals("")) {
826: return useDefault;
827: }
828:
829: return value;
830: }
831:
832: private void storeSupportProjectMessage(Connection connection) {
833: StringBuffer message = new StringBuffer(
834: "[color=#3AA315][size=18][b]Support JForum - Help the project[/b][/size][/color]")
835: .append("<hr>")
836: .append(
837: "This project is Open Source, and maintained by at least one full time Senior Developer, [i]which costs US$ 3,000.00 / month[/i]. ")
838: .append(
839: "If it helped you, please consider helping this project - especially with some [b][url=http://www.jforum.net/contribute.jsp]donation[/url][/b].")
840: .append('\n')
841: .append('\n')
842: .append(
843: "[color=#137C9F][size=14][b]Why supporting this project is a good thing[/b][/size][/color]")
844: .append("<hr>")
845: .append(
846: "The JForum Project started four years ago as a completely free and Open Source program, initially entirely developed on my (Rafael Steil) ")
847: .append(
848: "free time. Today, with the help of some very valuable people, I can spend more time on JForum, to improve it and implement new features ")
849: .append(
850: "(lots of things, requested either on the [url=http://www.jforum.net/forums/list.page]forums[/url] or registered in the ")
851: .append(
852: "[url=http://www.jforum.net/jira]bug tracker[/url]).")
853: .append('\n')
854: .append(
855: "That's why I'm asking you to financially support this work. I love Open Source. I love to use good products without having to pay for it too. ")
856: .append(
857: "But when I see some program that is valuable to my work, that helps me making money, I think it's a good idea to support this project.")
858: .append('\n')
859: .append('\n')
860: .append("[b]Some reasons to support open projects[/b]:")
861: .append("<ul><li>Because Open Source is cool? Yes")
862: .append("<li>To thank for a great tool? Yes")
863: .append(
864: "<li>To help the project evolve because this will help my work and my earnings? Yes</ul>")
865: .append(
866: "Also, as the project grows more and more, it would be great to, sometimes, reward some of the great people who help JForum.")
867: .append('\n')
868: .append('\n')
869: .append(
870: "So, that's what I'm asking you: if JForum helps your work, saves your time (time is money, remember?) and increase your earnings, support ")
871: .append(
872: "this project. The simpler way is to make [url=http://www.jforum.net/contribute.jsp]any donation[/url] via PayPal.")
873: .append('\n')
874: .append('\n')
875: .append(
876: "JForum has grown a lot every day, since four years ago, which is a great thing, and initially it wasn't my intention to fully work on this tool. ")
877: .append(
878: "Lately, I'm spending a lot of time on it, specially to make JForum 3 a reality, to help users, to improve the program, to research about ")
879: .append(
880: "better solutions. So, your support is very welcome!")
881: .append('\n')
882: .append('\n')
883: .append("Thanks!")
884: .append('\n')
885: .append('\n')
886: .append(
887: ":arrow: [size=16][b][url=http://www.jforum.net/contribute.jsp]Click here[/url][/b] to go to the [i][b][url=http://www.jforum.net/contribute.jsp]")
888: .append("\"Support JForum\"[/url][/b][/i] page.[/size]")
889: .append('\n').append('\n');
890:
891: try {
892: ConfigLoader.createLoginAuthenticator();
893: ConfigLoader.loadDaoImplementation();
894:
895: SystemGlobals.loadQueries(SystemGlobals
896: .getValue(ConfigKeys.SQL_QUERIES_GENERIC));
897: SystemGlobals.loadQueries(SystemGlobals
898: .getValue(ConfigKeys.SQL_QUERIES_DRIVER));
899:
900: SystemGlobals.setValue(ConfigKeys.SEARCH_INDEXING_ENABLED,
901: "false");
902:
903: JForumExecutionContext ex = JForumExecutionContext.get();
904: ex.setConnection(connection);
905: JForumExecutionContext.set(ex);
906:
907: User user = new User(2);
908:
909: // Create topic
910: Topic topic = new Topic();
911: topic.setPostedBy(user);
912: topic.setTitle("Support JForum - Please read");
913: topic.setTime(new Date());
914: topic.setType(Topic.TYPE_ANNOUNCE);
915: topic.setForumId(1);
916:
917: TopicDAO topicDao = DataAccessDriver.getInstance()
918: .newTopicDAO();
919: topicDao.addNew(topic);
920:
921: // Create post
922: Post post = new Post();
923: post.setSubject(topic.getTitle());
924: post.setTime(topic.getTime());
925: post.setUserId(user.getId());
926: post.setText(message.toString());
927: post.setForumId(topic.getForumId());
928: post.setSmiliesEnabled(true);
929: post.setHtmlEnabled(true);
930: post.setBbCodeEnabled(true);
931: post.setUserIp("127.0.0.1");
932: post.setTopicId(topic.getId());
933:
934: PostDAO postDao = DataAccessDriver.getInstance()
935: .newPostDAO();
936: postDao.addNew(post);
937:
938: // Update topic
939: topic.setFirstPostId(post.getId());
940: topic.setLastPostId(post.getId());
941:
942: topicDao.update(topic);
943:
944: // Update forum stats
945: ForumDAO forumDao = DataAccessDriver.getInstance()
946: .newForumDAO();
947: forumDao.incrementTotalTopics(1, 1);
948: forumDao.setLastPost(1, post.getId());
949: } finally {
950: SystemGlobals.setValue(ConfigKeys.SEARCH_INDEXING_ENABLED,
951: "true");
952:
953: JForumExecutionContext ex = JForumExecutionContext.get();
954: ex.setConnection(null);
955: JForumExecutionContext.set(ex);
956: }
957: }
958:
959: /**
960: * @see net.jforum.Command#list()
961: */
962: public void list() {
963: this .welcome();
964: }
965:
966: /**
967: * @see net.jforum.Command#process(net.jforum.context.RequestContext, net.jforum.context.ResponseContext, freemarker.template.SimpleHash)
968: * @param request AWebContextRequest
969: * @param response HttpServletResponse
970: * @param context SimpleHash
971: */
972: public Template process(RequestContext request,
973: ResponseContext response, SimpleHash context) {
974: this .setTemplateName("default/empty.htm");
975: return super.process(request, response, context);
976: }
977: }
|