/** * $RCSfile: DbForumFactory.java,v $ * $Revision: 1.8 $ * $Date: 2000/12/20 02:13:38 $ * * Copyright (C) 2000 CoolServlets.com. All rights reserved. * * =================================================================== * The Apache Software License, Version 1.1 * * 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. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by * CoolServlets.com (http://www.coolservlets.com)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Jive" and "CoolServlets.com" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please * contact webmaster@coolservlets.com. * * 5. Products derived from this software may not be called "Jive", * nor may "Jive" appear in their name, without prior written * permission of CoolServlets.com. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 COOLSERVLETS.COM OR * ITS 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 software consists of voluntary contributions made by many * individuals on behalf of CoolServlets.com. For more information * on CoolServlets.com, please see . */ package com.coolservlets.forum.database; import com.coolservlets.util.*; import com.coolservlets.forum.*; import java.sql.*; import java.util.*; import java.io.*; /** * Database implementation of the ForumFactory interface. */ public class DbForumFactory extends ForumFactory { /** DATABASE QUERIES **/ private static final String FORUM_COUNT = "SELECT count(*) FROM jiveForum"; private static final String DELETE_FORUM = "DELETE FROM jiveForum WHERE forumID=?"; private static final String DELETE_FORUM_USER_PERMS = "DELETE FROM jiveUserPerm WHERE forumID=?"; private static final String DELETE_FORUM_GROUP_PERMS = "DELETE FROM jiveGroupPerm WHERE forumID=?"; private static final String DELETE_FORUM_PROPERTIES = "DELETE FROM jiveForumProp WHERE forumID=?"; private static final String GET_USER_PERMS = "SELECT DISTINCT permission FROM jiveUserPerm WHERE forumID=? " + "AND userID=?"; private static final String USERS_WITH_PERM = "SELECT DISTINCT userID FROM jiveUserPerm WHERE forumID=? AND permission=?"; private static final String GET_GROUP_PERMS = "SELECT DISTINCT permission from jiveGroupPerm WHERE forumID=? " + "AND groupID=?"; private static final String GROUPS_WITH_PERM = "SELECT DISTINCT groupID FROM jiveGroupPerm WHERE forumID=? AND permission=?"; private static final String ALL_MESSAGES = "SELECT messageID FROM jiveMessage"; private static final String DELETE_MESSAGE = "DELETE FROM jiveMessage WHERE messageID=?"; protected DbCacheManager cacheManager; /** * The profile manager provides access to users and groups. */ private ProfileManager profileManager; /** * The search indexer periodically runs to index forum content */ private DbSearchIndexer searchIndexer; /** * Creates a new DbForumFactory. */ public DbForumFactory() { cacheManager = new DbCacheManager(); profileManager = new DbProfileManager(this); searchIndexer = new DbSearchIndexer(this); } //FROM THE FORUMFACTORY INTERFACE// public Forum createForum(String name, String description) throws UnauthorizedException, ForumAlreadyExistsException { Forum newForum = null; try { Forum existingForum = getForum(name); //The forum already exists since now exception, so: throw new ForumAlreadyExistsException(); } catch (ForumNotFoundException fnfe) { //The forum doesn't already exist so we can create a new one newForum = new DbForum(name, description, this); } return newForum; } public void deleteForum(Forum forum) throws UnauthorizedException { //First, remove forum from memory. cacheManager.remove(DbCacheManager.FORUM_CACHE, new Integer(forum.getID())); cacheManager.remove(DbCacheManager.USER_PERMS_CACHE, new Integer(forum.getID())); cacheManager.remove(DbCacheManager.FORUM_ID_CACHE, forum.getName()); //Delete all messages and threads in the forum. Iterator threads = forum.threads(); while (threads.hasNext()) { ForumThread thread = (ForumThread)threads.next(); forum.deleteThread(thread); } //Now, delete all filters associated with the forum. We delete in //reverse order since filter indexes will change if we don't delete //the last filter entry. int filterCount = forum.getForumMessageFilters().length; for (int i=filterCount-1; i>=0; i--) { forum.removeForumMessageFilter(i); } //Finally, delete the forum itself and all permissions and properties //associated with it. Connection con = null; PreparedStatement pstmt = null; try { con = DbConnectionManager.getConnection(); pstmt = con.prepareStatement(DELETE_FORUM); pstmt.setInt(1,forum.getID()); pstmt.execute(); pstmt.close(); //User perms pstmt = con.prepareStatement(DELETE_FORUM_USER_PERMS); pstmt.setInt(1,forum.getID()); pstmt.execute(); pstmt.close(); //Group perms pstmt = con.prepareStatement(DELETE_FORUM_GROUP_PERMS); pstmt.setInt(1,forum.getID()); pstmt.execute(); pstmt.close(); //Properties pstmt = con.prepareStatement(DELETE_FORUM_PROPERTIES); pstmt.setInt(1,forum.getID()); pstmt.execute(); } catch( Exception sqle ) { System.err.println("Error in DbForumFactory:deleteForum()-" + sqle); } finally { try { pstmt.close(); } catch (Exception e) { e.printStackTrace(); } try { con.close(); } catch (Exception e) { e.printStackTrace(); } } } public Forum getForum(int forumID) throws ForumNotFoundException, UnauthorizedException { //If cache is not enabled, do a new lookup of object if (!cacheManager.isCacheEnabled()) { return new DbForum(forumID, this); } //Cache is enabled. Integer forumIDInteger = new Integer(forumID); DbForum forum = (DbForum)cacheManager.get(DbCacheManager.FORUM_CACHE, forumIDInteger); if(forum == null) { forum = new DbForum(forumID, this); cacheManager.add(DbCacheManager.FORUM_CACHE, forumIDInteger, forum); } return forum; } public Forum getForum(String name) throws ForumNotFoundException, UnauthorizedException { //If cache is not enabled, do a new lookup of object if (!cacheManager.isCacheEnabled()) { Forum forum = new DbForum(name, this); return forum; } //Cache is enabled. CacheableInteger forumIDInteger = (CacheableInteger)cacheManager.get( DbCacheManager.FORUM_ID_CACHE, name ); //if id wan't found in cache, load it up and put it there. if (forumIDInteger == null) { Forum forum = new DbForum(name, this); forumIDInteger = new CacheableInteger(new Integer(forum.getID())); cacheManager.add(DbCacheManager.FORUM_ID_CACHE, name, forumIDInteger); } return getForum(forumIDInteger.getInteger().intValue()); } public int getForumCount() { int forumCount = 0; Connection con = null; PreparedStatement pstmt = null; try { con = DbConnectionManager.getConnection(); pstmt = con.prepareStatement(FORUM_COUNT); ResultSet rs = pstmt.executeQuery(); rs.next(); forumCount = rs.getInt(1); } catch( SQLException sqle ) { System.err.println("DbForumFactory:getForumCount() failed: " + sqle); } finally { try { pstmt.close(); } catch (Exception e) { e.printStackTrace(); } try { con.close(); } catch (Exception e) { e.printStackTrace(); } } return forumCount; } public Iterator forums() { return new DbForumFactoryIterator(this); } public ProfileManager getProfileManager() { return profileManager; } public SearchIndexer getSearchIndexer() { return searchIndexer; } public int[] usersWithPermission(int permissionType) throws UnauthorizedException { int [] users = new int[0]; Connection con = null; PreparedStatement pstmt = null; try { con = DbConnectionManager.getConnection(); pstmt = con.prepareStatement(USERS_WITH_PERM); pstmt.setInt(1,-1); pstmt.setInt(2,permissionType); ResultSet rs = pstmt.executeQuery(); ArrayList userList = new ArrayList(); while (rs.next()) { userList.add(new Integer(rs.getInt("userID"))); } users = new int[userList.size()]; for (int i=0; i *
  • Messages with no subject or body. *
  • Messages that do not belong to a thread. * * Please be aware that this method will permanently delete forum * content. You may want to perform a database backup before calling this * method.

    * * This method requires two database connections and may take a long time * to execute, as it must iterate through ever message record in the * database. */ public void cleanDatabase() { //Iterate through all forums, threads to delete unwanted messages. Iterator forums = forums(); while (forums.hasNext()) { Forum forum = (Forum)forums.next(); Iterator threads = forum.threads(); while (threads.hasNext()) { try { ForumThread thread = (ForumThread)threads.next(); Iterator messages = thread.messages(); while (messages.hasNext()) { try { ForumMessage message = (ForumMessage)messages.next(); //System.err.println("Evaluating message " + message.getID() + " for deletion"); if (/*message.getSubject() == null ||*/ message.getBody() == null) { //System.err.println("Deleting message..."); thread.deleteMessage(message); } } catch (Exception me) { me.printStackTrace(); } } } catch (Exception te) { te.printStackTrace(); } } } System.err.println("HERE"); /* //Select all message ID's directly from the message table. Connection con = null; PreparedStatement pstmt = null; try { con = DbConnectionManager.getConnection(); pstmt = con.prepareStatement(ALL_MESSAGES); ResultSet rs = pstmt.executeQuery(); while(rs.next()) { try { int messageID = rs.getInt(1); //Convert to object ForumMessage message = new DbForumMessage(messageID, this); ForumThread thread = message.getForumThread(); if (thread == null) { //manually delete this message from the database. It won't //appear in any search indexes or in any threads, so this //shouldn't have any side effects. Connection con2 = null; PreparedStatement pstmt2 = null; try { con2 = DbConnectionManager.getConnection(); pstmt2 = con.prepareStatement(DELETE_MESSAGE); pstmt2.setInt(1, messageID); pstmt2.execute(); } catch( SQLException sqle ) { sqle.printStackTrace(); } finally { try { pstmt2.close(); } catch (Exception e) { e.printStackTrace(); } try { con2.close(); } catch (Exception e) { e.printStackTrace(); } } } } catch (ForumMessageNotFoundException fmnfe) { fmnfe.printStackTrace(); } } } catch( SQLException sqle ) { sqle.printStackTrace(); } finally { try { pstmt.close(); } catch (Exception e) { e.printStackTrace(); } try { con.close(); } catch (Exception e) { e.printStackTrace(); } } */ } /** * Returns a thread specified by its id. Will return null * if the thread is not in the forum. If cache is turned * on, it will use it. */ public DbForumThread getThread(int threadID, DbForum forum) throws ForumThreadNotFoundException { //If cache is not enabled, do a new lookup of object if (!cacheManager.isCacheEnabled()) { return new DbForumThread(threadID, forum, this); } //Cache is enabled. Integer threadIDInteger = new Integer(threadID); DbForumThread thread = (DbForumThread)cacheManager.get( DbCacheManager.THREAD_CACHE, threadIDInteger ); if(thread == null) { thread = new DbForumThread(threadID, forum, this); cacheManager.add(DbCacheManager.THREAD_CACHE, threadIDInteger, thread); } return thread; } /** * Returns a message from the thread based on its id. If cache is turned * on, it will use it. * * @param messageID the ID of the message to get from the thread. */ protected DbForumMessage getMessage(int messageID) throws ForumMessageNotFoundException { //If cache is not enabled, do a new lookup of object if (!cacheManager.isCacheEnabled()) { return new DbForumMessage(messageID, this); } //Cache is enabled. Integer messageIDInteger = new Integer(messageID); DbForumMessage message = (DbForumMessage)cacheManager.get( DbCacheManager.MESSAGE_CACHE, messageIDInteger ); if(message == null) { //Load the message message = new DbForumMessage(messageID, this); //Add it to cache. cacheManager.add(DbCacheManager.MESSAGE_CACHE, messageIDInteger, message); } return message; } /** * Logs events in the system. Very beginnings here.... */ protected void log(String message, Exception e) { System.err.println("Log event : " + message); e.printStackTrace(); } /** * Returns the permissions that a particular user has for the forum. */ protected ForumPermissions getUserPermissions(int userID, int forumID) { Connection con = null; PreparedStatement pstmt = null; //Initialize a permissions array with no permissions. boolean [] permissions = new boolean[8]; for (int i=0; i