dbforumcategory.java

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

JAVA
1,544
字号
                // Delete category and all sub-categories.                category.deleteFromDb(con);                // Fix tree.                pstmt = con.prepareStatement(CHANGE_LFT);                pstmt.setInt(1, delta);                pstmt.setInt(2, lft);                pstmt.setInt(3, rgt);                pstmt.execute();                pstmt.close();                pstmt = con.prepareStatement(CHANGE_RGT);                pstmt.setInt(1, delta);                pstmt.setInt(2, rgt);                pstmt.execute();                pstmt.close();            }            catch (Exception e) {                e.printStackTrace();                abortTransaction = true;            }            finally {                try {  pstmt.close(); }                catch (Exception e) { e.printStackTrace(); }                ConnectionManager.closeTransactionConnection(con, abortTransaction);            }            refreshCategoryTree();        }    }    public PermissionsManager getPermissionsManager() {        return new DbPermissionsManager(JiveGlobals.FORUM_CATEGORY, id);    }    public ForumPermissions getPermissions(Authorization authorization) {        ForumPermissions catPerms = factory.permissionsManager.getFinalUserPerms(                JiveGlobals.FORUM_CATEGORY, this.id, authorization.getUserID());        ForumCategory parentCat = getParentCategory();        if (parentCat != null) {            int parentPerms = parentCat.getPermissions(authorization).toInt();            // Never inherit the show category permission.            ForumPermissions newPerms = new ForumPermissions(                    ForumPermissions.setBit(parentPerms, ForumPermissions.SHOW_CATEGORY, false));            catPerms = new ForumPermissions(catPerms, newPerms);        }        return catPerms;    }    public boolean hasPermission(int type) {        return true;    }    // OTHER METHODS //    /**     * Clears caches related to the object.     */    protected void clearCache() {        synchronized (queryKeys) {            // Clear out query cache of lists and counts.            Object [] listElements = queryKeys.toArray();            queryKeys.clear();            for (int i=0; i<listElements.length; i++) {                Object key = listElements[i];                // If the short-term query cache is enabled, move the object                // there.                if (factory.cacheManager.isShortTermQueryCacheEnabled()) {                    Object value = factory.cacheManager.queryCache.get(key);                    // Add the object to the short-term cache and then remove it                    // from the normal cache.                    if (value != null) {                        factory.cacheManager.shortTermQueryCache.put(key, value);                    }                }                factory.cacheManager.queryCache.remove(key);            }        }        // Re-add category to cache.        factory.cacheManager.categoryCache.put(new Long(this.id), this);    }    /**     * Loads the entire category tree into memory.     */    private void refreshCategoryTree() {        synchronized (lock) {            // First, wipe out the entire category cache. If the tree has            // been changed, then cached lft and rgt values stored with each            // category will no longer be correct.            factory.cacheManager.categoryCache.clear();            factory.cacheManager.queryCache.clear();            Connection con = null;            PreparedStatement pstmt = null;            try {                con = ConnectionManager.getConnection();                pstmt = con.prepareStatement(CATEGORY_COUNT);                ResultSet rs = pstmt.executeQuery();                rs.next();                int categoryCount = rs.getInt(1);                pstmt.close();                categoryTree = new LongTree(1, categoryCount);                // Load the category tree.                pstmt = con.prepareStatement(LOAD_CATEGORY_TREE);                rs = pstmt.executeQuery();                // Skip over root                rs.next();                // Because of the way the SQL structure works the elements will be                // in depth-first when we get them in order of their lft value. By                // using stacks, we can determine parentage without resorting                // to recursion.                LinkedList categoryStack = new LinkedList();                categoryStack.addFirst(new Long(1));                LinkedList lftStack = new LinkedList();                lftStack.addFirst(new Integer(rs.getInt(2)));                LinkedList rgtStack = new LinkedList();                rgtStack.addFirst(new Integer(rs.getInt(3)));                // Load in all other values.                while (rs.next()) {                    long categoryID = rs.getLong(1);                    int lft = rs.getInt(2);                    int rgt = rs.getInt(3);                    int stackLft = ((Integer)lftStack.getFirst()).intValue();                    int stackRgt = ((Integer)rgtStack.getFirst()).intValue();                    // If the category we're examining is the caller of this method, save the                    // lft and rgt values. This ensures that this instance of the object remains                    // consistent for further category operations.                    if (categoryID == this.id) {                        this.lft = lft;                        this.rgt = rgt;                    }                    // The basic test of whether the next element is a sibling                    // or child of the previous element is if the lft and rgt                    // values are between the previous element's values. If lft and                    // rgt are *not* between the previous elements values, we've                    // found a sibling. Keep popping values off the stack until we                    // find the level that the sibling is at.                    while (!(lft > stackLft && rgt < stackRgt)) {                        // Pop values off the stacks since this is a sibling.                        categoryStack.removeFirst();                        lftStack.removeFirst();                        rgtStack.removeFirst();                        stackLft = ((Integer)lftStack.getFirst()).intValue();                        stackRgt = ((Integer)rgtStack.getFirst()).intValue();                    }                    // Add the element to the tree.                    long parent = ((Long)categoryStack.getFirst()).longValue();                    categoryTree.addChild(parent, categoryID);                    // Push values onto the stacks.                    categoryStack.addFirst(new Long(categoryID));                    lftStack.addFirst(new Integer(lft));                    rgtStack.addFirst(new Integer(rgt));                }            }            catch (SQLException sqle) {                sqle.printStackTrace();            }            finally {                try {  pstmt.close(); }                catch (Exception e) { e.printStackTrace(); }                try {  con.close();   }                catch (Exception e) { e.printStackTrace(); }            }        }    }    /**     * Updates the modified date of this category and all parent categories. It accepts a     * Connection so that it can participate in trasactions.     */    protected void updateModifiedDate(long date, Connection con) throws SQLException {        // Only update the modified date if it is newer than the current one.        if (date > this.modifiedDate.getTime()) {        this.modifiedDate.setTime(date);            PreparedStatement pstmt = null;            try {                pstmt = con.prepareStatement(UPDATE_CATEGORY_MODIFIED_DATE);                pstmt.setString(1, StringUtils.dateToMillis(modifiedDate));                pstmt.setInt(2, lft);                pstmt.setInt(3, rgt);                pstmt.executeUpdate();            }            finally {                try {  pstmt.close(); }                catch (Exception e) { e.printStackTrace(); }            }        }    }    public int getCachedSize() {        int size = 0;        size += CacheSizes.sizeOfObject();              // overhead of object        size += CacheSizes.sizeOfLong();                // id        size += CacheSizes.sizeOfString(name);          // name        size += CacheSizes.sizeOfString(description);   // description        size += CacheSizes.sizeOfMap(properties);       // properties        // Make rough estimation of size of queryKeys        size += queryKeys.size() * 212;        return size;    }    /**     * Returns the SQL statement corresponding to a ResultFilter for threads.     *     * @param resultFilter the result filter to build the SQL from.     * @param countQuery true if this should be a count query.     * @param recursiveQuery if forums from all sub-categories should be in     *      the results.     */    protected String getForumListSQL(ResultFilter resultFilter,            boolean countQuery, boolean recursiveQuery)    {        int sortField = resultFilter.getSortField();        // Make sure the sort field is valid.        if (!countQuery && ! ( sortField == JiveGlobals.MODIFIED_DATE ||                sortField == JiveGlobals.CREATION_DATE ||                sortField == JiveGlobals.FORUM_CATEGORY_INDEX ||                sortField == JiveGlobals.FORUM_NAME ||                ( sortField == JiveGlobals.EXTENDED_PROPERTY &&                  resultFilter.getSortPropertyName() != null                )              )            )        {            throw new IllegalArgumentException("The specified sort field is not valid.");        }        StringBuffer query = new StringBuffer(80);        if (!countQuery) {            query.append("SELECT jiveForum.forumID");        }        else {            query.append("SELECT count(1)");        }        boolean filterCreationDate = resultFilter.getCreationDateRangeMin() != null ||                                     resultFilter.getCreationDateRangeMax() != null;        boolean filterModifiedDate = resultFilter.getModifiedDateRangeMin() != null ||                                     resultFilter.getModifiedDateRangeMax() != null;        int propertyCount = resultFilter.getPropertyCount();        // SELECT -- need to add value that we sort on        if (!countQuery) {            switch(sortField) {                case JiveGlobals.FORUM_NAME:                    query.append(", jiveForum.name");                    break;                case JiveGlobals.FORUM_CATEGORY_INDEX:                    query.append(", jiveForum.categoryIndex");                    break;                case JiveGlobals.MODIFIED_DATE:                    query.append(", jiveForum.modifiedDate");                    break;                case JiveGlobals.CREATION_DATE:                    query.append(", jiveForum.creationDate");                    break;                case JiveGlobals.EXTENDED_PROPERTY:                    query.append(", propTable.propValue");                    break;            }        }        // FROM -- values (in addition to jiveForum)        query.append(" FROM jiveForum");        for (int i=0; i<propertyCount; i++) {            query.append(", jiveForumProp p").append(i);        }        if (resultFilter.getSortField() == JiveGlobals.EXTENDED_PROPERTY)        {            query.append(", jiveForumProp propTable");        }        if (recursiveQuery) {            query.append(", jiveCategory");        }        // WHERE BLOCK        if (!recursiveQuery) {            query.append(" WHERE jiveForum.categoryID=").append(this.id);        }        else {            query.append(" WHERE jiveForum.categoryID=jiveCategory.categoryID");            query.append(" AND lft >= ").append(this.lft);            query.append(" AND rgt <= ").append(this.rgt);        }        // Properties        for (int i=0; i<propertyCount; i++) {            query.append(" AND jiveForum.forumID=p").append(i).append(".forumID");            query.append(" AND p").append(i).append(".name='");            query.append(resultFilter.getPropertyName(i));            query.append("' AND p").append(i).append(".propValue='");            query.append(resultFilter.getPropertyValue(i)).append("'");        }        // Sort on properties        if (sortField == JiveGlobals.EXTENDED_PROPERTY) {            query.append(" AND jiveForum.forumID=propTable.forumID");            query.append(" AND propTable.name='");            query.append(resultFilter.getSortPropertyName()).append("'");        }        // Creation date range        if (filterCreationDate) {            if (resultFilter.getCreationDateRangeMin() != null) {                query.append(" AND jiveForum.creationDate >= '");                query.append(StringUtils.dateToMillis(                        resultFilter.getCreationDateRangeMin()));                query.append("'");            }            if (resultFilter.getCreationDateRangeMax() != null) {                query.append(" AND jiveForum.creationDate <= '");                query.append(StringUtils.dateToMillis(                        resultFilter.getCreationDateRangeMax()));                query.append("'");            }        }        // Modified date range        if (filterModifiedDate) {            if (resultFilter.getModifiedDateRangeMin() != null) {                query.append(" AND jiveForum.modifiedDate >= '");                query.append(StringUtils.dateToMillis(                        resultFilter.getModifiedDateRangeMin()));                query.append("'");            }            if (resultFilter.getModifiedDateRangeMax() != null) {                query.append(" AND jiveForum.modifiedDate <= '");                query.append(StringUtils.dateToMillis(                        resultFilter.getModifiedDateRangeMax()));                query.append("'");            }        }        // ORDER BY        if (!countQuery) {            switch(sortField) {                case JiveGlobals.FORUM_CATEGORY_INDEX:                    query.append(" ORDER BY jiveForum.categoryIndex");                    break;                case JiveGlobals.FORUM_NAME:                    query.append(" ORDER BY jiveForum.name");                    break;                case JiveGlobals.MODIFIED_DATE:                    query.append(" ORDER BY jiveForum.modifiedDate");                    break;                case JiveGlobals.CREATION_DATE:                    query.append(" ORDER BY jiveForum.creationDate");                    break;                case JiveGlobals.EXTENDED_PROPERTY:                    query.append(" ORDER BY propTable.propValue");                    break;            }            if (resultFilter.getSortOrder() == ResultFilter.DESCENDING) {                query.append(" DESC");            }            else {                query.append(" ASC");            }        }        return query.toString();    }    /**     * Returns a block of objectID's (threads or messages) from a query and     * performs transparent caching of those blocks. The two parameters specify     * a database query and a startIndex for the results in that query.     *     * @param query the SQL message list query to cache blocks from.     * @param startIndex the startIndex in the list to get a block for.     */    protected long [] getBlock(String query, int startIndex) {        // First, find what block number the results will be in.        int blockID = startIndex / BLOCK_SIZE;        int blockStart = blockID * BLOCK_SIZE;        // Now, check cache to see if the block is already cached.        QueryCacheKey key = new QueryCacheKey(JiveGlobals.FORUM_CATEGORY, id, query, blockID);        // Synchronize on the sql query so that only one thread can try to load a        // block at once. This should help to prevent the database from        // becoming overloaded on busy sites.        StringBuffer internKey = new StringBuffer(query.length()+4).append(query).append(blockID);        synchronized (internKey.toString().intern()) {            // First, look in long-term cache.            long [] objectIDs = (long [])factory.cacheManager.queryCache.get(key);            // If lookup in long-term cache failed, look in short-term cache.

⌨️ 快捷键说明

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