/*
* 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);
}
}