dbforumcategory.java

来自「Jive是基于JSP/JAVA技术构架的一个大型BBS论坛系统,这是Jive论坛」· Java 代码 · 共 1,544 行 · 第 1/4 页

JAVA
1,544
字号
package com.jivesoftware.forum.database;import com.jivesoftware.forum.*;import com.jivesoftware.util.*;import java.util.*;import java.util.LinkedList;import java.util.Date;import java.sql.*;import java.io.IOException;/** * Database implementation of the ForumCategory interface. The SQL tree structure we * use is Joe Celko's. For more information, see: * http://searchdatabase.techtarget.com/tip/1,289483,sid13_gci537290,00.html. * <p> * The lft and rgt column values are responsible for defining the tree. * An example tree with the lft and rgt column values (respectively) is as * follows: <pre> * *            (1,12) *          /       \ *      (2,3)      (4,11) *               /   |   \ *             /     |    \ *          (5,6)  (7,8) (9,10) * </pre> * * As you can see from the tree, the lft and rgt values of a child are * always between the values of its parent. We can use this property to * load the entire tree into memory using a single select. The simple way to * to determine the lft and rgt values of an arbitrary tree structure is to * label lft then rgt by traversing the tree in depth-first order. */public class DbForumCategory implements ForumCategory, Cacheable {    /** DATABASE QUERIES **/    protected static final String FIND_FORUM_INDEX =        "SELECT categoryIndex FROM jiveForum WHERE forumID=? AND categoryID=?";    protected static final String FORUM_IN_CATEGORY_COUNT =        "SELECT count(categoryIndex) FROM jiveForum WHERE categoryID=?";    protected static final String SHIFT_FORUM_INDEX_1 =        "UPDATE jiveForum SET categoryIndex=categoryIndex+1 WHERE categoryID=? " +        "AND categoryIndex >= ? AND categoryIndex <?";    protected static final String SHIFT_FORUM_INDEX_2 =        "UPDATE jiveForum SET categoryIndex=categoryIndex-1 WHERE categoryID=? " +        "AND categoryIndex <= ? AND categoryIndex > ?";    protected static final String SHIFT_CATEGORY_INDEX_1 =        "UPDATE jiveCategory SET lft=lft+?, rgt=rgt+? WHERE lft>=? AND lft<?";    protected static final String SHIFT_CATEGORY_INDEX_2 =        "UPDATE jiveCategory SET lft=lft+?, rgt=rgt+? WHERE lft>? AND rgt>? AND rgt<=?";    private static final String SET_FORUM_INDEX =        "UPDATE jiveForum SET categoryIndex=? WHERE forumID=?";    private static final String MOVE_FORUM =        "UPDATE jiveForum SET categoryID=?, categoryIndex=? WHERE forumID=?";    private static final String LOAD_CATEGORY =        "SELECT name, description, creationDate, modifiedDate, lft, rgt FROM " +        "jiveCategory WHERE categoryID=?";    private static final String FIND_LFT_RGT =        "SELECT lft, rgt FROM jiveCategory WHERE categoryID=?";    private static final String CHANGE_LFT =        "UPDATE jiveCategory SET lft=lft+? WHERE lft > ? AND rgt > ?";    private static final String CHANGE_RGT =        "UPDATE jiveCategory SET rgt=rgt+? WHERE rgt >= ?";    private static final String UPDATE_CATEGORY_MODIFIED_DATE =        "UPDATE jiveCategory SET modifiedDate=? WHERE lft<? AND rgt>?";    private static final String INSERT_CATEGORY =        "INSERT INTO jiveCategory(categoryID,name,description,creationDate," +        "modifiedDate,lft,rgt) VALUES (?,?,?,?,?,?,?)";    private static final String SAVE_CATEGORY =        "UPDATE jiveCategory SET name=?, description=?, creationDate=?, " +        "modifiedDate=? WHERE categoryID=?";    private static final String DELETE_CATEGORY =        "DELETE FROM jiveCategory WHERE categoryID=?";    private static final String LOAD_PROPERTIES =        "SELECT name, propValue FROM jiveCategoryProp WHERE categoryID=?";    private static final String DELETE_PROPERTY =        "DELETE FROM jiveCategoryProp WHERE categoryID=? AND name=?";    private static final String UPDATE_PROPERTY =        "UPDATE jiveCategoryProp SET propValue=? WHERE name=? AND categoryID=?";    private static final String INSERT_PROPERTY =        "INSERT INTO jiveCategoryProp(categoryID,name,propValue) VALUES(?,?,?)";    private static final String CATEGORY_COUNT =        "SELECT count(*) FROM jiveCategory";    private static final String LOAD_CATEGORY_TREE =        "SELECT categoryID, lft, rgt FROM jiveCategory ORDER BY lft ASC";    private static LongTree categoryTree;    /**     * Number of forumID's per cache block.     */    public static final int BLOCK_SIZE = 50;    // Constant for an empty bock. This is returned in the case that there are    // no results when trying to load a thread or message block.    private static final long[] EMPTY_BLOCK = new long[0];    // A ResultFilter is used to filter and sort the values that are returned    // from the forums() method.    private static final ResultFilter DEFAULT_FORUM_FILTER =            ResultFilter.createDefaultForumFilter();    private static final long serialVersionUID = 01L;    /**     * Doing operations on the category tree is dangerious for databases without     * transaction support. To help minimize the risk, we use a static lock     * that must be acquired before modifying the tree.     */    private static Object lock = new Object();    private long id;    private String name;    private String description;    private Date creationDate;    private Date modifiedDate;    private Map properties;    int lft;    int rgt;    // List to keep track of the keys that we insert into global caches.    // Keeping track of the keys allows us to delete them from the caches    // as necessary.    private LinkedList queryKeys = new LinkedList();    private transient DbForumFactory factory;    /**     * Loads an existing category.     *     * @param id the ID of the category to load.     * @throws ForumCategoryNotFoundException     */    public DbForumCategory(long id) throws ForumCategoryNotFoundException    {        this.id = id;        loadFromDb();        init();    }    /**     * Creates a new category.     *     * @param name the name of the new category.     * @param description     * @param parentCategory     */    public DbForumCategory(String name, String description,            DbForumCategory parentCategory)    {        this.id = SequenceManager.nextID(JiveGlobals.FORUM_CATEGORY);        this.name = name;        this.description = description;        long now = System.currentTimeMillis();        creationDate = new java.util.Date(now);        modifiedDate = new java.util.Date(now);        insertIntoDb(parentCategory);        properties = new Hashtable();        init();    }    private void init() {        factory = DbForumFactory.getInstance();        if (categoryTree == null) {            refreshCategoryTree();        }    }    private void readObject(java.io.ObjectInputStream in)            throws IOException, ClassNotFoundException    {        in.defaultReadObject();        init();    }    public long getID() {        return id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;        saveToDb();        // Re-add category to cache.        factory.cacheManager.categoryCache.put(new Long(this.id), this);    }    public String getDescription() {        return description;    }    public void setDescription(String description) {        this.description = description;        saveToDb();        // Re-add category to cache.        factory.cacheManager.categoryCache.put(new Long(this.id), this);    }    public java.util.Date getCreationDate() {        return creationDate;    }    public void setCreationDate(java.util.Date creationDate) {       this.creationDate = creationDate;       saveToDb();       // Re-add category to cache.       factory.cacheManager.categoryCache.put(new Long(this.id), this);    }    public java.util.Date getModifiedDate() {        return modifiedDate;    }    public void setModifiedDate(java.util.Date modifiedDate)            throws UnauthorizedException    {        this.modifiedDate = modifiedDate;        saveToDb();        // Re-add category to cache.        factory.cacheManager.categoryCache.put(new Long(this.id), this);    }    public String getProperty(String name) {        return (String)properties.get(name);    }    public void setProperty(String name, String value) {        // Make sure the property name and value aren't null.        if (name == null || value == null || "".equals(name) || "".equals(value)) {            throw new NullPointerException("Cannot set property with empty or null value.");        }        // See if we need to update a property value or insert a new one.        if (properties.containsKey(name)) {            // Only update the value in the database if the property value            // has changed.            if (!(value.equals(properties.get(name)))) {                properties.put(name, value);                updatePropertyInDb(name, value);                // Re-add category to cache.                factory.cacheManager.categoryCache.put(new Long(this.id), this);            }        }        else {            properties.put(name, value);            insertPropertyIntoDb(name, value);            // Re-add category to cache.            factory.cacheManager.categoryCache.put(new Long(this.id), this);        }    }    public void deleteProperty(String name) throws UnauthorizedException {        // Only delete the property if it exists.        if (properties.containsKey(name)) {            properties.remove(name);            deletePropertyFromDb(name);            // Re-add category to cache.            factory.cacheManager.categoryCache.put(new Long(this.id), this);        }    }    public Iterator propertyNames() {        return Collections.unmodifiableSet(properties.keySet()).iterator();    }    public int getForumCount() {        return getForumCount(DEFAULT_FORUM_FILTER);    }    public int getForumCount(ResultFilter resultFilter) {        String sql = getForumListSQL(resultFilter, true, false);        QueryCacheKey key = new QueryCacheKey(JiveGlobals.FORUM_CATEGORY, id, sql, -1);        return getCount(key);    }    public int getRecursiveForumCount() {        return getRecursiveForumCount(DEFAULT_FORUM_FILTER);    }    public int getRecursiveForumCount(ResultFilter resultFilter) {        String sql = getForumListSQL(resultFilter, true, true);        QueryCacheKey key = new QueryCacheKey(JiveGlobals.FORUM_CATEGORY, id, sql, -1);        return getCount(key);    }    public Iterator forums() {        return forums(DEFAULT_FORUM_FILTER);    }    public Iterator forums(ResultFilter resultFilter) {        String query = getForumListSQL(resultFilter, false, false);        long [] forumBlock = getBlock(query.toString(), resultFilter.getStartIndex());        int startIndex = resultFilter.getStartIndex();        int endIndex;        // If number of results is set to inifinite, set endIndex to the total        // number of threads in the forum.        if (resultFilter.getNumResults() == ResultFilter.NULL_INT) {            endIndex = (int)getForumCount(resultFilter);        }        else {            endIndex = resultFilter.getNumResults() + startIndex;        }        return new ForumBlockIterator(forumBlock, query.toString(),                startIndex, endIndex, this.id, factory);    }    public Iterator recursiveForums() {        return recursiveForums(DEFAULT_FORUM_FILTER);    }    public Iterator recursiveForums(ResultFilter resultFilter) {        String query = getForumListSQL(resultFilter, false, true);        long [] forumBlock = getBlock(query.toString(), resultFilter.getStartIndex());        int startIndex = resultFilter.getStartIndex();        int endIndex;        // If number of results is set to inifinite, set endIndex to the total        // number of threads in the forum.        if (resultFilter.getNumResults() == ResultFilter.NULL_INT) {            endIndex = (int)getRecursiveForumCount(resultFilter);        }        else {            endIndex = resultFilter.getNumResults() + startIndex;        }        return new ForumBlockIterator(forumBlock, query.toString(),                startIndex, endIndex, this.id, factory);    }    public void setForumIndex(Forum forum, int newIndex) {        if (newIndex < 0 || newIndex > getForumCount() -1) {            throw new IllegalArgumentException("Invalid index");        }        Connection con = null;        PreparedStatement pstmt = null;        boolean abortTransaction = false;        try {            con = ConnectionManager.getTransactionConnection();            // First, find the old index value for the forum.            pstmt = con.prepareStatement(FIND_FORUM_INDEX);            pstmt.setLong(1, forum.getID());            pstmt.setLong(2, this.id);            ResultSet rs = pstmt.executeQuery();            // If we didn't find a row, that means the forum does not belong            // to the category. In that case, throw an exception.            if (!rs.next()) {                throw new IllegalArgumentException("Forum " + forum.getID() +                    " is not in category " + this.id);            }            int oldIndex = rs.getInt(1);            pstmt.close();            // We need to shift the values of other forums to make room for            // the new placement.            if (newIndex < oldIndex) {                pstmt = con.prepareStatement(SHIFT_FORUM_INDEX_1);            }            else {                pstmt = con.prepareStatement(SHIFT_FORUM_INDEX_2);            }            pstmt.setLong(1, this.id);            pstmt.setInt(2, newIndex);            pstmt.setInt(3, oldIndex);            pstmt.execute();            pstmt.close();            // Finally, update the actual entry.            pstmt = con.prepareStatement(SET_FORUM_INDEX);            pstmt.setInt(1, newIndex);            pstmt.setLong(2,  forum.getID());            pstmt.execute();        }        catch (SQLException sqle) {            sqle.printStackTrace();            abortTransaction = true;        }        finally {            try {  pstmt.close(); }            catch (Exception e) { e.printStackTrace(); }            ConnectionManager.closeTransactionConnection(con, abortTransaction);        }        // Expire cache.        clearCache();    }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?