001: /**
002: * Copyright (c) 2003-2007, David A. Czarnecki
003: * All rights reserved.
004: *
005: * Redistribution and use in source and binary forms, with or without
006: * modification, are permitted provided that the following conditions are met:
007: *
008: * Redistributions of source code must retain the above copyright notice, this list of conditions and the
009: * following disclaimer.
010: * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
011: * following disclaimer in the documentation and/or other materials provided with the distribution.
012: * Neither the name of "David A. Czarnecki" and "blojsom" nor the names of its contributors may be used to
013: * endorse or promote products derived from this software without specific prior written permission.
014: * Products derived from this software may not be called "blojsom", nor may "blojsom" appear in their name,
015: * without prior written permission of David A. Czarnecki.
016: *
017: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
018: * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
019: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
020: * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
021: * EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
022: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
023: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
025: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
026: * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
027: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
028: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
029: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
030: */package org.blojsom.plugin.comment;
031:
032: import org.apache.commons.logging.Log;
033: import org.apache.commons.logging.LogFactory;
034: import org.apache.commons.mail.Email;
035: import org.apache.commons.mail.EmailException;
036: import org.apache.commons.mail.HtmlEmail;
037: import org.blojsom.blog.Blog;
038: import org.blojsom.blog.Comment;
039: import org.blojsom.blog.Entry;
040: import org.blojsom.blog.User;
041: import org.blojsom.event.Event;
042: import org.blojsom.event.EventBroadcaster;
043: import org.blojsom.event.Listener;
044: import org.blojsom.fetcher.Fetcher;
045: import org.blojsom.fetcher.FetcherException;
046: import org.blojsom.plugin.PluginException;
047: import org.blojsom.plugin.comment.event.CommentAddedEvent;
048: import org.blojsom.plugin.comment.event.CommentResponseSubmissionEvent;
049: import org.blojsom.plugin.common.ResponseConstants;
050: import org.blojsom.plugin.email.EmailConstants;
051: import org.blojsom.plugin.velocity.StandaloneVelocityPlugin;
052: import org.blojsom.util.BlojsomConstants;
053: import org.blojsom.util.BlojsomUtils;
054: import org.blojsom.util.CookieUtils;
055:
056: import javax.mail.Session;
057: import javax.naming.Context;
058: import javax.naming.InitialContext;
059: import javax.naming.NamingException;
060: import javax.servlet.http.Cookie;
061: import javax.servlet.http.HttpServletRequest;
062: import javax.servlet.http.HttpServletResponse;
063: import java.util.*;
064: import java.io.IOException;
065:
066: /**
067: * CommentPlugin
068: *
069: * @author David Czarnecki
070: * @version $Id: CommentPlugin.java,v 1.14 2007/01/21 15:42:47 czarneckid Exp $
071: * @since blojsom 3.0
072: */
073: public class CommentPlugin extends StandaloneVelocityPlugin implements
074: Listener {
075:
076: private Log _logger = LogFactory.getLog(CommentPlugin.class);
077:
078: /**
079: * Template for comment e-mails
080: */
081: public static final String COMMENT_PLUGIN_EMAIL_TEMPLATE_TEXT = "org/blojsom/plugin/comment/comment-plugin-email-template-text.vm";
082: public static final String COMMENT_PLUGIN_EMAIL_TEMPLATE_HTML = "org/blojsom/plugin/comment/comment-plugin-email-template-html.vm";
083:
084: /**
085: * Default prefix for comment e-mail notification
086: */
087: public static final String DEFAULT_COMMENT_PREFIX = "[blojsom] Comment on: ";
088:
089: /**
090: * Initialization parameter for e-mail prefix
091: */
092: public static final String COMMENT_PREFIX_IP = "plugin-comment-email-prefix";
093:
094: /**
095: * Initialization parameter to do plugin autoformatting
096: */
097: public static final String COMMENT_AUTOFORMAT_IP = "plugin-comment-autoformat";
098:
099: /**
100: * Initialization parameter for the duration of the "remember me" cookies
101: */
102: public static final String COMMENT_COOKIE_EXPIRATION_DURATION_IP = "plugin-comment-expiration-duration";
103:
104: /**
105: * Initialization parameter for the throttling of comments from IP addresses
106: */
107: public static final String COMMENT_THROTTLE_MINUTES_IP = "plugin-comment-throttle";
108:
109: /**
110: * Initialization parameter for disabling comments on entries after a certain number of days
111: */
112: public static final String COMMENT_DAYS_EXPIRATION_IP = "plugin-comment-days-expiration";
113:
114: /**
115: * Default throttle value for comments from a particular IP address
116: */
117: private static final int COMMENT_THROTTLE_DEFAULT_MINUTES = 5;
118:
119: /**
120: * Request parameter for the "comment"
121: */
122: public static final String COMMENT_PARAM = "comment";
123:
124: /**
125: * Request parameter for the "author"
126: */
127: public static final String AUTHOR_PARAM = "author";
128:
129: /**
130: * Request parameter for the "authorEmail"
131: */
132: public static final String AUTHOR_EMAIL_PARAM = "authorEmail";
133:
134: /**
135: * Request parameter for the "authorURL"
136: */
137: public static final String AUTHOR_URL_PARAM = "authorURL";
138:
139: /**
140: * Request parameter for the "commentText"
141: */
142: public static final String COMMENT_TEXT_PARAM = "commentText";
143:
144: /**
145: * Request parameter to "remember" the poster
146: */
147: private static final String REMEMBER_ME_PARAM = "remember";
148:
149: /**
150: * Comment "Remember Me" Cookie for the Authors Name
151: */
152: private static final String COOKIE_AUTHOR = "blojsom.cookie.author";
153:
154: /**
155: * Comment "Remember Me" Cookie for the Authors Email
156: */
157: private static final String COOKIE_EMAIL = "blojsom.cookie.authorEmail";
158:
159: /**
160: * Comment "Remember Me" Cookie for the Authors URL
161: */
162: private static final String COOKIE_URL = "blojsom.cookie.authorURL";
163:
164: /**
165: * Comment "Remember Me" Cookie for the "Remember Me" checkbox
166: */
167: private static final String COOKIE_REMEMBER_ME = "blojsom.cookie.rememberme";
168:
169: /**
170: * Expiration age for the cookie (1 week)
171: */
172: private static final int COOKIE_EXPIRATION_AGE = 604800;
173:
174: /**
175: * Form item, comment parent ID
176: */
177: private static final String COMMENT_PARENT_ID = "comment_parent_id";
178:
179: /**
180: * Key under which the indicator this plugin is "live" will be placed
181: * (example: on the request for the JSPDispatcher)
182: */
183: public static final String BLOJSOM_COMMENT_PLUGIN_ENABLED = "BLOJSOM_COMMENT_PLUGIN_ENABLED";
184:
185: /**
186: * Key under which the author from the "remember me" cookie will be placed
187: * (example: on the request for the JSPDispatcher)
188: */
189: public static final String BLOJSOM_COMMENT_PLUGIN_AUTHOR = "BLOJSOM_COMMENT_PLUGIN_AUTHOR";
190:
191: /**
192: * Key under which the author's e-mail from the "remember me" cookie will be placed
193: * (example: on the request for the JSPDispatcher)
194: */
195: public static final String BLOJSOM_COMMENT_PLUGIN_AUTHOR_EMAIL = "BLOJSOM_COMMENT_PLUGIN_AUTHOR_EMAIL";
196:
197: /**
198: * Key under which the author's URL from the "remember me" cookie will be placed
199: * (example: on the request for the JSPDispatcher)
200: */
201: public static final String BLOJSOM_COMMENT_PLUGIN_AUTHOR_URL = "BLOJSOM_COMMENT_PLUGIN_AUTHOR_URL";
202:
203: /**
204: * Key under which the "remember me" checkbox from the "remember me" cookie will be placed
205: * (example: on the request for the JSPDispatcher)
206: */
207: public static final String BLOJSOM_COMMENT_PLUGIN_REMEMBER_ME = "BLOJSOM_COMMENT_PLUGIN_REMEMBER_ME";
208:
209: /**
210: * IP address meta-data
211: */
212: public static final String BLOJSOM_COMMENT_PLUGIN_METADATA_IP = "BLOJSOM_COMMENT_PLUGIN_METADATA_IP";
213:
214: /**
215: * Key under which the blog entry will be placed for merging the comment e-mail
216: */
217: public static final String BLOJSOM_COMMENT_PLUGIN_BLOG_ENTRY = "BLOJSOM_COMMENT_PLUGIN_BLOG_ENTRY";
218:
219: /**
220: * Key under which the blog comment will be placed for merging the comment e-mail
221: */
222: public static final String BLOJSOM_COMMENT_PLUGIN_BLOG_COMMENT = "BLOJSOM_COMMENT_PLUGIN_BLOG_COMMENT";
223:
224: public static final String BLOJSOM_PLUGIN_COMMENT_METADATA = "BLOJSOM_PLUGIN_COMMENT_METADATA";
225: public static final String BLOJSOM_PLUGIN_COMMENT_METADATA_DESTROY = "BLOJSOM_PLUGIN_COMMENT_METADATA_DESTROY";
226:
227: private Map _ipAddressCommentTimes;
228: private String _mailServer;
229: private String _mailServerUsername;
230: private String _mailServerPassword;
231: private Session _session;
232: private Fetcher _fetcher;
233: protected EventBroadcaster _eventBroadcaster;
234:
235: /**
236: * Set the {@link EventBroadcaster} event broadcaster
237: *
238: * @param eventBroadcaster {@link EventBroadcaster}
239: */
240: public void setEventBroadcaster(EventBroadcaster eventBroadcaster) {
241: _eventBroadcaster = eventBroadcaster;
242: }
243:
244: /**
245: * Set the {@link Fetcher}
246: *
247: * @param fetcher {@link Fetcher}
248: */
249: public void setFetcher(Fetcher fetcher) {
250: _fetcher = fetcher;
251: }
252:
253: /**
254: * Initialize this plugin. This method only called when the plugin is instantiated.
255: *
256: * @throws PluginException If there is an error initializing the plugin
257: */
258: public void init() throws PluginException {
259: super .init();
260:
261: _mailServer = _servletConfig
262: .getInitParameter(EmailConstants.SMTPSERVER_IP);
263:
264: if (_mailServer != null) {
265: if (_mailServer.startsWith("java:comp/env")) {
266: try {
267: Context context = new InitialContext();
268: _session = (Session) context.lookup(_mailServer);
269: } catch (NamingException e) {
270: if (_logger.isErrorEnabled()) {
271: _logger.error(e);
272: }
273:
274: throw new PluginException(e);
275: }
276: } else {
277: _mailServerUsername = _servletConfig
278: .getInitParameter(EmailConstants.SMTPSERVER_USERNAME_IP);
279: _mailServerPassword = _servletConfig
280: .getInitParameter(EmailConstants.SMTPSERVER_PASSWORD_IP);
281: }
282: } else {
283: if (_logger.isErrorEnabled()) {
284: _logger
285: .error("Missing SMTP servername servlet initialization parameter: "
286: + EmailConstants.SMTPSERVER_IP);
287: }
288: }
289:
290: _ipAddressCommentTimes = new WeakHashMap();
291: _eventBroadcaster.addListener(this );
292: }
293:
294: /**
295: * Process the blog entries
296: *
297: * @param httpServletRequest Request
298: * @param httpServletResponse Response
299: * @param blog {@link Blog} instance
300: * @param context Context
301: * @param entries Blog entries retrieved for the particular request
302: * @return Modified set of blog entries
303: * @throws PluginException If there is an error processing the blog entries
304: */
305: public Entry[] process(HttpServletRequest httpServletRequest,
306: HttpServletResponse httpServletResponse, Blog blog,
307: Map context, Entry[] entries) throws PluginException {
308: context.put(BLOJSOM_COMMENT_PLUGIN_ENABLED, blog
309: .getBlogCommentsEnabled());
310: if (!blog.getBlogCommentsEnabled().booleanValue()) {
311: if (_logger.isDebugEnabled()) {
312: _logger.debug("Comments not enabled for blog: "
313: + blog.getBlogId());
314: }
315:
316: return entries;
317: }
318:
319: Boolean _blogCommentsEnabled;
320: _blogCommentsEnabled = blog.getBlogCommentsEnabled();
321:
322: int _cookieExpiration;
323: String cookieExpiration = blog
324: .getProperty(COMMENT_COOKIE_EXPIRATION_DURATION_IP);
325: if (BlojsomUtils.checkNullOrBlank(cookieExpiration)) {
326: _cookieExpiration = COOKIE_EXPIRATION_AGE;
327: } else {
328: try {
329: _cookieExpiration = Integer.parseInt(cookieExpiration);
330: } catch (NumberFormatException e) {
331: _cookieExpiration = COOKIE_EXPIRATION_AGE;
332: }
333: }
334:
335: if (entries.length == 0) {
336: return entries;
337: }
338:
339: String author = httpServletRequest.getParameter(AUTHOR_PARAM);
340: String authorEmail = httpServletRequest
341: .getParameter(AUTHOR_EMAIL_PARAM);
342: String authorURL = httpServletRequest
343: .getParameter(AUTHOR_URL_PARAM);
344: String rememberMe = httpServletRequest
345: .getParameter(REMEMBER_ME_PARAM);
346:
347: // Check to see if the person has requested they be "remembered" and if so
348: // extract their information from the appropriate cookies
349: Cookie authorCookie = CookieUtils.getCookie(httpServletRequest,
350: COOKIE_AUTHOR);
351: if ((authorCookie != null)
352: && BlojsomUtils.checkNullOrBlank(author)) {
353: author = authorCookie.getValue();
354: if (_logger.isDebugEnabled()) {
355: _logger.debug("Pulling author from cookie: " + author);
356: }
357:
358: if ("".equals(author)) {
359: author = null;
360: } else {
361: context.put(BLOJSOM_COMMENT_PLUGIN_AUTHOR, author);
362: }
363:
364: Cookie authorEmailCookie = CookieUtils.getCookie(
365: httpServletRequest, COOKIE_EMAIL);
366: if ((authorEmailCookie != null)
367: && BlojsomUtils.checkNullOrBlank(authorEmail)) {
368: authorEmail = authorEmailCookie.getValue();
369: if (_logger.isDebugEnabled()) {
370: _logger.debug("Pulling author email from cookie: "
371: + authorEmail);
372: }
373:
374: if (authorEmail == null) {
375: authorEmail = "";
376: } else {
377: context.put(BLOJSOM_COMMENT_PLUGIN_AUTHOR_EMAIL,
378: authorEmail);
379: }
380: }
381:
382: Cookie authorUrlCookie = CookieUtils.getCookie(
383: httpServletRequest, COOKIE_URL);
384: if ((authorUrlCookie != null)
385: && BlojsomUtils.checkNullOrBlank(authorURL)) {
386: authorURL = authorUrlCookie.getValue();
387: if (_logger.isDebugEnabled()) {
388: _logger.debug("Pulling author URL from cookie: "
389: + authorURL);
390: }
391:
392: if (authorURL == null) {
393: authorURL = "";
394: } else {
395: context.put(BLOJSOM_COMMENT_PLUGIN_AUTHOR_URL,
396: authorURL);
397: }
398: }
399:
400: Cookie rememberMeCookie = CookieUtils.getCookie(
401: httpServletRequest, COOKIE_REMEMBER_ME);
402: if ((rememberMeCookie != null)
403: && ((rememberMe == null) || "".equals(rememberMe))) {
404: rememberMe = rememberMeCookie.getValue();
405: if (rememberMe != null) {
406: context.put(BLOJSOM_COMMENT_PLUGIN_REMEMBER_ME,
407: rememberMe);
408: }
409: }
410: }
411:
412: String remoteIPAddress = httpServletRequest.getRemoteAddr();
413:
414: // Comment handling
415: if ("y".equalsIgnoreCase(httpServletRequest
416: .getParameter(COMMENT_PARAM))
417: && _blogCommentsEnabled.booleanValue()) {
418: String commentText = httpServletRequest
419: .getParameter(COMMENT_TEXT_PARAM);
420: String remember = httpServletRequest
421: .getParameter(REMEMBER_ME_PARAM);
422:
423: if (!BlojsomUtils.checkNullOrBlank(author)
424: && !BlojsomUtils.checkNullOrBlank(commentText)) {
425: // Check for comment throttling
426: String commentThrottleValue = blog
427: .getProperty(COMMENT_THROTTLE_MINUTES_IP);
428: if (!BlojsomUtils
429: .checkNullOrBlank(commentThrottleValue)) {
430: int commentThrottleMinutes;
431:
432: try {
433: commentThrottleMinutes = Integer
434: .parseInt(commentThrottleValue);
435: } catch (NumberFormatException e) {
436: commentThrottleMinutes = COMMENT_THROTTLE_DEFAULT_MINUTES;
437: }
438: if (_logger.isDebugEnabled()) {
439: _logger.debug("Comment throttling enabled at: "
440: + commentThrottleMinutes + " minutes");
441: }
442:
443: if (_ipAddressCommentTimes
444: .containsKey(remoteIPAddress)) {
445: Calendar currentTime = Calendar.getInstance();
446: Calendar timeOfLastComment = (Calendar) _ipAddressCommentTimes
447: .get(remoteIPAddress);
448: long timeDifference = currentTime
449: .getTimeInMillis()
450: - timeOfLastComment.getTimeInMillis();
451:
452: long differenceInMinutes = timeDifference
453: / (60 * 1000);
454: if (differenceInMinutes < commentThrottleMinutes) {
455: if (_logger.isDebugEnabled()) {
456: _logger
457: .debug("Comment throttle enabled. Comment from IP address: "
458: + remoteIPAddress
459: + " in less than "
460: + commentThrottleMinutes
461: + " minutes");
462: }
463:
464: return entries;
465: } else {
466: if (_logger.isDebugEnabled()) {
467: _logger
468: .debug("Comment throttle enabled. Resetting date of last comment to current time");
469: }
470:
471: _ipAddressCommentTimes.put(remoteIPAddress,
472: currentTime);
473: }
474: } else {
475: Calendar calendar = Calendar.getInstance();
476: _ipAddressCommentTimes.put(remoteIPAddress,
477: calendar);
478: }
479: }
480:
481: author = author.trim();
482: author = BlojsomUtils.escapeStringSimple(author);
483: author = BlojsomUtils.stripLineTerminators(author, " ");
484:
485: commentText = commentText.trim();
486:
487: // Check if autoformatting of comment text should be done
488: boolean autoformatComments = Boolean.valueOf(
489: blog.getProperty(COMMENT_AUTOFORMAT_IP))
490: .booleanValue();
491: if (autoformatComments) {
492: commentText = BlojsomUtils.replace(commentText,
493: "\n", "<br />");
494: }
495:
496: if (authorEmail != null) {
497: authorEmail = authorEmail.trim();
498: authorEmail = BlojsomUtils
499: .escapeStringSimple(authorEmail);
500: authorEmail = BlojsomUtils.stripLineTerminators(
501: authorEmail, " ");
502: } else {
503: authorEmail = "";
504: }
505:
506: if (authorURL != null) {
507: authorURL = authorURL.trim();
508: authorURL = BlojsomUtils
509: .escapeStringSimple(authorURL);
510: authorURL = BlojsomUtils.stripLineTerminators(
511: authorURL, " ");
512: } else {
513: authorURL = "";
514: }
515:
516: if (!BlojsomUtils.checkNullOrBlank(authorURL)
517: && !authorURL.toLowerCase().startsWith(
518: "http://")) {
519: authorURL = "http://" + authorURL;
520: }
521:
522: Entry entryForComment = _fetcher.newEntry();
523: try {
524: String blogEntryId = BlojsomUtils.getRequestValue(
525: "entry_id", httpServletRequest);
526: Integer entryId;
527: try {
528: entryId = Integer.valueOf(blogEntryId);
529: } catch (NumberFormatException e) {
530: if (_logger.isErrorEnabled()) {
531: _logger.error(e);
532: }
533:
534: return entries;
535: }
536:
537: entryForComment.setId(entryId);
538:
539: _fetcher.loadEntry(blog, entryForComment);
540: if (_logger.isDebugEnabled()) {
541: _logger.debug("Loaded entry for comment: "
542: + entryId.toString());
543: }
544:
545: if (entryForComment.allowsComments().booleanValue()) {
546: // Check for a comment where the number of days between comment auto-expiration has passed
547: String commentDaysExpiration = blog
548: .getProperty(COMMENT_DAYS_EXPIRATION_IP);
549: if (!BlojsomUtils
550: .checkNullOrBlank(commentDaysExpiration)) {
551: try {
552: int daysExpiration = Integer
553: .parseInt(commentDaysExpiration);
554: int daysBetweenDates = BlojsomUtils
555: .daysBetweenDates(
556: entryForComment
557: .getDate(),
558: new Date());
559: if ((daysExpiration > 0)
560: && (daysBetweenDates >= daysExpiration)) {
561: if (_logger.isDebugEnabled()) {
562: _logger
563: .debug("Comment period for this entry has expired. Expiration period set at "
564: + daysExpiration
565: + " days. Difference in days: "
566: + daysBetweenDates);
567: }
568:
569: return entries;
570: }
571: } catch (NumberFormatException e) {
572: if (_logger.isErrorEnabled()) {
573: _logger
574: .error("Error in parameter "
575: + COMMENT_DAYS_EXPIRATION_IP
576: + ": "
577: + commentDaysExpiration);
578: }
579: }
580: }
581: } else {
582: if (_logger.isDebugEnabled()) {
583: _logger
584: .debug("Comments have been disabled for blog entry: "
585: + entryForComment.getId());
586: }
587:
588: return entries;
589: }
590: } catch (FetcherException e) {
591: if (_logger.isErrorEnabled()) {
592: _logger.error(e);
593: }
594:
595: return entries;
596: }
597:
598: Map commentMetaData = new HashMap();
599:
600: // Check to see if a previous plugin populated meta-data for the comment
601: if (context
602: .containsKey(BLOJSOM_PLUGIN_COMMENT_METADATA)) {
603: Map metaData = (Map) context
604: .get(BLOJSOM_PLUGIN_COMMENT_METADATA);
605:
606: Iterator metaDataKeys = metaData.keySet()
607: .iterator();
608: Object key;
609: Object value;
610: while (metaDataKeys.hasNext()) {
611: key = metaDataKeys.next();
612: value = metaData.get(key);
613: commentMetaData.put(key, value);
614: }
615: }
616:
617: CommentResponseSubmissionEvent commentResponseSubmissionEvent = new CommentResponseSubmissionEvent(
618: this , new Date(), blog, httpServletRequest,
619: httpServletResponse, author, authorEmail,
620: authorURL, commentText, entryForComment,
621: commentMetaData);
622: _eventBroadcaster
623: .processEvent(commentResponseSubmissionEvent);
624: author = commentResponseSubmissionEvent.getSubmitter();
625: authorEmail = commentResponseSubmissionEvent
626: .getSubmitterItem1();
627: authorURL = commentResponseSubmissionEvent
628: .getSubmitterItem2();
629: commentText = commentResponseSubmissionEvent
630: .getContent();
631:
632: // Check to see if the comment should be destroyed (not saved) automatically
633: if (!commentMetaData
634: .containsKey(BLOJSOM_PLUGIN_COMMENT_METADATA_DESTROY)) {
635: Comment comment = addBlogComment(author,
636: authorEmail, authorURL, commentText,
637: _blogCommentsEnabled.booleanValue(),
638: commentMetaData, blog, entries[0],
639: httpServletRequest);
640:
641: // For persisting the Last-Modified time
642: context.put(BlojsomConstants.BLOJSOM_LAST_MODIFIED,
643: new Long(new Date().getTime()));
644:
645: if (comment != null) {
646: try {
647: _fetcher.loadEntry(blog, entries[0]);
648: _fetcher.loadEntry(blog, entryForComment);
649: _eventBroadcaster
650: .broadcastEvent(new CommentAddedEvent(
651: this , new Date(), comment,
652: blog));
653: } catch (FetcherException e) {
654: if (_logger.isErrorEnabled()) {
655: _logger.error(e);
656: }
657: }
658: }
659: } else {
660: if (_logger.isDebugEnabled()) {
661: _logger
662: .debug("Comment meta-data contained destroy key. Comment was not saved");
663: }
664: }
665:
666: // If we're asked to remember the person, then add the appropriate cookies
667: if ((remember != null) && (!"".equals(remember))) {
668: CookieUtils.addCookie(httpServletResponse,
669: _cookieExpiration, COOKIE_AUTHOR, author);
670: context.put(BLOJSOM_COMMENT_PLUGIN_AUTHOR, author);
671: CookieUtils.addCookie(httpServletResponse,
672: _cookieExpiration, COOKIE_EMAIL,
673: authorEmail);
674: context.put(BLOJSOM_COMMENT_PLUGIN_AUTHOR_EMAIL,
675: authorEmail);
676: CookieUtils.addCookie(httpServletResponse,
677: _cookieExpiration, COOKIE_URL, authorURL);
678: context.put(BLOJSOM_COMMENT_PLUGIN_AUTHOR_URL,
679: authorURL);
680: CookieUtils.addCookie(httpServletResponse,
681: _cookieExpiration, COOKIE_REMEMBER_ME,
682: "true");
683: context.put(BLOJSOM_COMMENT_PLUGIN_REMEMBER_ME,
684: "true");
685: }
686: }
687:
688: String redirectTo = BlojsomUtils.getRequestValue(
689: BlojsomConstants.REDIRECT_TO_PARAM,
690: httpServletRequest);
691: if (!BlojsomUtils.checkNullOrBlank(redirectTo)) {
692: try {
693: httpServletResponse.sendRedirect(BlojsomUtils
694: .urlEncodeForLink(redirectTo));
695: httpServletRequest.setAttribute(
696: BlojsomConstants.IS_IN_REDIRECT,
697: Boolean.TRUE);
698: } catch (IOException e) {
699: }
700: }
701: }
702:
703: return entries;
704: }
705:
706: /**
707: * Add a comment to a particular blog entry
708: *
709: * @param author Comment author
710: * @param authorEmail Comment author e-mail
711: * @param authorURL Comment author URL
712: * @param userComment Comment
713: * @param blogCommentsEnabled If comments are enabled or not
714: * @param commentMetaData Metadata for the comment
715: * @param blog {@link Blog}
716: * @param entry {@link Entry}
717: * @param httpServletRequest {@link HttpServletRequest}
718: * @return BlogComment Entry
719: */
720: private Comment addBlogComment(String author, String authorEmail,
721: String authorURL, String userComment,
722: boolean blogCommentsEnabled, Map commentMetaData,
723: Blog blog, Entry entry,
724: HttpServletRequest httpServletRequest) {
725: Comment comment = null;
726:
727: if (blogCommentsEnabled) {
728: try {
729: comment = _fetcher.newComment();
730: comment.setBlogEntryId(entry.getId());
731: comment.setEntry(entry);
732: comment.setAuthor(author);
733: comment.setAuthorEmail(authorEmail);
734: comment.setAuthorURL(authorURL);
735: comment.setComment(userComment);
736: comment.setCommentDate(new Date());
737: comment.setBlogId(blog.getId());
738: comment.setIp(httpServletRequest.getRemoteAddr());
739: if (commentMetaData
740: .containsKey(CommentModerationPlugin.BLOJSOM_COMMENT_MODERATION_PLUGIN_APPROVED)
741: && "true"
742: .equals(commentMetaData
743: .get(CommentModerationPlugin.BLOJSOM_COMMENT_MODERATION_PLUGIN_APPROVED))) {
744: comment
745: .setStatus(ResponseConstants.APPROVED_STATUS);
746: } else {
747: if ("true"
748: .equals(blog
749: .getProperty(CommentModerationPlugin.COMMENT_MODERATION_ENABLED))) {
750: comment.setStatus(ResponseConstants.NEW_STATUS);
751: } else {
752: comment
753: .setStatus(ResponseConstants.APPROVED_STATUS);
754: }
755: }
756: comment.setMetaData(commentMetaData);
757:
758: String commentParentID = BlojsomUtils.getRequestValue(
759: COMMENT_PARENT_ID, httpServletRequest);
760: if (!BlojsomUtils.checkNullOrBlank(commentParentID)) {
761: try {
762: comment.setParentId(Integer
763: .valueOf(commentParentID));
764: } catch (NumberFormatException e) {
765: }
766: }
767:
768: _fetcher.saveComment(blog, comment);
769: } catch (FetcherException e) {
770: if (_logger.isErrorEnabled()) {
771: _logger.error(e);
772: }
773:
774: comment = null;
775: }
776: }
777:
778: return comment;
779: }
780:
781: /**
782: * Perform any cleanup for the plugin. Called after {@link #process}.
783: *
784: * @throws PluginException If there is an error performing cleanup for this plugin
785: */
786: public void cleanup() throws PluginException {
787: }
788:
789: /**
790: * Called when BlojsomServlet is taken out of service
791: *
792: * @throws PluginException If there is an error in finalizing this plugin
793: */
794: public void destroy() throws PluginException {
795: }
796:
797: /**
798: * Setup the comment e-mail
799: *
800: * @param blog {@link Blog} information
801: * @param entry {@link Entry}
802: * @param email Email message
803: * @throws EmailException If there is an error preparing the e-mail message
804: */
805: protected void setupEmail(Blog blog, Entry entry, Email email)
806: throws EmailException {
807: email.setCharset(BlojsomConstants.UTF8);
808:
809: // If we have a mail session for the environment, use that
810: if (_session != null) {
811: email.setMailSession(_session);
812: } else {
813: // Otherwise, if there is a username and password for the mail server, use that
814: if (!BlojsomUtils.checkNullOrBlank(_mailServerUsername)
815: && !BlojsomUtils
816: .checkNullOrBlank(_mailServerPassword)) {
817: email.setHostName(_mailServer);
818: email.setAuthentication(_mailServerUsername,
819: _mailServerPassword);
820: } else {
821: email.setHostName(_mailServer);
822: }
823: }
824:
825: email.setFrom(blog.getBlogOwnerEmail(), "Blojsom Comment");
826:
827: String author = entry.getAuthor();
828: if (BlojsomUtils.checkNullOrBlank(author)) {
829: author = blog.getBlogOwner();
830: }
831:
832: String authorEmail = blog.getBlogOwnerEmail();
833:
834: if (author != null) {
835: try {
836: User user = _fetcher.loadUser(blog, author);
837:
838: if (user == null) {
839: authorEmail = blog.getBlogOwnerEmail();
840: } else {
841: authorEmail = user.getUserEmail();
842: if (BlojsomUtils.checkNullOrBlank(authorEmail)) {
843: authorEmail = blog.getBlogOwnerEmail();
844: }
845: }
846: } catch (FetcherException e) {
847: }
848: }
849:
850: email.addTo(authorEmail, author);
851: email.setSentDate(new Date());
852: }
853:
854: /**
855: * Handle an event broadcast from another component
856: *
857: * @param event {@link org.blojsom.event.Event} to be handled
858: */
859: public void handleEvent(Event event) {
860: if (event instanceof CommentAddedEvent) {
861: HtmlEmail email = new HtmlEmail();
862: CommentAddedEvent commentAddedEvent = (CommentAddedEvent) event;
863:
864: if (commentAddedEvent.getBlog().getBlogEmailEnabled()
865: .booleanValue()
866: && _mailServer != null) {
867: try {
868: setupEmail(commentAddedEvent.getBlog(),
869: commentAddedEvent.getEntry(), email);
870:
871: Map emailTemplateContext = new HashMap();
872: emailTemplateContext.put(
873: BlojsomConstants.BLOJSOM_BLOG,
874: commentAddedEvent.getBlog());
875: emailTemplateContext.put(
876: BLOJSOM_COMMENT_PLUGIN_BLOG_COMMENT,
877: commentAddedEvent.getComment());
878: emailTemplateContext.put(
879: BLOJSOM_COMMENT_PLUGIN_BLOG_ENTRY,
880: commentAddedEvent.getEntry());
881:
882: String htmlText = mergeTemplate(
883: COMMENT_PLUGIN_EMAIL_TEMPLATE_HTML,
884: commentAddedEvent.getBlog(),
885: emailTemplateContext);
886: String plainText = mergeTemplate(
887: COMMENT_PLUGIN_EMAIL_TEMPLATE_TEXT,
888: commentAddedEvent.getBlog(),
889: emailTemplateContext);
890:
891: email.setHtmlMsg(htmlText);
892: email.setTextMsg(plainText);
893:
894: String emailPrefix = (String) commentAddedEvent
895: .getBlog().getProperties().get(
896: COMMENT_PREFIX_IP);
897: if (BlojsomUtils.checkNullOrBlank(emailPrefix)) {
898: emailPrefix = DEFAULT_COMMENT_PREFIX;
899: }
900:
901: email = (HtmlEmail) email.setSubject(emailPrefix
902: + commentAddedEvent.getEntry().getTitle());
903:
904: email.send();
905: } catch (EmailException e) {
906: if (_logger.isErrorEnabled()) {
907: _logger.error(e);
908: }
909: }
910: } else {
911: if (_logger.isErrorEnabled()) {
912: _logger
913: .error("Missing SMTP servername servlet initialization parameter: "
914: + EmailConstants.SMTPSERVER_IP);
915: }
916: }
917: }
918: }
919:
920: /**
921: * Process an event from another component
922: *
923: * @param event {@link org.blojsom.event.Event} to be handled
924: */
925: public void processEvent(Event event) {
926: }
927: }
|