KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > blojsom > plugin > moblog > MoblogPlugin


1 /**
2  * Copyright (c) 2003-2006, David A. Czarnecki
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * Redistributions of source code must retain the above copyright notice, this list of conditions and the
9  * following disclaimer.
10  * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
11  * following disclaimer in the documentation and/or other materials provided with the distribution.
12  * Neither the name of "David A. Czarnecki" and "blojsom" nor the names of its contributors may be used to
13  * endorse or promote products derived from this software without specific prior written permission.
14  * Products derived from this software may not be called "blojsom", nor may "blojsom" appear in their name,
15  * without prior written permission of David A. Czarnecki.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
18  * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
19  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
21  * EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */

31 package org.blojsom.plugin.moblog;
32
33 import org.apache.commons.logging.Log;
34 import org.apache.commons.logging.LogFactory;
35 import org.blojsom.blog.Blog;
36 import org.blojsom.blog.Entry;
37 import org.blojsom.event.EventBroadcaster;
38 import org.blojsom.fetcher.Fetcher;
39 import org.blojsom.fetcher.FetcherException;
40 import org.blojsom.plugin.PluginException;
41 import org.blojsom.plugin.admin.event.EntryAddedEvent;
42 import org.blojsom.plugin.email.EmailConstants;
43 import org.blojsom.plugin.email.SimpleAuthenticator;
44 import org.blojsom.plugin.velocity.StandaloneVelocityPlugin;
45 import org.blojsom.util.BlojsomConstants;
46 import org.blojsom.util.BlojsomMetaDataConstants;
47 import org.blojsom.util.BlojsomUtils;
48
49 import javax.mail.*;
50 import javax.mail.internet.InternetAddress JavaDoc;
51 import javax.mail.internet.MimeMultipart JavaDoc;
52 import javax.naming.Context JavaDoc;
53 import javax.naming.InitialContext JavaDoc;
54 import javax.naming.NamingException JavaDoc;
55 import javax.servlet.http.HttpServletRequest JavaDoc;
56 import javax.servlet.http.HttpServletResponse JavaDoc;
57 import java.io.*;
58 import java.net.ConnectException JavaDoc;
59 import java.util.*;
60 import java.util.regex.Matcher JavaDoc;
61 import java.util.regex.Pattern JavaDoc;
62
63 /**
64  * Moblog Plugin
65  *
66  * @author David Czarnecki
67  * @author Mark Lussier
68  * @version $Id: MoblogPlugin.java,v 1.5 2006/09/26 02:55:20 czarneckid Exp $
69  * @since blojsom 3.0
70  */

71 public class MoblogPlugin extends StandaloneVelocityPlugin {
72
73     private Log _logger = LogFactory.getLog(MoblogPlugin.class);
74
75     private static final String JavaDoc MOBLOG_ENTRY_TEMPLATE = "org/blojsom/plugin/moblog/moblog-plugin-template.vm";
76
77     private static final String JavaDoc MOBLOG_SUBJECT = "MOBLOG_SUBJECT";
78     private static final String JavaDoc MOBLOG_BODY_TEXT = "MOBLOG_BODY_TEXT";
79     private static final String JavaDoc MOBLOG_IMAGES = "MOBLOG_IMAGES";
80     private static final String JavaDoc MOBLOG_ATTACHMENTS = "MOBLOG_ATTACHMENTS";
81     private static final String JavaDoc MOBLOG_ATTACHMENT = "MOBLOG_ATTACHMENT";
82     private static final String JavaDoc MOBLOG_ATTACHMENT_URL = "MOBLOG_ATTACHMENT_URL";
83     private static final String JavaDoc MOBLOG_IMAGE = "MOBLOG_IMAGE";
84     private static final String JavaDoc MOBLOG_IMAGE_URL = "MOBLOG_IMAGE_URL";
85
86     /**
87      * Multipart/alternative mime-type
88      */

89     private static final String JavaDoc MULTIPART_ALTERNATIVE_MIME_TYPE = "multipart/alternative";
90
91     /**
92      * Text/html mime-type
93      */

94     private static final String JavaDoc TEXT_HTML_MIME_TYPE = "text/html";
95
96     /**
97      * Default mime-types for text
98      */

99     public static final String JavaDoc DEFAULT_TEXT_MIME_TYPES = "text/plain, text/html";
100
101     /**
102      * Default mime-types for images
103      */

104     public static final String JavaDoc DEFAULT_IMAGE_MIME_TYPES = "image/jpg, image/jpeg, image/gif, image/png";
105
106     /**
107      * Multipart mime-type
108      */

109     private static final String JavaDoc MULTIPART_TYPE = "multipart/*";
110
111     /**
112      * Default store
113      */

114     private static final String JavaDoc DEFAULT_MESSAGE_STORE = "pop3";
115
116     /**
117      * Default poll time (10 minutes)
118      */

119     private static final int DEFAULT_POLL_TIME = 720;
120
121     /**
122      * Moblog confifguration parameter for web.xml
123      */

124     public static final String JavaDoc PLUGIN_MOBLOG_CONFIGURATION_IP = "plugin-moblog";
125
126     /**
127      * Moblog configuration parameter for mailbox polling time (5 minutes)
128      */

129     public static final String JavaDoc PLUGIN_MOBLOG_POLL_TIME = "plugin-moblog-poll-time";
130
131     /**
132      * Moblog configuration parameter for message store provider
133      */

134     public static final String JavaDoc PLUGIN_MOBLOG_STORE_PROVIDER = "plugin-moblog-store-provider";
135
136     /**
137      * Default moblog authorization properties file which lists valid e-mail addresses who can moblog entries
138      */

139     public static final String JavaDoc DEFAULT_MOBLOG_AUTHORIZATION_FILE = "moblog-authorization.properties";
140
141     /**
142      * Configuration property for moblog authorization properties file to use
143      */

144     public static final String JavaDoc PROPERTY_AUTHORIZATION = "moblog-authorization";
145
146     /**
147      * Configuration property for mailhost
148      */

149     public static final String JavaDoc PROPERTY_HOSTNAME = "moblog-hostname";
150
151     /**
152      * Configuration property for mailbox user ID
153      */

154     public static final String JavaDoc PROPERTY_USERID = "moblog-userid";
155
156     /**
157      * Configuration property for mailbox user password
158      */

159     public static final String JavaDoc PROPERTY_PASSWORD = "moblog-password";
160
161     /**
162      * Configuration property for moblog category
163      */

164     public static final String JavaDoc PROPERTY_CATEGORY = "moblog-category";
165
166     /**
167      * Configuration property for whether or not moblog is enabled for this blog
168      */

169     public static final String JavaDoc PROPERTY_ENABLED = "moblog-enabled";
170
171     /**
172      * Configuration property for the secret word that must be present at the beginning of the subject
173      */

174     public static final String JavaDoc PLUGIN_MOBLOG_SECRET_WORD = "moblog-secret-word";
175
176     /**
177      * Configuration property for image mime-types
178      */

179     public static final String JavaDoc PLUGIN_MOBLOG_IMAGE_MIME_TYPES = "moblog-image-mime-types";
180
181     /**
182      * Configuration property for attachment mime-types
183      */

184     public static final String JavaDoc PLUGIN_MOBLOG_ATTACHMENT_MIME_TYPES = "moblog-attachment-mime-types";
185
186     /**
187      * Configuration property for text mime-types
188      */

189     public static final String JavaDoc PLUGIN_MOBLOG_TEXT_MIME_TYPES = "moblog-text-mime-types";
190
191     /**
192      * Configuration property for regular expression to ignore a certain portion of text
193      */

194     public static final String JavaDoc PLUGIN_MOBLOG_IGNORE_EXPRESSION = "moblog-ignore-expression";
195
196     public static final String JavaDoc PLUGIN_MOBLOG_AUTHORIZED_ADDRESSES = "moblog-authorized-addresses";
197
198     private int _pollTime;
199
200     private Session _storeSession;
201     private boolean _finished = false;
202     private MailboxChecker _checker;
203     private String JavaDoc _storeProvider;
204
205     private EventBroadcaster _eventBroadcaster;
206     private Fetcher _fetcher;
207
208     /**
209      * Set the {@link Fetcher}
210      *
211      * @param fetcher {@link Fetcher}
212      */

213     public void setFetcher(Fetcher fetcher) {
214         _fetcher = fetcher;
215     }
216
217     /**
218      * Set the {@link EventBroadcaster}
219      *
220      * @param eventBroadcaster {@link EventBroadcaster}
221      */

222     public void setEventBroadcaster(EventBroadcaster eventBroadcaster) {
223         _eventBroadcaster = eventBroadcaster;
224     }
225
226     /**
227      * Initialize this plugin. This method only called when the plugin is
228      * instantiated.
229      *
230      * @throws PluginException If there is an error initializing the plugin
231      */

232     public void init() throws PluginException {
233         super.init();
234
235         String JavaDoc moblogPollTime = _servletConfig.getInitParameter(PLUGIN_MOBLOG_POLL_TIME);
236         if (BlojsomUtils.checkNullOrBlank(moblogPollTime)) {
237             _pollTime = DEFAULT_POLL_TIME;
238         } else {
239             try {
240                 _pollTime = Integer.parseInt(moblogPollTime);
241             } catch (NumberFormatException JavaDoc e) {
242                 if (_logger.isErrorEnabled()) {
243                     if (_logger.isErrorEnabled()) {
244                         _logger.error("Invalid time specified for: " + PLUGIN_MOBLOG_POLL_TIME);
245                     }
246                 }
247                 _pollTime = DEFAULT_POLL_TIME;
248             }
249         }
250
251         _storeProvider = _servletConfig.getInitParameter(PLUGIN_MOBLOG_STORE_PROVIDER);
252         if (BlojsomUtils.checkNullOrBlank(_storeProvider)) {
253             _storeProvider = DEFAULT_MESSAGE_STORE;
254         }
255
256         _checker = new MailboxChecker();
257         _checker.setDaemon(true);
258
259         String JavaDoc hostname = _servletConfig.getInitParameter(EmailConstants.SMTPSERVER_IP);
260         if (hostname != null) {
261             if (hostname.startsWith("java:comp/env")) {
262                 try {
263                     Context JavaDoc context = new InitialContext JavaDoc();
264                     _storeSession = (Session) context.lookup(hostname);
265                 } catch (NamingException JavaDoc e) {
266                     if (_logger.isErrorEnabled()) {
267                         _logger.error(e);
268                     }
269
270                     throw new PluginException(e);
271                 }
272             } else {
273                 String JavaDoc username = _servletConfig.getInitParameter(EmailConstants.SMTPSERVER_USERNAME_IP);
274                 String JavaDoc password = _servletConfig.getInitParameter(EmailConstants.SMTPSERVER_PASSWORD_IP);
275
276                 Properties props = new Properties();
277                 props.put(EmailConstants.SESSION_NAME, hostname);
278                 if (BlojsomUtils.checkNullOrBlank(username) || BlojsomUtils.checkNullOrBlank(password)) {
279                     _storeSession = Session.getInstance(props, null);
280                 } else {
281                     _storeSession = Session.getInstance(props, new SimpleAuthenticator(username, password));
282                 }
283             }
284         }
285
286         _checker.start();
287     }
288
289     /**
290      * Process the blog entries
291      *
292      * @param httpServletRequest Request
293      * @param httpServletResponse Response
294      * @param blog {@link org.blojsom.blog.Blog} instance
295      * @param context Context
296      * @param entries Blog entries retrieved for the particular request
297      * @return Modified set of blog entries
298      * @throws PluginException If there is an error processing the blog entries
299      */

300     public Entry[] process(HttpServletRequest JavaDoc httpServletRequest, HttpServletResponse JavaDoc httpServletResponse, Blog blog, Map context, Entry[] entries) throws PluginException {
301         return entries;
302     }
303
304     /**
305      * Perform any cleanup for the plugin. Called after {@link #process}.
306      *
307      * @throws PluginException If there is an error performing cleanup for this plugin
308      */

309     public void cleanup() throws PluginException {
310     }
311
312     /**
313      * Called when BlojsomServlet is taken out of service
314      *
315      * @throws PluginException If there is an error in finalizing this plugin
316      */

317     public void destroy() throws PluginException {
318         _finished = true;
319     }
320
321     /**
322      * Thread that polls the mailboxes
323      */

324     private class MailboxChecker extends Thread JavaDoc {
325
326         /**
327          * Allocates a new <code>Thread</code> object. This constructor has
328          * the same effect as <code>Thread(null, null,</code>
329          * <i>gname</i><code>)</code>, where <b><i>gname</i></b> is
330          * a newly generated name. Automatically generated names are of the
331          * form <code>"Thread-"+</code><i>n</i>, where <i>n</i> is an integer.
332          *
333          * @see Thread#Thread(ThreadGroup,
334          * Runnable, String)
335          */

336         public MailboxChecker() {
337             super();
338         }
339
340         /**
341          * Perform the actual work of checking the POP3 mailbox configured for the blog user.
342          *
343          * @param mailbox Mailbox to be processed
344          */

345         private void processMailbox(Mailbox mailbox) {
346             Folder folder = null;
347             Store store = null;
348             String JavaDoc subject;
349
350             try {
351                 store = _storeSession.getStore(_storeProvider);
352                 store.connect(mailbox.getHostName(), mailbox.getUserId(), mailbox.getPassword());
353
354                 // -- Try to get hold of the default folder --
355
folder = store.getDefaultFolder();
356                 if (folder == null) {
357                     if (_logger.isErrorEnabled()) {
358                         _logger.error("Default folder is null.");
359                     }
360                     _finished = true;
361                 }
362
363                 // -- ...and its INBOX --
364
folder = folder.getFolder(mailbox.getFolder());
365                 if (folder == null) {
366                     if (_logger.isErrorEnabled()) {
367                         _logger.error("No POP3 folder called " + mailbox.getFolder());
368                     }
369                     _finished = true;
370                 }
371
372                 // -- Open the folder for read only --
373
folder.open(Folder.READ_WRITE);
374
375                 // -- Get the message wrappers and process them --
376
Message[] msgs = folder.getMessages();
377
378                 if (_logger.isDebugEnabled()) {
379                     _logger.debug("Found [" + msgs.length + "] messages");
380                 }
381
382                 for (int msgNum = 0; msgNum < msgs.length; msgNum++) {
383                     String JavaDoc from = ((InternetAddress JavaDoc) msgs[msgNum].getFrom()[0]).getAddress();
384                     if (_logger.isDebugEnabled()) {
385                         _logger.debug("Processing message: " + msgNum);
386                     }
387
388                     if (!checkSender(mailbox, from)) {
389                         if (_logger.isDebugEnabled()) {
390                             _logger.debug("Unauthorized sender address: " + from);
391                             _logger.debug("Deleting message: " + msgNum);
392                         }
393
394                         msgs[msgNum].setFlag(Flags.Flag.DELETED, true);
395                     } else {
396                         Message email = msgs[msgNum];
397                         subject = email.getSubject();
398
399                         StringBuffer JavaDoc description = new StringBuffer JavaDoc();
400                         Part messagePart;
401                         messagePart = email;
402                         Pattern JavaDoc pattern = null;
403                         List moblogImages = new ArrayList();
404                         List moblogAttachments = new ArrayList();
405                         Map moblogContext = new HashMap();
406
407                         if (mailbox.getIgnoreExpression() != null) {
408                             pattern = Pattern.compile(mailbox.getIgnoreExpression(), Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.UNICODE_CASE | Pattern.DOTALL);
409                         }
410
411                         if (subject == null) {
412                             subject = "";
413                         } else {
414                             subject = subject.trim();
415                         }
416
417                         String JavaDoc secretWord = mailbox.getSecretWord();
418                         if (secretWord != null) {
419                             if (!subject.startsWith(secretWord)) {
420                                 if (_logger.isErrorEnabled()) {
421                                     _logger.error("Message does not begin with secret word for user id: " + mailbox.getUserId());
422                                 }
423                                 msgs[msgNum].setFlag(Flags.Flag.DELETED, true);
424
425                                 continue;
426                             } else {
427                                 subject = subject.substring(secretWord.length());
428                             }
429                         }
430
431                         if (email.isMimeType(MULTIPART_TYPE)) {
432                             // Check for multipart/alternative
433
String JavaDoc overallType = email.getContentType();
434                             overallType = sanitizeContentType(overallType);
435
436                             boolean isMultipartAlternative = false;
437                             if (MULTIPART_ALTERNATIVE_MIME_TYPE.equals(overallType)) {
438                                 isMultipartAlternative = true;
439                             }
440
441                             Multipart JavaDoc mp = (Multipart JavaDoc) messagePart.getContent();
442                             int count = mp.getCount();
443
444                             for (int i = 0; i < count; i++) {
445                                 BodyPart bp = mp.getBodyPart(i);
446                                 String JavaDoc type = bp.getContentType();
447                                 if (type != null) {
448                                     type = sanitizeContentType(type);
449                                     Map imageMimeTypes = mailbox.getImageMimeTypes();
450                                     Map attachmentMimeTypes = mailbox.getAttachmentMimeTypes();
451                                     Map textMimeTypes = mailbox.getTextMimeTypes();
452
453                                     // Check for multipart alternative as part of a larger e-mail block
454
if (MULTIPART_ALTERNATIVE_MIME_TYPE.equals(type)) {
455                                         Object JavaDoc mimeMultipartContent = bp.getContent();
456                                         if (mimeMultipartContent instanceof MimeMultipart JavaDoc) {
457                                             MimeMultipart JavaDoc mimeMultipart = (MimeMultipart JavaDoc) mimeMultipartContent;
458                                             int mimeMultipartCount = mimeMultipart.getCount();
459                                             for (int j = 0; j < mimeMultipartCount; j++) {
460                                                 BodyPart mimeMultipartBodyPart = mimeMultipart.getBodyPart(j);
461                                                 String JavaDoc mmpbpType = mimeMultipartBodyPart.getContentType();
462                                                 if (mmpbpType != null) {
463                                                     mmpbpType = sanitizeContentType(mmpbpType);
464                                                     if (TEXT_HTML_MIME_TYPE.equals(mmpbpType)) {
465                                                         if (_logger.isDebugEnabled()) {
466                                                             _logger.debug("Using HTML part of multipart/alternative: " + type);
467                                                         }
468                                                         InputStream is = bp.getInputStream();
469
470                                                         BufferedReader reader = new BufferedReader(new InputStreamReader(is, BlojsomConstants.UTF8));
471                                                         String JavaDoc thisLine;
472
473                                                         while ((thisLine = reader.readLine()) != null) {
474                                                             description.append(thisLine);
475                                                             description.append(BlojsomConstants.LINE_SEPARATOR);
476                                                         }
477
478                                                         reader.close();
479                                                         if (pattern != null) {
480                                                             Matcher JavaDoc matcher = pattern.matcher(description);
481                                                             if (!matcher.find() && !matcher.matches()) {
482                                                                 //entry.append(description);
483
moblogContext.put(MOBLOG_BODY_TEXT, description.toString());
484                                                             }
485                                                         } else {
486                                                             //entry.append(description);
487
moblogContext.put(MOBLOG_BODY_TEXT, description.toString());
488                                                         }
489                                                     } else {
490                                                         if (_logger.isDebugEnabled()) {
491                                                             _logger.debug("Skipping non-HTML part of multipart/alternative block");
492                                                         }
493                                                     }
494                                                 } else {
495                                                     if (_logger.isInfoEnabled()) {
496                                                         _logger.info("Unknown mimetype for multipart/alternative block");
497                                                     }
498                                                 }
499                                             }
500                                         } else {
501                                             if (_logger.isDebugEnabled()) {
502                                                 _logger.debug("Multipart alternative block not instance of MimeMultipart");
503                                             }
504                                         }
505                                     } else {
506                                         if (imageMimeTypes.containsKey(type)) {
507                                             if (_logger.isDebugEnabled()) {
508                                                 _logger.debug("Creating image of type: " + type);
509                                             }
510                                             String JavaDoc outputFilename = BlojsomUtils.digestString(bp.getFileName() + "-" + new Date().getTime());
511                                             String JavaDoc extension = BlojsomUtils.getFileExtension(bp.getFileName());
512                                             if (BlojsomUtils.checkNullOrBlank(extension)) {
513                                                 extension = "";
514                                             }
515
516                                             if (_logger.isDebugEnabled()) {
517                                                 _logger.debug("Writing to: " + mailbox.getOutputDirectory() + File.separator + outputFilename + "." + extension);
518                                             }
519                                             MoblogPluginUtils.saveFile(mailbox.getOutputDirectory() + File.separator + outputFilename, "." + extension, bp.getInputStream());
520
521                                             String JavaDoc baseurl = mailbox.getBlogBaseURL();
522                                             Map moblogImageInformation = new HashMap();
523                                             moblogImageInformation.put(MOBLOG_IMAGE, outputFilename + "." + extension);
524                                             moblogImageInformation.put(MOBLOG_IMAGE_URL, baseurl + mailbox.getUrlPrefix() + outputFilename + "." + extension);
525                                             moblogImages.add(moblogImageInformation);
526                                         } else if (attachmentMimeTypes.containsKey(type)) {
527                                             if (_logger.isDebugEnabled()) {
528                                                 _logger.debug("Creating attachment of type: " + type);
529                                             }
530                                             String JavaDoc outputFilename = BlojsomUtils.digestString(bp.getFileName() + "-" + new Date().getTime());
531                                             String JavaDoc extension = BlojsomUtils.getFileExtension(bp.getFileName());
532                                             if (BlojsomUtils.checkNullOrBlank(extension)) {
533                                                 extension = "";
534                                             }
535
536                                             if (_logger.isDebugEnabled()) {
537                                                 _logger.debug("Writing to: " + mailbox.getOutputDirectory() + File.separator + outputFilename + "." + extension);
538                                             }
539                                             MoblogPluginUtils.saveFile(mailbox.getOutputDirectory() + File.separator + outputFilename, "." + extension, bp.getInputStream());
540
541                                             String JavaDoc baseurl = mailbox.getBlogBaseURL();
542                                             Map moblogAttachmentInformation = new HashMap();
543                                             moblogAttachmentInformation.put(MOBLOG_ATTACHMENT, bp.getFileName());
544                                             moblogAttachmentInformation.put(MOBLOG_ATTACHMENT_URL, baseurl + mailbox.getUrlPrefix() + outputFilename + "." + extension);
545                                             moblogAttachments.add(moblogAttachmentInformation);
546                                         } else if (textMimeTypes.containsKey(type)) {
547                                             if ((isMultipartAlternative && (TEXT_HTML_MIME_TYPE.equals(type))) || !isMultipartAlternative)
548                                             {
549                                                 if (_logger.isDebugEnabled()) {
550                                                     _logger.debug("Using text part of type: " + type);
551                                                 }
552                                                 InputStream is = bp.getInputStream();
553
554                                                 BufferedReader reader = new BufferedReader(new InputStreamReader(is, BlojsomConstants.UTF8));
555                                                 String JavaDoc thisLine;
556
557                                                 while ((thisLine = reader.readLine()) != null) {
558                                                     description.append(thisLine);
559                                                     description.append(BlojsomConstants.LINE_SEPARATOR);
560                                                 }
561
562                                                 reader.close();
563                                                 if (pattern != null) {
564                                                     Matcher JavaDoc matcher = pattern.matcher(description);
565                                                     if (!matcher.find() && !matcher.matches()) {
566                                                         moblogContext.put(MOBLOG_BODY_TEXT, description.toString());
567                                                     }
568                                                 } else {
569                                                     moblogContext.put(MOBLOG_BODY_TEXT, description.toString());
570                                                 }
571                                             }
572                                         } else {
573                                             if (_logger.isInfoEnabled()) {
574                                                 _logger.info("Unknown mimetype for multipart: " + type);
575                                             }
576                                         }
577                                     }
578                                 } else {
579                                     if (_logger.isDebugEnabled()) {
580                                         _logger.debug("Body part has no defined mime type. Skipping.");
581                                     }
582                                 }
583                             }
584                         } else {
585                             // Check for the message being one of the defined text mime types if it's not a multipart
586
Map textMimeTypes = mailbox.getTextMimeTypes();
587                             String JavaDoc mimeType = email.getContentType();
588                             if (mimeType != null) {
589                                 mimeType = sanitizeContentType(mimeType);
590                             }
591
592                             if ((mimeType != null) && (textMimeTypes.containsKey(mimeType))) {
593                                 InputStream is = email.getInputStream();
594
595                                 BufferedReader reader = new BufferedReader(new InputStreamReader(is, BlojsomConstants.UTF8));
596                                 String JavaDoc thisLine;
597
598                                 while ((thisLine = reader.readLine()) != null) {
599                                     description.append(thisLine);
600                                     description.append(BlojsomConstants.LINE_SEPARATOR);
601                                 }
602
603                                 reader.close();
604                                 if (pattern != null) {
605                                     Matcher JavaDoc matcher = pattern.matcher(description);
606                                     if (!matcher.find() && !matcher.matches()) {
607                                         moblogContext.put(MOBLOG_BODY_TEXT, description.toString());
608                                     }
609                                 } else {
610                                     moblogContext.put(MOBLOG_BODY_TEXT, description.toString());
611                                 }
612                             } else {
613                                 if (_logger.isInfoEnabled()) {
614                                     _logger.info("Unknown mimetype: " + mimeType);
615                                 }
616                             }
617                         }
618
619                         // Process subject to change category for moblog post
620
boolean categoryInSubject = false;
621                         String JavaDoc categoryFromSubject = null;
622                         if (subject.startsWith("[")) {
623                             int startIndex = subject.indexOf("[");
624                             if (startIndex != -1) {
625                                 int closingIndex = subject.indexOf("]", startIndex);
626                                 if (closingIndex != -1) {
627                                     categoryFromSubject = subject.substring(startIndex + 1, closingIndex);
628                                     subject = subject.substring(closingIndex + 1);
629                                     categoryFromSubject = BlojsomUtils.normalize(categoryFromSubject);
630                                     if (!categoryFromSubject.startsWith("/")) {
631                                         categoryFromSubject = "/" + categoryFromSubject;
632                                     }
633                                     if (!categoryFromSubject.endsWith("/")) {
634                                         categoryFromSubject += "/";
635                                     }
636                                     categoryInSubject = true;
637                                     if (_logger.isInfoEnabled()) {
638                                         _logger.info("Using category [" + categoryFromSubject + "] for entry: " + subject);
639                                     }
640                                 }
641                             }
642                         }
643
644                         String JavaDoc categoryID = categoryInSubject ? categoryFromSubject : mailbox.getCategoryId();
645
646                         moblogContext.put(MOBLOG_SUBJECT, subject);
647                         moblogContext.put(MOBLOG_IMAGES, moblogImages);
648                         moblogContext.put(MOBLOG_ATTACHMENTS, moblogAttachments);
649
650                         try {
651                             Blog blog = _fetcher.loadBlog(mailbox.getBlogId());
652                             String JavaDoc moblogText = mergeTemplate(MOBLOG_ENTRY_TEMPLATE, blog, moblogContext);
653
654                             Entry entry;
655                             entry = _fetcher.newEntry();
656
657                             entry.setBlogCategoryId(Integer.valueOf(categoryID));
658                             entry.setBlogId(mailbox.getId());
659                             entry.setDate(new Date());
660                             entry.setDescription(moblogText);
661                             entry.setTitle(subject);
662                             entry.setStatus(BlojsomMetaDataConstants.PUBLISHED_STATUS);
663
664                             Map entryMetaData = new HashMap();
665                             entryMetaData.put(BlojsomMetaDataConstants.BLOG_ENTRY_METADATA_AUTHOR_EXT, from);
666                             entry.setMetaData(entryMetaData);
667
668                             _fetcher.saveEntry(blog, entry);
669
670                             msgs[msgNum].setFlag(Flags.Flag.DELETED, true);
671
672                             _eventBroadcaster.broadcastEvent(new EntryAddedEvent(this, new Date(), entry, blog));
673                         } catch (FetcherException e) {
674                             if (_logger.isErrorEnabled()) {
675                                 _logger.error(e);
676                             }
677                         }
678                     }
679                 }
680
681                 // Delete the messages
682
try {
683                     if (folder != null) {
684                         folder.close(true);
685                     }
686
687                     if (store != null) {
688                         store.close();
689                     }
690                 } catch (MessagingException e) {
691                     if (_logger.isErrorEnabled()) {
692                         _logger.error(e);
693                     }
694                 }
695             } catch (ConnectException JavaDoc e) {
696                 if (_logger.isErrorEnabled()) {
697                     _logger.error(e);
698                 }
699             } catch (NoSuchProviderException e) {
700                 if (_logger.isErrorEnabled()) {
701                     _logger.error(e);
702                 }
703             } catch (MessagingException e) {
704                 if (_logger.isErrorEnabled()) {
705                     _logger.error(e);
706                 }
707             } catch (IOException e) {
708                 if (_logger.isErrorEnabled()) {
709                     _logger.error(e);
710                 }
711             } finally {
712                 try {
713                     if (folder != null && folder.isOpen()) {
714                         folder.close(true);
715                     }
716
717                     if (store != null) {
718                         store.close();
719                     }
720                 } catch (MessagingException e) {
721                     if (_logger.isErrorEnabled()) {
722                         _logger.error(e);
723                     }
724                 }
725             }
726         }
727
728         /**
729          * Process the moblog mailboxes for each user
730          */

731         public void run() {
732             try {
733                 while (!_finished) {
734                     if (_logger.isDebugEnabled()) {
735                         _logger.debug("Moblog plugin waking up and looking for new messages");
736                     }
737
738                     String JavaDoc[] blogIDs = _fetcher.loadBlogIDs();
739                     for (int i = 0; i < blogIDs.length; i++) {
740                         String JavaDoc blogID = blogIDs[i];
741                         Blog blog = _fetcher.loadBlog(blogID);
742
743                         Mailbox mailbox = MoblogPluginUtils.readMailboxSettingsForBlog( _servletConfig, blog);
744                         if (mailbox != null) {
745                             if (mailbox.isEnabled()) {
746                                 if (_logger.isDebugEnabled()) {
747                                     _logger.debug("Checking mailbox: " + mailbox.getUserId() + " for blog: " + mailbox.getBlogId());
748                                 }
749                                 processMailbox(mailbox);
750                             }
751                         }
752                     }
753
754                     if (_logger.isDebugEnabled()) {
755                         _logger.debug("Moblog plugin off to take a nap");
756                     }
757                     sleep(_pollTime * 1000);
758                 }
759             } catch (InterruptedException JavaDoc e) {
760                 if (_logger.isErrorEnabled()) {
761                     _logger.error(e);
762                 }
763             } catch (FetcherException e) {
764                 if (_logger.isErrorEnabled()) {
765                     _logger.error(e);
766                 }
767             }
768         }
769
770         /**
771          * Check to see that the sender is an authorized user to moblog
772          *
773          * @param mailbox Mailbox for user
774          * @param fromAddress E-mail address of sender
775          * @return <code>true</code> if the from address is specified as a valid poster to the moblog,
776          * <code>false</code> otherwise
777          */

778         private boolean checkSender(Mailbox mailbox, String JavaDoc fromAddress) {
779             boolean result = false;
780             Map authorizedAddresses = mailbox.getAuthorizedAddresses();
781
782             if (authorizedAddresses.containsKey(fromAddress)) {
783                 result = true;
784             }
785
786             return result;
787         }
788     }
789
790     /**
791      * Return a content type up to the first ; character
792      *
793      * @param contentType Content type
794      * @return Content type without any trailing information after a ;
795      */

796     protected String JavaDoc sanitizeContentType(String JavaDoc contentType) {
797         int semicolonIndex = contentType.indexOf(";");
798         if (semicolonIndex != -1) {
799             contentType = contentType.substring(0, semicolonIndex);
800         }
801
802         return contentType.toLowerCase();
803     }
804 }
805
Popular Tags