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.trackback;
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.Entry;
039: import org.blojsom.blog.Trackback;
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.common.ResponseConstants;
048: import org.blojsom.plugin.email.EmailConstants;
049: import org.blojsom.plugin.trackback.event.TrackbackAddedEvent;
050: import org.blojsom.plugin.trackback.event.TrackbackResponseSubmissionEvent;
051: import org.blojsom.plugin.velocity.StandaloneVelocityPlugin;
052: import org.blojsom.util.BlojsomConstants;
053: import org.blojsom.util.BlojsomMetaDataConstants;
054: import org.blojsom.util.BlojsomUtils;
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.HttpServletRequest;
061: import javax.servlet.http.HttpServletResponse;
062: import java.util.*;
063:
064: /**
065: * TrackbackPlugin
066: *
067: * @author David Czarnecki
068: * @since blojsom 3.0
069: * @version $Id: TrackbackPlugin.java,v 1.9 2007/01/17 02:35:14 czarneckid Exp $
070: */
071: public class TrackbackPlugin extends StandaloneVelocityPlugin implements
072: BlojsomMetaDataConstants, Listener, EmailConstants {
073:
074: private Log _logger = LogFactory.getLog(TrackbackPlugin.class);
075:
076: /**
077: * Template for comment e-mails
078: */
079: public static final String TRACKBACK_PLUGIN_EMAIL_TEMPLATE_TEXT = "org/blojsom/plugin/trackback/trackback-plugin-email-template-text.vm";
080: public static final String TRACKBACK_PLUGIN_EMAIL_TEMPLATE_HTML = "org/blojsom/plugin/trackback/trackback-plugin-email-template-html.vm";
081:
082: /**
083: * Default prefix for trackback e-mail notification
084: */
085: public static final String DEFAULT_TRACKBACK_PREFIX = "[blojsom] Trackback on: ";
086:
087: /**
088: * Initialization parameter for e-mail prefix
089: */
090: public static final String TRACKBACK_PREFIX_IP = "plugin-trackback-email-prefix";
091:
092: /**
093: * Initialization parameter for the throttling of trackbacks from IP addresses
094: */
095: public static final String TRACKBACK_THROTTLE_MINUTES_IP = "plugin-trackback-throttle";
096:
097: /**
098: * Initialization parameter for disabling trackbacks on entries after a certain number of days
099: */
100: public static final String TRACKBACK_DAYS_EXPIRATION_IP = "plugin-trackback-days-expiration";
101:
102: /**
103: * Default throttle value for trackbacks from a particular IP address
104: */
105: private static final int TRACKBACK_THROTTLE_DEFAULT_MINUTES = 5;
106:
107: /**
108: * Request parameter to indicate a trackback "tb"
109: */
110: public static final String TRACKBACK_PARAM = "tb";
111:
112: /**
113: * Request parameter for the trackback "title"
114: */
115: public static final String TRACKBACK_TITLE_PARAM = "title";
116:
117: /**
118: * Request parameter for the trackback "excerpt"
119: */
120: public static final String TRACKBACK_EXCERPT_PARAM = "excerpt";
121:
122: /**
123: * Request parameter for the trackback "url"
124: */
125: public static final String TRACKBACK_URL_PARAM = "url";
126:
127: /**
128: * Request parameter for the trackback "blog_name"
129: */
130: public static final String TRACKBACK_BLOG_NAME_PARAM = "blog_name";
131:
132: /**
133: * Key under which the indicator this plugin is "live" will be placed
134: * (example: on the request for the JSPDispatcher)
135: */
136: public static final String BLOJSOM_TRACKBACK_PLUGIN_ENABLED = "BLOJSOM_TRACKBACK_PLUGIN_ENABLED";
137:
138: /**
139: * Key under which the trackback return code will be placed
140: * (example: on the request for the JSPDispatcher)
141: */
142: public static final String BLOJSOM_TRACKBACK_RETURN_CODE = "BLOJSOM_TRACKBACK_RETURN_CODE";
143:
144: /**
145: * Key under which the trackback error message will be placed
146: * (example: on the request for the JSPDispatcher)
147: */
148: public static final String BLOJSOM_TRACKBACK_MESSAGE = "BLOJSOM_TRACKBACK_MESSAGE";
149:
150: /**
151: * IP address meta-data
152: */
153: public static final String BLOJSOM_TRACKBACK_PLUGIN_METADATA_IP = "BLOJSOM_TRACKBACK_PLUGIN_METADATA_IP";
154:
155: /**
156: * Trackback success page
157: */
158: private static final String TRACKBACK_SUCCESS_PAGE = "/trackback-success";
159:
160: /**
161: * Trackback failure page
162: */
163: private static final String TRACKBACK_FAILURE_PAGE = "/trackback-failure";
164:
165: /**
166: * Key under which the blog entry will be placed for merging the trackback e-mail
167: */
168: public static final String BLOJSOM_TRACKBACK_PLUGIN_BLOG_ENTRY = "BLOJSOM_TRACKBACK_PLUGIN_BLOG_ENTRY";
169:
170: /**
171: * Key under which the blog comment will be placed for merging the trackback e-mail
172: */
173: public static final String BLOJSOM_TRACKBACK_PLUGIN_TRACKBACK = "BLOJSOM_TRACKBACK_PLUGIN_TRACKBACK";
174:
175: public static final String BLOJSOM_PLUGIN_TRACKBACK_METADATA = "BLOJSOM_PLUGIN_TRACKBACK_METADATA";
176:
177: public static final String BLOJSOM_PLUGIN_TRACKBACK_METADATA_DESTROY = "BLOJSOM_PLUGIN_TRACKBACK_METADATA_DESTROY";
178:
179: private Map _ipAddressTrackbackTimes;
180: private String _mailServer;
181: private String _mailServerUsername;
182: private String _mailServerPassword;
183: private Session _session;
184: private Fetcher _fetcher;
185: private EventBroadcaster _eventBroadcaster;
186:
187: /**
188: * Default constructor
189: */
190: public TrackbackPlugin() {
191: }
192:
193: /**
194: * Set the {@link oEventBroadcaster} event broadcaster
195: *
196: * @param eventBroadcaster {@link EventBroadcaster}
197: */
198: public void setEventBroadcaster(EventBroadcaster eventBroadcaster) {
199: _eventBroadcaster = eventBroadcaster;
200: }
201:
202: /**
203: * Set the {@link Fetcher}
204: *
205: * @param fetcher {@link Fetcher}
206: */
207: public void setFetcher(Fetcher fetcher) {
208: _fetcher = fetcher;
209: }
210:
211: /**
212: * Initialize this plugin. This method only called when the plugin is instantiated.
213: *
214: * @throws PluginException If there is an error initializing the plugin
215: */
216: public void init() throws PluginException {
217: super .init();
218:
219: _mailServer = _servletConfig.getInitParameter(SMTPSERVER_IP);
220:
221: if (_mailServer != null) {
222: if (_mailServer.startsWith("java:comp/env")) {
223: try {
224: Context context = new InitialContext();
225: _session = (Session) context.lookup(_mailServer);
226: } catch (NamingException e) {
227: _logger.error(e);
228: throw new PluginException(e);
229: }
230: } else {
231: _mailServerUsername = _servletConfig
232: .getInitParameter(SMTPSERVER_USERNAME_IP);
233: _mailServerPassword = _servletConfig
234: .getInitParameter(SMTPSERVER_PASSWORD_IP);
235: }
236: } else {
237: throw new PluginException(
238: "Missing SMTP servername servlet initialization parameter: "
239: + SMTPSERVER_IP);
240: }
241:
242: _ipAddressTrackbackTimes = new WeakHashMap();
243: _eventBroadcaster.addListener(this );
244: }
245:
246: /**
247: * Process the blog entries
248: *
249: * @param httpServletRequest Request
250: * @param httpServletResponse Response
251: * @param blog {@link Blog} instance
252: * @param context Context
253: * @param entries Blog entries retrieved for the particular request
254: * @return Modified set of blog entries
255: * @throws PluginException If there is an error processing the blog entries
256: */
257: public Entry[] process(HttpServletRequest httpServletRequest,
258: HttpServletResponse httpServletResponse, Blog blog,
259: Map context, Entry[] entries) throws PluginException {
260: context.put(BLOJSOM_TRACKBACK_PLUGIN_ENABLED, blog
261: .getBlogTrackbacksEnabled());
262: if (!blog.getBlogTrackbacksEnabled().booleanValue()) {
263: if (_logger.isDebugEnabled()) {
264: _logger.debug("Trackbacks not enabled for blog: "
265: + blog.getBlogId());
266: }
267:
268: return entries;
269: }
270:
271: Boolean _blogTrackbacksEnabled;
272:
273: _blogTrackbacksEnabled = blog.getBlogTrackbacksEnabled();
274:
275: if (entries.length == 0) {
276: return entries;
277: }
278:
279: if (!_blogTrackbacksEnabled.booleanValue()) {
280: return entries;
281: }
282:
283: String url = httpServletRequest
284: .getParameter(TRACKBACK_URL_PARAM);
285: String permalink = httpServletRequest
286: .getParameter(BlojsomConstants.PERMALINK_PARAM);
287: String title = httpServletRequest
288: .getParameter(TRACKBACK_TITLE_PARAM);
289: String excerpt = httpServletRequest
290: .getParameter(TRACKBACK_EXCERPT_PARAM);
291: String blogName = httpServletRequest
292: .getParameter(TRACKBACK_BLOG_NAME_PARAM);
293: String tb = httpServletRequest.getParameter(TRACKBACK_PARAM);
294: String remoteIPAddress = httpServletRequest.getRemoteAddr();
295:
296: if ((permalink != null) && (!"".equals(permalink))
297: && (tb != null) && ("y".equalsIgnoreCase(tb))) {
298: if ((url == null) || ("".equals(url.trim()))) {
299: context.put(BLOJSOM_TRACKBACK_RETURN_CODE, new Integer(
300: 1));
301: context
302: .put(BLOJSOM_TRACKBACK_MESSAGE,
303: "No url parameter for trackback. url must be specified.");
304: httpServletRequest.setAttribute(
305: BlojsomConstants.PAGE_PARAM,
306: TRACKBACK_FAILURE_PAGE);
307:
308: return entries;
309: }
310:
311: // Check for trackback throttling
312: String trackbackThrottleValue = blog
313: .getProperty(TRACKBACK_THROTTLE_MINUTES_IP);
314: if (!BlojsomUtils.checkNullOrBlank(trackbackThrottleValue)) {
315: int trackbackThrottleMinutes;
316:
317: try {
318: trackbackThrottleMinutes = Integer
319: .parseInt(trackbackThrottleValue);
320: } catch (NumberFormatException e) {
321: trackbackThrottleMinutes = TRACKBACK_THROTTLE_DEFAULT_MINUTES;
322: }
323: if (_logger.isDebugEnabled()) {
324: _logger.debug("Trackback throttling enabled at: "
325: + trackbackThrottleMinutes + " minutes");
326: }
327:
328: if (_ipAddressTrackbackTimes
329: .containsKey(remoteIPAddress)) {
330: Calendar currentTime = Calendar.getInstance();
331: Calendar timeOfLastTrackback = (Calendar) _ipAddressTrackbackTimes
332: .get(remoteIPAddress);
333: long timeDifference = currentTime.getTimeInMillis()
334: - timeOfLastTrackback.getTimeInMillis();
335:
336: long differenceInMinutes = timeDifference
337: / (60 * 1000);
338: if (differenceInMinutes < trackbackThrottleMinutes) {
339: if (_logger.isDebugEnabled()) {
340: _logger
341: .debug("Trackback throttle enabled. Comment from IP address: "
342: + remoteIPAddress
343: + " in less than "
344: + trackbackThrottleMinutes
345: + " minutes");
346: }
347:
348: context.put(BLOJSOM_TRACKBACK_RETURN_CODE,
349: new Integer(1));
350: context.put(BLOJSOM_TRACKBACK_MESSAGE,
351: "Trackback throttling enabled.");
352: httpServletRequest.setAttribute(
353: BlojsomConstants.PAGE_PARAM,
354: TRACKBACK_FAILURE_PAGE);
355:
356: return entries;
357: } else {
358: if (_logger.isDebugEnabled()) {
359: _logger
360: .debug("Trackback throttle enabled. Resetting date of last comment to current time");
361: }
362: _ipAddressTrackbackTimes.put(remoteIPAddress,
363: currentTime);
364: }
365: } else {
366: Calendar calendar = Calendar.getInstance();
367: _ipAddressTrackbackTimes.put(remoteIPAddress,
368: calendar);
369: }
370: }
371:
372: url = url.trim();
373: if (!url.toLowerCase().startsWith("http://")) {
374: url = "http://" + url;
375: }
376:
377: if (BlojsomUtils.checkNullOrBlank(title)) {
378: title = url;
379: } else {
380: title = title.trim();
381: title = BlojsomUtils.escapeStringSimple(title);
382: title = BlojsomUtils.stripLineTerminators(title, " ");
383: }
384:
385: if (excerpt == null) {
386: excerpt = "";
387: } else {
388: if (excerpt.length() >= 255) {
389: excerpt = excerpt.substring(0, 252);
390: excerpt += "...";
391: }
392:
393: excerpt = BlojsomUtils.stripLineTerminators(excerpt,
394: " ");
395: }
396: excerpt = BlojsomUtils.escapeStringSimple(excerpt);
397:
398: if (blogName == null) {
399: blogName = "";
400: } else {
401: blogName = blogName.trim();
402: blogName = BlojsomUtils.escapeStringSimple(blogName);
403: blogName = BlojsomUtils.stripLineTerminators(blogName,
404: " ");
405: }
406:
407: Entry entryForTrackback = _fetcher.newEntry();
408: try {
409: String blogEntryId = BlojsomUtils.getRequestValue(
410: "entry_id", httpServletRequest);
411: Integer entryId;
412: try {
413: entryId = Integer.valueOf(blogEntryId);
414: } catch (NumberFormatException e) {
415: if (_logger.isErrorEnabled()) {
416: _logger.error(e);
417: }
418:
419: return entries;
420: }
421:
422: entryForTrackback.setId(entryId);
423:
424: _fetcher.loadEntry(blog, entryForTrackback);
425: if (_logger.isDebugEnabled()) {
426: _logger.debug("Loaded entry for trackback: "
427: + entryId.toString());
428: }
429:
430: // Check for a trackback where the number of days between trackback auto-expiration has passed
431: String trackbackDaysExpiration = blog
432: .getProperty(TRACKBACK_DAYS_EXPIRATION_IP);
433: if (!BlojsomUtils
434: .checkNullOrBlank(trackbackDaysExpiration)) {
435: try {
436: int daysExpiration = Integer
437: .parseInt(trackbackDaysExpiration);
438: int daysBetweenDates = BlojsomUtils
439: .daysBetweenDates(entryForTrackback
440: .getDate(), new Date());
441: if ((daysExpiration > 0)
442: && (daysBetweenDates >= daysExpiration)) {
443: if (_logger.isDebugEnabled()) {
444: _logger
445: .debug("Trackback period for this entry has expired. Expiration period set at "
446: + daysExpiration
447: + " days. Difference in days: "
448: + daysBetweenDates);
449: }
450:
451: return entries;
452: }
453: } catch (NumberFormatException e) {
454: }
455: }
456: } catch (FetcherException e) {
457: if (_logger.isErrorEnabled()) {
458: _logger.error(e);
459: }
460: }
461:
462: Map trackbackMetaData = new HashMap();
463:
464: // Check to see if a previous plugin populated meta-data for the comment
465: if (context.containsKey(BLOJSOM_PLUGIN_TRACKBACK_METADATA)) {
466: Map metaData = (Map) context
467: .get(BLOJSOM_PLUGIN_TRACKBACK_METADATA);
468:
469: Iterator metaDataKeys = metaData.keySet().iterator();
470: Object key;
471: Object value;
472: while (metaDataKeys.hasNext()) {
473: key = metaDataKeys.next();
474: value = metaData.get(key);
475: trackbackMetaData.put(key, value);
476: }
477: }
478:
479: Trackback trackback = _fetcher.newTrackback();
480: trackback.setBlogEntryId(entryForTrackback.getId());
481: trackback.setEntry(entryForTrackback);
482:
483: Integer code = new Integer(1);
484:
485: _eventBroadcaster
486: .processEvent(new TrackbackResponseSubmissionEvent(
487: this , new Date(), blog, httpServletRequest,
488: httpServletResponse, blogName, title, url,
489: excerpt, entryForTrackback,
490: trackbackMetaData));
491:
492: // Check to see if the trackback should be destroyed (not saved) automatically
493: if (!trackbackMetaData
494: .containsKey(BLOJSOM_PLUGIN_TRACKBACK_METADATA_DESTROY)) {
495: code = addTrackback(title, excerpt, url, blogName,
496: trackbackMetaData, trackback, blog, context,
497: httpServletRequest);
498:
499: // For persisting the Last-Modified time
500: context.put(BlojsomConstants.BLOJSOM_LAST_MODIFIED,
501: new Long(new Date().getTime()));
502: } else {
503: if (_logger.isInfoEnabled()) {
504: _logger
505: .info("Trackback meta-data contained destroy key. Trackback was not saved");
506: }
507: }
508:
509: context.put(BLOJSOM_TRACKBACK_RETURN_CODE, code);
510: if (code.intValue() == 0) {
511: httpServletRequest.setAttribute(
512: BlojsomConstants.PAGE_PARAM,
513: TRACKBACK_SUCCESS_PAGE);
514:
515: try {
516: _fetcher.loadEntry(blog, entries[0]);
517: _fetcher.loadEntry(blog, entryForTrackback);
518: _eventBroadcaster
519: .broadcastEvent(new TrackbackAddedEvent(
520: this , new Date(), trackback, blog));
521: } catch (FetcherException e) {
522: if (_logger.isErrorEnabled()) {
523: _logger.error(e);
524: }
525: }
526: } else {
527: httpServletRequest.setAttribute(
528: BlojsomConstants.PAGE_PARAM,
529: TRACKBACK_FAILURE_PAGE);
530: }
531: }
532:
533: return entries;
534: }
535:
536: /**
537: * Add a trackback
538: *
539: * @param title Title
540: * @param excerpt Excerpt
541: * @param url URL
542: * @param blogName Blog name
543: * @param trackbackMetaData Trackback meta-data
544: * @param trackback {@link Trackback}
545: * @param blog {@link Blog}
546: * @param context Context
547: * @param httpServletRequest {@link HttpServletRequest}
548: * @return <code>0</code> if adding the trackback was successful, <code>1</code> if there was an error
549: */
550: private Integer addTrackback(String title, String excerpt,
551: String url, String blogName, Map trackbackMetaData,
552: Trackback trackback, Blog blog, Map context,
553: HttpServletRequest httpServletRequest) {
554: try {
555: excerpt = BlojsomUtils.escapeMetaAndLink(excerpt);
556: trackback.setTitle(title);
557: trackback.setExcerpt(excerpt);
558: trackback.setUrl(url);
559: trackback.setBlogName(blogName);
560: trackback.setTrackbackDate(new Date());
561: trackback.setBlogId(blog.getId());
562: trackback.setIp(httpServletRequest.getRemoteAddr());
563: trackback.setMetaData(trackbackMetaData);
564: if (trackbackMetaData
565: .containsKey(TrackbackModerationPlugin.BLOJSOM_TRACKBACK_MODERATION_PLUGIN_APPROVED)
566: && "true"
567: .equals(trackbackMetaData
568: .get(TrackbackModerationPlugin.BLOJSOM_TRACKBACK_MODERATION_PLUGIN_APPROVED))) {
569: trackback.setStatus(ResponseConstants.APPROVED_STATUS);
570: } else {
571: if ("true"
572: .equals(blog
573: .getProperty(TrackbackModerationPlugin.TRACKBACK_MODERATION_ENABLED))) {
574: trackback.setStatus(ResponseConstants.NEW_STATUS);
575: } else {
576: trackback
577: .setStatus(ResponseConstants.APPROVED_STATUS);
578: }
579: }
580:
581: _fetcher.saveTrackback(blog, trackback);
582:
583: return new Integer(0);
584: } catch (FetcherException e) {
585: if (_logger.isErrorEnabled()) {
586: _logger.error(e);
587: }
588:
589: context.put(BLOJSOM_TRACKBACK_MESSAGE, e.getMessage());
590:
591: return new Integer(1);
592: }
593: }
594:
595: /**
596: * Perform any cleanup for the plugin. Called after {@link #process}.
597: *
598: * @throws PluginException If there is an error performing cleanup for this plugin
599: */
600: public void cleanup() throws PluginException {
601: }
602:
603: /**
604: * Called when BlojsomServlet is taken out of service
605: *
606: * @throws PluginException If there is an error in finalizing this plugin
607: */
608: public void destroy() throws PluginException {
609: }
610:
611: /**
612: * Setup the comment e-mail
613: *
614: * @param blog {@link Blog} information
615: * @param email Email message
616: * @throws EmailException If there is an error preparing the e-mail message
617: */
618: protected void setupEmail(Blog blog, Entry entry, Email email)
619: throws EmailException {
620: email.setCharset(BlojsomConstants.UTF8);
621:
622: // If we have a mail session for the environment, use that
623: if (_session != null) {
624: email.setMailSession(_session);
625: } else {
626: // Otherwise, if there is a username and password for the mail server, use that
627: if (!BlojsomUtils.checkNullOrBlank(_mailServerUsername)
628: && !BlojsomUtils
629: .checkNullOrBlank(_mailServerPassword)) {
630: email.setHostName(_mailServer);
631: email.setAuthentication(_mailServerUsername,
632: _mailServerPassword);
633: } else {
634: email.setHostName(_mailServer);
635: }
636: }
637:
638: email.setFrom(blog.getBlogOwnerEmail(), "Blojsom Trackback");
639:
640: String author = entry.getAuthor();
641: if (BlojsomUtils.checkNullOrBlank(author)) {
642: author = blog.getBlogOwner();
643: }
644:
645: String authorEmail = blog.getBlogOwnerEmail();
646:
647: if (author != null) {
648: try {
649: User user = _fetcher.loadUser(blog, author);
650:
651: if (user == null) {
652: authorEmail = blog.getBlogOwnerEmail();
653: } else {
654: authorEmail = user.getUserEmail();
655: if (BlojsomUtils.checkNullOrBlank(authorEmail)) {
656: authorEmail = blog.getBlogOwnerEmail();
657: }
658: }
659: } catch (FetcherException e) {
660: }
661: }
662:
663: email.addTo(authorEmail, author);
664: email.setSentDate(new Date());
665: }
666:
667: /**
668: * Handle an event broadcast from another component
669: *
670: * @param event {@link org.blojsom.event.Event} to be handled
671: */
672: public void handleEvent(Event event) {
673: if (event instanceof TrackbackAddedEvent) {
674: HtmlEmail email = new HtmlEmail();
675:
676: TrackbackAddedEvent trackbackAddedEvent = (TrackbackAddedEvent) event;
677:
678: if (trackbackAddedEvent.getBlog().getBlogEmailEnabled()
679: .booleanValue()) {
680: try {
681: setupEmail(trackbackAddedEvent.getBlog(),
682: trackbackAddedEvent.getEntry(), email);
683:
684: Map emailTemplateContext = new HashMap();
685: emailTemplateContext.put(
686: BlojsomConstants.BLOJSOM_BLOG,
687: trackbackAddedEvent.getBlog());
688: emailTemplateContext.put(
689: BLOJSOM_TRACKBACK_PLUGIN_TRACKBACK,
690: trackbackAddedEvent.getTrackback());
691: emailTemplateContext.put(
692: BLOJSOM_TRACKBACK_PLUGIN_BLOG_ENTRY,
693: trackbackAddedEvent.getEntry());
694:
695: String htmlText = mergeTemplate(
696: TRACKBACK_PLUGIN_EMAIL_TEMPLATE_HTML,
697: trackbackAddedEvent.getBlog(),
698: emailTemplateContext);
699: String plainText = mergeTemplate(
700: TRACKBACK_PLUGIN_EMAIL_TEMPLATE_TEXT,
701: trackbackAddedEvent.getBlog(),
702: emailTemplateContext);
703:
704: email = email.setHtmlMsg(htmlText);
705: email = email.setTextMsg(plainText);
706:
707: String emailPrefix = (String) trackbackAddedEvent
708: .getBlog().getProperties().get(
709: TRACKBACK_PREFIX_IP);
710: if (BlojsomUtils.checkNullOrBlank(emailPrefix)) {
711: emailPrefix = DEFAULT_TRACKBACK_PREFIX;
712: }
713:
714: email = (HtmlEmail) email
715: .setSubject(emailPrefix
716: + trackbackAddedEvent.getEntry()
717: .getTitle());
718:
719: email.send();
720: } catch (EmailException e) {
721: if (_logger.isErrorEnabled()) {
722: _logger.error(e);
723: }
724: }
725: }
726: }
727: }
728:
729: /**
730: * Process an event from another component
731: *
732: * @param event {@link org.blojsom.event.Event} to be handled
733: */
734: public void processEvent(Event event) {
735: }
736: }
|