0001: /*
0002: * $Header: /cvsroot/mvnforum/mvnforum/src/com/mvnforum/user/PostWebHandler.java,v 1.161 2008/01/25 10:49:07 tbtrung Exp $
0003: * $Author: tbtrung $
0004: * $Revision: 1.161 $
0005: * $Date: 2008/01/25 10:49:07 $
0006: *
0007: * ====================================================================
0008: *
0009: * Copyright (C) 2002-2007 by MyVietnam.net
0010: *
0011: * All copyright notices regarding mvnForum MUST remain
0012: * intact in the scripts and in the outputted HTML.
0013: * The "powered by" text/logo with a link back to
0014: * http://www.mvnForum.com and http://www.MyVietnam.net in
0015: * the footer of the pages MUST remain visible when the pages
0016: * are viewed on the internet or intranet.
0017: *
0018: * This program is free software; you can redistribute it and/or modify
0019: * it under the terms of the GNU General Public License as published by
0020: * the Free Software Foundation; either version 2 of the License, or
0021: * any later version.
0022: *
0023: * This program is distributed in the hope that it will be useful,
0024: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0025: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0026: * GNU General Public License for more details.
0027: *
0028: * You should have received a copy of the GNU General Public License
0029: * along with this program; if not, write to the Free Software
0030: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0031: *
0032: * Support can be obtained from support forums at:
0033: * http://www.mvnForum.com/mvnforum/index
0034: *
0035: * Correspondence and Marketing Questions can be sent to:
0036: * info at MyVietnam net
0037: *
0038: * @author: Minh Nguyen
0039: * @author: Mai Nguyen
0040: */
0041: package com.mvnforum.user;
0042:
0043: import java.io.IOException;
0044: import java.sql.Timestamp;
0045: import java.util.*;
0046:
0047: import javax.mail.MessagingException;
0048:
0049: import net.myvietnam.mvncore.exception.*;
0050: import net.myvietnam.mvncore.filter.DisableHtmlTagFilter;
0051: import net.myvietnam.mvncore.interceptor.InterceptorService;
0052: import net.myvietnam.mvncore.security.FloodControl;
0053: import net.myvietnam.mvncore.security.SecurityUtil;
0054: import net.myvietnam.mvncore.service.MvnCoreServiceFactory;
0055: import net.myvietnam.mvncore.util.*;
0056: import net.myvietnam.mvncore.web.GenericRequest;
0057: import net.myvietnam.mvncore.web.GenericResponse;
0058:
0059: import org.apache.commons.logging.Log;
0060: import org.apache.commons.logging.LogFactory;
0061:
0062: import com.mvnforum.*;
0063: import com.mvnforum.auth.*;
0064: import com.mvnforum.categorytree.*;
0065: import com.mvnforum.categorytree.impl.CategoryTreePath;
0066: import com.mvnforum.common.*;
0067: import com.mvnforum.db.*;
0068: import com.mvnforum.search.post.*;
0069: import com.mvnforum.service.CategoryService;
0070: import com.mvnforum.service.MvnForumServiceFactory;
0071:
0072: import freemarker.template.TemplateException;
0073:
0074: public class PostWebHandler {
0075:
0076: private static Log log = LogFactory.getLog(PostWebHandler.class);
0077:
0078: private OnlineUserManager onlineUserManager = OnlineUserManager
0079: .getInstance();
0080:
0081: private static CategoryService categoryService = MvnForumServiceFactory
0082: .getMvnForumService().getCategoryService();
0083: private static InterceptorService interceptorService = InterceptorService
0084: .getInstance();
0085:
0086: public PostWebHandler() {
0087: }
0088:
0089: /**
0090: * This method is for addpost page
0091: * @throws InterceptorException
0092: */
0093: public void prepareAdd(GenericRequest request,
0094: GenericResponse response) throws ObjectNotFoundException,
0095: DatabaseException, BadInputException,
0096: AuthenticationException, InterceptorException {
0097:
0098: Locale locale = I18nUtil.getLocaleInRequest(request);
0099:
0100: if (MVNForumConfig.getEnableNewPost() == false) {
0101: String localizedMessage = MVNForumResourceBundle
0102: .getString(locale,
0103: "java.lang.IllegalStateException.cannot_create_new_post.new_post_is_disabled");
0104: throw new IllegalStateException(localizedMessage);
0105: //throw new IllegalStateException("Cannot create new post because NEW_POST feature is disabled by administrator.");
0106: }
0107:
0108: OnlineUser onlineUser = onlineUserManager
0109: .getOnlineUser(request);
0110: MVNForumPermission permission = onlineUser.getPermission();
0111:
0112: if (MVNForumConfig.isGuestUserInDatabase() == false) {
0113: permission.ensureIsAuthenticated();
0114: }
0115:
0116: // we set this action attribute first because the return below can make method return prematurely
0117: request.setAttribute("action", "addnew");
0118:
0119: int parentPostID = 0;
0120: try {
0121: // if has parent --> there is no forum
0122: parentPostID = GenericParamUtil.getParameterInt(request,
0123: "parent");
0124: } catch (Exception ex) {
0125: // do nothing
0126: // NOTE: we cannot return here since user can have a parameter parent = 0
0127: }
0128: int forumID;
0129: String mode;
0130: String replyTopic;
0131:
0132: if (parentPostID == 0) {// new thread
0133: mode = MVNForumResourceBundle.getString(locale,
0134: "mvnforum.user.addpost.mode.addnew");
0135: replyTopic = "";
0136: forumID = GenericParamUtil
0137: .getParameterInt(request, "forum");
0138:
0139: ForumBean forumBean = null;
0140: try {
0141: forumBean = ForumCache.getInstance().getBean(forumID);
0142: } catch (ObjectNotFoundException e) {
0143: String localizedMessage = MVNForumResourceBundle
0144: .getString(
0145: locale,
0146: "mvncore.exception.ObjectNotFoundException.forumid_not_exists",
0147: new Object[] { new Integer(forumID) });
0148: throw new ObjectNotFoundException(localizedMessage);
0149: }
0150: forumBean.ensureNotDisabledForum();
0151: forumBean.ensureNotClosedForum();
0152: forumBean.ensureNotLockedForum();
0153:
0154: permission.ensureCanAddThread(forumID);
0155:
0156: // check if this thread is being watched
0157: Boolean isWatched = Boolean.FALSE;
0158: if (onlineUser.isMember()) {
0159: isWatched = new Boolean(WatchUtil.isForumWatched(
0160: onlineUser.getMemberID(), forumBean));
0161: }
0162: request.setAttribute("isWatched", isWatched);
0163: } else {// reply to a post
0164: // this is a parent post
0165: mode = MVNForumResourceBundle.getString(locale,
0166: "mvnforum.user.addpost.mode.reply");
0167: PostBean postBean = null;
0168: try {
0169: postBean = DAOFactory.getPostDAO()
0170: .getPost(parentPostID);// can throw DatabaseException
0171: } catch (ObjectNotFoundException ex) {
0172: String localizedMessage = MVNForumResourceBundle
0173: .getString(
0174: locale,
0175: "mvncore.exception.ObjectNotFoundException.postid_not_exists",
0176: new Object[] { new Integer(parentPostID) });
0177: throw new ObjectNotFoundException(localizedMessage);
0178: }
0179:
0180: // check permission
0181: forumID = postBean.getForumID();
0182: replyTopic = postBean.getPostTopic();
0183: ForumBean forumBean = null;
0184: try {
0185: forumBean = ForumCache.getInstance().getBean(forumID);
0186: } catch (ObjectNotFoundException e) {
0187: String localizedMessage = MVNForumResourceBundle
0188: .getString(
0189: locale,
0190: "mvncore.exception.ObjectNotFoundException.forumid_not_exists",
0191: new Object[] { new Integer(forumID) });
0192: throw new ObjectNotFoundException(localizedMessage);
0193: }
0194: forumBean.ensureNotDisabledForum();
0195: forumBean.ensureNotClosedForum();
0196: forumBean.ensureNotLockedForum();
0197:
0198: permission.ensureCanAddPost(forumID);
0199:
0200: // now we prepare to list latest post in the thread
0201: int threadID = postBean.getThreadID();
0202:
0203: // now check if thread is closed or locked, if it is, then cannot reply to a post
0204: ThreadBean threadBean = null;
0205: try {
0206: threadBean = DAOFactory.getThreadDAO().getThread(
0207: threadID);
0208: } catch (ObjectNotFoundException ex) {
0209: String localizedMessage = MVNForumResourceBundle
0210: .getString(
0211: locale,
0212: "mvncore.exception.ObjectNotFoundException.threadid_not_exists",
0213: new Object[] { new Integer(threadID) });
0214: throw new ObjectNotFoundException(localizedMessage);
0215: }
0216:
0217: threadBean.ensureStatusCanReply();
0218:
0219: Collection postBeans = DAOFactory.getPostDAO()
0220: .getLastEnablePosts_inThread_limit(threadID,
0221: MVNForumConfig.ROWS_IN_LAST_REPLIES);
0222: request.setAttribute("ParentPostBean", postBean);
0223: request.setAttribute("PostBeans", postBeans);
0224:
0225: // check if this thread is being watched
0226: Boolean isWatched = Boolean.FALSE;
0227: if (onlineUser.isMember()) {
0228: isWatched = new Boolean(WatchUtil
0229: .isThreadWatched(onlineUser.getMemberID(),
0230: threadBean, forumBean));
0231: }
0232: request.setAttribute("isWatched", isWatched);
0233: }
0234:
0235: boolean isPreviewing = GenericParamUtil.getParameterBoolean(
0236: request, "preview");
0237: if (isPreviewing) {
0238: MyUtil.saveVNTyperMode(request, response);
0239: //Get and Check if user enter some text or not
0240: String prePostTopic = GenericParamUtil.getParameter(
0241: request, "PostTopic", true);
0242: String prePostBody = GenericParamUtil.getParameter(request,
0243: "message", true);
0244: String prePostIcon = GenericParamUtil.getParameter(request,
0245: "PostIcon", false);
0246:
0247: //always disable HTML
0248: prePostTopic = DisableHtmlTagFilter.filter(prePostTopic);
0249: prePostBody = DisableHtmlTagFilter.filter(prePostBody);
0250: prePostIcon = DisableHtmlTagFilter.filter(prePostIcon);
0251:
0252: prePostTopic = interceptorService
0253: .validateContent(prePostTopic);
0254: prePostBody = interceptorService
0255: .validateContent(prePostBody);
0256:
0257: request.setAttribute("prePostTopic", prePostTopic);
0258: request.setAttribute("prePostBody", prePostBody);
0259: request.setAttribute("prePostIcon", prePostIcon);
0260:
0261: MemberBean memberBean = MemberCache.getInstance()
0262: .getMember(onlineUser.getMemberID());
0263: request.setAttribute("MemberBean", memberBean);
0264: }
0265:
0266: CategoryBuilder treebuilder = new DefaultCategoryBuilder();
0267: CategoryTree categorytree = new CategoryTree(treebuilder);
0268: CategoryTreeListener treelistener = new CategoryTreePath(
0269: request, response, forumID, mode, "addnew", replyTopic);
0270: categorytree.addCategeoryTreeListener(treelistener);
0271: request.setAttribute("tree", categorytree.build());
0272:
0273: CategoryBuilder builder = new DefaultCategoryBuilder();
0274: CategoryTree tree = new CategoryTree(builder);
0275: CategoryTreeListener listener = categoryService
0276: .getManagementCategorySelector(request, response,
0277: "addpost");
0278: tree.addCategeoryTreeListener(listener);
0279: request.setAttribute("Result", tree.build());
0280: }
0281:
0282: public void processAdd(GenericRequest request,
0283: GenericResponse response) throws ObjectNotFoundException,
0284: DatabaseException, CreateException, BadInputException,
0285: ForeignKeyNotFoundException, AuthenticationException,
0286: FloodException, InterceptorException, MessagingException,
0287: IOException, TemplateException {
0288:
0289: SecurityUtil.checkHttpPostMethod(request);
0290:
0291: Locale locale = I18nUtil.getLocaleInRequest(request);
0292: if (MVNForumConfig.getEnableNewPost() == false) {
0293: String localizedMessage = MVNForumResourceBundle
0294: .getString(locale,
0295: "java.lang.IllegalStateException.cannot_create_new_post.new_post_is_disabled");
0296: throw new IllegalStateException(localizedMessage);
0297: //throw new IllegalStateException("Cannot create new post because NEW_POST feature is disabled by administrator.");
0298: }
0299:
0300: OnlineUser onlineUser = onlineUserManager
0301: .getOnlineUser(request);
0302: MVNForumPermission permission = onlineUser.getPermission();
0303:
0304: int memberID = onlineUser.getMemberID();
0305: String memberName = onlineUser.getMemberName();
0306:
0307: try {
0308: FloodControl.ensureNotReachMaximum(
0309: MVNForumGlobal.FLOOD_ID_NEW_POST_PER_MEMBER,
0310: memberName);
0311: } catch (FloodException fe) {
0312: //throw new FloodException("You have reached the maximum number of the post adding actions for this page. Please try this page later. This is to prevent forum from being flooded.");
0313: Integer maxPosts = new Integer(
0314: FloodControl
0315: .getActionsPerHour(MVNForumGlobal.FLOOD_ID_NEW_POST_PER_MEMBER));
0316: String localizedMessage = MVNForumResourceBundle
0317: .getString(
0318: locale,
0319: "mvncore.exception.FloodException.add_post_too_many_times",
0320: new Object[] { maxPosts });
0321: throw new FloodException(localizedMessage);
0322: }
0323:
0324: String currentIP = request.getRemoteAddr();
0325: try {
0326: FloodControl.ensureNotReachMaximum(
0327: MVNForumGlobal.FLOOD_ID_NEW_POST_PER_IP, currentIP);
0328: } catch (FloodException fe) {
0329: //throw new FloodException("You have reached the maximum number of the post adding actions for this page. Please try this page later. This is to prevent forum from being flooded.");
0330: Integer maxPosts = new Integer(
0331: FloodControl
0332: .getActionsPerHour(MVNForumGlobal.FLOOD_ID_NEW_POST_PER_IP));
0333: String localizedMessage = MVNForumResourceBundle
0334: .getString(
0335: locale,
0336: "mvncore.exception.FloodException.add_post_too_many_times",
0337: new Object[] { maxPosts });
0338: throw new FloodException(localizedMessage);
0339: }
0340:
0341: MyUtil.saveVNTyperMode(request, response);
0342:
0343: Timestamp now = DateUtil.getCurrentGMTTimestamp();
0344:
0345: int parentPostID = GenericParamUtil.getParameterInt(request,
0346: "parent");
0347:
0348: boolean attachMore = GenericParamUtil.getParameterBoolean(
0349: request, "AttachMore");
0350: boolean addFavoriteThread = GenericParamUtil
0351: .getParameterBoolean(request, "AddFavoriteParentThread");
0352: boolean addWatchThread = GenericParamUtil.getParameterBoolean(
0353: request, "AddWatchParentThread");
0354:
0355: String postTopic = GenericParamUtil.getParameter(request,
0356: "PostTopic", true);
0357: postTopic = DisableHtmlTagFilter.filter(postTopic);// always disable HTML
0358: postTopic = interceptorService.validateContent(postTopic);
0359:
0360: String postBody = GenericParamUtil.getParameter(request,
0361: "message", true); // use message instead of MessageBody
0362: postBody = DisableHtmlTagFilter.filter(postBody);// always disable HTML
0363: String beforeValidated = postBody;
0364: postBody = interceptorService.validateContent(postBody);
0365:
0366: String postIcon = GenericParamUtil.getParameter(request,
0367: "PostIcon");
0368: postIcon = DisableHtmlTagFilter.filter(postIcon);// always disable HTML
0369:
0370: int forumID = 0;
0371: int threadID = 0;
0372: boolean isPendingThread = false;
0373: boolean isForumModerator = false;
0374: if (parentPostID == 0) {// new thread
0375:
0376: forumID = GenericParamUtil
0377: .getParameterInt(request, "forum");
0378: ForumBean forumBean = null;
0379: try {
0380: forumBean = ForumCache.getInstance().getBean(forumID);
0381: } catch (ObjectNotFoundException e) {
0382: String localizedMessage = MVNForumResourceBundle
0383: .getString(
0384: locale,
0385: "mvncore.exception.ObjectNotFoundException.forumid_not_exists",
0386: new Object[] { new Integer(forumID) });
0387: throw new ObjectNotFoundException(localizedMessage);
0388: }
0389: forumBean.ensureNotDisabledForum();
0390: forumBean.ensureNotClosedForum();
0391: forumBean.ensureNotLockedForum();
0392:
0393: // check permission
0394: isForumModerator = permission.canModerateThread(forumID);
0395: permission.ensureCanAddThread(forumID);
0396:
0397: String lastPostMemberName = memberName;
0398:
0399: int threadType = GenericParamUtil.getParameterUnsignedInt(
0400: request, "ThreadType",
0401: ThreadBean.THREAD_TYPE_DEFAULT);
0402: int threadPriority = GenericParamUtil
0403: .getParameterUnsignedInt(request, "ThreadPriority",
0404: ThreadBean.THREAD_PRIORITY_NORMAL);
0405:
0406: if (threadType > ThreadBean.THREAD_TYPE_GLOBAL_ANNOUNCEMENT /* 3 */) {
0407: //threadType = 0;
0408: throw new BadInputException(
0409: "Not support this thread type");
0410: }
0411:
0412: if (threadType == ThreadBean.THREAD_TYPE_GLOBAL_ANNOUNCEMENT) {
0413: permission.ensureCanAdminSystem();
0414: //forumID = -1; // this thread not belongs to any forum
0415: } else if (threadType != ThreadBean.THREAD_TYPE_DEFAULT) {
0416: permission.ensureCanModerateThread(forumID);
0417: }
0418:
0419: int threadOption = 0; //@todo review and support it later
0420: int threadStatus = ThreadBean.THREAD_STATUS_DEFAULT;
0421:
0422: // Ensure that moderator dont have to moderate the thread to enable it
0423: if (forumBean.shouldModerateThread() && !isForumModerator) {
0424: threadStatus = ThreadBean.THREAD_STATUS_DISABLED;
0425: isPendingThread = true;
0426: }
0427:
0428: int threadHasPoll = 0;//@todo review and support it later
0429: int threadDuration = 0;//@todo review and support it later
0430: int threadAttachCount = 0;
0431: threadID = DAOFactory.getThreadDAO().createThread(forumID,
0432: memberName, lastPostMemberName, postTopic,
0433: postBody, 0/*threadVoteCount*/,
0434: 0/*threadVoteTotalStars*/,
0435: now/*threadCreationDate*/,
0436: now/*threadLastPostDate*/, threadType,
0437: threadPriority, threadOption, threadStatus,
0438: threadHasPoll, 0/*threadViewCount*/,
0439: 0/*threadReplyCount*/, postIcon, threadDuration,
0440: threadAttachCount);
0441:
0442: } else {// reply to a post
0443: PostBean parentPostBean = null;
0444: try {
0445: parentPostBean = DAOFactory.getPostDAO().getPost(
0446: parentPostID);// can throw DatabaseException
0447: } catch (ObjectNotFoundException ex) {
0448: String localizedMessage = MVNForumResourceBundle
0449: .getString(
0450: locale,
0451: "mvncore.exception.ObjectNotFoundException.postid_not_exists",
0452: new Object[] { new Integer(parentPostID) });
0453: throw new ObjectNotFoundException(localizedMessage);
0454: }
0455: forumID = parentPostBean.getForumID();
0456: threadID = parentPostBean.getThreadID();
0457:
0458: ForumBean forumBean = null;
0459: try {
0460: forumBean = ForumCache.getInstance().getBean(forumID);
0461: } catch (ObjectNotFoundException e) {
0462: String localizedMessage = MVNForumResourceBundle
0463: .getString(
0464: locale,
0465: "mvncore.exception.ObjectNotFoundException.forumid_not_exists",
0466: new Object[] { new Integer(forumID) });
0467: throw new ObjectNotFoundException(localizedMessage);
0468: }
0469: forumBean.ensureNotDisabledForum();
0470: forumBean.ensureNotClosedForum();
0471: forumBean.ensureNotLockedForum();
0472:
0473: // check permission
0474: isForumModerator = permission.canModerateThread(forumID);
0475: permission.ensureCanAddPost(forumID);
0476:
0477: // now check if thread is closed or locked, if it is, then cannot reply to a post
0478: ThreadBean threadBean = null;
0479: try {
0480: threadBean = DAOFactory.getThreadDAO().getThread(
0481: threadID);
0482: } catch (ObjectNotFoundException ex) {
0483: String localizedMessage = MVNForumResourceBundle
0484: .getString(
0485: locale,
0486: "mvncore.exception.ObjectNotFoundException.threadid_not_exists",
0487: new Object[] { new Integer(threadID) });
0488: throw new ObjectNotFoundException(localizedMessage);
0489: }
0490: threadBean.ensureStatusCanReply();
0491:
0492: }
0493:
0494: //Timestamp postLastEditDate = now;
0495: String postCreationIP = currentIP;
0496: String postLastEditIP = "";// should we init it to postCreationIP ???
0497: int postFormatOption = 0;
0498: int postOption = 0;
0499: int postStatus = PostBean.POST_STATUS_DEFAULT;
0500:
0501: try {
0502: // Ensure that moderator dont have to moderate the thread to enable it
0503: if (ForumCache.getInstance().getBean(forumID)
0504: .shouldModeratePost()
0505: && !isForumModerator) {
0506: // we will not disble post that is a thread (parentPostID == 0)
0507: if (parentPostID != 0) {// replied post
0508: postStatus = PostBean.POST_STATUS_DISABLED;
0509: }
0510: }
0511: } catch (ObjectNotFoundException e) {
0512: String localizedMessage = MVNForumResourceBundle
0513: .getString(
0514: locale,
0515: "mvncore.exception.ObjectNotFoundException.forumid_not_exists",
0516: new Object[] { new Integer(forumID) });
0517: throw new ObjectNotFoundException(localizedMessage);
0518: }
0519:
0520: int postAttachCount = 0;
0521:
0522: int postID = DAOFactory.getPostDAO().createPost(parentPostID,
0523: forumID, threadID, memberID, memberName,
0524: ""/*lastEditMemberName*/, postTopic, postBody,
0525: now/*postCreationDate*/, now/*postLastEditDate*/,
0526: postCreationIP, postLastEditIP, 0/*postEditCount*/,
0527: postFormatOption, postOption, postStatus, postIcon,
0528: postAttachCount);
0529:
0530: // check whether censored words existed, if so send mail to Admin
0531: if (MVNForumConfig
0532: .getEnableEmailToAdminContentWithCensoredWords()) {
0533: if (beforeValidated.equals(postBody) == false) {
0534: PostUtil.sendEmailToAdminBecauseCensoredPost(request,
0535: postID, forumID, threadID, memberID);
0536: }
0537: }
0538:
0539: StatisticsUtil.updateMemberStatistics(memberID);
0540: StatisticsUtil.updateForumStatistics(forumID);
0541: StatisticsUtil.updateThreadStatistics(threadID);
0542:
0543: /** @todo Update PostEditLog table here */
0544:
0545: //add favorite thread if user checked it
0546: if (addFavoriteThread) {
0547: permission.ensureIsAuthenticated();
0548: //@todo: add checking of MVNForumConfig.getEnableFavoriteThread()
0549: // check to make sure that this user does not exceed his favorite max
0550: int currentFavoriteCount = DAOFactory
0551: .getFavoriteThreadDAO()
0552: .getNumberOfFavoriteThreads_inMember(memberID);
0553: int maxFavorites = MVNForumConfig.getMaxFavoriteThreads();
0554: if (currentFavoriteCount < maxFavorites) {
0555: Timestamp favoriteCreationDate = now;
0556: int favoriteType = 0; //@todo implement it later
0557: int favoriteOption = 0; //@todo implement it later
0558: int favoriteStatus = 0; //@todo implement it later
0559:
0560: // now check permission the this user have the readPost permission
0561: permission.ensureCanReadPost(forumID);
0562:
0563: // has the permission now, then insert to database
0564: try {
0565: DAOFactory.getFavoriteThreadDAO().create(memberID,
0566: threadID, forumID, favoriteCreationDate,
0567: favoriteType, favoriteOption,
0568: favoriteStatus);
0569: } catch (DuplicateKeyException ex) {
0570: // already add favorite thread, just ignore
0571: }
0572: }
0573: }
0574:
0575: //add watch if user checked it
0576: if (addWatchThread) {
0577: permission.ensureIsAuthenticated();
0578: permission.ensureIsActivated();
0579: if (MVNForumConfig.getEnableWatch() == false) {
0580: // should never happen, because if it happen, then the whole process is broken
0581: String localizedMessage = MVNForumResourceBundle
0582: .getString(locale,
0583: "java.lang.IllegalStateException.cannot_add_watch.watch_is_disabled");
0584: throw new IllegalStateException(localizedMessage);
0585: //throw new IllegalStateException("Cannot add Watch because Watch feature is disabled by administrator.");
0586: }
0587:
0588: int watchType = 0;//GenericParamUtil.getParameterInt(request, "WatchType");
0589: int watchOption = 0;//GenericParamUtil.getParameterInt(request, "WatchOption");
0590: int watchStatus = 0;//GenericParamUtil.getParameterInt(request, "WatchStatus");
0591: Timestamp watchCreationDate = now;
0592: Timestamp watchLastSentDate = now;
0593: Timestamp watchEndDate = now;// @todo: check it !!!
0594:
0595: try {
0596: DAOFactory.getWatchDAO().create(memberID,
0597: 0/*watchCategoryID*/, 0/*watchForumID*/,
0598: threadID, watchType, watchOption, watchStatus,
0599: watchCreationDate, watchLastSentDate,
0600: watchEndDate);
0601: } catch (DuplicateKeyException ex) {
0602: // User try to create a duplicate watch, just ignore
0603: }
0604: }
0605:
0606: // Now clear the cache
0607: MemberCache.getInstance().clear();
0608: PostCache.getInstance().clear();
0609: ThreadCache.getInstance().clear();
0610: ForumCache.getInstance().clear();// forum store the statistics of posts and threads
0611:
0612: // now, update the Search Index
0613: //@todo check the performance here
0614: PostBean justAddedPostBean = null;
0615: try {
0616: justAddedPostBean = DAOFactory.getPostDAO().getPost(postID);
0617: } catch (ObjectNotFoundException ex) {
0618: String localizedMessage = MVNForumResourceBundle
0619: .getString(
0620: locale,
0621: "mvncore.exception.ObjectNotFoundException.postid_not_exists",
0622: new Object[] { new Integer(postID) });
0623: throw new ObjectNotFoundException(localizedMessage);
0624: }
0625:
0626: PostIndexer.scheduleAddPostTask(justAddedPostBean);
0627:
0628: request.setAttribute("ForumID", String.valueOf(forumID));
0629: request.setAttribute("ThreadID", String.valueOf(threadID));
0630: request.setAttribute("PostID", String.valueOf(postID));
0631: request.setAttribute("AttachMore", new Boolean(attachMore));
0632: request.setAttribute("AddFavoriteParentThread", new Boolean(
0633: addFavoriteThread));
0634: request.setAttribute("AddWatchParentThread", new Boolean(
0635: addWatchThread));
0636: request.setAttribute("IsPendingThread", new Boolean(
0637: isPendingThread));
0638: /**@todo: review, this variable is still reserved*/
0639: //request.setAttribute("ParentPostID", String.valueOf(parentPostID));
0640: // for enterprise
0641: if ((MvnCoreServiceFactory.getMvnCoreService()
0642: .getEnvironmentService().isEnterprise())
0643: && (MVNForumConfig.getEnableAttachment())
0644: && (permission.canAddAttachment(forumID))) {
0645: request.setAttribute("UploadApplet", new Boolean(
0646: GenericParamUtil.getParameterBoolean(request,
0647: "UploadApplet")));
0648: }
0649: if ((MvnCoreServiceFactory.getMvnCoreService()
0650: .getEnvironmentService().isEnterprise())
0651: && (MVNForumConfig.getEnablePoll())
0652: && (permission.canAddPoll(forumID))) {
0653: boolean addPoll = GenericParamUtil.getParameterBoolean(
0654: request, "AddPoll");
0655: request.setAttribute("AddPoll", new Boolean(addPoll));
0656: }
0657:
0658: FloodControl.increaseCount(
0659: MVNForumGlobal.FLOOD_ID_NEW_POST_PER_IP, currentIP);
0660: FloodControl
0661: .increaseCount(
0662: MVNForumGlobal.FLOOD_ID_NEW_POST_PER_MEMBER,
0663: memberName);
0664:
0665: }
0666:
0667: public void addPostSuccessForRender(GenericRequest request,
0668: GenericResponse response) throws DatabaseException,
0669: ObjectNotFoundException, AuthenticationException {
0670:
0671: Locale locale = I18nUtil.getLocaleInRequest(request);
0672:
0673: int postID = (Integer.valueOf((String) request
0674: .getAttribute("PostID"))).intValue();
0675: int forumID = (Integer.valueOf((String) request
0676: .getAttribute("ForumID"))).intValue();
0677: // now, update the Search Index
0678: //@todo check the performance here
0679: PostBean justAddedPostBean = null;
0680: try {
0681: justAddedPostBean = DAOFactory.getPostDAO().getPost(postID);
0682: } catch (ObjectNotFoundException ex) {
0683: String localizedMessage = MVNForumResourceBundle
0684: .getString(
0685: locale,
0686: "mvncore.exception.ObjectNotFoundException.postid_not_exists",
0687: new Object[] { new Integer(postID) });
0688: throw new ObjectNotFoundException(localizedMessage);
0689: }
0690:
0691: String addPostSuccessLabel = MVNForumResourceBundle.getString(
0692: locale, "mvnforum.user.addpostsuccess.title");
0693: CategoryBuilder treebuilder = new DefaultCategoryBuilder();
0694: CategoryTree categorytree = new CategoryTree(treebuilder);
0695: CategoryTreeListener treelistener = new CategoryTreePath(
0696: request, response, forumID, null, null,
0697: addPostSuccessLabel);
0698: categorytree.addCategeoryTreeListener(treelistener);
0699: request.setAttribute("tree", categorytree.build());
0700:
0701: request.setAttribute("PostBean", justAddedPostBean);
0702: }
0703:
0704: public void preparePrintPost(GenericRequest request)
0705: throws ObjectNotFoundException, DatabaseException,
0706: BadInputException, AuthenticationException {
0707:
0708: OnlineUser onlineUser = onlineUserManager
0709: .getOnlineUser(request);
0710: MVNForumPermission permission = onlineUser.getPermission();
0711:
0712: int postID = GenericParamUtil.getParameterInt(request, "post");
0713: Locale locale = I18nUtil.getLocaleInRequest(request);
0714:
0715: PostBean postBean = null;
0716: try {
0717: postBean = DAOFactory.getPostDAO().getPost(postID);
0718: } catch (ObjectNotFoundException ex) {
0719: String localizedMessage = MVNForumResourceBundle
0720: .getString(
0721: locale,
0722: "mvncore.exception.ObjectNotFoundException.postid_not_exists",
0723: new Object[] { new Integer(postID) });
0724: throw new ObjectNotFoundException(localizedMessage);
0725: }
0726: int threadID = postBean.getThreadID();
0727: int forumID = postBean.getForumID();
0728:
0729: try {
0730: ForumCache.getInstance().getBean(forumID)
0731: .ensureNotDisabledForum();
0732: } catch (ObjectNotFoundException e) {
0733: String localizedMessage = MVNForumResourceBundle
0734: .getString(
0735: locale,
0736: "mvncore.exception.ObjectNotFoundException.forumid_not_exists",
0737: new Object[] { new Integer(forumID) });
0738: throw new ObjectNotFoundException(localizedMessage);
0739: }
0740:
0741: permission.ensureCanReadPost(forumID);
0742:
0743: // to show the thread topic
0744: ThreadBean threadBean = null;
0745: try {
0746: threadBean = DAOFactory.getThreadDAO().getThread(threadID);
0747: } catch (ObjectNotFoundException ex) {
0748: String localizedMessage = MVNForumResourceBundle
0749: .getString(
0750: locale,
0751: "mvncore.exception.ObjectNotFoundException.threadid_not_exists",
0752: new Object[] { new Integer(threadID) });
0753: throw new ObjectNotFoundException(localizedMessage);
0754: }
0755:
0756: MemberBean memberBean = null;
0757: if (postBean.getMemberID() > 0) {
0758: memberBean = MemberCache.getInstance().getMember(
0759: postBean.getMemberID());
0760: //memberBean = DAOFactory.getMemberDAO().getMember(postBean.getMemberID());
0761: }
0762: postBean.setMemberBean(memberBean);
0763:
0764: int postAttachCount = postBean.getPostAttachCount();
0765: if ((postAttachCount > 0)
0766: && MVNForumConfig.getEnableAttachment()) {
0767: Collection attachBeans = DAOFactory.getAttachmentDAO()
0768: .getAttachments_inPost(postID);
0769: int actualAttachCount = attachBeans.size();
0770:
0771: // now check if the attachCount in talbe Post equals to the actual attachCount in table Attachment
0772: if (postAttachCount != actualAttachCount) {
0773: if (actualAttachCount != DAOFactory.getAttachmentDAO()
0774: .getNumberOfAttachments_inPost(postID)) {
0775: String localizedMessage = MVNForumResourceBundle
0776: .getString(locale,
0777: "java.lang.AssertionError.serious_error.cannot_process_attachment_count");
0778: throw new AssertionError(localizedMessage);
0779: //throw new AssertionError("AssertionError: Serious error: cannot process Attachment Count in table Attachment");
0780: }
0781: log
0782: .warn("The attachment count in table Post and Attachment are not synchronized. In table Post = "
0783: + postAttachCount
0784: + " and in table Attachment = "
0785: + actualAttachCount
0786: + ". Synchronize to "
0787: + actualAttachCount);
0788: DAOFactory.getPostDAO().updateAttachCount(postID,
0789: actualAttachCount);
0790: }
0791: if (actualAttachCount > 0) {
0792: postBean.setAttachmentBeans(attachBeans);
0793: }
0794: }
0795:
0796: request.setAttribute("PostBean", postBean);
0797: request.setAttribute("ThreadBean", threadBean);
0798: }
0799:
0800: /**
0801: * then, it will be forward to addpost.jsp
0802: * NOTE: This method MUST NOT use parameter MessageParent (need some process to figure out)
0803: * @throws IOException
0804: * @throws InterceptorException
0805: */
0806: public void prepareEdit(GenericRequest request,
0807: GenericResponse response) throws ObjectNotFoundException,
0808: DatabaseException, BadInputException,
0809: AuthenticationException, IOException, InterceptorException {
0810:
0811: OnlineUser onlineUser = onlineUserManager
0812: .getOnlineUser(request);
0813: MVNForumPermission permission = onlineUser.getPermission();
0814:
0815: // a guest CANNOT edit a post, because it need Authenticated Permission
0816: permission.ensureIsAuthenticated();
0817: Locale locale = I18nUtil.getLocaleInRequest(request);
0818:
0819: String mode = MVNForumResourceBundle.getString(locale,
0820: "mvnforum.user.addpost.mode.update");
0821:
0822: int postID = GenericParamUtil.getParameterInt(request, "post");
0823: PostBean postBean = null;
0824: try {
0825: postBean = DAOFactory.getPostDAO().getPost(postID);
0826: } catch (ObjectNotFoundException ex) {
0827: String localizedMessage = MVNForumResourceBundle
0828: .getString(
0829: locale,
0830: "mvncore.exception.ObjectNotFoundException.postid_not_exists",
0831: new Object[] { new Integer(postID) });
0832: throw new ObjectNotFoundException(localizedMessage);
0833: }
0834: int forumID = postBean.getForumID();
0835: String replyTopic = postBean.getPostTopic();
0836:
0837: ForumBean forumBean = null;
0838: try {
0839: forumBean = ForumCache.getInstance().getBean(forumID);
0840: } catch (ObjectNotFoundException e) {
0841: String localizedMessage = MVNForumResourceBundle
0842: .getString(
0843: locale,
0844: "mvncore.exception.ObjectNotFoundException.forumid_not_exists",
0845: new Object[] { new Integer(forumID) });
0846: throw new ObjectNotFoundException(localizedMessage);
0847: }
0848: forumBean.ensureNotDisabledForum();
0849: forumBean.ensureNotLockedForum();
0850:
0851: // now check if thread is closed or locked, if it is, then cannot reply to a post
0852: int threadID = postBean.getThreadID();
0853: ThreadBean threadBean = null;
0854: try {
0855: threadBean = DAOFactory.getThreadDAO().getThread(threadID);
0856: } catch (ObjectNotFoundException ex) {
0857: String localizedMessage = MVNForumResourceBundle
0858: .getString(
0859: locale,
0860: "mvncore.exception.ObjectNotFoundException.threadid_not_exists",
0861: new Object[] { new Integer(threadID) });
0862: throw new ObjectNotFoundException(localizedMessage);
0863: }
0864: threadBean.ensureStatusCanEdit();
0865: int priority = threadBean.getThreadPriority();
0866:
0867: /*
0868: int logonMemberID = onlineUser.getMemberID();
0869: int authorID = postBean.getMemberID();
0870:
0871: // check constraint
0872: if (permission.canEditPost(forumID)) {
0873: // have permission, just do nothing, that is do not check the max day constraint
0874: } else if (logonMemberID == authorID) {// same author
0875: // make sure user have permission to edit his own post
0876: permission.ensureCanEditOwnPost(forumID);
0877:
0878: // check date here, usually must not older than 7 days
0879: Timestamp now = DateUtil.getCurrentGMTTimestamp();
0880: Timestamp postDate = postBean.getPostCreationDate();
0881: int maxDays = MVNForumConfig.getMaxEditDays();
0882: if ( (now.getTime() - postDate.getTime()) > (DateUtil.DAY * maxDays) ) {
0883: // @todo choose a better Exception here
0884: String localizedMessage = MVNForumResourceBundle.getString(locale, "mvncore.exception.BadInputException.cannot_edit.post_is_too_old", new Object[] {new Integer(maxDays)});
0885: throw new BadInputException(localizedMessage);
0886: //throw new BadInputException("You cannot edit a post which is older than " + maxDays + " days.");
0887: }
0888:
0889: // check status of this post
0890: if (postBean.getPostStatus() == PostBean.POST_STATUS_DISABLED) {
0891: String localizedMessage = MVNForumResourceBundle.getString(locale, "mvncore.exception.BadInputException.cannot_edit_your_post.which_is_disabled");
0892: throw new BadInputException(localizedMessage);
0893: //throw new BadInputException("Cannot edit message which is disable.");
0894: }
0895: } else {//not an author, so this user must have Edit Permission
0896: permission.ensureCanEditPost(forumID);// this method ALWAYS throws AuthenticationException
0897: }
0898: */
0899:
0900: PostChecker.checkEditPost(onlineUser, postBean);
0901:
0902: request.setAttribute("PostToEdit", postBean);
0903: request.setAttribute("Priority", new Integer(priority));
0904: request.setAttribute("action", "update");
0905:
0906: boolean isPreviewing = GenericParamUtil.getParameterBoolean(
0907: request, "preview");
0908: if (isPreviewing) {
0909: // Check if user enter some text or not
0910: GenericParamUtil.getParameter(request, "PostTopic", true);
0911: GenericParamUtil.getParameter(request, "message", true);// use message instead of MessageBody
0912:
0913: MemberBean memberBean = MemberCache.getInstance()
0914: .getMember(onlineUser.getMemberID());
0915: request.setAttribute("MemberBean", memberBean);
0916:
0917: String prePostTopic = GenericParamUtil.getParameter(
0918: request, "PostTopic");
0919: request.setAttribute("prePostTopic", prePostTopic);
0920:
0921: String prePostBody = GenericParamUtil.getParameter(request,
0922: "message");
0923: request.setAttribute("prePostBody", prePostBody);
0924:
0925: String prePostIcon = GenericParamUtil.getParameter(request,
0926: "PostIcon");
0927: request.setAttribute("prePostIcon", prePostIcon);
0928: }
0929:
0930: CategoryBuilder treebuilder = new DefaultCategoryBuilder();
0931: CategoryTree categorytree = new CategoryTree(treebuilder);
0932: CategoryTreeListener treelistener = new CategoryTreePath(
0933: request, response, forumID, mode, "update", replyTopic);
0934: categorytree.addCategeoryTreeListener(treelistener);
0935: request.setAttribute("tree", categorytree.build());
0936:
0937: CategoryBuilder builder = new DefaultCategoryBuilder();
0938: CategoryTree tree = new CategoryTree(builder);
0939: CategoryTreeListener listener = categoryService
0940: .getManagementCategorySelector(request, response,
0941: "addpost");
0942: tree.addCategeoryTreeListener(listener);
0943: request.setAttribute("Result", tree.build());
0944:
0945: // check if this thread is being watched
0946: Boolean isWatched = Boolean.FALSE;
0947: if (onlineUser.isMember()) {
0948: isWatched = new Boolean(WatchUtil.isThreadWatched(
0949: onlineUser.getMemberID(), threadBean, forumBean));
0950: }
0951: request.setAttribute("isWatched", isWatched);
0952: }
0953:
0954: /**
0955: * @throws MessagingException
0956: * @throws TemplateException
0957: * @todo: log the modification
0958: * @todo: check the comment below, it's obsolete now :(
0959: * @todo: check coi messageTopic co the la optional khi reply
0960: * NOTE: This method MUST NOT get parameter MessageParent (need some process to figure out)
0961: * so it needs to call setAttribute with messageParent for page updatepostsuccess.jsp
0962: */
0963: public void processUpdate(GenericRequest request)
0964: throws ObjectNotFoundException, BadInputException,
0965: DatabaseException, CreateException,
0966: ForeignKeyNotFoundException, AuthenticationException,
0967: InterceptorException, IOException, MessagingException,
0968: TemplateException {
0969:
0970: OnlineUser onlineUser = onlineUserManager
0971: .getOnlineUser(request);
0972: MVNForumPermission permission = onlineUser.getPermission();
0973:
0974: // a guest CANNOT edit a post, because it need Authenticated Permission
0975: permission.ensureIsAuthenticated();
0976: Locale locale = I18nUtil.getLocaleInRequest(request);
0977:
0978: Timestamp now = DateUtil.getCurrentGMTTimestamp();
0979:
0980: int postID = GenericParamUtil.getParameterInt(request, "post");// dont change
0981:
0982: // check constraint
0983: PostBean postBean = null;
0984: try {
0985: postBean = DAOFactory.getPostDAO().getPost(postID);
0986: } catch (ObjectNotFoundException ex) {
0987: String localizedMessage = MVNForumResourceBundle
0988: .getString(
0989: locale,
0990: "mvncore.exception.ObjectNotFoundException.postid_not_exists",
0991: new Object[] { new Integer(postID) });
0992: throw new ObjectNotFoundException(localizedMessage);
0993: }
0994: int forumID = postBean.getForumID();
0995: int threadID = postBean.getThreadID();
0996:
0997: ForumBean forumBean = ForumCache.getInstance().getBean(forumID);
0998: forumBean.ensureNotDisabledForum();
0999: forumBean.ensureNotLockedForum();
1000:
1001: // now check if thread is locked, if it is, then cannot reply to a post
1002: // Please note that if the threadStatus is closed, post can still be edited
1003: ThreadBean threadBean = null;
1004: try {
1005: threadBean = DAOFactory.getThreadDAO().getThread(threadID);
1006: } catch (ObjectNotFoundException ex) {
1007: String localizedMessage = MVNForumResourceBundle
1008: .getString(
1009: locale,
1010: "mvncore.exception.ObjectNotFoundException.threadid_not_exists",
1011: new Object[] { new Integer(threadID) });
1012: throw new ObjectNotFoundException(localizedMessage);
1013: }
1014: threadBean.ensureStatusCanEdit();
1015:
1016: String postTopic = GenericParamUtil.getParameter(request,
1017: "PostTopic", true);
1018: postTopic = DisableHtmlTagFilter.filter(postTopic);// always disable HTML
1019: postTopic = interceptorService.validateContent(postTopic);
1020:
1021: String postBody = GenericParamUtil.getParameter(request,
1022: "message", true);// use message instead of PostBody
1023: postBody = DisableHtmlTagFilter.filter(postBody);// always disable HTML
1024: String beforeValidated = postBody;
1025: postBody = interceptorService.validateContent(postBody);
1026:
1027: int logonMemberID = onlineUser.getMemberID();
1028: String logonMemberName = onlineUser.getMemberName();
1029:
1030: PostChecker.checkEditPost(onlineUser, postBean);
1031:
1032: String postLastEditIP = request.getRemoteAddr();
1033: int postFormatOption = 0;//@todo review and support it later
1034: int postOption = 0;//@todo review and support it later
1035: int postStatus = postBean.getPostStatus();// use old post status
1036: String postIcon = GenericParamUtil.getParameter(request,
1037: "PostIcon");
1038: postIcon = DisableHtmlTagFilter.filter(postIcon);// always disable HTML
1039:
1040: /*
1041: * Note that although the 2 methods below can be combined,
1042: * I dont do that for clearness
1043: */
1044: /** @todo log the modification here */
1045: DAOFactory.getPostDAO().update(
1046: postID, // primary key
1047: logonMemberName, postTopic, postBody,
1048: now/*postLastEditDate*/, postLastEditIP,
1049: postFormatOption, postOption, postStatus, postIcon);
1050: DAOFactory.getPostDAO().increaseEditCount(postID);
1051:
1052: // check whether censored words existed, if so send mail to Admin
1053: if (MVNForumConfig
1054: .getEnableEmailToAdminContentWithCensoredWords()) {
1055: if (beforeValidated.equals(postBody) == false) {
1056: PostUtil.sendEmailToAdminBecauseCensoredPost(request,
1057: postID, forumID, threadID, logonMemberID);
1058: }
1059: }
1060: if (postBean.getParentPostID() == 0) {//edit a top post (thread)
1061: String threadIcon = postIcon;
1062: int threadPriority = GenericParamUtil
1063: .getParameterUnsignedInt(request, "ThreadPriority",
1064: ThreadBean.THREAD_PRIORITY_NORMAL);
1065: DAOFactory.getThreadDAO().updateTopic_Body_Icon(threadID,
1066: postTopic, postBody, threadIcon, threadPriority);
1067: }
1068:
1069: boolean attachMore = GenericParamUtil.getParameterBoolean(
1070: request, "AttachMore");
1071: boolean addFavoriteThread = GenericParamUtil
1072: .getParameterBoolean(request, "AddFavoriteParentThread");
1073: boolean addWatchThread = GenericParamUtil.getParameterBoolean(
1074: request, "AddWatchParentThread");
1075: //add favorite thread if user checked it
1076: if (addFavoriteThread) {
1077: permission.ensureIsAuthenticated();
1078: //@todo: add checking of MVNForumConfig.getEnableFavoriteThread()
1079: // check to make sure that this user does not exceed his favorite max
1080: int currentFavoriteCount = DAOFactory
1081: .getFavoriteThreadDAO()
1082: .getNumberOfFavoriteThreads_inMember(logonMemberID);
1083: int maxFavorites = MVNForumConfig.getMaxFavoriteThreads();
1084: if (currentFavoriteCount < maxFavorites) {
1085: Timestamp favoriteCreationDate = now;
1086: int favoriteType = 0; //@todo implement it later
1087: int favoriteOption = 0; //@todo implement it later
1088: int favoriteStatus = 0; //@todo implement it later
1089:
1090: // now check permission the this user have the readPost permission
1091: permission.ensureCanReadPost(forumID);
1092:
1093: // has the permission now, then insert to database
1094: try {
1095: DAOFactory.getFavoriteThreadDAO().create(
1096: logonMemberID, threadID, forumID,
1097: favoriteCreationDate, favoriteType,
1098: favoriteOption, favoriteStatus);
1099: } catch (DuplicateKeyException ex) {
1100: // already add favorite thread, just ignore
1101: }
1102: }
1103: }
1104:
1105: //add watch if user checked it
1106: if (addWatchThread) {
1107: permission.ensureIsAuthenticated();
1108: permission.ensureIsActivated();
1109: if (MVNForumConfig.getEnableWatch() == false) {
1110: // should never happen, because if it happen, then the whole process is broken
1111: String localizedMessage = MVNForumResourceBundle
1112: .getString(locale,
1113: "java.lang.IllegalStateException.cannot_add_watch.watch_is_disabled");
1114: throw new IllegalStateException(localizedMessage);
1115: //throw new IllegalStateException("Cannot add Watch because Watch feature is disabled by administrator.");
1116: }
1117:
1118: int watchType = 0;//GenericParamUtil.getParameterInt(request, "WatchType");
1119: int watchOption = 0;//GenericParamUtil.getParameterInt(request, "WatchOption");
1120: int watchStatus = 0;//GenericParamUtil.getParameterInt(request, "WatchStatus");
1121: Timestamp watchCreationDate = now;
1122: Timestamp watchLastSentDate = now;
1123: Timestamp watchEndDate = now;// @todo: check it !!!
1124:
1125: try {
1126: DAOFactory.getWatchDAO().create(logonMemberID,
1127: 0/*watchCategoryID*/, 0/*watchForumID*/,
1128: threadID, watchType, watchOption, watchStatus,
1129: watchCreationDate, watchLastSentDate,
1130: watchEndDate);
1131: } catch (DuplicateKeyException ex) {
1132: // User try to create a duplicate watch, just ignore
1133: }
1134: }
1135:
1136: //- dat bien nay trong render portlet
1137: //- option add poll
1138: if (MvnCoreServiceFactory.getMvnCoreService()
1139: .getEnvironmentService().isEnterprise()
1140: && MVNForumConfig.getEnableAttachment()
1141: && permission.canAddAttachment(forumID)) {
1142: request.setAttribute("UploadApplet", new Boolean(
1143: GenericParamUtil.getParameterBoolean(request,
1144: "UploadApplet")));
1145: }
1146:
1147: request.setAttribute("PostID", String.valueOf(postID));
1148: request.setAttribute("ForumID", String.valueOf(forumID));
1149: request.setAttribute("ThreadID", String.valueOf(threadID));
1150: request.setAttribute("AttachMore", new Boolean(attachMore));
1151:
1152: // now update the search index
1153: //@todo : modify for better performance here
1154: PostIndexer.scheduleUpdatePostTask(DAOFactory.getPostDAO()
1155: .getPost(postID));
1156:
1157: // Clear the cache
1158: PostCache.getInstance().clear();
1159: ThreadCache.getInstance().clear();
1160: }
1161:
1162: public void updatePostSuccessForRender(GenericRequest request,
1163: GenericResponse response) throws DatabaseException,
1164: ObjectNotFoundException, AuthenticationException {
1165:
1166: Locale locale = I18nUtil.getLocaleInRequest(request);
1167:
1168: int postID = (Integer.valueOf((String) request
1169: .getAttribute("PostID"))).intValue();
1170: int forumID = (Integer.valueOf((String) request
1171: .getAttribute("ForumID"))).intValue();
1172:
1173: PostBean postBean = DAOFactory.getPostDAO().getPost(postID);
1174:
1175: String addPostSuccessLabel = MVNForumResourceBundle.getString(
1176: locale, "mvnforum.user.updatepostsuccess.title");
1177: CategoryBuilder treebuilder = new DefaultCategoryBuilder();
1178: CategoryTree categorytree = new CategoryTree(treebuilder);
1179: CategoryTreeListener treelistener = new CategoryTreePath(
1180: request, response, forumID, null, null,
1181: addPostSuccessLabel);
1182: categorytree.addCategeoryTreeListener(treelistener);
1183: request.setAttribute("tree", categorytree.build());
1184:
1185: request.setAttribute("PostBean", postBean);
1186: }
1187:
1188: public void prepareDelete(GenericRequest request,
1189: GenericResponse response) throws ObjectNotFoundException,
1190: BadInputException, DatabaseException,
1191: AuthenticationException {
1192:
1193: OnlineUser onlineUser = onlineUserManager
1194: .getOnlineUser(request);
1195: MVNForumPermission permission = onlineUser.getPermission();
1196:
1197: // user must have been authenticated before he can delete
1198: permission.ensureIsAuthenticated();
1199: Locale locale = I18nUtil.getLocaleInRequest(request);
1200:
1201: // primary key column(s)
1202: int postID = GenericParamUtil.getParameterInt(request, "post");
1203:
1204: PostBean postBean = null;
1205: try {
1206: postBean = DAOFactory.getPostDAO().getPost(postID);
1207: } catch (ObjectNotFoundException ex) {
1208: String localizedMessage = MVNForumResourceBundle
1209: .getString(
1210: locale,
1211: "mvncore.exception.ObjectNotFoundException.postid_not_exists",
1212: new Object[] { new Integer(postID) });
1213: throw new ObjectNotFoundException(localizedMessage);
1214: }
1215: int forumID = postBean.getForumID();
1216:
1217: try {
1218: ForumCache.getInstance().getBean(forumID)
1219: .ensureNotDisabledForum();
1220: } catch (ObjectNotFoundException e) {
1221: String localizedMessage = MVNForumResourceBundle
1222: .getString(
1223: locale,
1224: "mvncore.exception.ObjectNotFoundException.forumid_not_exists",
1225: new Object[] { new Integer(forumID) });
1226: throw new ObjectNotFoundException(localizedMessage);
1227: }
1228:
1229: PostChecker.checkRootOfThread(onlineUser, postBean);
1230:
1231: // check other constraints
1232: if (permission.canDeletePost(forumID)) {
1233: // have permission, just do nothing, that is dont check the max day contraint
1234: } else if (PostChecker.isAuthorOfPost(onlineUser, postBean)) {// same author
1235: // check date here, usually must not older than 7 days
1236: PostChecker.checkTooOld(onlineUser, postBean);
1237:
1238: //Check to make sure that "no reply" for this post
1239: PostChecker.checkNoReply(onlineUser, postBean);
1240:
1241: //Check to make ensure that this post is enabled
1242: PostChecker.checkDisable(onlineUser, postBean);
1243: } else {//not an author, so this user must have Edit Permission
1244: permission.ensureCanDeletePost(forumID);// this method ALWAYS throws AuthenticationException
1245: }
1246:
1247: request.setAttribute("PostBean", postBean);
1248:
1249: String title = MVNForumResourceBundle.getString(locale,
1250: "mvnforum.user.deletepost.title");
1251:
1252: StringBuffer stb = new StringBuffer();
1253: stb.append(title).append(": ").append(postBean.getPostTopic());
1254: CategoryBuilder treebuilder = new DefaultCategoryBuilder();
1255: CategoryTree categorytree = new CategoryTree(treebuilder);
1256: CategoryTreeListener treelistener = new CategoryTreePath(
1257: request, response, forumID, null, null, stb.toString());
1258: categorytree.addCategeoryTreeListener(treelistener);
1259: request.setAttribute("tree", categorytree.build());
1260:
1261: }
1262:
1263: public void processDelete(GenericRequest request)
1264: throws BadInputException, DatabaseException,
1265: AuthenticationException, ObjectNotFoundException {
1266:
1267: SecurityUtil.checkHttpPostMethod(request);
1268:
1269: Locale locale = I18nUtil.getLocaleInRequest(request);
1270:
1271: // primary key column(s)
1272: int postID = GenericParamUtil.getParameterInt(request, "post");
1273: PostBean postBean = null;
1274: try {
1275: postBean = DAOFactory.getPostDAO().getPost(postID);
1276: } catch (ObjectNotFoundException ex) {
1277: String localizedMessage = MVNForumResourceBundle
1278: .getString(
1279: locale,
1280: "mvncore.exception.ObjectNotFoundException.postid_not_exists",
1281: new Object[] { new Integer(postID) });
1282: throw new ObjectNotFoundException(localizedMessage);
1283: }
1284:
1285: // now check the password
1286: MyUtil.ensureCorrectCurrentPassword(request);
1287:
1288: ForumCache.getInstance().getBean(postBean.getForumID())
1289: .ensureNotDisabledForum();
1290:
1291: // delete the post and children attachments
1292: deletePost(request, postBean);
1293:
1294: int threadID = postBean.getThreadID();
1295: int forumID = postBean.getForumID();
1296:
1297: // now update the forum and thread statistics
1298: StatisticsUtil.updateForumStatistics(forumID);
1299: StatisticsUtil.updateThreadStatistics(threadID);
1300:
1301: // Clear the cache
1302: PostCache.getInstance().clear();
1303:
1304: request.setAttribute("ForumID", String.valueOf(forumID));
1305: request.setAttribute("ThreadID", String.valueOf(threadID));
1306: }
1307:
1308: // Note that this method does not update the forum statistics and thread statistics
1309: private void deletePost(GenericRequest request, PostBean postBean)
1310: throws DatabaseException, AuthenticationException,
1311: BadInputException, ObjectNotFoundException {
1312:
1313: OnlineUser onlineUser = onlineUserManager
1314: .getOnlineUser(request);
1315: MVNForumPermission permission = onlineUser.getPermission();
1316:
1317: // user must have been authenticated before he can delete
1318: permission.ensureIsAuthenticated();
1319:
1320: int parentPostID = postBean.getParentPostID();
1321:
1322: Locale locale = I18nUtil.getLocaleInRequest(request);
1323:
1324: if (parentPostID == 0) {
1325: String localizedMessage = MVNForumResourceBundle
1326: .getString(locale,
1327: "mvncore.exception.BadInputException.cannot_delete_root_post");
1328: throw new BadInputException(localizedMessage);
1329: //throw new BadInputException("Cannot delete a root post. Use delete thread instead.");
1330: }
1331:
1332: int forumID = postBean.getForumID();
1333:
1334: // check constraint
1335: int logonMemberID = onlineUser.getMemberID();
1336: int authorID = postBean.getMemberID();
1337: if (permission.canDeletePost(forumID)) {
1338: // have permission, just do nothing, that is dont check the max day contraint
1339: } else if (logonMemberID == authorID) {// same author
1340: // check date here, usually must not older than 7 days
1341: Timestamp now = DateUtil.getCurrentGMTTimestamp();
1342: Timestamp postDate = postBean.getPostCreationDate();
1343: int maxDays = MVNForumConfig.getMaxDeleteDays();
1344: if ((now.getTime() - postDate.getTime()) > (DateUtil.DAY * maxDays)) {
1345: /** @todo choose a better Exception here */
1346: String localizedMessage = MVNForumResourceBundle
1347: .getString(
1348: locale,
1349: "mvncore.exception.BadInputException.cannot_delete.post_is_too_old",
1350: new Object[] { new Integer(maxDays) });
1351: throw new BadInputException(localizedMessage);
1352: //throw new BadInputException("You cannot delete a post which is older than " + maxDays + " days.");
1353: }
1354:
1355: //Check to make sure that "no reply" for this post
1356: int threadID = postBean.getThreadID();
1357: Collection postBeans = DAOFactory.getPostDAO()
1358: .getEnablePosts_inThread_limit(threadID, 0, 10000);
1359: boolean foundReply = false;
1360: for (Iterator ite = postBeans.iterator(); ite.hasNext();) {
1361: PostBean tPostBean = (PostBean) ite.next();
1362: if (tPostBean.getParentPostID() == postBean.getPostID()) {
1363: foundReply = true;
1364: break;
1365: }
1366: }
1367: if (foundReply) {
1368: String localizedMessage = MVNForumResourceBundle
1369: .getString(locale,
1370: "mvncore.exception.BadInputException.cannot_delete_post.post_has_reply");
1371: throw new BadInputException(localizedMessage);
1372: //throw new BadInputException("Cannot delete a post that has reply!");
1373: }
1374:
1375: if (postBean.getPostStatus() == PostBean.POST_STATUS_DISABLED) {
1376: String localizedMessage = MVNForumResourceBundle
1377: .getString(
1378: locale,
1379: "mvncore.exception.BadInputException.cannot_delete_your_own_post.post_is_in_pending_status");
1380: throw new BadInputException(localizedMessage);
1381: //throw new BadInputException("Cannot delete your own disabled post.");
1382: }
1383: } else {//not an author, so this user must have Edit Permission
1384: permission.ensureCanDeletePost(forumID);// this method ALWAYS throws AuthenticationException
1385: }
1386:
1387: int postID = postBean.getPostID();
1388:
1389: // Delete all attachments in this post,
1390: // we must call this before any attempt to delete the post
1391: AttachmentWebHandler.deleteAttachments_inPost(postID);
1392:
1393: // now delete the post, note that we delete it after delete all child objects (attachment)
1394: DAOFactory.getPostDAO().delete(postID);
1395:
1396: try {
1397: DAOFactory.getPostDAO().updateParentPostID(postID,
1398: parentPostID);
1399: } catch (ObjectNotFoundException ex) {
1400: // we just ignore if no post is affect by this method
1401: }
1402:
1403: int memberID = postBean.getMemberID();
1404: StatisticsUtil.updateMemberStatistics(memberID);
1405:
1406: // now update the search index
1407: PostIndexer.scheduleDeletePostTask(postID,
1408: DeletePostIndexTask.OBJECT_TYPE_POST);
1409: }
1410:
1411: public void deleteSuccessForRender(GenericRequest request,
1412: GenericResponse response) throws ObjectNotFoundException,
1413: DatabaseException, AuthenticationException {
1414:
1415: Locale locale = I18nUtil.getLocaleInRequest(request);
1416:
1417: int forumID = (Integer.valueOf((String) request
1418: .getAttribute("ForumID"))).intValue();
1419:
1420: String addPostSuccessLabel = MVNForumResourceBundle.getString(
1421: locale, "mvnforum.user.deletepostsuccess.title");
1422: CategoryBuilder treebuilder = new DefaultCategoryBuilder();
1423: CategoryTree categorytree = new CategoryTree(treebuilder);
1424: CategoryTreeListener treelistener = new CategoryTreePath(
1425: request, response, forumID, null, null,
1426: addPostSuccessLabel);
1427: categorytree.addCategeoryTreeListener(treelistener);
1428:
1429: request.setAttribute("tree", categorytree.build());
1430: }
1431:
1432: public void prepareModeratePendingPosts_limit(GenericRequest request)
1433: throws DatabaseException, AuthenticationException,
1434: BadInputException, DatabaseException,
1435: ObjectNotFoundException {
1436:
1437: OnlineUser onlineUser = onlineUserManager
1438: .getOnlineUser(request);
1439: MVNForumPermission permission = onlineUser.getPermission();
1440:
1441: Locale locale = I18nUtil.getLocaleInRequest(request);
1442:
1443: int threadID = GenericParamUtil.getParameterInt(request,
1444: "thread");
1445: ThreadBean threadBean = null;
1446: try {
1447: threadBean = DAOFactory.getThreadDAO().getThread(threadID);
1448: } catch (ObjectNotFoundException ex) {
1449: String localizedMessage = MVNForumResourceBundle
1450: .getString(
1451: locale,
1452: "mvncore.exception.ObjectNotFoundException.threadid_not_exists",
1453: new Object[] { new Integer(threadID) });
1454: throw new ObjectNotFoundException(localizedMessage);
1455: }
1456: int forumID = threadBean.getForumID();
1457:
1458: try {
1459: ForumCache.getInstance().getBean(forumID)
1460: .ensureNotDisabledForum();
1461: } catch (ObjectNotFoundException e) {
1462: String localizedMessage = MVNForumResourceBundle
1463: .getString(
1464: locale,
1465: "mvncore.exception.ObjectNotFoundException.forumid_not_exists",
1466: new Object[] { new Integer(forumID) });
1467: throw new ObjectNotFoundException(localizedMessage);
1468: }
1469:
1470: int numberOfPosts = DAOFactory.getPostDAO()
1471: .getNumberOfDisablePosts_inThread(threadID);
1472:
1473: // user must have been authenticated before he can view pending/disabled threads
1474: permission.ensureIsAuthenticated();
1475:
1476: // check normal permission
1477: permission.ensureCanModerateThread(forumID);
1478:
1479: int postsPerPage = 10000;
1480: int offset = 0;
1481:
1482: Collection postBeans = DAOFactory.getPostDAO()
1483: .getDisablePosts_inThread_limit(threadID, offset,
1484: postsPerPage);
1485:
1486: Iterator iterator = postBeans.iterator();
1487: while (iterator.hasNext()) {
1488: PostBean postBean = (PostBean) iterator.next();
1489: // very slow here
1490: /** @todo find a better solution */
1491: MemberBean memberBean = null;
1492: if (postBean.getMemberID() != 0
1493: && postBean.getMemberID() != MVNForumConstant.MEMBER_ID_OF_GUEST) {
1494: memberBean = MemberCache.getInstance().getMember(
1495: postBean.getMemberID());
1496: }
1497: postBean.setMemberBean(memberBean);
1498:
1499: int postAttachCount = postBean.getPostAttachCount();
1500: if ((postAttachCount > 0)
1501: && MVNForumConfig.getEnableAttachment()) {
1502: int postID = postBean.getPostID();
1503: Collection attachBeans = DAOFactory.getAttachmentDAO()
1504: .getAttachments_inPost(postID);
1505: int actualAttachCount = attachBeans.size();
1506:
1507: // now check if the attachCount in talbe Post equals to the actual attachCount in table Attachment
1508: if (postAttachCount != actualAttachCount) {
1509: if (actualAttachCount != DAOFactory
1510: .getAttachmentDAO()
1511: .getNumberOfAttachments_inPost(postID)) {
1512: String localizedMessage = MVNForumResourceBundle
1513: .getString(locale,
1514: "java.lang.AssertionError.serious_error.cannot_process_attachment_count");
1515: throw new AssertionError(localizedMessage);
1516: //throw new AssertionError("AssertionError: Serious error: cannot process Attachment Count in table Attachment");
1517: }
1518: log
1519: .warn("The attachment count in table Post and Attachment are not synchronized. In table Post = "
1520: + postAttachCount
1521: + " and in table Attachment = "
1522: + actualAttachCount
1523: + ". Synchronize to "
1524: + actualAttachCount);
1525: DAOFactory.getPostDAO().updateAttachCount(postID,
1526: actualAttachCount);
1527: }
1528: if (actualAttachCount > 0) {
1529: postBean.setAttachmentBeans(attachBeans);
1530: }
1531: }
1532: }
1533:
1534: PostBean firstPostBean = DAOFactory.getPostDAO()
1535: .getFirstPost_inThread(threadID);
1536: if (firstPostBean.getMemberID() != 0
1537: && firstPostBean.getMemberID() != MVNForumConstant.MEMBER_ID_OF_GUEST) {
1538: MemberBean memberBean = MemberCache.getInstance()
1539: .getMember(firstPostBean.getMemberID());
1540: firstPostBean.setMemberBean(memberBean);
1541: }
1542:
1543: request.setAttribute("ThreadBean", threadBean);
1544: request.setAttribute("FirstPostBean", firstPostBean);
1545: request.setAttribute("PostBeans", postBeans);
1546: request.setAttribute("NumberOfPosts",
1547: new Integer(numberOfPosts));
1548: }
1549:
1550: public void processModeratePendingPosts(GenericRequest request)
1551: throws DatabaseException, AuthenticationException,
1552: BadInputException, DatabaseException,
1553: ObjectNotFoundException {
1554:
1555: OnlineUser onlineUser = onlineUserManager
1556: .getOnlineUser(request);
1557: MVNForumPermission permission = onlineUser.getPermission();
1558: Locale locale = I18nUtil.getLocaleInRequest(request);
1559:
1560: // user must have been authenticated before he can moderate pending/disabled posts
1561: permission.ensureIsAuthenticated();
1562:
1563: // check normal permission, note that we dont check
1564: // permission on a forumID because we allow moderate posts
1565: // in multiple forums even if the web interface does not support it
1566: int threadID = -1;
1567: int forumID = -1;
1568: try {
1569: threadID = GenericParamUtil.getParameterInt(request,
1570: "thread");
1571: ThreadBean threadBean = null;
1572: try {
1573: threadBean = DAOFactory.getThreadDAO().getThread(
1574: threadID);
1575: } catch (ObjectNotFoundException ex) {
1576: String localizedMessage = MVNForumResourceBundle
1577: .getString(
1578: locale,
1579: "mvncore.exception.ObjectNotFoundException.threadid_not_exists",
1580: new Object[] { new Integer(threadID) });
1581: throw new ObjectNotFoundException(localizedMessage);
1582: }
1583: forumID = threadBean.getForumID();
1584: permission.ensureCanModerateThread(forumID);
1585: ForumCache.getInstance().getBean(forumID)
1586: .ensureNotDisabledForum();
1587: } catch (BadInputException ex) {
1588: // just ignore, in case of use customized client
1589: }
1590: permission.ensureCanModerateThreadInAnyForum();
1591:
1592: try {
1593: String prefix = "modpostaction_";
1594: for (Enumeration enumeration = request.getParameterNames(); enumeration
1595: .hasMoreElements();) {
1596: String param = (String) enumeration.nextElement();
1597: if (param.startsWith(prefix)) {
1598: String modValue = GenericParamUtil.getParameter(
1599: request, param, true);
1600: String strPostID = param.substring(prefix.length());
1601: int postID = Integer.parseInt(strPostID);
1602: if (modValue.equals("approve")) {
1603: PostBean postBean = null;
1604: try {
1605: postBean = DAOFactory.getPostDAO().getPost(
1606: postID);
1607: } catch (ObjectNotFoundException ex) {
1608: String localizedMessage = MVNForumResourceBundle
1609: .getString(
1610: locale,
1611: "mvncore.exception.ObjectNotFoundException.postid_not_exists",
1612: new Object[] { new Integer(
1613: postID) });
1614: throw new ObjectNotFoundException(
1615: localizedMessage);
1616: }
1617: int currentForumID = postBean.getForumID();
1618: permission
1619: .ensureCanModerateThread(currentForumID);
1620: DAOFactory.getPostDAO().updateStatus(postID,
1621: PostBean.POST_STATUS_DEFAULT);
1622: } else if (modValue.equals("delete")) {
1623: PostBean postBean = null;
1624: try {
1625: postBean = DAOFactory.getPostDAO().getPost(
1626: postID);
1627: } catch (ObjectNotFoundException ex) {
1628: String localizedMessage = MVNForumResourceBundle
1629: .getString(
1630: locale,
1631: "mvncore.exception.ObjectNotFoundException.postid_not_exists",
1632: new Object[] { new Integer(
1633: postID) });
1634: throw new ObjectNotFoundException(
1635: localizedMessage);
1636: }
1637: deletePost(request, postBean);
1638: } else {
1639: // it means ignore, do nothing
1640: }
1641: }
1642: }
1643: } finally {
1644: // now update the forum statistics
1645: if (forumID != -1) {
1646: StatisticsUtil.updateForumStatistics(forumID);
1647: }
1648:
1649: // now update the thread statistics
1650: if (threadID != -1) {
1651: StatisticsUtil.updateThreadStatistics(threadID);
1652: }
1653: }
1654:
1655: // Now clear the cache
1656: PostCache.getInstance().clear();
1657: ThreadCache.getInstance().clear();
1658:
1659: request.setAttribute("ForumID", String.valueOf(forumID));
1660: request.setAttribute("ThreadID", String.valueOf(threadID));
1661: }
1662:
1663: /**
1664: * This method is for viewthread page and printthread page
1665: * @throws DatabaseException
1666: * @throws AuthenticationException
1667: * @throws BadInputException
1668: * @throws ObjectNotFoundException
1669: * @throws MissingURLMapEntryException
1670: */
1671: public void prepareViewThread(GenericRequest request,
1672: GenericResponse response, String requestURI)
1673: throws AuthenticationException, DatabaseException,
1674: BadInputException, ObjectNotFoundException,
1675: MissingURLMapEntryException {
1676:
1677: OnlineUserUtil.updateOnlineUserAction(request, requestURI);
1678:
1679: OnlineUser onlineUser = onlineUserManager
1680: .getOnlineUser(request);
1681: MVNForumPermission permission = onlineUser.getPermission();
1682:
1683: Locale locale = I18nUtil.getLocaleInRequest(request);
1684:
1685: int threadID = GenericParamUtil.getParameterInt(request,
1686: "thread");
1687: boolean printAll = GenericParamUtil.getParameterBoolean(
1688: request, "printall");
1689: ThreadBean threadBean = null;
1690: try {
1691: threadBean = DAOFactory.getThreadDAO().getThread(threadID);
1692: } catch (ObjectNotFoundException ex) {
1693: String localizedMessage = MVNForumResourceBundle
1694: .getString(
1695: locale,
1696: "mvncore.exception.ObjectNotFoundException.threadid_not_exists",
1697: new Object[] { new Integer(threadID) });
1698: throw new ObjectNotFoundException(localizedMessage);
1699: }
1700: int forumID = threadBean.getForumID();
1701: int numberOfPosts = DAOFactory.getPostDAO()
1702: .getNumberOfEnablePosts_inThread(threadID);
1703:
1704: // check normal permission
1705: permission.ensureCanReadPost(forumID);
1706:
1707: ForumBean forumBean = null;
1708: try {
1709: forumBean = ForumCache.getInstance().getBean(forumID);
1710: forumBean.ensureNotDisabledForum();
1711: } catch (ObjectNotFoundException e) {
1712: String localizedMessage = MVNForumResourceBundle
1713: .getString(
1714: locale,
1715: "mvncore.exception.ObjectNotFoundException.forumid_not_exists",
1716: new Object[] { new Integer(forumID) });
1717: throw new ObjectNotFoundException(localizedMessage);
1718: }
1719:
1720: // Only moderator can view disable threads
1721: if (threadBean.getThreadStatus() == ThreadBean.THREAD_STATUS_DISABLED) {
1722: permission.ensureCanModerateThread(forumID);
1723: }
1724:
1725: int postsPerPage = onlineUser.getPostsPerPage();
1726: int offset = 0;
1727: boolean lastPage = GenericParamUtil.getParameterBoolean(
1728: request, "lastpage");
1729: if (lastPage) {
1730: // note that in the worst case, numberOfPosts could equals 0 (bad database)
1731: int pageCount = numberOfPosts / postsPerPage;
1732: int odd = numberOfPosts % postsPerPage;
1733: if (odd > 0) {
1734: pageCount++;
1735: }
1736: if (pageCount < 1) {
1737: pageCount = 1;// at least, there is one page
1738: }
1739: offset = (pageCount - 1) * postsPerPage;
1740: } else {
1741: try {
1742: offset = GenericParamUtil.getParameterUnsignedInt(
1743: request, "offset");
1744: } catch (BadInputException e) {
1745: // do nothing
1746: }
1747: }
1748: if (printAll) {
1749: postsPerPage = 10000; //We assume that big number
1750: offset = 0;
1751: }
1752:
1753: Collection postBeans = PostCache.getInstance()
1754: .getEnablePosts_inThread_limit(threadID, offset,
1755: postsPerPage);
1756:
1757: Iterator iterator = postBeans.iterator();
1758: while (iterator.hasNext()) {
1759: PostBean postBean = (PostBean) iterator.next();
1760: MemberBean memberBean = null;
1761: if (postBean.getMemberID() != 0
1762: && postBean.getMemberID() != MVNForumConstant.MEMBER_ID_OF_GUEST) {
1763: // Use cache for maximum performance
1764: try {
1765: memberBean = MemberCache.getInstance().getMember(
1766: postBean.getMemberID());
1767: } catch (ObjectNotFoundException e) {
1768: // do nothing, we accept null member because sometime in LDAP or portal, we cannot control delete user in LDAP
1769: }
1770: }
1771: postBean.setMemberBean(memberBean);
1772:
1773: int postAttachCount = postBean.getPostAttachCount();
1774: if ((postAttachCount > 0)
1775: && MVNForumConfig.getEnableAttachment()) {
1776: int postID = postBean.getPostID();
1777: Collection attachBeans = DAOFactory.getAttachmentDAO()
1778: .getAttachments_inPost(postID);
1779: int actualAttachCount = attachBeans.size();
1780:
1781: // now check if the attachCount in talbe Post equals to the actual attachCount in table Attachment
1782: if (postAttachCount != actualAttachCount) {
1783: if (actualAttachCount != DAOFactory
1784: .getAttachmentDAO()
1785: .getNumberOfAttachments_inPost(postID)) {
1786: String localizedMessage = MVNForumResourceBundle
1787: .getString(locale,
1788: "java.lang.AssertionError.serious_error.cannot_process_attachment_count");
1789: throw new AssertionError(localizedMessage);
1790: //throw new AssertionError("AssertionError: Serious error: cannot process Attachment Count in table Attachment");
1791: }
1792: log
1793: .warn("The attachment count in table Post and Attachment are not synchronized. In table Post = "
1794: + postAttachCount
1795: + " and in table Attachment = "
1796: + actualAttachCount
1797: + ". Synchronize to "
1798: + actualAttachCount);
1799: DAOFactory.getPostDAO().updateAttachCount(postID,
1800: actualAttachCount);
1801: }
1802: if (actualAttachCount > 0) {
1803: postBean.setAttachmentBeans(attachBeans);
1804: }
1805: }
1806: }
1807:
1808: //int previousTopic = DAOFactory.getThreadDAO().getPreviousEnableThread(forumID, threadID);// can throw AssertionError
1809: //int nextTopic = DAOFactory.getThreadDAO().getNextEnableThread(forumID, threadID);// can throw AssertionError
1810: int previousTopic = ThreadCache.getInstance()
1811: .getPreviousEnableThread(forumID, threadID);// can throw AssertionError
1812: int nextTopic = ThreadCache.getInstance().getNextEnableThread(
1813: forumID, threadID);// can throw AssertionError
1814:
1815: int pendingPostCount = 0;
1816: if (permission.canModerateThread(forumID)) {
1817: pendingPostCount = DAOFactory.getPostDAO()
1818: .getNumberOfDisablePosts_inThread(threadID);
1819: }
1820:
1821: DAOFactory.getThreadDAO().increaseViewCount(threadID);
1822: PostBean lastpostBean = PostCache.getInstance()
1823: .getLastEnablePost_inThread(threadBean.getThreadID());
1824: request.setAttribute("ThreadBean", threadBean);
1825: request.setAttribute("PostBeans", postBeans);
1826: request.setAttribute("lastpostBean", lastpostBean);
1827: request.setAttribute("NumberOfPosts",
1828: new Integer(numberOfPosts));
1829: request.setAttribute("PreviousTopic",
1830: new Integer(previousTopic));
1831: request.setAttribute("NextTopic", new Integer(nextTopic));
1832: request.setAttribute("PendingPostCount", new Integer(
1833: pendingPostCount));
1834:
1835: String threadLabel = MVNForumResourceBundle.getString(locale,
1836: "mvnforum.common.thread");
1837:
1838: CategoryBuilder treebuilder = new DefaultCategoryBuilder();
1839: CategoryTree categorytree = new CategoryTree(treebuilder);
1840: CategoryTreeListener treelistener = new CategoryTreePath(
1841: request, response, forumID, 0, threadLabel + ": "
1842: + threadBean.getThreadTopic());
1843: categorytree.addCategeoryTreeListener(treelistener);
1844: request.setAttribute("tree", categorytree.build());
1845:
1846: CategoryBuilder builder = new DefaultCategoryBuilder();
1847: CategoryTree tree = new CategoryTree(builder);
1848: CategoryTreeListener listener = categoryService
1849: .getManagementCategorySelector(request, response,
1850: "listthreads", forumID);
1851: tree.addCategeoryTreeListener(listener);
1852: request.setAttribute("Result", tree.build());
1853:
1854: if (MVNForumConfig.getEnableOnlineUsers()) {
1855: OnlineUserUtil.setRequestAttributeOfOnlineActions(request,
1856: Action.PAGE_ID_VIEWTHREAD, new Integer(threadID));
1857: }
1858:
1859: if (MVNForumConfig.getEnableEasyWatching()) {
1860: // check if this thread is being watched
1861: Boolean isWatched = Boolean.FALSE;
1862: if (onlineUser.isMember()) {
1863: isWatched = new Boolean(WatchUtil
1864: .isThreadWatched(onlineUser.getMemberID(),
1865: threadBean, forumBean));
1866: }
1867: request.setAttribute("isWatched", isWatched);
1868: }
1869: }
1870:
1871: public void processSearch(GenericRequest request,
1872: GenericResponse response) throws BadInputException,
1873: IOException, DatabaseException, ObjectNotFoundException,
1874: AuthenticationException {
1875:
1876: OnlineUser onlineUser = onlineUserManager
1877: .getOnlineUser(request);
1878: MVNForumPermission permission = onlineUser.getPermission();
1879:
1880: Locale locale = I18nUtil.getLocaleInRequest(request);
1881:
1882: if (!MVNForumConfig.getEnableSearch()) {
1883: String localizedMessage = MVNForumResourceBundle.getString(
1884: locale,
1885: "java.lang.IllegalStateException.search_disabled");
1886: throw new IllegalStateException(localizedMessage);
1887: }
1888:
1889: MyUtil.saveVNTyperMode(request, response);
1890:
1891: CategoryBuilder builder = new DefaultCategoryBuilder();
1892: CategoryTree tree = new CategoryTree(builder);
1893: CategoryTreeListener listener = categoryService
1894: .getManagementCategorySelector(request, response,
1895: "search");
1896: tree.addCategeoryTreeListener(listener);
1897: request.setAttribute("Result", tree.build());
1898:
1899: // if user does not enter MemberName or attachment, then user must enter "key"
1900: String key = GenericParamUtil.getParameter(request, "key");
1901:
1902: String memberName = GenericParamUtil.getParameter(request,
1903: "member");
1904: StringUtil.checkGoodName(memberName);
1905:
1906: int minAttachmentCount = GenericParamUtil.getParameterInt(
1907: request, "minattach", 0);
1908:
1909: if ((key.length() == 0) && (memberName.length() == 0)
1910: && (minAttachmentCount == 0)) {
1911: return;
1912: }
1913: int forumID = GenericParamUtil.getParameterInt(request,
1914: "forum", 0);//negative means category
1915: int sort = GenericParamUtil.getParameterInt(request, "sort",
1916: PostSearchQuery.SEARCH_SORT_DEFAULT);
1917: int offset = GenericParamUtil.getParameterUnsignedInt(request,
1918: "offset", 0);
1919: int rows = GenericParamUtil.getParameterUnsignedInt(request,
1920: "rows", 20);
1921: if (rows == 0) {
1922: rows = 20;// fix NullPointerException when rows = 0
1923: }
1924:
1925: // offset should be even when divide with rowsToReturn
1926: offset = (offset / rows) * rows;
1927:
1928: PostSearchQuery query = new PostSearchQuery();
1929:
1930: if (key.length() > 0) {
1931: query.setSearchString(key);
1932: int scopeInPost = GenericParamUtil.getParameterInt(request,
1933: "scopeinpost", PostSearchQuery.SEARCH_ONLY_BODY
1934: | PostSearchQuery.SEARCH_ONLY_TITLE);
1935: query.setScopeInPost(scopeInPost);
1936: }
1937:
1938: if (memberName.length() > 0) {
1939: try {
1940: int memberID = MemberCache.getInstance()
1941: .getMemberIDFromMemberName(memberName);
1942: query.setMemberId(memberID);
1943: } catch (ObjectNotFoundException ex) {
1944: String localizedMessage = MVNForumResourceBundle
1945: .getString(
1946: locale,
1947: "mvncore.exception.ObjectNotFoundException.membername_not_exists",
1948: new Object[] { memberName });
1949: throw new ObjectNotFoundException(localizedMessage);
1950: }
1951: }
1952:
1953: if (minAttachmentCount > 0) {
1954: query.setMinAttachmentCount(minAttachmentCount);
1955: }
1956:
1957: int searchDate = GenericParamUtil.getParameterUnsignedInt(
1958: request, "date", PostSearchQuery.SEARCH_ANY_DATE);
1959: int searchBeforeAfter = GenericParamUtil.getParameterInt(
1960: request, "beforeafter", PostSearchQuery.SEARCH_NEWER);
1961:
1962: if ((searchDate != PostSearchQuery.SEARCH_ANY_DATE)
1963: && (searchDate < 365 * 10)) { // 10 years
1964: long deltaTime = DateUtil.DAY * searchDate;
1965:
1966: Timestamp now = DateUtil.getCurrentGMTTimestamp();
1967: Timestamp from = null;
1968: Timestamp to = null;
1969:
1970: long currentTime = now.getTime();
1971:
1972: if (searchBeforeAfter == PostSearchQuery.SEARCH_NEWER) {
1973: from = new Timestamp(currentTime - deltaTime);
1974: } else {// older
1975: to = new Timestamp(currentTime - deltaTime);
1976: }
1977:
1978: query.setFromDate(from);
1979: query.setToDate(to);
1980: }
1981:
1982: if (forumID > 0) {
1983: query.setForumId(forumID);
1984: } else if (forumID < 0) {
1985: // choose to search in a category
1986: query.setForumId(forumID);
1987: } else {
1988: // forumID equals to 0, it mean global searching
1989: // just do nothing, lucene will search all forums (globally)
1990: }
1991:
1992: query.setSort(sort);
1993:
1994: query.searchDocuments(offset, rows, permission);
1995: int hitCount = query.getHitCount();
1996: Collection result = query.getPostResult();
1997:
1998: // Remove posts that current user do not have permission
1999: // NOTE: these below code does not remove the enable posts in
2000: // a disabled thread. This is not usually the case because
2001: // normally we will delete the thread instead of change it
2002: // from Enable to Disabled
2003: for (Iterator iter = result.iterator(); iter.hasNext();) {
2004: PostBean postBean = (PostBean) iter.next();
2005: int currentForumID = postBean.getForumID();
2006: if (ForumCache.getInstance().getBean(currentForumID)
2007: .getForumStatus() == ForumBean.FORUM_STATUS_DISABLED) {
2008: iter.remove();
2009: } else if ((permission.canReadPost(currentForumID) == false)
2010: || (postBean.getPostStatus() == PostBean.POST_STATUS_DISABLED)) {
2011: iter.remove();
2012: } else if (postBean.getParentPostID() == 0) {// first post
2013: // Please note that the first post is always Enable even if
2014: // the thread is Disable. In this case always show result
2015: // if the current user is moderator
2016: if (permission.canModerateThread(currentForumID) == false) {
2017: int threadID = postBean.getThreadID();
2018: ThreadBean threadBean = null;
2019: try {
2020: threadBean = DAOFactory.getThreadDAO()
2021: .getThread(threadID);
2022: } catch (ObjectNotFoundException ex) {
2023: String localizedMessage = MVNForumResourceBundle
2024: .getString(
2025: locale,
2026: "mvncore.exception.ObjectNotFoundException.threadid_not_exists",
2027: new Object[] { new Integer(
2028: threadID) });
2029: throw new ObjectNotFoundException(
2030: localizedMessage);
2031: }
2032: if (threadBean.getThreadStatus() == ThreadBean.THREAD_STATUS_DISABLED) {
2033: iter.remove();
2034: }
2035: }
2036: }
2037: }
2038:
2039: if (offset > hitCount) {
2040: String localizedMessage = MVNForumResourceBundle
2041: .getString(locale,
2042: "mvncore.exception.BadInputException.offset_greater_than_total_rows");
2043: throw new BadInputException(localizedMessage);
2044: //throw new BadInputException("Cannot search with offset > total posts");
2045: }
2046:
2047: // request.setAttribute("key", Encoder.encodeURL(key));
2048: // request.setAttribute("member", memberName);
2049: // request.setAttribute("forum", new Integer(forumID));
2050: // request.setAttribute("offset", new Integer(offset));
2051: // request.setAttribute("attachment", new Boolean(withAttachment));
2052: request.setAttribute("rows", new Integer(rows));
2053: request.setAttribute("TotalPosts", new Integer(hitCount));
2054: request.setAttribute("PostBeans", result);
2055: request.setAttribute("SearchQuery", query);
2056: }
2057:
2058: }
|