/* * 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 * * This file creation date: 27/08/2004 - 18:15:54 * The JForum Project * http://www.jforum.net */ package net.jforum.view.install; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Statement; import java.util.Date; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Properties; import net.jforum.Command; import net.jforum.ConfigLoader; import net.jforum.DBConnection; import net.jforum.DataSourceConnection; import net.jforum.JForumExecutionContext; import net.jforum.SessionFacade; import net.jforum.SimpleConnection; import net.jforum.context.RequestContext; import net.jforum.context.ResponseContext; import net.jforum.dao.DataAccessDriver; import net.jforum.dao.ForumDAO; import net.jforum.dao.PostDAO; import net.jforum.dao.TopicDAO; import net.jforum.entities.Post; import net.jforum.entities.Topic; import net.jforum.entities.User; import net.jforum.entities.UserSession; import net.jforum.exceptions.DatabaseException; import net.jforum.exceptions.ForumException; import net.jforum.util.DbUtils; import net.jforum.util.FileMonitor; import net.jforum.util.I18n; import net.jforum.util.MD5; import net.jforum.util.preferences.ConfigKeys; import net.jforum.util.preferences.SystemGlobals; import net.jforum.util.preferences.SystemGlobalsListener; import net.jforum.util.preferences.TemplateKeys; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import freemarker.template.SimpleHash; import freemarker.template.Template; /** * JForum Web Installer. * * @author Rafael Steil * @version $Id: InstallAction.java,v 1.79 2007/10/08 17:34:40 rafaelsteil Exp $ */ public class InstallAction extends Command { private static Logger logger = Logger.getLogger(InstallAction.class); private static final String POOLED_CONNECTION = net.jforum.PooledConnection.class.getName(); private static final String SIMPLE_CONNECTION = net.jforum.SimpleConnection.class.getName(); private static final String DATASOURCE_CONNECTION = net.jforum.DataSourceConnection.class.getName(); public void welcome() { this.checkLanguage(); this.context.put("language", this.getFromSession("language")); this.context.put("database", this.getFromSession("database")); this.context.put("dbhost", this.getFromSession("dbHost")); this.context.put("dbuser", this.getFromSession("dbUser")); this.context.put("dbname", this.getFromSession("dbName")); this.context.put("dbport", this.getFromSession("dbPort")); this.context.put("dbpasswd", this.getFromSession("dbPassword")); this.context.put("dbencoding", this.getFromSession("dbEncoding")); this.context.put("use_pool", this.getFromSession("usePool")); this.context.put("forumLink", this.getFromSession("forumLink")); this.context.put("siteLink", this.getFromSession("siteLink")); this.context.put("dbdatasource", this.getFromSession("dbdatasource")); this.setTemplateName(TemplateKeys.INSTALL_WELCOME); } private void checkLanguage() { String lang = this.request.getParameter("l"); if (lang == null) { Locale locale = this.request.getLocale(); lang = locale.getLanguage() + "_" + locale.getCountry(); } if (!I18n.languageExists(lang)) { return; } I18n.load(lang); UserSession us = new UserSession(); us.setLang(lang); SessionFacade.add(us); this.addToSessionAndContext("language", lang); } private String getFromSession(String key) { return (String)this.request.getSessionContext().getAttribute(key); } private void error() { this.setTemplateName(TemplateKeys.INSTALL_ERROR); } public void doInstall() { if (!this.checkForWritableDir()) { return; } this.removeUserConfig(); Connection conn = null; if (!"passed".equals(this.getFromSession("configureDatabase"))) { logger.info("Going to configure the database..."); conn = this.configureDatabase(); if (conn == null) { this.context.put("message", I18n.getMessage("Install.databaseError")); this.error(); return; } } logger.info("Database configuration ok"); // Database Configuration is ok this.addToSessionAndContext("configureDatabase", "passed"); DBConnection simpleConnection = new SimpleConnection(); if (conn == null) { conn = simpleConnection.getConnection(); } boolean dbError = false; try { //this.setupAutoCommit(conn); if (!"passed".equals(this.getFromSession("createTables")) && !this.createTables(conn)) { this.context.put("message", I18n.getMessage("Install.createTablesError")); dbError = true; this.error(); return; } // Create tables is ok this.addToSessionAndContext("createTables", "passed"); logger.info("Table creation is ok"); this.setupAutoCommit(conn); if (!"passed".equals(this.getFromSession("importTablesData")) && !this.importTablesData(conn)) { this.context.put("message", I18n.getMessage("Install.importTablesDataError")); dbError = true; this.error(); return; } // Dump is ok this.addToSessionAndContext("importTablesData", "passed"); if (!this.updateAdminPassword(conn)) { this.context.put("message", I18n.getMessage("Install.updateAdminError")); dbError = true; this.error(); return; } this.storeSupportProjectMessage(conn); } finally { if (conn != null) { try { if (dbError) { conn.rollback(); } else { conn.commit(); } } catch (SQLException e) { } simpleConnection.releaseConnection(conn); } } JForumExecutionContext.setRedirect(this.request.getContextPath() + "/install/install" + SystemGlobals.getValue(ConfigKeys.SERVLET_EXTENSION) + "?module=install&action=finished"); } private void setupAutoCommit(Connection conn) { try { conn.setAutoCommit(false); } catch (SQLException e) { throw new DatabaseException(e); } } private void removeUserConfig() { File f = new File(SystemGlobals.getValue(ConfigKeys.INSTALLATION_CONFIG)); if (f.exists() && f.canWrite()) { try { f.delete(); } catch (Exception e) { logger.info(e.toString()); } } } public void finished() { this.setTemplateName(TemplateKeys.INSTALL_FINISHED); this.context.put("clickHere", I18n.getMessage("Install.clickHere")); this.context.put("forumLink", this.getFromSession("forumLink")); String lang = this.getFromSession("language"); if (lang == null) { lang = "en_US"; } this.context.put("lang", lang); this.fixModulesMapping(); this.configureSystemGlobals(); SystemGlobals.loadQueries(SystemGlobals.getValue(ConfigKeys.SQL_QUERIES_GENERIC)); SystemGlobals.loadQueries(SystemGlobals.getValue(ConfigKeys.SQL_QUERIES_DRIVER)); SessionFacade.remove(this.request.getSessionContext().getId()); } private void fixModulesMapping() { FileInputStream fis = null; FileOutputStream fos = null; try { // Modules Mapping String modulesMapping = SystemGlobals.getValue(ConfigKeys.CONFIG_DIR) + "/modulesMapping.properties"; if (new File(modulesMapping).canWrite()) { Properties p = new Properties(); fis = new FileInputStream(modulesMapping); p.load(fis); if (p.containsKey("install")) { p.remove("install"); fos = new FileOutputStream(modulesMapping); p.store(fos, "Modified by JForum Installer"); ConfigLoader.loadModulesMapping(SystemGlobals.getValue(ConfigKeys.CONFIG_DIR)); } this.addToSessionAndContext("mappingFixed", "true"); } } catch (Exception e) { logger.warn("Error while working on modulesMapping.properties: " + e); } finally { if (fis != null) { try { fis.close(); } catch (Exception e) {} } if (fos != null) { try { fos.close(); } catch (Exception e) {} } } } private void configureSystemGlobals() { SystemGlobals.setValue(ConfigKeys.USER_HASH_SEQUENCE, MD5.crypt(this.getFromSession("dbPassword") + System.currentTimeMillis())); SystemGlobals.setValue(ConfigKeys.FORUM_LINK, this.getFromSession("forumLink")); SystemGlobals.setValue(ConfigKeys.HOMEPAGE_LINK, this.getFromSession("siteLink")); SystemGlobals.setValue(ConfigKeys.I18N_DEFAULT, this.getFromSession("language")); SystemGlobals.setValue(ConfigKeys.INSTALLED, "true"); SystemGlobals.saveInstallation(); this.restartSystemGlobals(); } private boolean importTablesData(Connection conn) { try { boolean status = true; boolean autoCommit = conn.getAutoCommit(); conn.setAutoCommit(false); String dbType = this.getFromSession("database"); List statements = ParseDBDumpFile.parse(SystemGlobals.getValue(ConfigKeys.CONFIG_DIR) + "/database/" + dbType + "/" + dbType + "_data_dump.sql"); for (Iterator iter = statements.iterator(); iter.hasNext();) { String query = (String)iter.next(); if (query == null || "".equals(query.trim())) { continue; } query = query.trim(); Statement s = conn.createStatement(); try { if (query.startsWith("UPDATE") || query.startsWith("INSERT") || query.startsWith("SET")) { s.executeUpdate(query); } else if (query.startsWith("SELECT")) { s.executeQuery(query); } else { throw new SQLException("Invalid query: " + query); } } catch (SQLException ex) { status = false; conn.rollback(); logger.error("Error importing data for " + query + ": " + ex, ex); this.context.put("exceptionMessage", ex.getMessage() + "\n" + query); break; } finally { s.close(); } } conn.setAutoCommit(autoCommit); return status; } catch (Exception e) { throw new ForumException(e); } } private boolean createTables(Connection conn) { logger.info("Going to create tables..."); String dbType = this.getFromSession("database"); if ("postgresql".equals(dbType) || "oracle".equals(dbType)) { // This should be in a separate transaction block; otherwise, an empty database will fail. this.dropOracleOrPostgreSQLTables(dbType, conn); } try { boolean status = true; boolean autoCommit = conn.getAutoCommit(); conn.setAutoCommit(false); List statements = ParseDBStructFile.parse(SystemGlobals.getValue(ConfigKeys.CONFIG_DIR) + "/database/" + dbType + "/" + dbType + "_db_struct.sql"); for (Iterator iter = statements.iterator(); iter.hasNext(); ) { String query = (String)iter.next(); if (query == null || "".equals(query.trim())) { continue; } Statement s = null; try { s = conn.createStatement(); s.executeUpdate(query); } catch (SQLException ex) { status = false; logger.error("Error executing query: " + query + ": " + ex, ex); this.context.put("exceptionMessage", ex.getMessage() + "\n" + query); break; } finally { DbUtils.close(s); } } conn.setAutoCommit(autoCommit); return status; } catch (Exception e) { throw new ForumException(e); } } private void dropOracleOrPostgreSQLTables(String dbName, Connection conn) { Statement s = null; try { boolean autoCommit = conn.getAutoCommit(); conn.setAutoCommit(false); List statements = ParseDBStructFile.parse(SystemGlobals.getValue(ConfigKeys.CONFIG_DIR) + "/database/" + dbName + "/" + dbName + "_drop_tables.sql"); this.setupAutoCommit(conn); for (Iterator iter = statements.iterator(); iter.hasNext(); ) { try { String query = (String)iter.next(); if (query == null || "".equals(query.trim())) { continue; } s = conn.createStatement(); s.executeUpdate(query); s.close(); } catch (Exception e) { logger.error("IGNORE: " + e.toString()); } } conn.setAutoCommit(autoCommit); } catch (Exception e) { logger.error(e.toString(), e); } finally { DbUtils.close(s); } } private boolean checkForWritableDir() { boolean canWriteToWebInf = this.canWriteToWebInf(); boolean canWriteToLuceneIndex = this.canWriteToLuceneIndex(); if (!canWriteToWebInf || !canWriteToLuceneIndex) { if (!canWriteToWebInf) { this.context.put("message", I18n.getMessage("Install.noWritePermission")); } else if (!canWriteToLuceneIndex) { this.context.put("message", I18n.getMessage("Install.noWritePermissionLucene", new Object[] { SystemGlobals.getValue(ConfigKeys.LUCENE_INDEX_WRITE_PATH) } )); } this.context.put("tryAgain", true); this.error(); return false; } return true; } private boolean canWriteToWebInf() { return new File(SystemGlobals.getValue(ConfigKeys.CONFIG_DIR) + "/modulesMapping.properties").canWrite(); } private boolean canWriteToLuceneIndex() { File file = new File(SystemGlobals.getValue(ConfigKeys.LUCENE_INDEX_WRITE_PATH)); if (!file.exists()) { return file.mkdir(); } return file.canWrite(); } private void handleDatabasePort(Properties p, String port) { String portKey = ":${database.connection.port}"; String connectionString = p.getProperty(ConfigKeys.DATABASE_CONNECTION_STRING); if (port == null || port.trim().length() == 0) { int index = connectionString.indexOf(portKey); if (index > -1) { if (connectionString.charAt(index - 1) == '\\') { connectionString = connectionString.replaceAll("\\" + portKey, ""); } else { connectionString = connectionString.replaceAll(portKey, ""); } } } else if (connectionString.indexOf(portKey) == -1) { String hostKey = "${database.connection.host}"; connectionString = StringUtils.replace(connectionString, hostKey, hostKey + portKey); } p.setProperty(ConfigKeys.DATABASE_CONNECTION_STRING, connectionString); } private void configureJDBCConnection() { String username = this.getFromSession("dbUser"); String password = this.getFromSession("dbPassword"); String dbName = this.getFromSession("dbName"); String host = this.getFromSession("dbHost"); String type = this.getFromSession("database"); String encoding = this.getFromSession("dbEncoding"); String port = this.getFromSession("dbPort"); String dbConfigFilePath = SystemGlobals.getValue(ConfigKeys.CONFIG_DIR) + "/database/" + type + "/" + type + ".properties"; Properties p = new Properties(); FileInputStream fis = null; try { fis = new FileInputStream(dbConfigFilePath); p.load(fis); } catch (IOException e) { throw new ForumException(e); } finally { if (fis != null) { try { fis.close(); } catch (Exception e) {} } } this.handleDatabasePort(p, port); // Write database information to the respective file p.setProperty(ConfigKeys.DATABASE_CONNECTION_HOST, host); p.setProperty(ConfigKeys.DATABASE_CONNECTION_USERNAME, username); p.setProperty(ConfigKeys.DATABASE_CONNECTION_PASSWORD, password); p.setProperty(ConfigKeys.DATABASE_CONNECTION_DBNAME, dbName); p.setProperty(ConfigKeys.DATABASE_CONNECTION_ENCODING, encoding); p.setProperty(ConfigKeys.DATABASE_CONNECTION_PORT, port); p.setProperty(ConfigKeys.DATABASE_DRIVER_NAME, type); FileOutputStream fos = null; try { fos = new FileOutputStream(dbConfigFilePath); p.store(fos, null); } catch (Exception e) { logger.warn("Error while trying to write to " + type + ".properties: " + e); } finally { if (fos != null) { try { fos.close(); } catch (IOException e) { } } } // Proceed to SystemGlobals / jforum-custom.conf configuration for (Enumeration e = p.keys(); e.hasMoreElements(); ) { String key = (String)e.nextElement(); String value = p.getProperty(key); SystemGlobals.setValue(key, value); logger.info("Updating key " + key + " with value " + value); } } private Connection configureDatabase() { String database = this.getFromSession("database"); String connectionType = this.getFromSession("db_connection_type"); String implementation; boolean isDatasource = false; if ("JDBC".equals(connectionType)) { implementation = "yes".equals(this.getFromSession("usePool")) && !"hsqldb".equals(database) ? POOLED_CONNECTION : SIMPLE_CONNECTION; this.configureJDBCConnection(); } else { isDatasource = true; implementation = DATASOURCE_CONNECTION; SystemGlobals.setValue(ConfigKeys.DATABASE_DATASOURCE_NAME, this.getFromSession("dbdatasource")); } SystemGlobals.setValue(ConfigKeys.DATABASE_CONNECTION_IMPLEMENTATION, implementation); SystemGlobals.setValue(ConfigKeys.DATABASE_DRIVER_NAME, database); SystemGlobals.saveInstallation(); this.restartSystemGlobals(); int fileChangesDelay = SystemGlobals.getIntValue(ConfigKeys.FILECHANGES_DELAY); if (fileChangesDelay > 0) { FileMonitor.getInstance().addFileChangeListener(new SystemGlobalsListener(), SystemGlobals.getValue(ConfigKeys.INSTALLATION_CONFIG), fileChangesDelay); } Connection conn; try { DBConnection s; if (!isDatasource) { s = new SimpleConnection(); } else { s = new DataSourceConnection(); } s.init(); conn = s.getConnection(); } catch (Exception e) { logger.warn("Error while trying to get a connection: " + e); this.context.put("exceptionMessage", e.getMessage()); return null; } return conn; } private void restartSystemGlobals() { String appPath = SystemGlobals.getApplicationPath(); SystemGlobals.reset(); ConfigLoader.startSystemglobals(appPath); } private boolean updateAdminPassword(Connection conn) { logger.info("Going to update the administrator's password"); boolean status = false; PreparedStatement p = null; try { p = conn.prepareStatement("UPDATE jforum_users SET user_password = ? WHERE username = 'Admin'"); p.setString(1, MD5.crypt(this.getFromSession("adminPassword"))); p.executeUpdate(); status = true; } catch (Exception e) { logger.warn("Error while trying to update the administrator's password: " + e); this.context.put("exceptionMessage", e.getMessage()); } finally { DbUtils.close(p); } return status; } public void checkInformation() { this.setTemplateName(TemplateKeys.INSTALL_CHECK_INFO); String language = this.request.getParameter("language"); String database = this.request.getParameter("database"); String dbHost = this.request.getParameter("dbhost"); String dbPort = this.request.getParameter("dbport"); String dbUser = this.request.getParameter("dbuser"); String dbName = this.request.getParameter("dbname"); String dbPassword = this.request.getParameter("dbpasswd"); String dbEncoding = this.request.getParameter("dbencoding"); String dbEncodingOther = this.request.getParameter("dbencoding_other"); String usePool = this.request.getParameter("use_pool"); String forumLink = this.request.getParameter("forum_link"); String adminPassword = this.request.getParameter("admin_pass1"); dbHost = this.notNullDefault(dbHost, "localhost"); dbEncodingOther = this.notNullDefault(dbEncodingOther, "utf-8"); dbEncoding = this.notNullDefault(dbEncoding, dbEncodingOther); forumLink = this.notNullDefault(forumLink, "http://localhost"); dbName = this.notNullDefault(dbName, "jforum"); if ("hsqldb".equals(database)) { dbUser = this.notNullDefault(dbUser, "sa"); } this.addToSessionAndContext("language", language); this.addToSessionAndContext("database", database); this.addToSessionAndContext("dbHost", dbHost); this.addToSessionAndContext("dbPort", dbPort); this.addToSessionAndContext("dbUser", dbUser); this.addToSessionAndContext("dbName", dbName); this.addToSessionAndContext("dbPassword", dbPassword); this.addToSessionAndContext("dbEncoding", dbEncoding); this.addToSessionAndContext("usePool", usePool); this.addToSessionAndContext("forumLink", forumLink); this.addToSessionAndContext("siteLink", this.request.getParameter("site_link")); this.addToSessionAndContext("adminPassword", adminPassword); this.addToSessionAndContext("dbdatasource", this.request.getParameter("dbdatasource")); this.addToSessionAndContext("db_connection_type", this.request.getParameter("db_connection_type")); this.addToSessionAndContext("configureDatabase", null); this.addToSessionAndContext("createTables", null); this.addToSessionAndContext("importTablesData", null); this.context.put("canWriteToWebInf", this.canWriteToWebInf()); this.context.put("moduleAction", "install_check_info.htm"); } private void addToSessionAndContext(String key, String value) { this.request.getSessionContext().setAttribute(key, value); this.context.put(key, value); } private String notNullDefault(String value, String useDefault) { if (value == null || value.trim().equals("")) { return useDefault; } return value; } private void storeSupportProjectMessage(Connection connection) { StringBuffer message = new StringBuffer("[color=#3AA315][size=18][b]Support JForum - Help the project[/b][/size][/color]") .append("<hr>") .append("This project is Open Source, and maintained by at least one full time Senior Developer, [i]which costs US$ 3,000.00 / month[/i]. ") .append("If it helped you, please consider helping this project - especially with some [b][url=http://www.jforum.net/contribute.jsp]donation[/url][/b].") .append('\n') .append('\n') .append("[color=#137C9F][size=14][b]Why supporting this project is a good thing[/b][/size][/color]") .append("<hr>") .append("The JForum Project started four years ago as a completely free and Open Source program, initially entirely developed on my (Rafael Steil) ") .append("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 ") .append("(lots of things, requested either on the [url=http://www.jforum.net/forums/list.page]forums[/url] or registered in the ") .append("[url=http://www.jforum.net/jira]bug tracker[/url]).") .append('\n') .append("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. ") .append("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.") .append('\n') .append('\n') .append("[b]Some reasons to support open projects[/b]:") .append("<ul><li>Because Open Source is cool? Yes") .append("<li>To thank for a great tool? Yes") .append("<li>To help the project evolve because this will help my work and my earnings? Yes</ul>") .append("Also, as the project grows more and more, it would be great to, sometimes, reward some of the great people who help JForum.") .append('\n') .append('\n') .append("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 ") .append("this project. The simpler way is to make [url=http://www.jforum.net/contribute.jsp]any donation[/url] via PayPal.") .append('\n') .append('\n') .append("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. ") .append("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 ") .append("better solutions. So, your support is very welcome!") .append('\n') .append('\n') .append("Thanks!") .append('\n') .append('\n') .append(":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]") .append("\"Support JForum\"[/url][/b][/i] page.[/size]") .append('\n') .append('\n'); try { ConfigLoader.createLoginAuthenticator(); ConfigLoader.loadDaoImplementation(); SystemGlobals.loadQueries(SystemGlobals.getValue(ConfigKeys.SQL_QUERIES_GENERIC)); SystemGlobals.loadQueries(SystemGlobals.getValue(ConfigKeys.SQL_QUERIES_DRIVER)); SystemGlobals.setValue(ConfigKeys.SEARCH_INDEXING_ENABLED, "false"); JForumExecutionContext ex = JForumExecutionContext.get(); ex.setConnection(connection); JForumExecutionContext.set(ex); User user = new User(2); // Create topic Topic topic = new Topic(); topic.setPostedBy(user); topic.setTitle("Support JForum - Please read"); topic.setTime(new Date()); topic.setType(Topic.TYPE_ANNOUNCE); topic.setForumId(1); TopicDAO topicDao = DataAccessDriver.getInstance().newTopicDAO(); topicDao.addNew(topic); // Create post Post post = new Post(); post.setSubject(topic.getTitle()); post.setTime(topic.getTime()); post.setUserId(user.getId()); post.setText(message.toString()); post.setForumId(topic.getForumId()); post.setSmiliesEnabled(true); post.setHtmlEnabled(true); post.setBbCodeEnabled(true); post.setUserIp("127.0.0.1"); post.setTopicId(topic.getId()); PostDAO postDao = DataAccessDriver.getInstance().newPostDAO(); postDao.addNew(post); // Update topic topic.setFirstPostId(post.getId()); topic.setLastPostId(post.getId()); topicDao.update(topic); // Update forum stats ForumDAO forumDao = DataAccessDriver.getInstance().newForumDAO(); forumDao.incrementTotalTopics(1, 1); forumDao.setLastPost(1, post.getId()); } finally { SystemGlobals.setValue(ConfigKeys.SEARCH_INDEXING_ENABLED, "true"); JForumExecutionContext ex = JForumExecutionContext.get(); ex.setConnection(null); JForumExecutionContext.set(ex); } } /** * @see net.jforum.Command#list() */ public void list() { this.welcome(); } /** * @see net.jforum.Command#process(net.jforum.context.RequestContext, net.jforum.context.ResponseContext, freemarker.template.SimpleHash) * @param request AWebContextRequest * @param response HttpServletResponse * @param context SimpleHash */ public Template process(RequestContext request, ResponseContext response, SimpleHash context) { this.setTemplateName("default/empty.htm"); return super.process(request, response, context); } }