0001: /**
0002: * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
0003: *
0004: * Permission is hereby granted, free of charge, to any person obtaining a copy
0005: * of this software and associated documentation files (the "Software"), to deal
0006: * in the Software without restriction, including without limitation the rights
0007: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
0008: * copies of the Software, and to permit persons to whom the Software is
0009: * furnished to do so, subject to the following conditions:
0010: *
0011: * The above copyright notice and this permission notice shall be included in
0012: * all copies or substantial portions of the Software.
0013: *
0014: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
0017: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0018: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
0019: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
0020: * SOFTWARE.
0021: */package com.liferay.portlet.mail.util;
0022:
0023: import com.liferay.portal.kernel.servlet.HttpHeaders;
0024: import com.liferay.portal.kernel.util.Constants;
0025: import com.liferay.portal.kernel.util.ContentTypes;
0026: import com.liferay.portal.kernel.util.GetterUtil;
0027: import com.liferay.portal.kernel.util.ParamUtil;
0028: import com.liferay.portal.kernel.util.StringMaker;
0029: import com.liferay.portal.kernel.util.StringPool;
0030: import com.liferay.portal.kernel.util.StringUtil;
0031: import com.liferay.portal.kernel.util.Validator;
0032: import com.liferay.portal.model.Company;
0033: import com.liferay.portal.model.User;
0034: import com.liferay.portal.service.UserLocalServiceUtil;
0035: import com.liferay.portal.theme.ThemeDisplay;
0036: import com.liferay.portal.util.PortalUtil;
0037: import com.liferay.portal.util.PropsUtil;
0038: import com.liferay.portal.util.WebKeys;
0039: import com.liferay.portlet.mail.ContentException;
0040: import com.liferay.portlet.mail.ContentPathException;
0041: import com.liferay.portlet.mail.FolderException;
0042: import com.liferay.portlet.mail.MailAccountsException;
0043: import com.liferay.portlet.mail.RecipientException;
0044: import com.liferay.portlet.mail.StoreException;
0045: import com.liferay.portlet.mail.model.MailAttachment;
0046: import com.liferay.portlet.mail.model.MailContent;
0047: import com.liferay.portlet.mail.model.MailEnvelope;
0048: import com.liferay.portlet.mail.model.MailFolder;
0049: import com.liferay.portlet.mail.model.MailMessage;
0050: import com.liferay.portlet.mail.model.RemoteMailAttachment;
0051: import com.liferay.portlet.mail.search.MailDisplayTerms;
0052: import com.liferay.portlet.mail.util.multiaccount.MailAccount;
0053: import com.liferay.portlet.mail.util.multiaccount.MailAccounts;
0054: import com.liferay.portlet.mail.util.multiaccount.MailCache;
0055: import com.liferay.util.Http;
0056: import com.liferay.util.mail.JavaMailUtil;
0057: import com.liferay.util.mail.MailEngine;
0058: import com.liferay.util.mail.MailServerException;
0059:
0060: import com.sun.mail.imap.IMAPFolder;
0061:
0062: import java.io.IOException;
0063:
0064: import java.net.SocketException;
0065:
0066: import java.util.ArrayList;
0067: import java.util.Collection;
0068: import java.util.Comparator;
0069: import java.util.Date;
0070: import java.util.Iterator;
0071: import java.util.List;
0072: import java.util.ListIterator;
0073: import java.util.Set;
0074: import java.util.TreeSet;
0075: import java.util.regex.Matcher;
0076: import java.util.regex.Pattern;
0077:
0078: import javax.activation.DataHandler;
0079: import javax.activation.DataSource;
0080:
0081: import javax.mail.Address;
0082: import javax.mail.AuthenticationFailedException;
0083: import javax.mail.BodyPart;
0084: import javax.mail.FetchProfile;
0085: import javax.mail.Flags.Flag;
0086: import javax.mail.Flags;
0087: import javax.mail.Folder;
0088: import javax.mail.Message.RecipientType;
0089: import javax.mail.Message;
0090: import javax.mail.MessagingException;
0091: import javax.mail.Multipart;
0092: import javax.mail.Part;
0093: import javax.mail.Session;
0094: import javax.mail.Store;
0095: import javax.mail.Transport;
0096: import javax.mail.UIDFolder.FetchProfileItem;
0097: import javax.mail.internet.InternetAddress;
0098: import javax.mail.internet.MimeBodyPart;
0099: import javax.mail.internet.MimeMessage;
0100: import javax.mail.internet.MimeMultipart;
0101: import javax.mail.search.AndTerm;
0102: import javax.mail.search.BodyTerm;
0103: import javax.mail.search.DateTerm;
0104: import javax.mail.search.FromStringTerm;
0105: import javax.mail.search.OrTerm;
0106: import javax.mail.search.RecipientStringTerm;
0107: import javax.mail.search.SearchTerm;
0108: import javax.mail.search.SentDateTerm;
0109: import javax.mail.search.SubjectTerm;
0110: import javax.mail.util.ByteArrayDataSource;
0111:
0112: import javax.naming.NamingException;
0113:
0114: import javax.servlet.http.HttpServletRequest;
0115: import javax.servlet.http.HttpSession;
0116:
0117: import org.apache.commons.collections.map.MultiValueMap;
0118: import org.apache.commons.logging.Log;
0119: import org.apache.commons.logging.LogFactory;
0120:
0121: /**
0122: * Used as a fascade to the JavaMail API. All JavaMail objects are wrappered in
0123: * model classes and returned out of this utility fascade.
0124: *
0125: * <a href="MailUtil.java.html"><b><i>View Source</i></b></a>
0126: *
0127: * @author Alexander Chow
0128: *
0129: */
0130: public class MailUtil {
0131:
0132: public static final String MAIL_BOX_STYLE = PropsUtil
0133: .get(PropsUtil.MAIL_BOX_STYLE);
0134:
0135: public static final String MAIL_INBOX_NAME = PropsUtil
0136: .get(PropsUtil.MAIL_INBOX_NAME);
0137:
0138: public static final String MAIL_DRAFTS_NAME = MAIL_BOX_STYLE
0139: + PropsUtil.get(PropsUtil.MAIL_DRAFTS_NAME);
0140:
0141: public static final String MAIL_SENT_NAME = MAIL_BOX_STYLE
0142: + PropsUtil.get(PropsUtil.MAIL_SENT_NAME);
0143:
0144: public static final String MAIL_SPAM_NAME = MAIL_BOX_STYLE
0145: + PropsUtil.get(PropsUtil.MAIL_SPAM_NAME);
0146:
0147: public static final String MAIL_TRASH_NAME = MAIL_BOX_STYLE
0148: + PropsUtil.get(PropsUtil.MAIL_TRASH_NAME);
0149:
0150: public static final String[] DEFAULT_FOLDERS = { MAIL_INBOX_NAME,
0151: MAIL_DRAFTS_NAME, MAIL_SPAM_NAME, MAIL_SENT_NAME,
0152: MAIL_TRASH_NAME };
0153:
0154: public static void completeMessage(HttpServletRequest req,
0155: MailMessage mailMessage, boolean send, String originalId,
0156: boolean wasDraft) throws ContentException,
0157: ContentPathException, FolderException, MailServerException,
0158: RecipientException, StoreException {
0159:
0160: HttpSession ses = req.getSession();
0161:
0162: try {
0163: if (send && Validator.isNull(mailMessage.getTo())
0164: && Validator.isNull(mailMessage.getCc())
0165: && Validator.isNull(mailMessage.getBcc())) {
0166:
0167: if (_log.isErrorEnabled()) {
0168: _log
0169: .error("A message with no recipients cannot be sent");
0170: }
0171:
0172: throw new RecipientException();
0173: }
0174:
0175: Message message = new MimeMessage(MailEngine.getSession());
0176:
0177: message.setFrom(mailMessage.getFrom());
0178:
0179: if (Validator.isNotNull(mailMessage.getTo())) {
0180: message.setRecipients(Message.RecipientType.TO,
0181: _resolveAddresses(req, mailMessage.getTo()));
0182: }
0183:
0184: if (Validator.isNotNull(mailMessage.getCc())) {
0185: message.setRecipients(Message.RecipientType.CC,
0186: _resolveAddresses(req, mailMessage.getCc()));
0187: }
0188:
0189: if (Validator.isNotNull(mailMessage.getBcc())) {
0190: message.setRecipients(Message.RecipientType.BCC,
0191: _resolveAddresses(req, mailMessage.getBcc()));
0192: }
0193:
0194: if (Validator.isNotNull(mailMessage.getInReplyTo())) {
0195: message.setHeader("In-Reply-To", mailMessage
0196: .getInReplyTo());
0197: }
0198:
0199: if (Validator.isNotNull(mailMessage.getReferences())) {
0200: message.setHeader("References", mailMessage
0201: .getReferences());
0202: }
0203:
0204: message.setSubject(mailMessage.getSubject());
0205:
0206: _replaceEmbeddedImages(req, mailMessage,
0207: _getAttachmentURL(req));
0208:
0209: Multipart multipart = new MimeMultipart();
0210:
0211: BodyPart bodyPart = new MimeBodyPart();
0212:
0213: bodyPart.setContent(mailMessage.getBody(),
0214: ContentTypes.TEXT_HTML_UTF8);
0215:
0216: multipart.addBodyPart(bodyPart);
0217:
0218: List attachments = mailMessage.getAttachments();
0219:
0220: Iterator itr = attachments.iterator();
0221:
0222: while (itr.hasNext()) {
0223: MailAttachment mailAttachment = (MailAttachment) itr
0224: .next();
0225:
0226: DataSource dataSource = new ByteArrayDataSource(
0227: mailAttachment.getContent(), mailAttachment
0228: .getContentType());
0229:
0230: BodyPart attachment = new MimeBodyPart();
0231:
0232: attachment.setFileName(mailAttachment.getFilename());
0233: attachment.setDataHandler(new DataHandler(dataSource));
0234:
0235: if (Validator.isNotNull(mailAttachment.getContentId())) {
0236: attachment.addHeader(HttpHeaders.CONTENT_ID,
0237: mailAttachment.getContentId());
0238: }
0239:
0240: multipart.addBodyPart(attachment);
0241: }
0242:
0243: List remoteAttachments = mailMessage.getRemoteAttachments();
0244:
0245: itr = remoteAttachments.iterator();
0246:
0247: while (itr.hasNext()) {
0248: RemoteMailAttachment remoteMailAttachment = (RemoteMailAttachment) itr
0249: .next();
0250:
0251: Object[] parts = getAttachment(req,
0252: remoteMailAttachment.getContentPath());
0253:
0254: DataSource dataSource = new ByteArrayDataSource(
0255: (byte[]) parts[0], (String) parts[1]);
0256:
0257: BodyPart attachment = new MimeBodyPart();
0258:
0259: attachment.setFileName(remoteMailAttachment
0260: .getFilename());
0261: attachment.setDataHandler(new DataHandler(dataSource));
0262:
0263: multipart.addBodyPart(attachment);
0264: }
0265:
0266: message.setContent(multipart);
0267: message.setSentDate(new Date());
0268:
0269: if (send) {
0270: Transport.send(message);
0271: }
0272:
0273: try {
0274: MailSessionLock.lock(req);
0275:
0276: String lastFolderName = getFolderName(req);
0277:
0278: IMAPFolder folder = null;
0279:
0280: if (send) {
0281: folder = _getFolder(req, MAIL_SENT_NAME);
0282:
0283: message.setFlag(Flag.SEEN, true);
0284: } else {
0285: folder = _getFolder(req, MAIL_DRAFTS_NAME);
0286: }
0287:
0288: folder.appendMessages(new Message[] { message });
0289:
0290: long origId = GetterUtil.getLong(originalId);
0291:
0292: if (wasDraft) {
0293: folder = _getFolder(req, MAIL_DRAFTS_NAME);
0294:
0295: Message msg = folder.getMessageByUID(origId);
0296:
0297: folder.setFlags(new Message[] { msg }, new Flags(
0298: Flags.Flag.DELETED), true);
0299:
0300: folder.expunge();
0301: } else if (origId > 0L) {
0302: folder = _getFolder(req, lastFolderName);
0303:
0304: Message msg = folder.getMessageByUID(origId);
0305:
0306: folder.setFlags(new Message[] { msg }, new Flags(
0307: Flags.Flag.ANSWERED), true);
0308: }
0309:
0310: // Make sure to explicitly close and open the correct folder
0311:
0312: _closeFolder(ses);
0313:
0314: setFolder(req, lastFolderName);
0315: } finally {
0316: MailSessionLock.unlock(req);
0317: }
0318: } catch (MessagingException me) {
0319: throw new ContentException(me);
0320: } catch (NamingException ne) {
0321: throw new ContentException(ne);
0322: }
0323: }
0324:
0325: public static void createFolder(HttpServletRequest req,
0326: String folderName) throws FolderException,
0327: MailServerException, StoreException {
0328:
0329: Folder folder = null;
0330:
0331: try {
0332: MailSessionLock.lock(req);
0333:
0334: Iterator itr = getFolders(req).iterator();
0335:
0336: while (itr.hasNext()) {
0337: MailFolder mailFolder = (MailFolder) itr.next();
0338:
0339: if (mailFolder.getName().equals(folderName)) {
0340: throw new FolderException("Folder " + folderName
0341: + " already exists");
0342: }
0343: }
0344:
0345: Store store = _getStore(req);
0346:
0347: folderName = _getResolvedFolderName(folderName);
0348:
0349: folder = store.getFolder(folderName);
0350:
0351: folder.create(Folder.HOLDS_MESSAGES);
0352: } catch (MessagingException me) {
0353: throw new FolderException(me);
0354: } finally {
0355: try {
0356: if ((folder != null) && folder.isOpen()) {
0357: folder.close(false);
0358: }
0359: } catch (Exception e) {
0360: }
0361:
0362: MailSessionLock.unlock(req);
0363: }
0364: }
0365:
0366: public static void deleteMessages(HttpServletRequest req,
0367: MultiValueMap msgMap) throws FolderException,
0368: MailServerException, StoreException {
0369:
0370: deleteMessages(req, msgMap, false);
0371: }
0372:
0373: public static void deleteMessages(HttpServletRequest req,
0374: MultiValueMap msgMap, boolean permanently)
0375: throws FolderException, MailServerException, StoreException {
0376:
0377: try {
0378: MailSessionLock.lock(req);
0379:
0380: Iterator itr = msgMap.keySet().iterator();
0381:
0382: while (itr.hasNext()) {
0383: String key = (String) itr.next();
0384:
0385: IMAPFolder folder = _getFolder(req);
0386:
0387: String folderName = _getResolvedFolderName(folder
0388: .getName());
0389:
0390: if (permanently || folderName.equals(MAIL_TRASH_NAME)) {
0391: Message[] messages = folder
0392: .getMessagesByUID(_getMessageIds(msgMap,
0393: key));
0394:
0395: folder.setFlags(messages, new Flags(
0396: Flags.Flag.DELETED), true);
0397:
0398: folder.expunge();
0399:
0400: msgMap.remove(key);
0401: }
0402: }
0403:
0404: if (!msgMap.isEmpty()) {
0405: moveMessages(req, msgMap, MAIL_TRASH_NAME);
0406: }
0407: } catch (MessagingException me) {
0408: throw new FolderException(me);
0409: } finally {
0410: MailSessionLock.unlock(req);
0411: }
0412: }
0413:
0414: public static void emptyFolder(HttpServletRequest req,
0415: String folderName) throws FolderException,
0416: MailServerException, StoreException {
0417:
0418: try {
0419: MailSessionLock.lock(req);
0420:
0421: String lastFolderName = getFolderName(req);
0422:
0423: IMAPFolder folder = _getFolder(req, folderName);
0424:
0425: long[] ids = new long[0];
0426:
0427: try {
0428: Message[] msgs = folder.getMessages();
0429:
0430: FetchProfile fetchProfile = new FetchProfile();
0431:
0432: fetchProfile.add(FetchProfile.Item.ENVELOPE);
0433:
0434: folder.fetch(msgs, fetchProfile);
0435:
0436: ids = new long[msgs.length];
0437:
0438: for (int i = 0; i < msgs.length; i++) {
0439: ids[i] = folder.getUID(msgs[i]);
0440: }
0441:
0442: Message[] messages = folder.getMessagesByUID(ids);
0443:
0444: folder.setFlags(messages,
0445: new Flags(Flags.Flag.DELETED), true);
0446:
0447: folder.expunge();
0448: } catch (MessagingException me) {
0449: throw new FolderException(me);
0450: } finally {
0451: setFolder(req, lastFolderName);
0452: }
0453: } finally {
0454: MailSessionLock.unlock(req);
0455: }
0456: }
0457:
0458: public static Object[] getAttachment(HttpServletRequest req,
0459: String contentPath) throws ContentException,
0460: ContentPathException, FolderException, MailServerException,
0461: StoreException {
0462:
0463: Object[] parts = null;
0464:
0465: try {
0466: MailSessionLock.lock(req);
0467:
0468: String[] path = RemoteMailAttachment.parsePath(contentPath);
0469:
0470: String folderName = path[0];
0471: long messageId = GetterUtil.getLong(path[1]);
0472: String mimePath = path[2];
0473:
0474: IMAPFolder folder = _getFolder(req, folderName);
0475:
0476: Message message = folder.getMessageByUID(messageId);
0477:
0478: parts = _getAttachmentFromPath(message, mimePath);
0479: } catch (ContentPathException cpe) {
0480: throw cpe;
0481: } catch (IOException ioe) {
0482: throw new ContentException(ioe);
0483: } catch (MessagingException me) {
0484: throw new ContentException(me);
0485: } finally {
0486: MailSessionLock.unlock(req);
0487: }
0488:
0489: return parts;
0490: }
0491:
0492: public static Set getEnvelopes(HttpServletRequest req,
0493: Comparator comparator) throws FolderException {
0494:
0495: Set envelopes = new TreeSet(comparator);
0496:
0497: try {
0498: MailSessionLock.lock(req);
0499:
0500: IMAPFolder folder = _getFolder(req);
0501:
0502: String folderName = _getResolvedFolderName(folder.getName());
0503:
0504: Message[] messages = folder.getMessages();
0505:
0506: FetchProfile fetchProfile = new FetchProfile();
0507:
0508: fetchProfile.add(IMAPFolder.FetchProfileItem.SIZE);
0509: fetchProfile.add(FetchProfile.Item.ENVELOPE);
0510: fetchProfile.add(FetchProfile.Item.FLAGS);
0511: fetchProfile.add(FetchProfileItem.UID);
0512:
0513: folder.fetch(messages, fetchProfile);
0514:
0515: _convertEnvelopes(folder, folderName, messages, envelopes);
0516:
0517: return envelopes;
0518: } catch (MessagingException me) {
0519: throw new FolderException(me);
0520: } finally {
0521: MailSessionLock.unlock(req);
0522: }
0523: }
0524:
0525: public static MailFolder getFolder(HttpServletRequest req)
0526: throws FolderException, MailServerException,
0527: MessagingException, StoreException {
0528:
0529: try {
0530:
0531: // Make sure a store has been retrieved first
0532:
0533: _getStore(req);
0534:
0535: MailSessionLock.lock(req);
0536:
0537: IMAPFolder folder = _getFolder(req);
0538:
0539: List list = new ArrayList();
0540:
0541: _getFolders(list, new IMAPFolder[] { folder });
0542:
0543: return (MailFolder) list.get(0);
0544: } finally {
0545: MailSessionLock.unlock(req);
0546: }
0547: }
0548:
0549: public static String getFolderName(HttpServletRequest req)
0550: throws FolderException, StoreException {
0551:
0552: try {
0553: MailSessionLock.lock(req);
0554:
0555: IMAPFolder folder = _getFolder(req);
0556:
0557: return folder.getName();
0558: } finally {
0559: MailSessionLock.unlock(req);
0560: }
0561: }
0562:
0563: public static List getFolders(HttpServletRequest req)
0564: throws FolderException, MailServerException, StoreException {
0565:
0566: List list = new ArrayList();
0567:
0568: IMAPFolder root = null;
0569:
0570: try {
0571: List tempList = new ArrayList();
0572:
0573: Store store = _getStore(req);
0574:
0575: root = (IMAPFolder) store.getDefaultFolder();
0576:
0577: Folder[] folders = root.list();
0578:
0579: _getFolders(tempList, folders);
0580:
0581: for (int i = 0; i < DEFAULT_FOLDERS.length; i++) {
0582: ListIterator itr = tempList.listIterator();
0583:
0584: while (itr.hasNext()) {
0585: MailFolder mailFolder = (MailFolder) itr.next();
0586:
0587: if (DEFAULT_FOLDERS[i]
0588: .equals(_getResolvedFolderName(mailFolder
0589: .getName()))) {
0590:
0591: list.add(mailFolder);
0592:
0593: itr.remove();
0594:
0595: break;
0596: }
0597: }
0598: }
0599:
0600: list.addAll(tempList);
0601: } catch (MessagingException me) {
0602: throw new FolderException(me);
0603: } finally {
0604: try {
0605: if ((root != null) && root.isOpen()) {
0606: root.close(false);
0607: }
0608: } catch (Exception ex) {
0609: }
0610: }
0611:
0612: return list;
0613: }
0614:
0615: public static MailMessage getMessage(HttpServletRequest req)
0616: throws ContentException, FolderException, StoreException {
0617:
0618: try {
0619: MailSessionLock.lock(req);
0620:
0621: long messageId = getMessageId(req);
0622:
0623: if (messageId != -1L) {
0624: return getMessage(req, messageId);
0625: } else {
0626: return null;
0627: }
0628: } finally {
0629: MailSessionLock.unlock(req);
0630: }
0631: }
0632:
0633: public static MailMessage getMessage(HttpServletRequest req,
0634: long messageId) throws ContentException, FolderException,
0635: StoreException {
0636:
0637: HttpSession ses = req.getSession();
0638:
0639: MailMessage mailMessage = new MailMessage();
0640:
0641: try {
0642: MailSessionLock.lock(req);
0643:
0644: IMAPFolder folder = _getFolder(req);
0645:
0646: Message message = folder.getMessageByUID(messageId);
0647:
0648: mailMessage.setMessageId(messageId);
0649:
0650: if (Validator.isNotNull(message.getFrom())) {
0651: mailMessage.setFrom(message.getFrom()[0]);
0652: }
0653:
0654: mailMessage.setTo(message.getRecipients(RecipientType.TO));
0655: mailMessage.setCc(message.getRecipients(RecipientType.CC));
0656: mailMessage
0657: .setBcc(message.getRecipients(RecipientType.BCC));
0658: mailMessage.setReplyTo(message.getReplyTo());
0659:
0660: String[] messageIdHeader = message.getHeader("Message-ID");
0661: String[] referencesHeader = message.getHeader("References");
0662:
0663: if (Validator.isNotNull(messageIdHeader)) {
0664: mailMessage.setInReplyTo(messageIdHeader[0]);
0665:
0666: if (Validator.isNull(referencesHeader)) {
0667: mailMessage.setReferences(messageIdHeader[0]);
0668: } else {
0669: mailMessage.setReferences(referencesHeader[0]
0670: + StringPool.SPACE + messageIdHeader[0]);
0671: }
0672: } else {
0673: if (Validator.isNotNull(referencesHeader[0])) {
0674: mailMessage.setReferences(referencesHeader[0]);
0675: }
0676: }
0677:
0678: mailMessage.setSubject(message.getSubject());
0679: mailMessage.setSentDate(message.getSentDate());
0680:
0681: String contentPath = RemoteMailAttachment.buildContentPath(
0682: folder.getName(), messageId);
0683:
0684: MailContent content = new MailContent();
0685:
0686: mailMessage = _getContent(message, mailMessage, content,
0687: contentPath);
0688:
0689: mailMessage.setMailContent(content);
0690:
0691: if (_log.isDebugEnabled()) {
0692: _log.debug("Body before replacing content ids\n"
0693: + content);
0694: }
0695:
0696: _replaceContentIds(content, mailMessage
0697: .getRemoteAttachments(), _getAttachmentURL(req));
0698:
0699: if (_log.isDebugEnabled()) {
0700: _log.debug("Body after replacing content ids\n"
0701: + content);
0702: }
0703:
0704: mailMessage.purgeDirtyRemoteAttachments();
0705:
0706: ses.setAttribute(WebKeys.MAIL_MESSAGE_ID, new Long(
0707: messageId));
0708:
0709: return mailMessage;
0710: } catch (MessagingException me) {
0711: throw new FolderException(me);
0712: } finally {
0713: MailSessionLock.unlock(req);
0714: }
0715: }
0716:
0717: public static long getMessageId(HttpServletRequest req)
0718: throws ContentException, FolderException, StoreException {
0719:
0720: HttpSession ses = req.getSession();
0721:
0722: try {
0723: MailSessionLock.lock(req);
0724:
0725: Long messageId = (Long) ses
0726: .getAttribute(WebKeys.MAIL_MESSAGE_ID);
0727:
0728: if (messageId != null) {
0729: return messageId.longValue();
0730: } else {
0731: return -1L;
0732: }
0733: } finally {
0734: MailSessionLock.unlock(req);
0735: }
0736: }
0737:
0738: public static void moveMessages(HttpServletRequest req,
0739: MultiValueMap msgMap, String toFolderName)
0740: throws FolderException, MailServerException, StoreException {
0741:
0742: IMAPFolder toFolder = null;
0743:
0744: toFolderName = _getResolvedFolderName(toFolderName);
0745:
0746: try {
0747: MailSessionLock.lock(req);
0748:
0749: Iterator itr = msgMap.keySet().iterator();
0750:
0751: while (itr.hasNext()) {
0752: String folderName = (String) itr.next();
0753:
0754: long[] messageIds = _getMessageIds(msgMap, folderName);
0755:
0756: IMAPFolder folder = _getFolder(req, folderName);
0757:
0758: folderName = _getResolvedFolderName(folder.getName());
0759:
0760: if (folderName.equals(toFolderName)) {
0761: continue;
0762: }
0763:
0764: if ((folderName.equals(MAIL_DRAFTS_NAME) || toFolderName
0765: .equals(MAIL_DRAFTS_NAME))
0766: && (!toFolderName.equals(MAIL_TRASH_NAME))) {
0767:
0768: continue;
0769: }
0770:
0771: Store store = _getStore(req);
0772:
0773: toFolder = (IMAPFolder) store.getFolder(toFolderName);
0774:
0775: toFolder.open(IMAPFolder.READ_WRITE);
0776:
0777: Message[] messages = folder
0778: .getMessagesByUID(messageIds);
0779:
0780: folder.copyMessages(messages, toFolder);
0781:
0782: folder.setFlags(messages,
0783: new Flags(Flags.Flag.DELETED), true);
0784:
0785: folder.expunge();
0786: }
0787: } catch (MessagingException me) {
0788: throw new FolderException(me);
0789: } finally {
0790: try {
0791: if ((toFolder != null) && toFolder.isOpen()) {
0792: toFolder.close(true);
0793: }
0794: } catch (Exception e) {
0795: }
0796:
0797: MailSessionLock.unlock(req);
0798: }
0799: }
0800:
0801: public static void removeFolder(HttpServletRequest req,
0802: String folderName) throws FolderException,
0803: MailServerException, StoreException {
0804:
0805: try {
0806: folderName = _getResolvedFolderName(folderName);
0807:
0808: for (int i = 0; i < DEFAULT_FOLDERS.length; i++) {
0809: if (DEFAULT_FOLDERS[i].equals(folderName)) {
0810: if (_log.isErrorEnabled()) {
0811: _log
0812: .error("Folder "
0813: + folderName
0814: + " is a system folder and cannot be changed");
0815: }
0816:
0817: throw new FolderException();
0818: }
0819: }
0820:
0821: try {
0822: MailSessionLock.lock(req);
0823:
0824: setFolder(req, MAIL_INBOX_NAME);
0825:
0826: Store store = _getStore(req);
0827:
0828: Folder folder = store.getFolder(folderName);
0829:
0830: if (!folder.exists()) {
0831: if (_log.isErrorEnabled()) {
0832: _log.error("Folder " + folderName
0833: + " does not exist");
0834: }
0835:
0836: throw new FolderException();
0837: }
0838:
0839: folder.delete(true);
0840: } finally {
0841: MailSessionLock.unlock(req);
0842: }
0843: } catch (MessagingException me) {
0844: throw new FolderException(me);
0845: }
0846: }
0847:
0848: public static void renameFolder(HttpServletRequest req,
0849: String oldFolderName, String newFolderName)
0850: throws FolderException, MailServerException, StoreException {
0851:
0852: try {
0853: oldFolderName = _getResolvedFolderName(oldFolderName);
0854: newFolderName = _getResolvedFolderName(newFolderName);
0855:
0856: for (int i = 0; i < DEFAULT_FOLDERS.length; i++) {
0857: if (DEFAULT_FOLDERS[i].equals(oldFolderName)) {
0858: if (_log.isErrorEnabled()) {
0859: _log
0860: .error("Folder "
0861: + oldFolderName
0862: + " is a system folder and cannot be changed");
0863: }
0864:
0865: throw new FolderException();
0866: } else if (DEFAULT_FOLDERS[i].equals(newFolderName)) {
0867: if (_log.isErrorEnabled()) {
0868: _log
0869: .error("Folder "
0870: + newFolderName
0871: + " is a system folder and cannot be changed");
0872: }
0873:
0874: throw new FolderException();
0875: }
0876: }
0877:
0878: try {
0879: MailSessionLock.lock(req);
0880:
0881: setFolder(req, MAIL_INBOX_NAME);
0882:
0883: Store store = _getStore(req);
0884:
0885: Folder oldFolder = store.getFolder(oldFolderName);
0886: Folder newFolder = store.getFolder(newFolderName);
0887:
0888: if (!oldFolder.exists()) {
0889: if (_log.isErrorEnabled()) {
0890: _log.error("Folder " + oldFolderName
0891: + " does not exist");
0892: }
0893:
0894: throw new FolderException();
0895: } else if (newFolder.exists()) {
0896: if (_log.isErrorEnabled()) {
0897: _log.error("Folder " + newFolderName
0898: + " already exists");
0899: }
0900:
0901: throw new FolderException();
0902: }
0903:
0904: oldFolder.renameTo(newFolder);
0905: } finally {
0906: MailSessionLock.unlock(req);
0907: }
0908: } catch (MessagingException me) {
0909: throw new FolderException(me);
0910: }
0911: }
0912:
0913: public static Set search(HttpServletRequest req,
0914: MailDisplayTerms displayTerms, Comparator comparator)
0915: throws FolderException, MailServerException, StoreException {
0916:
0917: Set results = new TreeSet(comparator);
0918:
0919: if (Validator.isNotNull(displayTerms.getFolderName())) {
0920: _search(req, displayTerms, results);
0921: } else {
0922: List folders = getFolders(req);
0923:
0924: Iterator itr = folders.iterator();
0925:
0926: while (itr.hasNext()) {
0927: MailFolder mailFolder = (MailFolder) itr.next();
0928:
0929: String resolvedName = _getResolvedFolderName(mailFolder
0930: .getName());
0931:
0932: if (resolvedName.equals(MAIL_SPAM_NAME)
0933: || resolvedName.equals(MAIL_TRASH_NAME)) {
0934:
0935: continue;
0936: }
0937:
0938: displayTerms.setFolderName(mailFolder.getName());
0939:
0940: _search(req, displayTerms, results);
0941: }
0942: }
0943:
0944: return results;
0945: }
0946:
0947: public static void setAccount(HttpServletRequest req) {
0948: String accountName = ParamUtil.getString(req,
0949: Constants.MAIL_ACCOUNT);
0950:
0951: try {
0952: if (Validator.isNotNull(accountName)) {
0953: MailAccounts.setAccount(req, accountName);
0954: }
0955: } catch (MailAccountsException e) {
0956: if (_log.isWarnEnabled()) {
0957: _log.warn("Error setting account " + accountName, e);
0958: }
0959: }
0960: }
0961:
0962: public static void setFolder(HttpServletRequest req,
0963: String folderName) throws FolderException,
0964: MailServerException, StoreException {
0965:
0966: try {
0967: MailSessionLock.lock(req);
0968:
0969: _getFolder(req, folderName);
0970: } finally {
0971: MailSessionLock.unlock(req);
0972: }
0973: }
0974:
0975: public static void setMessageId(HttpServletRequest req,
0976: long messageId) {
0977: HttpSession ses = req.getSession();
0978:
0979: ses.setAttribute(WebKeys.MAIL_MESSAGE_ID, new Long(messageId));
0980: }
0981:
0982: protected static void cleanUp(HttpSession ses)
0983: throws StoreException {
0984: try {
0985: _closeFolder(ses);
0986:
0987: MailCache.clearCache(ses);
0988:
0989: ses.removeAttribute(WebKeys.MAIL_MESSAGE_ID);
0990: } catch (MessagingException me) {
0991: throw new StoreException(me);
0992: }
0993: }
0994:
0995: private static SearchTerm _appendSearchTerm(SearchTerm fullTerm,
0996: SearchTerm term, boolean isAndOperator) {
0997:
0998: if (fullTerm == null) {
0999: return term;
1000: }
1001:
1002: if (isAndOperator) {
1003: return new AndTerm(fullTerm, term);
1004: } else {
1005: return new OrTerm(fullTerm, term);
1006: }
1007: }
1008:
1009: private static void _closeFolder(HttpSession ses) {
1010: IMAPFolder folder = (IMAPFolder) ses
1011: .getAttribute(WebKeys.MAIL_FOLDER);
1012:
1013: if ((folder != null) && folder.isOpen()) {
1014: try {
1015: folder.close(false);
1016: } catch (MessagingException me) {
1017: if (_log.isWarnEnabled()) {
1018: _log.warn(me);
1019: }
1020: }
1021:
1022: ses.removeAttribute(WebKeys.MAIL_FOLDER);
1023: }
1024: }
1025:
1026: private static void _convertEnvelopes(IMAPFolder folder,
1027: String folderName, Message[] messages, Set envelopes)
1028: throws MessagingException {
1029:
1030: for (int i = 0; i < messages.length; i++) {
1031: Message message = messages[i];
1032:
1033: if (message.isExpunged()) {
1034: continue;
1035: }
1036:
1037: MailEnvelope mailEnvelope = new MailEnvelope();
1038:
1039: mailEnvelope.setMessageId(folder.getUID(message));
1040: mailEnvelope.setFolderName(folder.getName());
1041:
1042: if (MAIL_SENT_NAME.equals(folderName)
1043: || MAIL_DRAFTS_NAME.equals(folderName)) {
1044:
1045: Address[] recipients = message.getAllRecipients();
1046:
1047: StringMaker sm = new StringMaker();
1048:
1049: if (Validator.isNotNull(recipients)) {
1050: for (int j = 0; j < recipients.length; j++) {
1051: InternetAddress address = (InternetAddress) recipients[j];
1052:
1053: String recipient = GetterUtil.getString(address
1054: .getPersonal(), address.getAddress());
1055:
1056: sm.append(recipient);
1057:
1058: if (j < (recipients.length - 1)) {
1059: sm.append(", ");
1060: }
1061: }
1062: }
1063:
1064: if (sm.length() > 0) {
1065: mailEnvelope.setRecipient(sm.toString());
1066: }
1067: } else {
1068: Address[] from = message.getFrom();
1069:
1070: if (Validator.isNotNull(from)) {
1071: InternetAddress address = (InternetAddress) from[0];
1072:
1073: String recipient = GetterUtil.getString(address
1074: .getPersonal(), address.getAddress());
1075:
1076: mailEnvelope.setRecipient(recipient);
1077: }
1078: }
1079:
1080: mailEnvelope.setSubject(message.getSubject());
1081: mailEnvelope.setDate(message.getSentDate());
1082: mailEnvelope
1083: .setSize((int) (message.getSize() * _ENCODING_FACTOR));
1084: mailEnvelope.setRead(message.isSet(Flag.SEEN));
1085: mailEnvelope.setFlagged(message.isSet(Flag.FLAGGED));
1086: mailEnvelope.setAnswered(message.isSet(Flag.ANSWERED));
1087:
1088: envelopes.add(mailEnvelope);
1089: }
1090: }
1091:
1092: private static Store _createStore(HttpServletRequest req,
1093: MailAccount account) throws FolderException,
1094: MailServerException, MessagingException, NamingException,
1095: StoreException {
1096:
1097: HttpSession ses = req.getSession();
1098:
1099: Session session = MailEngine.getSession();
1100:
1101: Store store = session.getStore("imap");
1102:
1103: String serviceName = account.getUserId() + StringPool.COLON
1104: + WebKeys.MAIL_STORE;
1105:
1106: store
1107: .addConnectionListener(new ConnectionListener(
1108: serviceName));
1109:
1110: String imapHost = session.getProperty("mail.imap.host");
1111:
1112: store.connect(imapHost, account.getUserId(), account
1113: .getPassword());
1114:
1115: MailCache.putStore(ses, account.getName(), store);
1116:
1117: List list = getFolders(req);
1118:
1119: for (int i = 0; i < DEFAULT_FOLDERS.length; i++) {
1120: boolean exists = false;
1121:
1122: Iterator itr = list.iterator();
1123:
1124: while (itr.hasNext()) {
1125: MailFolder mailFolder = (MailFolder) itr.next();
1126:
1127: if (DEFAULT_FOLDERS[i].equals(mailFolder.getName())) {
1128: exists = true;
1129:
1130: break;
1131: }
1132: }
1133:
1134: if (!exists) {
1135: createFolder(req, DEFAULT_FOLDERS[i]);
1136: }
1137: }
1138:
1139: if (ses.getAttribute(WebKeys.MAIL_FOLDER) == null) {
1140: setFolder(req, MAIL_INBOX_NAME);
1141: }
1142:
1143: return store;
1144: }
1145:
1146: private static String _customizeHtml(String html) {
1147: for (int i = 0; i < _HTML_START_TAGS.length; i++) {
1148: Pattern startPattern = Pattern.compile(_HTML_START_TAGS[i],
1149: Pattern.CASE_INSENSITIVE);
1150:
1151: Matcher startMatcher = startPattern.matcher(html);
1152:
1153: while (startMatcher.find()) {
1154: int start = startMatcher.start();
1155: int end = html.indexOf(">", start);
1156:
1157: if (end == -1) {
1158: html = StringUtil.replace(html, html
1159: .substring(start), StringPool.BLANK);
1160: } else {
1161: html = StringUtil.replace(html, html.substring(
1162: start, end + 1), StringPool.BLANK);
1163: }
1164:
1165: if (i < _HTML_END_TAGS.length) {
1166: Pattern endPattern = Pattern
1167: .compile(_HTML_END_TAGS[i],
1168: Pattern.CASE_INSENSITIVE);
1169:
1170: Matcher endMatcher = endPattern.matcher(html);
1171:
1172: html = endMatcher.replaceFirst(StringPool.BLANK);
1173: } else {
1174: startMatcher.reset(html);
1175: }
1176: }
1177: }
1178:
1179: return html.trim();
1180: }
1181:
1182: private static Object[] _getAttachmentFromPath(Part part,
1183: String mimePath) throws ContentPathException, IOException,
1184: MessagingException {
1185:
1186: int index = GetterUtil.getInteger(StringUtil.split(mimePath
1187: .substring(1), StringPool.PERIOD)[0]);
1188:
1189: if (part.getContent() instanceof Multipart) {
1190: String prefix = String.valueOf(index) + StringPool.PERIOD;
1191:
1192: Multipart multipart = (Multipart) part.getContent();
1193:
1194: for (int i = 0; i < multipart.getCount(); i++) {
1195: if (index == i) {
1196: return _getAttachmentFromPath(multipart
1197: .getBodyPart(i), mimePath.substring(prefix
1198: .length()));
1199: }
1200: }
1201:
1202: throw new ContentPathException();
1203: } else if (index != -1) {
1204: throw new ContentPathException();
1205: }
1206:
1207: byte[] byteArray = JavaMailUtil.getBytes(part);
1208:
1209: return new Object[] { byteArray, part.getContentType() };
1210: }
1211:
1212: private static String _getAttachmentURL(HttpServletRequest req) {
1213: ThemeDisplay themeDisplay = (ThemeDisplay) req
1214: .getAttribute(WebKeys.THEME_DISPLAY);
1215:
1216: return themeDisplay.getPathMain() + "/mail/get_attachment?";
1217: }
1218:
1219: private static MailMessage _getContent(Part part,
1220: MailMessage mailMessage, MailContent content,
1221: String contentPath) throws ContentException {
1222:
1223: try {
1224: String contentType = part.getContentType().toLowerCase();
1225:
1226: boolean attachment = true;
1227:
1228: if (part.getContent() instanceof Multipart) {
1229: attachment = false;
1230:
1231: Multipart multipart = (Multipart) part.getContent();
1232:
1233: for (int i = 0; i < multipart.getCount(); i++) {
1234: Part curPart = multipart.getBodyPart(i);
1235:
1236: mailMessage = _getContent(curPart, mailMessage,
1237: content, contentPath + StringPool.PERIOD
1238: + i);
1239: }
1240: } else if (Validator.isNull(part.getFileName())) {
1241: attachment = false;
1242:
1243: if (contentType.startsWith(ContentTypes.TEXT_PLAIN)) {
1244: content.appendPlainBody((String) part.getContent());
1245: } else if (contentType
1246: .startsWith(ContentTypes.TEXT_HTML)) {
1247: content.appendHtmlBody(_customizeHtml((String) part
1248: .getContent()));
1249: } else if (contentType
1250: .startsWith(ContentTypes.MESSAGE_RFC822)) {
1251: MailContent subContent = new MailContent();
1252:
1253: mailMessage = _getContent((Part) part.getContent(),
1254: mailMessage, subContent, contentPath
1255: + StringPool.PERIOD + 0);
1256:
1257: content.appendSubContent(subContent);
1258: }
1259: }
1260:
1261: if (attachment) {
1262: mailMessage
1263: .appendRemoteAttachment(_getRemoteAttachment(
1264: part, contentPath + StringPool.PERIOD
1265: + -1));
1266: }
1267: } catch (IOException ioe) {
1268: throw new ContentException(ioe);
1269: } catch (MessagingException me) {
1270: throw new ContentException(me);
1271: }
1272:
1273: return mailMessage;
1274: }
1275:
1276: private static IMAPFolder _getFolder(HttpServletRequest req)
1277: throws FolderException {
1278:
1279: HttpSession ses = req.getSession();
1280:
1281: IMAPFolder folder = (IMAPFolder) ses
1282: .getAttribute(WebKeys.MAIL_FOLDER);
1283:
1284: if (folder != null) {
1285: return folder;
1286: } else {
1287: throw new FolderException();
1288: }
1289: }
1290:
1291: private static IMAPFolder _getFolder(HttpServletRequest req,
1292: String folderName) throws FolderException,
1293: MailServerException, StoreException {
1294:
1295: HttpSession ses = req.getSession();
1296:
1297: try {
1298: folderName = _getResolvedFolderName(folderName);
1299:
1300: IMAPFolder folder = (IMAPFolder) ses
1301: .getAttribute(WebKeys.MAIL_FOLDER);
1302:
1303: if (folder != null) {
1304: String currFolderName = _getResolvedFolderName(folder
1305: .getName());
1306:
1307: if (!currFolderName.equals(folderName)) {
1308: _closeFolder(ses);
1309:
1310: folder = null;
1311: } else if (!folder.isOpen()) {
1312: if (_log.isInfoEnabled()) {
1313: _log
1314: .info("The folder is closed and needs to be reopened");
1315: }
1316:
1317: _closeFolder(ses);
1318:
1319: folder = null;
1320: }
1321: }
1322:
1323: if (folder == null) {
1324: Long userIdObj = (Long) ses
1325: .getAttribute(WebKeys.USER_ID);
1326:
1327: String serviceName = userIdObj + StringPool.COLON
1328: + WebKeys.MAIL_FOLDER + StringPool.PERIOD
1329: + folderName;
1330:
1331: Store store = _getStore(req);
1332:
1333: folder = (IMAPFolder) store.getFolder(folderName);
1334:
1335: folder.addConnectionListener(new ConnectionListener(
1336: serviceName));
1337:
1338: folder.open(IMAPFolder.READ_WRITE);
1339:
1340: ses.setAttribute(WebKeys.MAIL_FOLDER, folder);
1341:
1342: ses.removeAttribute(WebKeys.MAIL_MESSAGE_ID);
1343: }
1344:
1345: return folder;
1346: } catch (MessagingException me) {
1347: throw new FolderException(me);
1348: }
1349: }
1350:
1351: private static void _getFolders(List list, Folder[] folders) {
1352: for (int i = 0; i < folders.length; i++) {
1353: Folder folder = folders[i];
1354:
1355: try {
1356: int folderType = folder.getType();
1357:
1358: if ((folderType & IMAPFolder.HOLDS_MESSAGES) != 0) {
1359: MailFolder mailFolder = new MailFolder(folder
1360: .getName(), folder.getMessageCount(),
1361: folder.getUnreadMessageCount());
1362:
1363: list.add(mailFolder);
1364: }
1365:
1366: if ((folderType & IMAPFolder.HOLDS_FOLDERS) != 0) {
1367: _getFolders(list, folder.list());
1368: }
1369: } catch (MessagingException me) {
1370: _log.error("Skipping IMAP folder because "
1371: + me.getMessage());
1372: }
1373: }
1374: }
1375:
1376: private static long[] _getMessageIds(MultiValueMap msgMap,
1377: String folderName) {
1378:
1379: Collection messages = msgMap.getCollection(folderName);
1380:
1381: long[] messageIds = new long[messages.size()];
1382:
1383: Iterator msgItr = messages.iterator();
1384:
1385: for (int i = 0; msgItr.hasNext(); i++) {
1386: messageIds[i] = GetterUtil.getLong((String) msgItr.next());
1387: }
1388:
1389: return messageIds;
1390: }
1391:
1392: private static RemoteMailAttachment _getRemoteAttachment(Part part,
1393: String contentPath) throws ContentException {
1394:
1395: RemoteMailAttachment remoteMailAttachment = new RemoteMailAttachment();
1396:
1397: try {
1398: remoteMailAttachment.setFilename(part.getFileName());
1399: remoteMailAttachment.setContentPath(contentPath);
1400:
1401: String[] contentId = part.getHeader(HttpHeaders.CONTENT_ID);
1402:
1403: if ((contentId != null) && (contentId.length == 1)) {
1404: remoteMailAttachment.setContentId(contentId[0]);
1405: }
1406: } catch (MessagingException me) {
1407: if (_log.isErrorEnabled()) {
1408: _log
1409: .error("Unable to properly get file name of MIME attachment");
1410: }
1411:
1412: throw new ContentException(me);
1413: }
1414:
1415: return remoteMailAttachment;
1416: }
1417:
1418: private static String _getResolvedFolderName(String folderName) {
1419: String resolvedName = folderName;
1420:
1421: if (Validator.isNull(folderName)) {
1422: resolvedName = MAIL_INBOX_NAME;
1423: } else if (!folderName.equals(MAIL_INBOX_NAME)
1424: && !folderName.startsWith(MAIL_BOX_STYLE)) {
1425:
1426: resolvedName = MAIL_BOX_STYLE + folderName;
1427: }
1428:
1429: return resolvedName;
1430: }
1431:
1432: private static Store _getStore(HttpServletRequest req)
1433: throws FolderException, MailServerException, StoreException {
1434:
1435: HttpSession ses = req.getSession();
1436:
1437: MailAccount currentAccount = MailAccounts
1438: .getCurrentAccount(req);
1439:
1440: try {
1441: Store store = MailCache.getStore(ses, currentAccount
1442: .getName());
1443:
1444: if (store != null && !store.isConnected()) {
1445: if (_log.isInfoEnabled()) {
1446: _log.info("The store needs to be reconnected");
1447: }
1448:
1449: cleanUp(ses);
1450:
1451: store = null;
1452: }
1453:
1454: if (store == null) {
1455: store = _createStore(req, currentAccount);
1456: }
1457:
1458: return store;
1459: } catch (AuthenticationFailedException afe) {
1460: _log.error("Failed to authenticate the userId "
1461: + currentAccount.getUserId());
1462:
1463: throw new StoreException(afe);
1464: } catch (MessagingException me) {
1465: Exception e = me.getNextException();
1466:
1467: if (e instanceof SocketException) {
1468: if (_log.isWarnEnabled()) {
1469: _log
1470: .warn("Failed to connect to a valid mail server. Please "
1471: + "make sure one is properly configured.");
1472: }
1473:
1474: throw new MailServerException(e);
1475: } else {
1476: throw new StoreException(me);
1477: }
1478: } catch (NamingException ne) {
1479: throw new StoreException(ne);
1480: }
1481: }
1482:
1483: private static void _replaceContentIds(MailContent content,
1484: List rmas, String url) {
1485:
1486: String body = content.getHtmlBody();
1487:
1488: for (int i = 0; i < rmas.size(); i++) {
1489: RemoteMailAttachment rma = (RemoteMailAttachment) rmas
1490: .get(i);
1491:
1492: if (Validator.isNotNull(rma.getContentId())) {
1493: String contentId = rma.getContentId();
1494:
1495: if (contentId.startsWith(StringPool.LESS_THAN)
1496: && contentId.endsWith(StringPool.GREATER_THAN)) {
1497:
1498: contentId = "cid:"
1499: + contentId.substring(1,
1500: contentId.length() - 1);
1501: }
1502:
1503: String remotePath = url + "fileName="
1504: + rma.getFilename() + "&contentPath="
1505: + rma.getContentPath();
1506:
1507: body = StringUtil.replace(body, contentId, remotePath);
1508:
1509: rma.setDirty(true);
1510: }
1511: }
1512:
1513: content.setHtmlBody(body);
1514:
1515: for (int i = 0; i < content.getSubContent().size(); i++) {
1516: _replaceContentIds((MailContent) content.getSubContent()
1517: .get(i), rmas, url);
1518: }
1519: }
1520:
1521: private static void _replaceEmbeddedImages(HttpServletRequest req,
1522: MailMessage mailMessage, String url)
1523: throws ContentException, ContentPathException,
1524: FolderException, MailServerException, StoreException {
1525:
1526: HttpSession ses = req.getSession();
1527:
1528: String prefix = ses.getId() + System.currentTimeMillis();
1529:
1530: int count = 0;
1531:
1532: String body = mailMessage.getBody();
1533:
1534: if (_log.isDebugEnabled()) {
1535: _log
1536: .debug("Body before replacing embedded images\n"
1537: + body);
1538: }
1539:
1540: int x = body.indexOf(url);
1541:
1542: while (x >= 0) {
1543: int y = body.indexOf("-1", x);
1544:
1545: if (y > 0) {
1546: y += 2;
1547:
1548: String attachmentPath = body.substring(x, y);
1549:
1550: String fileName = Http.getParameter(attachmentPath,
1551: "fileName");
1552: String contentPath = Http.getParameter(attachmentPath,
1553: "contentPath");
1554:
1555: String contentId = prefix + count;
1556:
1557: Object[] parts = getAttachment(req, contentPath);
1558:
1559: MailAttachment mailAttachment = new MailAttachment();
1560:
1561: mailAttachment.setFilename(fileName);
1562: mailAttachment.setContent((byte[]) parts[0]);
1563: mailAttachment.setContentType((String) parts[1]);
1564: mailAttachment.setContentId(StringPool.LESS_THAN
1565: + contentId + StringPool.GREATER_THAN);
1566:
1567: mailMessage.appendAttachment(mailAttachment);
1568:
1569: body = StringUtil.replace(body, attachmentPath, "cid:"
1570: + contentId);
1571:
1572: count++;
1573:
1574: x = body.indexOf(url);
1575: } else {
1576: x = body.indexOf(url, x + 1);
1577: }
1578: }
1579:
1580: if (count > 0) {
1581: mailMessage.setBody(body);
1582: }
1583:
1584: if (_log.isDebugEnabled()) {
1585: _log.debug("Body after replacing embedded images\n" + body);
1586: }
1587: }
1588:
1589: private static Address[] _resolveAddresses(HttpServletRequest req,
1590: Address[] addresses) throws RecipientException {
1591:
1592: Company company = null;
1593:
1594: try {
1595: company = PortalUtil.getCompany(req);
1596: } catch (Exception e) {
1597: return addresses;
1598: }
1599:
1600: for (int i = 0; i < addresses.length; i++) {
1601: InternetAddress address = (InternetAddress) addresses[i];
1602:
1603: if ((address.getPersonal() == null)
1604: && !Validator.isEmailAddress(address.getAddress())) {
1605:
1606: try {
1607: User user = UserLocalServiceUtil
1608: .getUserByEmailAddress(company
1609: .getCompanyId(), address
1610: .getAddress().trim()
1611: + StringPool.AT + company.getMx());
1612:
1613: addresses[i] = new InternetAddress(user
1614: .getEmailAddress(), user.getFullName());
1615: } catch (Exception e) {
1616: if (_log.isErrorEnabled()) {
1617: _log
1618: .error("Problems found trying to resolve email address "
1619: + address);
1620: }
1621:
1622: throw new RecipientException(e);
1623: }
1624: }
1625: }
1626:
1627: return addresses;
1628: }
1629:
1630: private static void _search(HttpServletRequest req,
1631: MailDisplayTerms displayTerms, Set results)
1632: throws FolderException, MailServerException, StoreException {
1633:
1634: Store store = _getStore(req);
1635:
1636: SearchTerm fullTerm = null;
1637:
1638: if (Validator.isNotNull(displayTerms.getFrom())) {
1639: fullTerm = new FromStringTerm(displayTerms.getFrom());
1640: }
1641:
1642: if (Validator.isNotNull(displayTerms.getTo())) {
1643: SearchTerm to = new RecipientStringTerm(
1644: Message.RecipientType.TO, displayTerms.getTo());
1645: SearchTerm cc = new RecipientStringTerm(
1646: Message.RecipientType.CC, displayTerms.getTo());
1647: SearchTerm bcc = new RecipientStringTerm(
1648: Message.RecipientType.BCC, displayTerms.getTo());
1649:
1650: SearchTerm term = to;
1651: term = _appendSearchTerm(term, cc, false);
1652: term = _appendSearchTerm(term, bcc, false);
1653:
1654: fullTerm = _appendSearchTerm(fullTerm, term, displayTerms
1655: .isAndOperator());
1656: }
1657:
1658: if (Validator.isNotNull(displayTerms.getSubject())) {
1659: SearchTerm term = new SubjectTerm(displayTerms.getSubject());
1660:
1661: fullTerm = _appendSearchTerm(fullTerm, term, displayTerms
1662: .isAndOperator());
1663: }
1664:
1665: if (Validator.isNotNull(displayTerms.getEntireMessage())) {
1666: String em = displayTerms.getEntireMessage();
1667:
1668: SearchTerm from = new FromStringTerm(em);
1669: SearchTerm to = new RecipientStringTerm(
1670: Message.RecipientType.TO, em);
1671: SearchTerm cc = new RecipientStringTerm(
1672: Message.RecipientType.CC, em);
1673: SearchTerm bcc = new RecipientStringTerm(
1674: Message.RecipientType.BCC, em);
1675: SearchTerm subject = new SubjectTerm(em);
1676: SearchTerm body = new BodyTerm(em);
1677:
1678: SearchTerm term = from;
1679: term = _appendSearchTerm(term, to, false);
1680: term = _appendSearchTerm(term, cc, false);
1681: term = _appendSearchTerm(term, bcc, false);
1682: term = _appendSearchTerm(term, subject, false);
1683: term = _appendSearchTerm(term, body, false);
1684:
1685: fullTerm = _appendSearchTerm(fullTerm, term, displayTerms
1686: .isAndOperator());
1687: }
1688:
1689: if (displayTerms.hasDate()) {
1690: SearchTerm startDate = new SentDateTerm(DateTerm.GE,
1691: displayTerms.getStartDate());
1692: SearchTerm endDate = new SentDateTerm(DateTerm.LE,
1693: displayTerms.getEndDate());
1694:
1695: SearchTerm term = startDate;
1696: term = _appendSearchTerm(term, endDate, true);
1697:
1698: fullTerm = _appendSearchTerm(fullTerm, term, displayTerms
1699: .isAndOperator());
1700: }
1701:
1702: if (fullTerm != null) {
1703: try {
1704: IMAPFolder folder = (IMAPFolder) store
1705: .getFolder(_getResolvedFolderName(displayTerms
1706: .getFolderName()));
1707:
1708: folder.open(IMAPFolder.READ_ONLY);
1709:
1710: Message[] messages = folder.search(fullTerm);
1711:
1712: _convertEnvelopes(folder, displayTerms.getFolderName(),
1713: messages, results);
1714: } catch (MessagingException me) {
1715: throw new FolderException(me);
1716: }
1717: }
1718: }
1719:
1720: private static final String[] _HTML_START_TAGS = new String[] {
1721: "<html", "<head", "<body", "<meta", "<o:SmartTagType" };
1722:
1723: private static final String[] _HTML_END_TAGS = new String[] {
1724: "</html>", "</head>", "</body>" };
1725:
1726: private static final double _ENCODING_FACTOR = 0.65;
1727:
1728: private static Log _log = LogFactory.getLog(MailUtil.class);
1729:
1730: }
|