001: /*
002: * $Header: /cvsroot/mvnforum/mvnforum/src/com/mvnforum/user/WatchWebHandler.java,v 1.72 2008/01/18 03:37:59 tbtrung Exp $
003: * $Author: tbtrung $
004: * $Revision: 1.72 $
005: * $Date: 2008/01/18 03:37:59 $
006: *
007: * ====================================================================
008: *
009: * Copyright (C) 2002-2007 by MyVietnam.net
010: *
011: * All copyright notices regarding mvnForum MUST remain
012: * intact in the scripts and in the outputted HTML.
013: * The "powered by" text/logo with a link back to
014: * http://www.mvnForum.com and http://www.MyVietnam.net in
015: * the footer of the pages MUST remain visible when the pages
016: * are viewed on the internet or intranet.
017: *
018: * This program is free software; you can redistribute it and/or modify
019: * it under the terms of the GNU General Public License as published by
020: * the Free Software Foundation; either version 2 of the License, or
021: * any later version.
022: *
023: * This program is distributed in the hope that it will be useful,
024: * but WITHOUT ANY WARRANTY; without even the implied warranty of
025: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
026: * GNU General Public License for more details.
027: *
028: * You should have received a copy of the GNU General Public License
029: * along with this program; if not, write to the Free Software
030: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
031: *
032: * Support can be obtained from support forums at:
033: * http://www.mvnForum.com/mvnforum/index
034: *
035: * Correspondence and Marketing Questions can be sent to:
036: * info at MyVietnam net
037: *
038: * @author: Minh Nguyen
039: * @author: Mai Nguyen
040: */
041: package com.mvnforum.user;
042:
043: import java.io.IOException;
044: import java.io.UnsupportedEncodingException;
045: import java.sql.Timestamp;
046: import java.util.*;
047:
048: import javax.mail.MessagingException;
049:
050: import net.myvietnam.mvncore.exception.*;
051: import net.myvietnam.mvncore.security.SecurityUtil;
052: import net.myvietnam.mvncore.util.*;
053: import net.myvietnam.mvncore.web.GenericRequest;
054: import net.myvietnam.mvncore.web.GenericResponse;
055:
056: import com.mvnforum.MVNForumConfig;
057: import com.mvnforum.MVNForumResourceBundle;
058: import com.mvnforum.auth.*;
059: import com.mvnforum.categorytree.*;
060: import com.mvnforum.db.*;
061: import com.mvnforum.service.CategoryService;
062: import com.mvnforum.service.MvnForumServiceFactory;
063:
064: import freemarker.template.TemplateException;
065:
066: import org.apache.commons.logging.Log;
067: import org.apache.commons.logging.LogFactory;
068:
069: public class WatchWebHandler {
070:
071: private static Log log = LogFactory.getLog(WatchWebHandler.class);
072:
073: private static CategoryService categoryService = MvnForumServiceFactory
074: .getMvnForumService().getCategoryService();
075:
076: private OnlineUserManager onlineUserManager = OnlineUserManager
077: .getInstance();
078:
079: //private DateFormat dateFormat = SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.DEFAULT, SimpleDateFormat.DEFAULT);
080:
081: public WatchWebHandler() {
082: }
083:
084: public void sendMail() throws DatabaseException,
085: MessagingException, BadInputException,
086: ObjectNotFoundException, TemplateException, IOException {
087:
088: if (MVNForumConfig.getEnableWatch() == false) {
089: log
090: .warn("Ingore Watch sendMail because this feature is disabled by administrator.");
091: return;
092: }
093: String forumBase = ParamUtil.getServerPath()
094: + ParamUtil.getContextPath()
095: + UserModuleConfig.getUrlPattern();
096: //log.debug("Forum base = " + forumBase);
097:
098: //get the list of watch for each member, the watch is choosen based on oldest last sent time
099: Collection beans = DAOFactory.getWatchDAO().getMemberBeans();
100: //log.debug("Watch: total member = " + beans.size());
101:
102: for (Iterator iterator = beans.iterator(); iterator.hasNext();) {
103:
104: if (TimerUtil.getInstance().isTimerCanceled()) {
105: break;
106: }
107:
108: WatchBean watchBean = (WatchBean) iterator.next();
109: int memberID = watchBean.getMemberID();
110:
111: // check if member is enable here
112: if (DAOFactory.getMemberDAO().getActivateCode(memberID)
113: .equals(MemberBean.MEMBER_ACTIVATECODE_ACTIVATED) == false) {
114: // Not activated, then we continue with the next user
115: continue;
116: }
117:
118: // Check the frequency of the update
119: Timestamp lastSent = watchBean.getWatchLastSentDate();
120: Timestamp now = DateUtil.getCurrentGMTTimestamp();
121:
122: // We will now support a single watch standard, but should be
123: // bitmasked in future to support multiple watch schedule for the same
124: // thread or forum
125: long minimumWaitTime = 0;
126: int watchOption = watchBean.getWatchOption();
127: if (watchOption == WatchBean.WATCH_OPTION_DEFAULT) {
128: watchOption = MVNForumConfig.getDefaultWatchOption();
129: }
130:
131: switch (watchOption) {
132: case WatchBean.WATCH_OPTION_LIVE:
133: minimumWaitTime = 0;
134: break;
135: case WatchBean.WATCH_OPTION_HOURLY:
136: minimumWaitTime = DateUtil.HOUR;
137: break;
138: case WatchBean.WATCH_OPTION_DAILY:
139: minimumWaitTime = DateUtil.DAY;
140: break;
141: case WatchBean.WATCH_OPTION_WEEKLY:
142: minimumWaitTime = DateUtil.WEEK;
143: break;
144: default:// currently only default is processed (WatchOption = 0)
145: // note that watch option might have any value so we have to have default fallback
146: minimumWaitTime = DateUtil.DAY;
147: break;
148: }
149: if ((now.getTime() - lastSent.getTime()) > minimumWaitTime) {
150: sendMail_forMember(memberID, forumBase, lastSent);
151: }
152: }//for
153: }
154:
155: void sendMail_forMember(int memberID, String forumBase,
156: Timestamp lastSent) throws DatabaseException,
157: MessagingException, BadInputException,
158: ObjectNotFoundException, TemplateException, IOException {
159:
160: MemberBean receiver = null;
161: try {
162: receiver = DAOFactory.getMemberDAO().getMember(memberID);
163: } catch (ObjectNotFoundException e) {
164: String message = "Cannot get member with id = " + memberID;
165: log.error(message, e);
166:
167: MailMessageStruct mailMessageStruct = new MailMessageStruct();
168: mailMessageStruct.setFrom(MVNForumConfig
169: .getWebMasterEmail());
170: mailMessageStruct.setTo(MVNForumConfig.getWebMasterEmail());
171: mailMessageStruct
172: .setSubject("Warning of LDAP deleted members");
173: mailMessageStruct.setMessage(message);
174: MailUtil.sendMail(mailMessageStruct);
175: return;// do nothing just return if member does not exist
176: }
177:
178: if ((receiver.getMemberEmail() == null)
179: || (receiver.getMemberEmail().length() == 0)) {
180: //AssertionUtil.doAssert(false, "Cannot get email from member with id = " + receiver.getMemberID() + " and login name = " + receiver.getMemberName() + " in WatchWebHandler.sendMail_forMember()");
181: String message = "Cannot get email from member with id = "
182: + receiver.getMemberID() + " and login name = "
183: + receiver.getMemberName()
184: + " in WatchWebHandler.sendMail_forMember()";
185: log.warn(message);
186:
187: MailMessageStruct mailMessageStruct = new MailMessageStruct();
188: mailMessageStruct.setFrom(MVNForumConfig
189: .getWebMasterEmail());
190: mailMessageStruct.setTo(MVNForumConfig.getWebMasterEmail());
191: mailMessageStruct
192: .setSubject("Warning of LDAP members missing email");
193: mailMessageStruct.setMessage(message);
194: MailUtil.sendMail(mailMessageStruct);
195: return;
196: }
197:
198: MVNForumPermission permission = null;
199: try {
200: permission = MVNForumPermissionFactory
201: .getAuthenticatedPermission(receiver);
202: } catch (AssertionError e) {
203: log.error("Cannot create watch mail for Guest with id = "
204: + memberID, e);
205: return;// do nothing, just return if member is guest.
206: }
207:
208: if (permission.isActivated() == false) {
209: // if member is not activated, then we ignore this member
210: return;
211: }
212:
213: Collection watchBeans = DAOFactory.getWatchDAO()
214: .getWatches_forMember(memberID);
215: //log.debug("Watch size = " + watchBeans.size() + " for memberid = " + memberID);
216: Timestamp now = DateUtil.getCurrentGMTTimestamp();
217:
218: //then optimize the watchBeans
219: watchBeans = WatchUtil.optimize(watchBeans);
220:
221: WatchMail watchMailDigest = new WatchMail(receiver, permission,
222: forumBase, lastSent, now);
223: SingleWatchMail watchMailSingle = new SingleWatchMail(receiver,
224: permission, forumBase, lastSent, now);
225:
226: for (Iterator watchIterator = watchBeans.iterator(); watchIterator
227: .hasNext();) {
228: WatchBean watchBean = (WatchBean) watchIterator.next();
229: boolean isDigest = false;
230: /*if (watchBean.getWatchType() == WatchBean.WATCH_TYPE_DEFAULT) {
231: //@todo : get from config file
232: isDigest = true;
233: }*/
234:
235: switch (watchBean.getWatchType()) {
236: case WatchBean.WATCH_TYPE_DIGEST:
237: isDigest = true;
238: break;
239: case WatchBean.WATCH_TYPE_NONDIGEST:
240: isDigest = false;
241: break;
242: case WatchBean.WATCH_TYPE_DEFAULT:
243: switch (MVNForumConfig.getDefaultWatchType()) {
244: case WatchBean.WATCH_TYPE_DIGEST:
245: isDigest = true;
246: break;
247: case WatchBean.WATCH_TYPE_NONDIGEST:
248: isDigest = false;
249: break;
250: default:
251: isDigest = true;
252: break;
253: }
254: break;
255: default:// currently only default is processed (WatchType = 0)
256: // note that watch type might have any value so we have to have default fallback
257: isDigest = true;
258: break;
259: }
260:
261: if (isDigest) {
262: watchMailDigest.appendWatch(watchBean);
263: } else {
264: watchMailSingle.appendWatch(watchBean);
265: }
266: }
267:
268: if ((watchMailDigest.haveAtLeastOneNewThread() == false)
269: && (watchMailSingle.haveAtLeastOneNewThread() == false)) {
270: log.debug("No new thread in watch mail for MemberID = "
271: + memberID);
272: return;
273: }
274:
275: // Send the digest watch email
276: if (watchMailDigest.haveAtLeastOneNewThread()) {
277: log.debug("About to send digest watch mail to member = "
278: + memberID + " with email = "
279: + receiver.getMemberEmail());
280: // send mail now
281: String from = MVNForumConfig.getWatchEmail();
282: String to = receiver.getMemberEmail();
283: String subject = watchMailDigest.getWatchMailSubject();
284: String content = watchMailDigest.getWatchMailBody();
285: //log.debug("Send message from webmaster to ~ " + to + "~");
286: try {
287: MailMessageStruct mailMessageStruct = new MailMessageStruct();
288: mailMessageStruct.setFrom(from);
289: mailMessageStruct.setTo(to);
290: mailMessageStruct.setSubject(subject);
291: mailMessageStruct.setMessage(content);
292: mailMessageStruct.setSendAsHtml(MVNForumConfig
293: .getSendWatchMailAsHTML());
294:
295: MailUtil.sendMail(mailMessageStruct);
296: } catch (UnsupportedEncodingException e) {
297: log.error("Cannot support encoding", e);
298: }
299: }
300:
301: // Send the single watch email
302: if (watchMailSingle.haveAtLeastOneNewThread()) {
303: log.debug("About to send single watch mail to member = "
304: + memberID + " with email = "
305: + receiver.getMemberEmail());
306: Collection mailMessageStructs = watchMailSingle
307: .getMailMessageStructs(MVNForumConfig
308: .getWatchEmail(), receiver.getMemberEmail());
309: MailUtil.sendMail(mailMessageStructs);
310: }
311:
312: // finally, update the lastsent
313: DAOFactory.getWatchDAO().updateLastSentDate_forMember(memberID,
314: now);
315: }
316:
317: public void prepareList(GenericRequest request)
318: throws DatabaseException, AuthenticationException,
319: ObjectNotFoundException {
320:
321: OnlineUser onlineUser = onlineUserManager
322: .getOnlineUser(request);
323: MVNForumPermission permission = onlineUser.getPermission();
324: permission.ensureIsAuthenticated();
325:
326: int memberID = onlineUser.getMemberID();
327: Locale locale = I18nUtil.getLocaleInRequest(request);
328:
329: Collection watchBeans = DAOFactory.getWatchDAO()
330: .getWatches_forMember(memberID);
331:
332: Collection globalWatchBeans = WatchUtil
333: .getGlobalWatchs(watchBeans);
334: Collection categoryWatchBeans = WatchUtil
335: .getCategoryWatchs(watchBeans);
336: Collection forumWatchBeans = WatchUtil
337: .getForumWatchs(watchBeans);
338: Collection threadWatchBeans = WatchUtil
339: .getThreadWatchs(watchBeans);
340:
341: // @todo Improve the performance of the below code
342: for (Iterator iter = threadWatchBeans.iterator(); iter
343: .hasNext();) {
344: WatchBean threadWatchBean = (WatchBean) iter.next();
345: int threadID = threadWatchBean.getThreadID();
346:
347: ThreadBean threadBean = null;
348: try {
349: threadBean = DAOFactory.getThreadDAO().getThread(
350: threadID);
351: } catch (ObjectNotFoundException e) {
352: String localizedMessage = MVNForumResourceBundle
353: .getString(
354: locale,
355: "mvncore.exception.ObjectNotFoundException.threadid_not_exists",
356: new Object[] { new Integer(threadID) });
357: //throw new ObjectNotFoundException(localizedMessage);
358: iter.remove();
359: DAOFactory.getWatchDAO().delete_inThread(threadID);
360: log.error(localizedMessage, e);
361: }
362: threadWatchBean.setThreadBean(threadBean);
363: }
364:
365: request.setAttribute("WatchBeans", watchBeans);
366: request.setAttribute("GlobalWatchBeans", globalWatchBeans);
367: request.setAttribute("CategoryWatchBeans", categoryWatchBeans);
368: request.setAttribute("ForumWatchBeans", forumWatchBeans);
369: request.setAttribute("ThreadWatchBeans", threadWatchBeans);
370: }
371:
372: public void prepareAdd(GenericRequest request,
373: GenericResponse response) throws DatabaseException,
374: AuthenticationException {
375:
376: Locale locale = I18nUtil.getLocaleInRequest(request);
377:
378: if (MVNForumConfig.getEnableWatch() == false) {
379: String localizedMessage = MVNForumResourceBundle
380: .getString(locale,
381: "java.lang.IllegalStateException.cannot_add_watch.watch_is_disabled");
382: throw new IllegalStateException(localizedMessage);
383: //throw new IllegalStateException("Cannot add Watch because Watch feature is disabled by administrator.");
384: }
385:
386: OnlineUser onlineUser = onlineUserManager
387: .getOnlineUser(request);
388: MVNForumPermission permission = onlineUser.getPermission();
389: permission.ensureIsAuthenticated();
390: if (MVNForumConfig.getRequireActivation() == true) {
391: permission.ensureIsActivated();
392: }
393:
394: CategoryBuilder builder = new DefaultCategoryBuilder();
395: CategoryTree tree = new CategoryTree(builder);
396: CategoryTreeListener listener = categoryService
397: .getManagementCategorySelector(request, response, true,
398: "category");
399: tree.addCategeoryTreeListener(listener);
400: request.setAttribute("Result", tree.build());
401: }
402:
403: public void processAdd(GenericRequest request)
404: throws BadInputException, CreateException,
405: DatabaseException, ObjectNotFoundException,
406: ForeignKeyNotFoundException, AuthenticationException {
407:
408: // This method must not check post method because it can be called from viewthread
409: //SecurityUtil.checkHttpPostMethod(request);
410:
411: Locale locale = I18nUtil.getLocaleInRequest(request);
412:
413: if (MVNForumConfig.getEnableWatch() == false) {
414: String localizedMessage = MVNForumResourceBundle
415: .getString(locale,
416: "java.lang.IllegalStateException.cannot_add_watch.watch_is_disabled");
417: throw new IllegalStateException(localizedMessage);
418: //throw new IllegalStateException("Cannot add Watch because Watch feature is disabled by administrator.");
419: }
420:
421: OnlineUser onlineUser = onlineUserManager
422: .getOnlineUser(request);
423: MVNForumPermission permission = onlineUser.getPermission();
424: permission.ensureIsAuthenticated();
425: if (MVNForumConfig.getRequireActivation() == true) {
426: permission.ensureIsActivated();
427: }
428:
429: Timestamp now = DateUtil.getCurrentGMTTimestamp();
430:
431: int memberID = onlineUser.getMemberID();
432: int categoryID = 0;
433: int forumID = 0;
434: int threadID = 0;
435: int watchType = GenericParamUtil.getParameterInt(request,
436: "WatchType");
437: int watchOption = WatchBean.WATCH_OPTION_DEFAULT;//GenericParamUtil.getParameterInt(request, "WatchOption");
438: int watchStatus = 0;//GenericParamUtil.getParameterInt(request, "WatchStatus");
439: Timestamp watchCreationDate = now;
440: Timestamp watchLastSentDate = now;
441: Timestamp watchEndDate = now;// @todo: check it !!!
442:
443: int watchSelector = GenericParamUtil.getParameterInt(request,
444: "WatchSelector");
445: switch (watchSelector) {
446: case WatchBean.SELECT_GLOBAL_WATCH:
447: break;
448: case WatchBean.SELECT_CATEGORY_WATCH:
449: categoryID = GenericParamUtil.getParameterInt(request,
450: "category");
451: break;
452: case WatchBean.SELECT_FORUM_WATCH:
453: forumID = GenericParamUtil
454: .getParameterInt(request, "forum");
455: ForumCache.getInstance().getBean(forumID)
456: .ensureNotDisabledForum();
457: break;
458: case WatchBean.SELECT_THREAD_WATCH:
459: threadID = GenericParamUtil.getParameterInt(request,
460: "thread");
461: DAOFactory.getThreadDAO().findByPrimaryKey(threadID);
462: break;
463: default:
464: // please do not localize this
465: AssertionUtil.doAssert(false,
466: "Cannot process WatchSelector = " + watchSelector);
467: }
468:
469: try {
470: DAOFactory.getWatchDAO().create(memberID, categoryID,
471: forumID, threadID, watchType, watchOption,
472: watchStatus, watchCreationDate, watchLastSentDate,
473: watchEndDate);
474: } catch (DuplicateKeyException ex) {
475: // User try to create a duplicate watch, just ignore
476: }
477: }
478:
479: public void processDelete(GenericRequest request)
480: throws BadInputException, DatabaseException,
481: AuthenticationException, ObjectNotFoundException {
482:
483: OnlineUser onlineUser = onlineUserManager
484: .getOnlineUser(request);
485: MVNForumPermission permission = onlineUser.getPermission();
486: permission.ensureIsAuthenticated();
487:
488: int memberID = onlineUser.getMemberID();
489:
490: Locale locale = I18nUtil.getLocaleInRequest(request);
491:
492: // primary key column(s)
493: int watchID = GenericParamUtil
494: .getParameterInt(request, "watch");
495:
496: WatchBean watchBean = DAOFactory.getWatchDAO()
497: .getWatch(watchID);
498:
499: // check if the watch is owned by the current member
500: if (watchBean.getMemberID() != memberID) {
501: String localizedMessage = MVNForumResourceBundle
502: .getString(
503: locale,
504: "mvncore.exception.BadInputException.cannot_delete.watch_is_not_owned_by_current_member");
505: throw new BadInputException(localizedMessage);
506: //throw new BadInputException("Cannot delete watch: this watch is not owned by the current member.");
507: }
508:
509: //now delete the watch
510: DAOFactory.getWatchDAO().delete(watchID);
511: }
512:
513: public void prepareEdit(GenericRequest request)
514: throws BadInputException, ObjectNotFoundException,
515: DatabaseException, AuthenticationException {
516:
517: OnlineUser onlineUser = onlineUserManager
518: .getOnlineUser(request);
519: MVNForumPermission permission = onlineUser.getPermission();
520: permission.ensureIsAuthenticated();
521:
522: Locale locale = I18nUtil.getLocaleInRequest(request);
523: int memberID = onlineUser.getMemberID();
524:
525: int watchID = GenericParamUtil
526: .getParameterInt(request, "watch");
527:
528: WatchBean watchBean = DAOFactory.getWatchDAO()
529: .getWatch(watchID);
530:
531: if (watchBean.getMemberID() != memberID) {
532: String localizedMessage = MVNForumResourceBundle
533: .getString(
534: locale,
535: "mvncore.exception.BadInputException.cannot_edit.watch_is_not_owned_by_current_member");
536: throw new BadInputException(localizedMessage);
537: //throw new BadInputException("Cannot edit watch: this watch is not owned by the current member.");
538: }
539:
540: request.setAttribute("WatchBean", watchBean);
541: }
542:
543: public void processEdit(GenericRequest request)
544: throws AuthenticationException, DatabaseException,
545: BadInputException, ObjectNotFoundException {
546:
547: SecurityUtil.checkHttpPostMethod(request);
548:
549: OnlineUser onlineUser = onlineUserManager
550: .getOnlineUser(request);
551: MVNForumPermission permission = onlineUser.getPermission();
552: permission.ensureIsAuthenticated();
553:
554: int memberID = onlineUser.getMemberID();
555:
556: Locale locale = I18nUtil.getLocaleInRequest(request);
557:
558: // primary key column(s)
559: int watchID = GenericParamUtil.getParameterInt(request,
560: "WatchID");
561: int watchType = GenericParamUtil.getParameterInt(request,
562: "WatchType");
563:
564: WatchBean watchBean = DAOFactory.getWatchDAO()
565: .getWatch(watchID);
566:
567: if (watchBean.getMemberID() != memberID) {
568: String localizedMessage = MVNForumResourceBundle
569: .getString(
570: locale,
571: "mvncore.exception.BadInputException.cannot_edit.watch_is_not_owned_by_current_member");
572: throw new BadInputException(localizedMessage);
573: //throw new BadInputException("Cannot edit watch: this watch is not owned by the current member.");
574: }
575:
576: DAOFactory.getWatchDAO().updateWatchType(watchID, watchType);
577: }
578: }
|