1
22
23 package com.liferay.portlet.mail.util;
24
25 import com.liferay.portal.kernel.servlet.HttpHeaders;
26 import com.liferay.portal.kernel.util.Constants;
27 import com.liferay.portal.kernel.util.ContentTypes;
28 import com.liferay.portal.kernel.util.GetterUtil;
29 import com.liferay.portal.kernel.util.HttpUtil;
30 import com.liferay.portal.kernel.util.ParamUtil;
31 import com.liferay.portal.kernel.util.StringMaker;
32 import com.liferay.portal.kernel.util.StringPool;
33 import com.liferay.portal.kernel.util.StringUtil;
34 import com.liferay.portal.kernel.util.Validator;
35 import com.liferay.portal.model.Company;
36 import com.liferay.portal.model.User;
37 import com.liferay.portal.service.UserLocalServiceUtil;
38 import com.liferay.portal.theme.ThemeDisplay;
39 import com.liferay.portal.util.PortalUtil;
40 import com.liferay.portal.util.PropsUtil;
41 import com.liferay.portal.util.WebKeys;
42 import com.liferay.portlet.mail.ContentException;
43 import com.liferay.portlet.mail.ContentPathException;
44 import com.liferay.portlet.mail.FolderException;
45 import com.liferay.portlet.mail.MailAccountsException;
46 import com.liferay.portlet.mail.RecipientException;
47 import com.liferay.portlet.mail.StoreException;
48 import com.liferay.portlet.mail.model.MailAttachment;
49 import com.liferay.portlet.mail.model.MailContent;
50 import com.liferay.portlet.mail.model.MailEnvelope;
51 import com.liferay.portlet.mail.model.MailFolder;
52 import com.liferay.portlet.mail.model.MailMessage;
53 import com.liferay.portlet.mail.model.RemoteMailAttachment;
54 import com.liferay.portlet.mail.search.MailDisplayTerms;
55 import com.liferay.portlet.mail.util.multiaccount.MailAccount;
56 import com.liferay.portlet.mail.util.multiaccount.MailAccounts;
57 import com.liferay.portlet.mail.util.multiaccount.MailCache;
58 import com.liferay.util.mail.JavaMailUtil;
59 import com.liferay.util.mail.MailEngine;
60 import com.liferay.util.mail.MailServerException;
61
62 import com.sun.mail.imap.IMAPFolder;
63
64 import java.io.IOException;
65
66 import java.net.SocketException;
67
68 import java.util.ArrayList;
69 import java.util.Collection;
70 import java.util.Comparator;
71 import java.util.Date;
72 import java.util.Iterator;
73 import java.util.List;
74 import java.util.ListIterator;
75 import java.util.Set;
76 import java.util.TreeSet;
77 import java.util.regex.Matcher;
78 import java.util.regex.Pattern;
79
80 import javax.activation.DataHandler;
81 import javax.activation.DataSource;
82
83 import javax.mail.Address;
84 import javax.mail.AuthenticationFailedException;
85 import javax.mail.BodyPart;
86 import javax.mail.FetchProfile;
87 import javax.mail.Flags.Flag;
88 import javax.mail.Flags;
89 import javax.mail.Folder;
90 import javax.mail.Message.RecipientType;
91 import javax.mail.Message;
92 import javax.mail.MessagingException;
93 import javax.mail.Multipart;
94 import javax.mail.Part;
95 import javax.mail.Session;
96 import javax.mail.Store;
97 import javax.mail.Transport;
98 import javax.mail.UIDFolder.FetchProfileItem;
99 import javax.mail.internet.InternetAddress;
100 import javax.mail.internet.MimeBodyPart;
101 import javax.mail.internet.MimeMessage;
102 import javax.mail.internet.MimeMultipart;
103 import javax.mail.search.AndTerm;
104 import javax.mail.search.BodyTerm;
105 import javax.mail.search.DateTerm;
106 import javax.mail.search.FromStringTerm;
107 import javax.mail.search.OrTerm;
108 import javax.mail.search.RecipientStringTerm;
109 import javax.mail.search.SearchTerm;
110 import javax.mail.search.SentDateTerm;
111 import javax.mail.search.SubjectTerm;
112 import javax.mail.util.ByteArrayDataSource;
113
114 import javax.naming.NamingException;
115
116 import javax.servlet.http.HttpServletRequest;
117 import javax.servlet.http.HttpSession;
118
119 import org.apache.commons.collections.map.MultiValueMap;
120 import org.apache.commons.logging.Log;
121 import org.apache.commons.logging.LogFactory;
122
123
132 public class MailUtil {
133
134 public static final String MAIL_BOX_STYLE =
135 PropsUtil.get(PropsUtil.MAIL_BOX_STYLE);
136
137 public static final String MAIL_INBOX_NAME =
138 PropsUtil.get(PropsUtil.MAIL_INBOX_NAME);
139
140 public static final String MAIL_DRAFTS_NAME =
141 MAIL_BOX_STYLE + PropsUtil.get(PropsUtil.MAIL_DRAFTS_NAME);
142
143 public static final String MAIL_SENT_NAME =
144 MAIL_BOX_STYLE + PropsUtil.get(PropsUtil.MAIL_SENT_NAME);
145
146 public static final String MAIL_SPAM_NAME =
147 MAIL_BOX_STYLE + PropsUtil.get(PropsUtil.MAIL_SPAM_NAME);
148
149 public static final String MAIL_TRASH_NAME =
150 MAIL_BOX_STYLE + PropsUtil.get(PropsUtil.MAIL_TRASH_NAME);
151
152 public static final String[] DEFAULT_FOLDERS = {
153 MAIL_INBOX_NAME, MAIL_DRAFTS_NAME, MAIL_SPAM_NAME, MAIL_SENT_NAME,
154 MAIL_TRASH_NAME
155 };
156
157 public static void completeMessage(
158 HttpServletRequest req, MailMessage mailMessage, boolean send,
159 String originalId, boolean wasDraft)
160 throws ContentException, ContentPathException, FolderException,
161 MailServerException, RecipientException, StoreException {
162
163 HttpSession ses = req.getSession();
164
165 try {
166 if (send && Validator.isNull(mailMessage.getTo()) &&
167 Validator.isNull(mailMessage.getCc()) &&
168 Validator.isNull(mailMessage.getBcc())) {
169
170 if (_log.isErrorEnabled()) {
171 _log.error("A message with no recipients cannot be sent");
172 }
173
174 throw new RecipientException();
175 }
176
177 Message message = new MimeMessage(MailEngine.getSession());
178
179 message.setFrom(mailMessage.getFrom());
180
181 if (Validator.isNotNull(mailMessage.getTo())) {
182 message.setRecipients(
183 Message.RecipientType.TO,
184 _resolveAddresses(req, mailMessage.getTo()));
185 }
186
187 if (Validator.isNotNull(mailMessage.getCc())) {
188 message.setRecipients(
189 Message.RecipientType.CC,
190 _resolveAddresses(req, mailMessage.getCc()));
191 }
192
193 if (Validator.isNotNull(mailMessage.getBcc())) {
194 message.setRecipients(
195 Message.RecipientType.BCC,
196 _resolveAddresses(req, mailMessage.getBcc()));
197 }
198
199 if (Validator.isNotNull(mailMessage.getInReplyTo())) {
200 message.setHeader("In-Reply-To", mailMessage.getInReplyTo());
201 }
202
203 if (Validator.isNotNull(mailMessage.getReferences())) {
204 message.setHeader("References", mailMessage.getReferences());
205 }
206
207 message.setSubject(mailMessage.getSubject());
208
209 _replaceEmbeddedImages(req, mailMessage, _getAttachmentURL(req));
210
211 Multipart multipart = new MimeMultipart();
212
213 BodyPart bodyPart = new MimeBodyPart();
214
215 bodyPart.setContent(
216 mailMessage.getBody(), ContentTypes.TEXT_HTML_UTF8);
217
218 multipart.addBodyPart(bodyPart);
219
220 List attachments = mailMessage.getAttachments();
221
222 Iterator itr = attachments.iterator();
223
224 while (itr.hasNext()) {
225 MailAttachment mailAttachment = (MailAttachment)itr.next();
226
227 DataSource dataSource = new ByteArrayDataSource(
228 mailAttachment.getContent(),
229 mailAttachment.getContentType());
230
231 BodyPart attachment = new MimeBodyPart();
232
233 attachment.setFileName(mailAttachment.getFilename());
234 attachment.setDataHandler(new DataHandler(dataSource));
235
236 if (Validator.isNotNull(mailAttachment.getContentId())) {
237 attachment.addHeader(
238 HttpHeaders.CONTENT_ID, mailAttachment.getContentId());
239 }
240
241 multipart.addBodyPart(attachment);
242 }
243
244 List remoteAttachments = mailMessage.getRemoteAttachments();
245
246 itr = remoteAttachments.iterator();
247
248 while (itr.hasNext()) {
249 RemoteMailAttachment remoteMailAttachment =
250 (RemoteMailAttachment)itr.next();
251
252 Object[] parts = getAttachment(
253 req, remoteMailAttachment.getContentPath());
254
255 DataSource dataSource = new ByteArrayDataSource(
256 (byte[])parts[0], (String)parts[1]);
257
258 BodyPart attachment = new MimeBodyPart();
259
260 attachment.setFileName(remoteMailAttachment.getFilename());
261 attachment.setDataHandler(new DataHandler(dataSource));
262
263 multipart.addBodyPart(attachment);
264 }
265
266 message.setContent(multipart);
267 message.setSentDate(new Date());
268
269 if (send) {
270 Transport.send(message);
271 }
272
273 try {
274 MailSessionLock.lock(req);
275
276 String lastFolderName = getFolderName(req);
277
278 IMAPFolder folder = null;
279
280 if (send) {
281 folder = _getFolder(req, MAIL_SENT_NAME);
282
283 message.setFlag(Flag.SEEN, true);
284 }
285 else {
286 folder = _getFolder(req, MAIL_DRAFTS_NAME);
287 }
288
289 folder.appendMessages(new Message[] {message});
290
291 long origId = GetterUtil.getLong(originalId);
292
293 if (wasDraft) {
294 folder = _getFolder(req, MAIL_DRAFTS_NAME);
295
296 Message msg = folder.getMessageByUID(origId);
297
298 folder.setFlags(
299 new Message[] {msg}, new Flags(Flags.Flag.DELETED),
300 true);
301
302 folder.expunge();
303 }
304 else if (origId > 0L) {
305 folder = _getFolder(req, lastFolderName);
306
307 Message msg =
308 folder.getMessageByUID(origId);
309
310 folder.setFlags(
311 new Message[] {msg}, new Flags(Flags.Flag.ANSWERED),
312 true);
313 }
314
315
317 _closeFolder(ses);
318
319 setFolder(req, lastFolderName);
320 }
321 finally {
322 MailSessionLock.unlock(req);
323 }
324 }
325 catch (MessagingException me) {
326 throw new ContentException(me);
327 }
328 catch (NamingException ne) {
329 throw new ContentException(ne);
330 }
331 }
332
333 public static void createFolder(HttpServletRequest req, String folderName)
334 throws FolderException, MailServerException, StoreException {
335
336 Folder folder = null;
337
338 try {
339 MailSessionLock.lock(req);
340
341 Iterator itr = getFolders(req).iterator();
342
343 while (itr.hasNext()) {
344 MailFolder mailFolder = (MailFolder)itr.next();
345
346 if (mailFolder.getName().equals(folderName)) {
347 throw new FolderException(
348 "Folder " + folderName + " already exists");
349 }
350 }
351
352 Store store = _getStore(req);
353
354 folderName = _getResolvedFolderName(folderName);
355
356 folder = store.getFolder(folderName);
357
358 folder.create(Folder.HOLDS_MESSAGES);
359 }
360 catch (MessagingException me) {
361 throw new FolderException(me);
362 }
363 finally {
364 try {
365 if ((folder != null) && folder.isOpen()) {
366 folder.close(false);
367 }
368 }
369 catch (Exception e) {
370 }
371
372 MailSessionLock.unlock(req);
373 }
374 }
375
376 public static void deleteMessages(
377 HttpServletRequest req, MultiValueMap msgMap)
378 throws FolderException, MailServerException, StoreException {
379
380 deleteMessages(req, msgMap, false);
381 }
382
383 public static void deleteMessages(
384 HttpServletRequest req, MultiValueMap msgMap, boolean permanently)
385 throws FolderException, MailServerException, StoreException {
386
387 try {
388 MailSessionLock.lock(req);
389
390 Iterator itr = msgMap.keySet().iterator();
391
392 while (itr.hasNext()) {
393 String key = (String)itr.next();
394
395 IMAPFolder folder = _getFolder(req);
396
397 String folderName = _getResolvedFolderName(folder.getName());
398
399 if (permanently || folderName.equals(MAIL_TRASH_NAME)) {
400 Message[] messages =
401 folder.getMessagesByUID(_getMessageIds(msgMap, key));
402
403 folder.setFlags(
404 messages, new Flags(Flags.Flag.DELETED), true);
405
406 folder.expunge();
407
408 msgMap.remove(key);
409 }
410 }
411
412 if (!msgMap.isEmpty()) {
413 moveMessages(req, msgMap, MAIL_TRASH_NAME);
414 }
415 }
416 catch (MessagingException me) {
417 throw new FolderException(me);
418 }
419 finally {
420 MailSessionLock.unlock(req);
421 }
422 }
423
424 public static void emptyFolder(HttpServletRequest req, String folderName)
425 throws FolderException, MailServerException, StoreException {
426
427 try {
428 MailSessionLock.lock(req);
429
430 String lastFolderName = getFolderName(req);
431
432 IMAPFolder folder = _getFolder(req, folderName);
433
434 long[] ids = new long[0];
435
436 try {
437 Message[] msgs = folder.getMessages();
438
439 FetchProfile fetchProfile = new FetchProfile();
440
441 fetchProfile.add(FetchProfile.Item.ENVELOPE);
442
443 folder.fetch(msgs, fetchProfile);
444
445 ids = new long[msgs.length];
446
447 for (int i = 0; i < msgs.length; i++) {
448 ids[i] = folder.getUID(msgs[i]);
449 }
450
451 Message[] messages = folder.getMessagesByUID(ids);
452
453 folder.setFlags(messages, new Flags(Flags.Flag.DELETED), true);
454
455 folder.expunge();
456 }
457 catch (MessagingException me) {
458 throw new FolderException(me);
459 }
460 finally {
461 setFolder(req, lastFolderName);
462 }
463 }
464 finally {
465 MailSessionLock.unlock(req);
466 }
467 }
468
469 public static Object[] getAttachment(
470 HttpServletRequest req, String contentPath)
471 throws ContentException, ContentPathException, FolderException,
472 MailServerException, StoreException {
473
474 Object[] parts = null;
475
476 try {
477 MailSessionLock.lock(req);
478
479 String[] path = RemoteMailAttachment.parsePath(contentPath);
480
481 String folderName = path[0];
482 long messageId = GetterUtil.getLong(path[1]);
483 String mimePath = path[2];
484
485 IMAPFolder folder = _getFolder(req, folderName);
486
487 Message message = folder.getMessageByUID(messageId);
488
489 parts = _getAttachmentFromPath(message, mimePath);
490 }
491 catch (ContentPathException cpe) {
492 throw cpe;
493 }
494 catch (IOException ioe) {
495 throw new ContentException(ioe);
496 }
497 catch (MessagingException me) {
498 throw new ContentException(me);
499 }
500 finally {
501 MailSessionLock.unlock(req);
502 }
503
504 return parts;
505 }
506
507 public static Set getEnvelopes(
508 HttpServletRequest req, Comparator comparator)
509 throws FolderException {
510
511 Set envelopes = new TreeSet(comparator);
512
513 try {
514 MailSessionLock.lock(req);
515
516 IMAPFolder folder = _getFolder(req);
517
518 String folderName = _getResolvedFolderName(folder.getName());
519
520 Message[] messages = folder.getMessages();
521
522 FetchProfile fetchProfile = new FetchProfile();
523
524 fetchProfile.add(IMAPFolder.FetchProfileItem.SIZE);
525 fetchProfile.add(FetchProfile.Item.ENVELOPE);
526 fetchProfile.add(FetchProfile.Item.FLAGS);
527 fetchProfile.add(FetchProfileItem.UID);
528
529 folder.fetch(messages, fetchProfile);
530
531 _convertEnvelopes(folder, folderName, messages, envelopes);
532
533 return envelopes;
534 }
535 catch (MessagingException me) {
536 throw new FolderException(me);
537 }
538 finally {
539 MailSessionLock.unlock(req);
540 }
541 }
542
543 public static MailFolder getFolder(HttpServletRequest req)
544 throws FolderException, MailServerException, MessagingException,
545 StoreException {
546
547 try {
548
549
551 _getStore(req);
552
553 MailSessionLock.lock(req);
554
555 IMAPFolder folder = _getFolder(req);
556
557 List list = new ArrayList();
558
559 _getFolders(list, new IMAPFolder[] {folder});
560
561 return (MailFolder)list.get(0);
562 }
563 finally {
564 MailSessionLock.unlock(req);
565 }
566 }
567
568 public static String getFolderName(HttpServletRequest req)
569 throws FolderException, StoreException {
570
571 try {
572 MailSessionLock.lock(req);
573
574 IMAPFolder folder = _getFolder(req);
575
576 return folder.getName();
577 }
578 finally {
579 MailSessionLock.unlock(req);
580 }
581 }
582
583 public static List getFolders(HttpServletRequest req)
584 throws FolderException, MailServerException, StoreException {
585
586 List list = new ArrayList();
587
588 IMAPFolder root = null;
589
590 try {
591 List tempList = new ArrayList();
592
593 Store store = _getStore(req);
594
595 root = (IMAPFolder)store.getDefaultFolder();
596
597 Folder[] folders = root.list();
598
599 _getFolders(tempList, folders);
600
601 for (int i = 0; i < DEFAULT_FOLDERS.length; i++) {
602 ListIterator itr = tempList.listIterator();
603
604 while (itr.hasNext()){
605 MailFolder mailFolder = (MailFolder)itr.next();
606
607 if (DEFAULT_FOLDERS[i].equals(
608 _getResolvedFolderName(mailFolder.getName()))) {
609
610 list.add(mailFolder);
611
612 itr.remove();
613
614 break;
615 }
616 }
617 }
618
619 list.addAll(tempList);
620 }
621 catch (MessagingException me) {
622 throw new FolderException(me);
623 }
624 finally {
625 try {
626 if ((root != null) && root.isOpen()) {
627 root.close(false);
628 }
629 }
630 catch (Exception ex) {
631 }
632 }
633
634 return list;
635 }
636
637 public static MailMessage getMessage(HttpServletRequest req)
638 throws ContentException, FolderException, StoreException {
639
640 try {
641 MailSessionLock.lock(req);
642
643 long messageId = getMessageId(req);
644
645 if (messageId != -1L) {
646 return getMessage(req, messageId);
647 }
648 else {
649 return null;
650 }
651 }
652 finally {
653 MailSessionLock.unlock(req);
654 }
655 }
656
657 public static MailMessage getMessage(HttpServletRequest req, long messageId)
658 throws ContentException, FolderException, StoreException {
659
660 HttpSession ses = req.getSession();
661
662 MailMessage mailMessage = new MailMessage();
663
664 try {
665 MailSessionLock.lock(req);
666
667 IMAPFolder folder = _getFolder(req);
668
669 Message message = folder.getMessageByUID(messageId);
670
671 mailMessage.setMessageId(messageId);
672
673 if (Validator.isNotNull(message.getFrom())) {
674 mailMessage.setFrom(message.getFrom()[0]);
675 }
676
677 mailMessage.setTo(message.getRecipients(RecipientType.TO));
678 mailMessage.setCc(message.getRecipients(RecipientType.CC));
679 mailMessage.setBcc(message.getRecipients(RecipientType.BCC));
680 mailMessage.setReplyTo(message.getReplyTo());
681
682 String[] messageIdHeader = message.getHeader("Message-ID");
683 String[] referencesHeader = message.getHeader("References");
684
685 if (Validator.isNotNull(messageIdHeader)) {
686 mailMessage.setInReplyTo(messageIdHeader[0]);
687
688 if (Validator.isNull(referencesHeader)) {
689 mailMessage.setReferences(messageIdHeader[0]);
690 }
691 else {
692 mailMessage.setReferences(
693 referencesHeader[0] + StringPool.SPACE +
694 messageIdHeader[0]);
695 }
696 }
697 else {
698 if (Validator.isNotNull(referencesHeader[0])) {
699 mailMessage.setReferences(referencesHeader[0]);
700 }
701 }
702
703 mailMessage.setSubject(message.getSubject());
704 mailMessage.setSentDate(message.getSentDate());
705
706 String contentPath = RemoteMailAttachment.buildContentPath(
707 folder.getName(), messageId);
708
709 MailContent content = new MailContent();
710
711 mailMessage = _getContent(
712 message, mailMessage, content, contentPath);
713
714 mailMessage.setMailContent(content);
715
716 if (_log.isDebugEnabled()) {
717 _log.debug("Body before replacing content ids\n" + content);
718 }
719
720 _replaceContentIds(
721 content, mailMessage.getRemoteAttachments(),
722 _getAttachmentURL(req));
723
724 if (_log.isDebugEnabled()) {
725 _log.debug("Body after replacing content ids\n" + content);
726 }
727
728 mailMessage.purgeDirtyRemoteAttachments();
729
730 ses.setAttribute(WebKeys.MAIL_MESSAGE_ID, new Long(messageId));
731
732 return mailMessage;
733 }
734 catch (MessagingException me) {
735 throw new FolderException(me);
736 }
737 finally {
738 MailSessionLock.unlock(req);
739 }
740 }
741
742 public static long getMessageId(HttpServletRequest req)
743 throws ContentException, FolderException, StoreException {
744
745 HttpSession ses = req.getSession();
746
747 try {
748 MailSessionLock.lock(req);
749
750 Long messageId = (Long)ses.getAttribute(WebKeys.MAIL_MESSAGE_ID);
751
752 if (messageId != null) {
753 return messageId.longValue();
754 }
755 else {
756 return -1L;
757 }
758 }
759 finally {
760 MailSessionLock.unlock(req);
761 }
762 }
763
764 public static void moveMessages(
765 HttpServletRequest req, MultiValueMap msgMap, String toFolderName)
766 throws FolderException, MailServerException, StoreException {
767
768 IMAPFolder toFolder = null;
769
770 toFolderName = _getResolvedFolderName(toFolderName);
771
772 try {
773 MailSessionLock.lock(req);
774
775 Iterator itr = msgMap.keySet().iterator();
776
777 while (itr.hasNext()) {
778 String folderName = (String)itr.next();
779
780 long[] messageIds = _getMessageIds(msgMap, folderName);
781
782 IMAPFolder folder = _getFolder(req, folderName);
783
784 folderName = _getResolvedFolderName(folder.getName());
785
786 if (folderName.equals(toFolderName)) {
787 continue;
788 }
789
790 if ((folderName.equals(MAIL_DRAFTS_NAME) ||
791 toFolderName.equals(MAIL_DRAFTS_NAME)) &&
792 (!toFolderName.equals(MAIL_TRASH_NAME))) {
793
794 continue;
795 }
796
797 Store store = _getStore(req);
798
799 toFolder = (IMAPFolder)store.getFolder(toFolderName);
800
801 toFolder.open(IMAPFolder.READ_WRITE);
802
803 Message[] messages = folder.getMessagesByUID(messageIds);
804
805 folder.copyMessages(messages, toFolder);
806
807 folder.setFlags(messages, new Flags(Flags.Flag.DELETED), true);
808
809 folder.expunge();
810 }
811 }
812 catch (MessagingException me) {
813 throw new FolderException(me);
814 }
815 finally {
816 try {
817 if ((toFolder != null) && toFolder.isOpen()) {
818 toFolder.close(true);
819 }
820 }
821 catch (Exception e) {
822 }
823
824 MailSessionLock.unlock(req);
825 }
826 }
827
828 public static void removeFolder(HttpServletRequest req, String folderName)
829 throws FolderException, MailServerException, StoreException {
830
831 try {
832 folderName = _getResolvedFolderName(folderName);
833
834 for (int i = 0; i < DEFAULT_FOLDERS.length; i++) {
835 if (DEFAULT_FOLDERS[i].equals(folderName)) {
836 if (_log.isErrorEnabled()) {
837 _log.error(
838 "Folder " + folderName +
839 " is a system folder and cannot be changed");
840 }
841
842 throw new FolderException();
843 }
844 }
845
846 try {
847 MailSessionLock.lock(req);
848
849 setFolder(req, MAIL_INBOX_NAME);
850
851 Store store = _getStore(req);
852
853 Folder folder = store.getFolder(folderName);
854
855 if (!folder.exists()) {
856 if (_log.isErrorEnabled()) {
857 _log.error("Folder " + folderName + " does not exist");
858 }
859
860 throw new FolderException();
861 }
862
863 folder.delete(true);
864 }
865 finally {
866 MailSessionLock.unlock(req);
867 }
868 }
869 catch (MessagingException me) {
870 throw new FolderException(me);
871 }
872 }
873
874 public static void renameFolder(
875 HttpServletRequest req, String oldFolderName, String newFolderName)
876 throws FolderException, MailServerException, StoreException {
877
878 try {
879 oldFolderName = _getResolvedFolderName(oldFolderName);
880 newFolderName = _getResolvedFolderName(newFolderName);
881
882 for (int i = 0; i < DEFAULT_FOLDERS.length; i++) {
883 if (DEFAULT_FOLDERS[i].equals(oldFolderName)) {
884 if (_log.isErrorEnabled()) {
885 _log.error(
886 "Folder " + oldFolderName +
887 " is a system folder and cannot be changed");
888 }
889
890 throw new FolderException();
891 }
892 else if (DEFAULT_FOLDERS[i].equals(newFolderName)) {
893 if (_log.isErrorEnabled()) {
894 _log.error(
895 "Folder " + newFolderName +
896 " is a system folder and cannot be changed");
897 }
898
899 throw new FolderException();
900 }
901 }
902
903 try {
904 MailSessionLock.lock(req);
905
906 setFolder(req, MAIL_INBOX_NAME);
907
908 Store store = _getStore(req);
909
910 Folder oldFolder = store.getFolder(oldFolderName);
911 Folder newFolder = store.getFolder(newFolderName);
912
913 if (!oldFolder.exists()) {
914 if (_log.isErrorEnabled()) {
915 _log.error(
916 "Folder " + oldFolderName + " does not exist");
917 }
918
919 throw new FolderException();
920 }
921 else if (newFolder.exists()) {
922 if (_log.isErrorEnabled()) {
923 _log.error(
924 "Folder " + newFolderName + " already exists");
925 }
926
927 throw new FolderException();
928 }
929
930 oldFolder.renameTo(newFolder);
931 }
932 finally {
933 MailSessionLock.unlock(req);
934 }
935 }
936 catch (MessagingException me) {
937 throw new FolderException(me);
938 }
939 }
940
941 public static Set search(
942 HttpServletRequest req, MailDisplayTerms displayTerms,
943 Comparator comparator)
944 throws FolderException, MailServerException, StoreException {
945
946 Set results = new TreeSet(comparator);
947
948 if (Validator.isNotNull(displayTerms.getFolderName())) {
949 _search(req, displayTerms, results);
950 }
951 else {
952 List folders = getFolders(req);
953
954 Iterator itr = folders.iterator();
955
956 while (itr.hasNext()) {
957 MailFolder mailFolder = (MailFolder)itr.next();
958
959 String resolvedName =
960 _getResolvedFolderName(mailFolder.getName());
961
962 if (resolvedName.equals(MAIL_SPAM_NAME) ||
963 resolvedName.equals(MAIL_TRASH_NAME)) {
964
965 continue;
966 }
967
968 displayTerms.setFolderName(mailFolder.getName());
969
970 _search(req, displayTerms, results);
971 }
972 }
973
974 return results;
975 }
976
977 public static void setAccount(HttpServletRequest req) {
978 String accountName = ParamUtil.getString(req, Constants.MAIL_ACCOUNT);
979
980 try {
981 if (Validator.isNotNull(accountName)) {
982 MailAccounts.setAccount(req, accountName);
983 }
984 }
985 catch (MailAccountsException e) {
986 if (_log.isWarnEnabled()) {
987 _log.warn("Error setting account " + accountName, e);
988 }
989 }
990 }
991
992 public static void setFolder(HttpServletRequest req, String folderName)
993 throws FolderException, MailServerException, StoreException {
994
995 try {
996 MailSessionLock.lock(req);
997
998 _getFolder(req, folderName);
999 }
1000 finally {
1001 MailSessionLock.unlock(req);
1002 }
1003 }
1004
1005 public static void setMessageId(HttpServletRequest req, long messageId) {
1006 HttpSession ses = req.getSession();
1007
1008 ses.setAttribute(WebKeys.MAIL_MESSAGE_ID, new Long(messageId));
1009 }
1010
1011 protected static void cleanUp(HttpSession ses) throws StoreException {
1012 try {
1013 _closeFolder(ses);
1014
1015 MailCache.clearCache(ses);
1016
1017 ses.removeAttribute(WebKeys.MAIL_MESSAGE_ID);
1018 }
1019 catch (MessagingException me) {
1020 throw new StoreException(me);
1021 }
1022 }
1023
1024 private static SearchTerm _appendSearchTerm(
1025 SearchTerm fullTerm, SearchTerm term, boolean isAndOperator) {
1026
1027 if (fullTerm == null) {
1028 return term;
1029 }
1030
1031 if (isAndOperator) {
1032 return new AndTerm(fullTerm, term);
1033 }
1034 else {
1035 return new OrTerm(fullTerm, term);
1036 }
1037 }
1038
1039 private static void _closeFolder(HttpSession ses) {
1040 IMAPFolder folder = (IMAPFolder)ses.getAttribute(WebKeys.MAIL_FOLDER);
1041
1042 if ((folder != null) && folder.isOpen()) {
1043 try {
1044 folder.close(false);
1045 }
1046 catch (MessagingException me) {
1047 if (_log.isWarnEnabled()) {
1048 _log.warn(me);
1049 }
1050 }
1051
1052 ses.removeAttribute(WebKeys.MAIL_FOLDER);
1053 }
1054 }
1055
1056 private static void _convertEnvelopes(
1057 IMAPFolder folder, String folderName, Message[] messages,
1058 Set envelopes)
1059 throws MessagingException {
1060
1061 for (int i = 0; i < messages.length; i++) {
1062 Message message = messages[i];
1063
1064 if (message.isExpunged()) {
1065 continue;
1066 }
1067
1068 MailEnvelope mailEnvelope = new MailEnvelope();
1069
1070 mailEnvelope.setMessageId(folder.getUID(message));
1071 mailEnvelope.setFolderName(folder.getName());
1072
1073 if (MAIL_SENT_NAME.equals(folderName) ||
1074 MAIL_DRAFTS_NAME.equals(folderName)) {
1075
1076 Address[] recipients = message.getAllRecipients();
1077
1078 StringMaker sm = new StringMaker();
1079
1080 if (Validator.isNotNull(recipients)) {
1081 for (int j = 0; j < recipients.length; j++) {
1082 InternetAddress address =
1083 (InternetAddress)recipients[j];
1084
1085 String recipient = GetterUtil.getString(
1086 address.getPersonal(), address.getAddress());
1087
1088 sm.append(recipient);
1089
1090 if (j < (recipients.length - 1)) {
1091 sm.append(", ");
1092 }
1093 }
1094 }
1095
1096 if (sm.length() > 0) {
1097 mailEnvelope.setRecipient(sm.toString());
1098 }
1099 }
1100 else {
1101 Address[] from = message.getFrom();
1102
1103 if (Validator.isNotNull(from)) {
1104 InternetAddress address = (InternetAddress)from[0];
1105
1106 String recipient = GetterUtil.getString(
1107 address.getPersonal(), address.getAddress());
1108
1109 mailEnvelope.setRecipient(recipient);
1110 }
1111 }
1112
1113 mailEnvelope.setSubject(message.getSubject());
1114 mailEnvelope.setDate(message.getSentDate());
1115 mailEnvelope.setSize(
1116 (int)(message.getSize() * _ENCODING_FACTOR));
1117 mailEnvelope.setRead(message.isSet(Flag.SEEN));
1118 mailEnvelope.setFlagged(message.isSet(Flag.FLAGGED));
1119 mailEnvelope.setAnswered(message.isSet(Flag.ANSWERED));
1120
1121 envelopes.add(mailEnvelope);
1122 }
1123 }
1124
1125 private static Store _createStore(
1126 HttpServletRequest req, MailAccount account)
1127 throws FolderException, MailServerException, MessagingException,
1128 NamingException, StoreException {
1129
1130 HttpSession ses = req.getSession();
1131
1132 Session session = MailEngine.getSession();
1133
1134 Store store = session.getStore("imap");
1135
1136 String serviceName =
1137 account.getUserId() + StringPool.COLON + WebKeys.MAIL_STORE;
1138
1139 store.addConnectionListener(new ConnectionListener(serviceName));
1140
1141 String imapHost = session.getProperty("mail.imap.host");
1142
1143 store.connect(imapHost, account.getUserId(), account.getPassword());
1144
1145 MailCache.putStore(ses, account.getName(), store);
1146
1147 List list = getFolders(req);
1148
1149 for (int i = 0; i < DEFAULT_FOLDERS.length; i++) {
1150 boolean exists = false;
1151
1152 Iterator itr = list.iterator();
1153
1154 while (itr.hasNext()) {
1155 MailFolder mailFolder = (MailFolder)itr.next();
1156
1157 if (DEFAULT_FOLDERS[i].equals(mailFolder.getName())) {
1158 exists = true;
1159
1160 break;
1161 }
1162 }
1163
1164 if (!exists) {
1165 createFolder(req, DEFAULT_FOLDERS[i]);
1166 }
1167 }
1168
1169 if (ses.getAttribute(WebKeys.MAIL_FOLDER) == null) {
1170 setFolder(req, MAIL_INBOX_NAME);
1171 }
1172
1173 return store;
1174 }
1175
1176 private static String _customizeHtml(String html) {
1177 for (int i = 0; i < _HTML_START_TAGS.length; i++) {
1178 Pattern startPattern = Pattern.compile(
1179 _HTML_START_TAGS[i], Pattern.CASE_INSENSITIVE);
1180
1181 Matcher startMatcher = startPattern.matcher(html);
1182
1183 while (startMatcher.find()) {
1184 int start = startMatcher.start();
1185 int end = html.indexOf(">", start);
1186
1187 if (end == -1) {
1188 html = StringUtil.replace(
1189 html, html.substring(start), StringPool.BLANK);
1190 }
1191 else {
1192 html = StringUtil.replace(
1193 html, html.substring(start, end + 1), StringPool.BLANK);
1194 }
1195
1196 if (i < _HTML_END_TAGS.length) {
1197 Pattern endPattern = Pattern.compile(
1198 _HTML_END_TAGS[i], Pattern.CASE_INSENSITIVE);
1199
1200 Matcher endMatcher = endPattern.matcher(html);
1201
1202 html = endMatcher.replaceFirst(StringPool.BLANK);
1203 }
1204 else {
1205 startMatcher.reset(html);
1206 }
1207 }
1208 }
1209
1210 return html.trim();
1211 }
1212
1213 private static Object[] _getAttachmentFromPath(Part part, String mimePath)
1214 throws ContentPathException, IOException, MessagingException {
1215
1216 int index = GetterUtil.getInteger(
1217 StringUtil.split(mimePath.substring(1), StringPool.PERIOD)[0]);
1218
1219 if (part.getContent() instanceof Multipart) {
1220 String prefix = String.valueOf(index) + StringPool.PERIOD;
1221
1222 Multipart multipart = (Multipart)part.getContent();
1223
1224 for (int i = 0; i < multipart.getCount(); i++) {
1225 if (index == i) {
1226 return _getAttachmentFromPath(
1227 multipart.getBodyPart(i),
1228 mimePath.substring(prefix.length()));
1229 }
1230 }
1231
1232 throw new ContentPathException();
1233 }
1234 else if (index != -1) {
1235 throw new ContentPathException();
1236 }
1237
1238 byte[] byteArray = JavaMailUtil.getBytes(part);
1239
1240 return new Object[] {byteArray, part.getContentType()};
1241 }
1242
1243 private static String _getAttachmentURL(HttpServletRequest req) {
1244 ThemeDisplay themeDisplay =
1245 (ThemeDisplay)req.getAttribute(WebKeys.THEME_DISPLAY);
1246
1247 return themeDisplay.getPathMain() + "/mail/get_attachment?";
1248 }
1249
1250 private static MailMessage _getContent(
1251 Part part, MailMessage mailMessage, MailContent content,
1252 String contentPath)
1253 throws ContentException {
1254
1255 try {
1256 String contentType = part.getContentType().toLowerCase();
1257
1258 boolean attachment = true;
1259
1260 if (part.getContent() instanceof Multipart) {
1261 attachment = false;
1262
1263 Multipart multipart = (Multipart)part.getContent();
1264
1265 for (int i = 0; i < multipart.getCount(); i++) {
1266 Part curPart = multipart.getBodyPart(i);
1267
1268 mailMessage = _getContent(
1269 curPart, mailMessage, content,
1270 contentPath + StringPool.PERIOD + i);
1271 }
1272 }
1273 else if (Validator.isNull(part.getFileName())) {
1274 attachment = false;
1275
1276 if (contentType.startsWith(ContentTypes.TEXT_PLAIN)) {
1277 content.appendPlainBody((String)part.getContent());
1278 }
1279 else if (contentType.startsWith(ContentTypes.TEXT_HTML)) {
1280 content.appendHtmlBody(
1281 _customizeHtml((String)part.getContent()));
1282 }
1283 else if (contentType.startsWith(ContentTypes.MESSAGE_RFC822)) {
1284 MailContent subContent = new MailContent();
1285
1286 mailMessage = _getContent(
1287 (Part)part.getContent(), mailMessage, subContent,
1288 contentPath + StringPool.PERIOD + 0);
1289
1290 content.appendSubContent(subContent);
1291 }
1292 }
1293
1294 if (attachment) {
1295 mailMessage.appendRemoteAttachment(
1296 _getRemoteAttachment(
1297 part, contentPath + StringPool.PERIOD + -1));
1298 }
1299 }
1300 catch (IOException ioe) {
1301 throw new ContentException(ioe);
1302 }
1303 catch (MessagingException me) {
1304 throw new ContentException(me);
1305 }
1306
1307 return mailMessage;
1308 }
1309
1310 private static IMAPFolder _getFolder(HttpServletRequest req)
1311 throws FolderException {
1312
1313 HttpSession ses = req.getSession();
1314
1315 IMAPFolder folder = (IMAPFolder)ses.getAttribute(WebKeys.MAIL_FOLDER);
1316
1317 if (folder != null) {
1318 return folder;
1319 }
1320 else {
1321 throw new FolderException();
1322 }
1323 }
1324
1325 private static IMAPFolder _getFolder(
1326 HttpServletRequest req, String folderName)
1327 throws FolderException, MailServerException, StoreException {
1328
1329 HttpSession ses = req.getSession();
1330
1331 try {
1332 folderName = _getResolvedFolderName(folderName);
1333
1334 IMAPFolder folder = (IMAPFolder)ses.getAttribute(
1335 WebKeys.MAIL_FOLDER);
1336
1337 if (folder != null) {
1338 String currFolderName =
1339 _getResolvedFolderName(folder.getName());
1340
1341 if (!currFolderName.equals(folderName)) {
1342 _closeFolder(ses);
1343
1344 folder = null;
1345 }
1346 else if (!folder.isOpen()) {
1347 if (_log.isInfoEnabled()) {
1348 _log.info(
1349 "The folder is closed and needs to be reopened");
1350 }
1351
1352 _closeFolder(ses);
1353
1354 folder = null;
1355 }
1356 }
1357
1358 if (folder == null) {
1359 Long userIdObj = (Long)ses.getAttribute(WebKeys.USER_ID);
1360
1361 String serviceName = userIdObj + StringPool.COLON +
1362 WebKeys.MAIL_FOLDER + StringPool.PERIOD + folderName;
1363
1364 Store store = _getStore(req);
1365
1366 folder = (IMAPFolder)store.getFolder(folderName);
1367
1368 folder.addConnectionListener(
1369 new ConnectionListener(serviceName));
1370
1371 folder.open(IMAPFolder.READ_WRITE);
1372
1373 ses.setAttribute(WebKeys.MAIL_FOLDER, folder);
1374
1375 ses.removeAttribute(WebKeys.MAIL_MESSAGE_ID);
1376 }
1377
1378 return folder;
1379 }
1380 catch (MessagingException me) {
1381 throw new FolderException(me);
1382 }
1383 }
1384
1385 private static void _getFolders(List list, Folder[] folders) {
1386 for (int i = 0; i < folders.length; i++) {
1387 Folder folder = folders[i];
1388
1389 try {
1390 int folderType = folder.getType();
1391
1392 if ((folderType & IMAPFolder.HOLDS_MESSAGES) != 0) {
1393 MailFolder mailFolder = new MailFolder(
1394 folder.getName(), folder.getMessageCount(),
1395 folder.getUnreadMessageCount());
1396
1397 list.add(mailFolder);
1398 }
1399
1400 if ((folderType & IMAPFolder.HOLDS_FOLDERS) != 0) {
1401 _getFolders(list, folder.list());
1402 }
1403 }
1404 catch (MessagingException me) {
1405 _log.error("Skipping IMAP folder because " + me.getMessage());
1406 }
1407 }
1408 }
1409
1410 private static long[] _getMessageIds(
1411 MultiValueMap msgMap, String folderName) {
1412
1413 Collection messages = msgMap.getCollection(folderName);
1414
1415 long[] messageIds = new long[messages.size()];
1416
1417 Iterator msgItr = messages.iterator();
1418
1419 for (int i = 0; msgItr.hasNext(); i++) {
1420 messageIds[i] = GetterUtil.getLong((String)msgItr.next());
1421 }
1422
1423 return messageIds;
1424 }
1425
1426 private static RemoteMailAttachment _getRemoteAttachment(
1427 Part part, String contentPath)
1428 throws ContentException {
1429
1430 RemoteMailAttachment remoteMailAttachment = new RemoteMailAttachment();
1431
1432 try {
1433 remoteMailAttachment.setFilename(part.getFileName());
1434 remoteMailAttachment.setContentPath(contentPath);
1435
1436 String[] contentId = part.getHeader(HttpHeaders.CONTENT_ID);
1437
1438 if ((contentId != null) && (contentId.length == 1)) {
1439 remoteMailAttachment.setContentId(contentId[0]);
1440 }
1441 }
1442 catch (MessagingException me) {
1443 if (_log.isErrorEnabled()) {
1444 _log.error(
1445 "Unable to properly get file name of MIME attachment");
1446 }
1447
1448 throw new ContentException(me);
1449 }
1450
1451 return remoteMailAttachment;
1452 }
1453
1454 private static String _getResolvedFolderName(String folderName) {
1455 String resolvedName = folderName;
1456
1457 if (Validator.isNull(folderName)) {
1458 resolvedName = MAIL_INBOX_NAME;
1459 }
1460 else if (!folderName.equals(MAIL_INBOX_NAME) &&
1461 !folderName.startsWith(MAIL_BOX_STYLE)) {
1462
1463 resolvedName = MAIL_BOX_STYLE + folderName;
1464 }
1465
1466 return resolvedName;
1467 }
1468
1469 private static Store _getStore(HttpServletRequest req)
1470 throws FolderException, MailServerException, StoreException {
1471
1472 HttpSession ses = req.getSession();
1473
1474 MailAccount currentAccount = MailAccounts.getCurrentAccount(req);
1475
1476 try {
1477 Store store = MailCache.getStore(ses, currentAccount.getName());
1478
1479 if (store != null && !store.isConnected()) {
1480 if (_log.isInfoEnabled()) {
1481 _log.info("The store needs to be reconnected");
1482 }
1483
1484 cleanUp(ses);
1485
1486 store = null;
1487 }
1488
1489 if (store == null) {
1490 store = _createStore(req, currentAccount);
1491 }
1492
1493 return store;
1494 }
1495 catch (AuthenticationFailedException afe) {
1496 _log.error(
1497 "Failed to authenticate the userId " +
1498 currentAccount.getUserId());
1499
1500 throw new StoreException(afe);
1501 }
1502 catch (MessagingException me) {
1503 Exception e = me.getNextException();
1504
1505 if (e instanceof SocketException) {
1506 if (_log.isWarnEnabled()) {
1507 _log.warn(
1508 "Failed to connect to a valid mail server. Please " +
1509 "make sure one is properly configured.");
1510 }
1511
1512 throw new MailServerException(e);
1513 }
1514 else {
1515 throw new StoreException(me);
1516 }
1517 }
1518 catch (NamingException ne) {
1519 throw new StoreException(ne);
1520 }
1521 }
1522
1523 private static void _replaceContentIds(
1524 MailContent content, List rmas, String url) {
1525
1526 String body = content.getHtmlBody();
1527
1528 for (int i = 0; i < rmas.size(); i++) {
1529 RemoteMailAttachment rma = (RemoteMailAttachment)rmas.get(i);
1530
1531 if (Validator.isNotNull(rma.getContentId())) {
1532 String contentId = rma.getContentId();
1533
1534 if (contentId.startsWith(StringPool.LESS_THAN) &&
1535 contentId.endsWith(StringPool.GREATER_THAN)) {
1536
1537 contentId =
1538 "cid:" + contentId.substring(1, contentId.length() - 1);
1539 }
1540
1541 String remotePath =
1542 url + "fileName=" + rma.getFilename() + "&contentPath=" +
1543 rma.getContentPath();
1544
1545 body = StringUtil.replace(body, contentId, remotePath);
1546
1547 rma.setDirty(true);
1548 }
1549 }
1550
1551 content.setHtmlBody(body);
1552
1553 for (int i = 0; i < content.getSubContent().size(); i++) {
1554 _replaceContentIds(
1555 (MailContent)content.getSubContent().get(i), rmas, url);
1556 }
1557 }
1558
1559 private static void _replaceEmbeddedImages(
1560 HttpServletRequest req, MailMessage mailMessage, String url)
1561 throws ContentException, ContentPathException, FolderException,
1562 MailServerException, StoreException {
1563
1564 HttpSession ses = req.getSession();
1565
1566 String prefix = ses.getId() + System.currentTimeMillis();
1567
1568 int count = 0;
1569
1570 String body = mailMessage.getBody();
1571
1572 if (_log.isDebugEnabled()) {
1573 _log.debug("Body before replacing embedded images\n" + body);
1574 }
1575
1576 int x = body.indexOf(url);
1577
1578 while (x >= 0) {
1579 int y = body.indexOf("-1", x);
1580
1581 if (y > 0) {
1582 y += 2;
1583
1584 String attachmentPath = body.substring(x, y);
1585
1586 String fileName = HttpUtil.getParameter(
1587 attachmentPath, "fileName");
1588 String contentPath = HttpUtil.getParameter(
1589 attachmentPath, "contentPath");
1590
1591 String contentId = prefix + count;
1592
1593 Object[] parts = getAttachment(req, contentPath);
1594
1595 MailAttachment mailAttachment = new MailAttachment();
1596
1597 mailAttachment.setFilename(fileName);
1598 mailAttachment.setContent((byte[])parts[0]);
1599 mailAttachment.setContentType((String)parts[1]);
1600 mailAttachment.setContentId(
1601 StringPool.LESS_THAN + contentId + StringPool.GREATER_THAN);
1602
1603 mailMessage.appendAttachment(mailAttachment);
1604
1605 body = StringUtil.replace(
1606 body, attachmentPath, "cid:" + contentId);
1607
1608 count++;
1609
1610 x = body.indexOf(url);
1611 }
1612 else {
1613 x = body.indexOf(url, x + 1);
1614 }
1615 }
1616
1617 if (count > 0) {
1618 mailMessage.setBody(body);
1619 }
1620
1621 if (_log.isDebugEnabled()) {
1622 _log.debug("Body after replacing embedded images\n" + body);
1623 }
1624 }
1625
1626 private static Address[] _resolveAddresses(
1627 HttpServletRequest req, Address[] addresses)
1628 throws RecipientException {
1629
1630 Company company = null;
1631
1632 try {
1633 company = PortalUtil.getCompany(req);
1634 }
1635 catch (Exception e) {
1636 return addresses;
1637 }
1638
1639 for (int i = 0; i < addresses.length; i++) {
1640 InternetAddress address = (InternetAddress)addresses[i];
1641
1642 if ((address.getPersonal() == null) &&
1643 !Validator.isEmailAddress(address.getAddress())) {
1644
1645 try {
1646 User user = UserLocalServiceUtil.getUserByEmailAddress(
1647 company.getCompanyId(), address.getAddress().trim() +
1648 StringPool.AT + company.getMx());
1649
1650 addresses[i] = new InternetAddress(
1651 user.getEmailAddress(), user.getFullName());
1652 }
1653 catch (Exception e) {
1654 if (_log.isErrorEnabled()) {
1655 _log.error(
1656 "Problems found trying to resolve email address " +
1657 address);
1658 }
1659
1660 throw new RecipientException(e);
1661 }
1662 }
1663 }
1664
1665 return addresses;
1666 }
1667
1668 private static void _search(
1669 HttpServletRequest req, MailDisplayTerms displayTerms, Set results)
1670 throws FolderException, MailServerException, StoreException {
1671
1672 Store store = _getStore(req);
1673
1674 SearchTerm fullTerm = null;
1675
1676 if (Validator.isNotNull(displayTerms.getFrom())) {
1677 fullTerm = new FromStringTerm(displayTerms.getFrom());
1678 }
1679
1680 if (Validator.isNotNull(displayTerms.getTo())) {
1681 SearchTerm to = new RecipientStringTerm(
1682 Message.RecipientType.TO, displayTerms.getTo());
1683 SearchTerm cc = new RecipientStringTerm(
1684 Message.RecipientType.CC, displayTerms.getTo());
1685 SearchTerm bcc = new RecipientStringTerm(
1686 Message.RecipientType.BCC, displayTerms.getTo());
1687
1688 SearchTerm term = to;
1689 term = _appendSearchTerm(term, cc, false);
1690 term = _appendSearchTerm(term, bcc, false);
1691
1692 fullTerm = _appendSearchTerm(
1693 fullTerm, term, displayTerms.isAndOperator());
1694 }
1695
1696 if (Validator.isNotNull(displayTerms.getSubject())) {
1697 SearchTerm term = new SubjectTerm(displayTerms.getSubject());
1698
1699 fullTerm = _appendSearchTerm(
1700 fullTerm, term, displayTerms.isAndOperator());
1701 }
1702
1703 if (Validator.isNotNull(displayTerms.getEntireMessage())) {
1704 String em = displayTerms.getEntireMessage();
1705
1706 SearchTerm from = new FromStringTerm(em);
1707 SearchTerm to = new RecipientStringTerm(
1708 Message.RecipientType.TO, em);
1709 SearchTerm cc = new RecipientStringTerm(
1710 Message.RecipientType.CC, em);
1711 SearchTerm bcc = new RecipientStringTerm(
1712 Message.RecipientType.BCC, em);
1713 SearchTerm subject = new SubjectTerm(em);
1714 SearchTerm body = new BodyTerm(em);
1715
1716 SearchTerm term = from;
1717 term = _appendSearchTerm(term, to, false);
1718 term = _appendSearchTerm(term, cc, false);
1719 term = _appendSearchTerm(term, bcc, false);
1720 term = _appendSearchTerm(term, subject, false);
1721 term = _appendSearchTerm(term, body, false);
1722
1723 fullTerm = _appendSearchTerm(
1724 fullTerm, term, displayTerms.isAndOperator());
1725 }
1726
1727 if (displayTerms.hasDate()) {
1728 SearchTerm startDate =
1729 new SentDateTerm(DateTerm.GE, displayTerms.getStartDate());
1730 SearchTerm endDate =
1731 new SentDateTerm(DateTerm.LE, displayTerms.getEndDate());
1732
1733 SearchTerm term = startDate;
1734 term = _appendSearchTerm(term, endDate, true);
1735
1736 fullTerm = _appendSearchTerm(
1737 fullTerm, term, displayTerms.isAndOperator());
1738 }
1739
1740 if (fullTerm != null) {
1741 try {
1742 IMAPFolder folder = (IMAPFolder)store.getFolder(
1743 _getResolvedFolderName(displayTerms.getFolderName()));
1744
1745 folder.open(IMAPFolder.READ_ONLY);
1746
1747 Message[] messages = folder.search(fullTerm);
1748
1749 _convertEnvelopes(
1750 folder, displayTerms.getFolderName(), messages, results);
1751 }
1752 catch (MessagingException me) {
1753 throw new FolderException(me);
1754 }
1755 }
1756 }
1757
1758 private static final String[] _HTML_START_TAGS = new String[] {
1759 "<html", "<head", "<body", "<meta", "<o:SmartTagType"
1760 };
1761
1762 private static final String[] _HTML_END_TAGS = new String[] {
1763 "</html>", "</head>", "</body>"
1764 };
1765
1766 private static final double _ENCODING_FACTOR = 0.65;
1767
1768 private static Log _log = LogFactory.getLog(MailUtil.class);
1769
1770}