Search in sources :

Example 11 with ZMimeMultipart

use of com.zimbra.common.zmime.ZMimeMultipart in project zm-mailbox by Zimbra.

the class ParseMimeMessage method setContent.

/**
     * The <mp>'s from the client and the MimeBodyParts in alternatives[] all want to be "content"
     * of this MimeMessage.  The alternatives[] all need to be "alternative" to whatever the client sends
     * us....but we want to be careful so that we do NOT create a nested multipart/alternative structure
     * within another one (that would be very tacky)....so this is a bit complicated.
     */
private static void setContent(MimeMessage mm, MimeMultipart mmp, Element elem, MimeBodyPart[] alternatives, ParseMessageContext ctxt) throws MessagingException, ServiceException, IOException {
    String type = elem.getAttribute(MailConstants.A_CONTENT_TYPE, MimeConstants.CT_DEFAULT).trim();
    ContentType ctype = new ContentType(type, ctxt.use2231).cleanup();
    // is the client passing us a multipart?
    if (ctype.getPrimaryType().equals("multipart")) {
        // handle multipart content separately...
        setMultipartContent(ctype, mm, mmp, elem, alternatives, ctxt);
        return;
    }
    Element inline = elem.getOptionalElement(MailConstants.E_ATTACH);
    if (inline != null) {
        handleAttachments(inline, mmp, ctxt, elem.getAttribute(MailConstants.A_CONTENT_ID, null), Part.INLINE);
        return;
    }
    if (alternatives != null) {
        // create a multipart/alternative to hold all the alternatives
        MimeMultipart mmpNew = new ZMimeMultipart("alternative");
        if (mmp == null) {
            mm.setContent(mmpNew);
        } else {
            MimeBodyPart mbpWrapper = new ZMimeBodyPart();
            mbpWrapper.setContent(mmpNew);
            mmp.addBodyPart(mbpWrapper);
        }
        mmp = mmpNew;
    }
    // once we get here, mmp is either NULL, a multipart/mixed from the toplevel,
    // or a multipart/alternative created just above....either way we are safe to stick
    // the client's nice and simple body right here
    String text = elem.getAttribute(MailConstants.E_CONTENT, "");
    byte[] raw = text.getBytes(Charsets.UTF_8);
    if (raw.length > 0 || !LC.mime_exclude_empty_content.booleanValue() || ctype.getPrimaryType().equals("text")) {
        ctxt.incrementSize("message body", raw.length);
        // if the user has specified an alternative charset, make sure it exists and can encode the content
        String charset = CharsetUtil.checkCharset(text, ctxt.defaultCharset);
        ctype.setCharset(charset).setParameter(MimeConstants.P_CHARSET, charset);
        Object content = ctype.getContentType().equals(ContentType.MESSAGE_RFC822) ? new ZMimeMessage(JMSession.getSession(), new SharedByteArrayInputStream(raw)) : text;
        if (mmp != null) {
            MimeBodyPart mbp = new ZMimeBodyPart();
            mbp.setContent(content, ctype.toString());
            mmp.addBodyPart(mbp);
        } else {
            mm.setContent(content, ctype.toString());
        }
    }
    if (alternatives != null) {
        for (int i = 0; i < alternatives.length; i++) {
            ctxt.incrementSize("alternative body", alternatives[i].getSize());
            mmp.addBodyPart(alternatives[i]);
        }
    }
}
Also used : ZMimeMessage(com.zimbra.common.zmime.ZMimeMessage) ContentType(com.zimbra.common.mime.ContentType) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) MimeMultipart(javax.mail.internet.MimeMultipart) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) Element(com.zimbra.common.soap.Element) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MimeBodyPart(javax.mail.internet.MimeBodyPart) Mountpoint(com.zimbra.cs.mailbox.Mountpoint) SharedByteArrayInputStream(javax.mail.util.SharedByteArrayInputStream)

Example 12 with ZMimeMultipart

use of com.zimbra.common.zmime.ZMimeMultipart in project zm-mailbox by Zimbra.

the class SendDeliveryReport method sendReport.

public static void sendReport(Account authAccount, Message msg, boolean automatic, String requestHost, String userAgent) throws ServiceException {
    MimeMessage mm = msg.getMimeMessage();
    Account owner = msg.getMailbox().getAccount();
    String charset = authAccount.getPrefMailDefaultCharset();
    if (charset == null) {
        charset = MimeConstants.P_CHARSET_UTF8;
    }
    try {
        InternetAddress[] recipients = Mime.parseAddressHeader(mm, "Disposition-Notification-To");
        if (recipients == null || recipients.length == 0)
            return;
        SMTPMessage report = new SMTPMessage(JMSession.getSmtpSession());
        String subject = "Read-Receipt: " + msg.getSubject();
        report.setSubject(subject, CharsetUtil.checkCharset(subject, charset));
        report.setSentDate(new Date());
        report.setFrom(AccountUtil.getFriendlyEmailAddress(authAccount));
        report.addRecipients(javax.mail.Message.RecipientType.TO, recipients);
        report.setHeader("Auto-Submitted", "auto-replied (zimbra; read-receipt)");
        report.setHeader("Precedence", "bulk");
        if (Provisioning.getInstance().getConfig().isAutoSubmittedNullReturnPath()) {
            report.setEnvelopeFrom("<>");
        } else {
            report.setEnvelopeFrom(authAccount.getName());
        }
        MimeMultipart multi = new ZMimeMultipart("report");
        // part 1: human-readable notification
        String text = generateTextPart(owner, mm, authAccount.getLocale());
        MimeBodyPart mpText = new ZMimeBodyPart();
        mpText.setText(text, CharsetUtil.checkCharset(text, charset));
        multi.addBodyPart(mpText);
        // part 2: disposition notification
        String mdn = generateReport(owner, mm, automatic, requestHost, userAgent);
        MimeBodyPart mpMDN = new ZMimeBodyPart();
        mpMDN.setText(mdn, MimeConstants.P_CHARSET_UTF8);
        mpMDN.setHeader("Content-Type", "message/disposition-notification; charset=utf-8");
        multi.addBodyPart(mpMDN);
        //            // part 3: original message
        //            MimeBodyPart mpOriginal = new ZMimeBodyPart();
        //            mpOriginal.setDataHandler(new DataHandler(new BlobDataSource(msg.getBlob())));
        //            mpOriginal.setHeader("Content-Type", MimeConstants.CT_MESSAGE_RFC822);
        //            mpOriginal.setHeader("Content-Disposition", Part.ATTACHMENT);
        //            multi.addBodyPart(mpOriginal);
        report.setContent(multi);
        report.setHeader("Content-Type", multi.getContentType() + "; report-type=disposition-notification");
        report.saveChanges();
        Transport.send(report);
    } catch (MessagingException me) {
        throw ServiceException.FAILURE("error while sending read receipt", me);
    }
}
Also used : Account(com.zimbra.cs.account.Account) InternetAddress(javax.mail.internet.InternetAddress) SMTPMessage(com.sun.mail.smtp.SMTPMessage) MimeMessage(javax.mail.internet.MimeMessage) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) MimeMultipart(javax.mail.internet.MimeMultipart) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MessagingException(javax.mail.MessagingException) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MimeBodyPart(javax.mail.internet.MimeBodyPart) Date(java.util.Date)

Example 13 with ZMimeMultipart

use of com.zimbra.common.zmime.ZMimeMultipart in project zm-mailbox by Zimbra.

the class ParseMimeMessage method setMultipartContent.

private static void setMultipartContent(ContentType contentType, MimeMessage mm, MimeMultipart mmp, Element elem, MimeBodyPart[] alternatives, ParseMessageContext ctxt) throws MessagingException, ServiceException, IOException {
    // do we need to add a multipart/alternative for the alternatives?
    if (alternatives == null || contentType.getSubType().equals("alternative")) {
        // no need to add an extra multipart/alternative!
        // create the MimeMultipart and attach it to the existing structure:
        MimeMultipart mmpNew = new ZMimeMultipart(contentType);
        if (mmp == null) {
            // there were no multiparts at all, we need to create one
            mm.setContent(mmpNew);
        } else {
            // there was already a multipart/mixed at the top of the mm
            MimeBodyPart mbpWrapper = new ZMimeBodyPart();
            mbpWrapper.setContent(mmpNew);
            mmp.addBodyPart(mbpWrapper);
        }
        // add each part in turn (recursively) below
        for (Element subpart : elem.listElements()) {
            setContent(mm, mmpNew, subpart, null, ctxt);
        }
        // finally, add the alternatives if there are any...
        if (alternatives != null) {
            for (int i = 0; i < alternatives.length; i++) {
                ctxt.incrementSize("alternative", alternatives[i].getSize());
                mmpNew.addBodyPart(alternatives[i]);
            }
        }
    } else {
        // create a multipart/alternative to hold all the client's struct + the alternatives
        MimeMultipart mmpNew = new ZMimeMultipart("alternative");
        if (mmp == null) {
            mm.setContent(mmpNew);
        } else {
            MimeBodyPart mbpWrapper = new ZMimeBodyPart();
            mbpWrapper.setContent(mmpNew);
            mmp.addBodyPart(mbpWrapper);
        }
        // add the entire client's multipart/whatever here inside our multipart/alternative
        setContent(mm, mmpNew, elem, null, ctxt);
        // add all the alternatives
        for (int i = 0; i < alternatives.length; i++) {
            ctxt.incrementSize("alternative", alternatives[i].getSize());
            mmpNew.addBodyPart(alternatives[i]);
        }
    }
}
Also used : ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) MimeMultipart(javax.mail.internet.MimeMultipart) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) Element(com.zimbra.common.soap.Element) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MimeBodyPart(javax.mail.internet.MimeBodyPart) Mountpoint(com.zimbra.cs.mailbox.Mountpoint)

Example 14 with ZMimeMultipart

use of com.zimbra.common.zmime.ZMimeMultipart in project zm-mailbox by Zimbra.

the class CalendarMailSender method createForwardNotifyMessage.

public static MimeMessage createForwardNotifyMessage(Account senderAcct, Account toAcct, String to, Address[] rcpts, Invite inv) throws MessagingException, ServiceException {
    MimeMessage mm = new Mime.FixedMimeMessage(JMSession.getSession());
    Locale lc = toAcct.getLocale();
    mm.setSubject(L10nUtil.getMessage(MsgKey.calendarForwardNotificationSubject, lc, inv.getName()), MimeConstants.P_CHARSET_UTF8);
    mm.setSentDate(new Date());
    String postmaster = senderAcct.getAttr(Provisioning.A_zimbraNewMailNotificationFrom);
    Map<String, String> vars = new HashMap<String, String>();
    vars.put("RECIPIENT_DOMAIN", senderAcct.getDomainName());
    postmaster = StringUtil.fillTemplate(postmaster, vars);
    mm.setSender(new JavaMailInternetAddress(postmaster));
    mm.setFrom(new JavaMailInternetAddress(senderAcct.getName()));
    mm.setRecipient(RecipientType.TO, new JavaMailInternetAddress(to));
    MimeMultipart mmp = new ZMimeMultipart("alternative");
    mm.setContent(mmp);
    String sender = senderAcct.getCn() + " <" + senderAcct.getName() + ">";
    String time = FriendlyCalendaringDescription.getTimeDisplayString(inv.getStartTime(), inv.getEndTime(), inv.isRecurrence(), inv.isAllDayEvent(), lc, toAcct);
    StringBuilder sb = new StringBuilder();
    StringBuilder sbHtml = new StringBuilder();
    for (Address rcpt : rcpts) {
        sb.append(rcpt.toString()).append("\n\t");
        InternetAddress address = new JavaMailInternetAddress(rcpt.toString());
        sbHtml.append("<a href=\"mailto:").append(address.getAddress()).append("\">");
        if (address.getPersonal() != null) {
            sbHtml.append(address.getPersonal()).append("</a>").append("<br>");
        } else {
            sbHtml.append(address.getAddress()).append("</a>").append("<br>");
        }
    }
    String recipients = sb.toString();
    String recipientsHtml = sbHtml.toString();
    if (inv.isRecurrence()) {
        ZRecur zr = FriendlyCalendaringDescription.getRecur(inv);
        time += " (" + FriendlyCalendaringDescription.getRecurrenceDisplayString(zr, inv.getStartTime().getCalendarCopy(), lc) + ")";
    }
    String text = L10nUtil.getMessage(MsgKey.calendarForwardNotificationBody, lc, sender, inv.getName(), time, recipients);
    MimeBodyPart textPart = new ZMimeBodyPart();
    textPart.setText(text, MimeConstants.P_CHARSET_UTF8);
    mmp.addBodyPart(textPart);
    sender = "<a href=\"mailto:" + senderAcct.getName() + "\">" + senderAcct.getCn() + "</a>";
    String html = L10nUtil.getMessage(MsgKey.calendarForwardNotificationBodyHtml, lc, sender, inv.getName(), time, recipientsHtml);
    MimeBodyPart htmlPart = new ZMimeBodyPart();
    htmlPart.setContent(html, MimeConstants.CT_TEXT_HTML + "; " + MimeConstants.P_CHARSET + "=" + MimeConstants.P_CHARSET_UTF8);
    mmp.addBodyPart(htmlPart);
    mm.saveChanges();
    return mm;
}
Also used : Locale(java.util.Locale) InternetAddress(javax.mail.internet.InternetAddress) JavaMailInternetAddress(com.zimbra.common.mime.shim.JavaMailInternetAddress) Address(javax.mail.Address) InternetAddress(javax.mail.internet.InternetAddress) JavaMailInternetAddress(com.zimbra.common.mime.shim.JavaMailInternetAddress) HashMap(java.util.HashMap) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) Date(java.util.Date) ZMimeMessage(com.zimbra.common.zmime.ZMimeMessage) MimeMessage(javax.mail.internet.MimeMessage) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) MimeMultipart(javax.mail.internet.MimeMultipart) JavaMailInternetAddress(com.zimbra.common.mime.shim.JavaMailInternetAddress) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MimeBodyPart(javax.mail.internet.MimeBodyPart)

Example 15 with ZMimeMultipart

use of com.zimbra.common.zmime.ZMimeMultipart in project zm-mailbox by Zimbra.

the class CalendarMailSender method createCalendarMessage.

public static MimeMessage createCalendarMessage(Account account, Address fromAddr, Address senderAddr, List<Address> toAddrs, String subject, String desc, String descHtml, String uid, ZCalendar.ZVCalendar cal, List<Attach> attaches, boolean replyToSender) throws ServiceException {
    if (desc == null)
        desc = "";
    try {
        MimeMessage mm = new Mime.FixedMimeMessage(JMSession.getSmtpSession(account));
        MimeMultipart mpAlternatives = new ZMimeMultipart("alternative");
        if (attaches != null && !attaches.isEmpty()) {
            MimeMultipart mpMixed = new ZMimeMultipart("mixed");
            mm.setContent(mpMixed);
            MimeBodyPart mbpWrapper = new ZMimeBodyPart();
            mbpWrapper.setContent(mpAlternatives);
            mpMixed.addBodyPart(mbpWrapper);
            for (Attach attach : attaches) {
                byte[] rawData = attach.getDecodedData();
                if (rawData == null) {
                    continue;
                }
                ContentDisposition cdisp = new ContentDisposition(Part.ATTACHMENT, true);
                String ctypeAsString = attach.getContentType();
                if (ctypeAsString == null) {
                    ctypeAsString = MimeConstants.CT_APPLICATION_OCTET_STREAM;
                }
                ContentType ctype = new ContentType(ctypeAsString);
                if (attach.getFileName() != null) {
                    ctype.setParameter("name", attach.getFileName());
                    cdisp.setParameter("filename", attach.getFileName());
                }
                MimeBodyPart mbp2 = new ZMimeBodyPart();
                ByteArrayDataSource bads = new ByteArrayDataSource(rawData, ctypeAsString);
                mbp2.setDataHandler(new DataHandler(bads));
                mbp2.setHeader("Content-Type", ctype.toString());
                mbp2.setHeader("Content-Disposition", cdisp.toString());
                mbp2.setHeader("Content-Transfer-Encoding", "base64");
                mpMixed.addBodyPart(mbp2);
            }
        } else {
            mm.setContent(mpAlternatives);
        }
        // Add the text as DESCRIPTION property in the iCalendar part.
        // MS Entourage for Mac wants this.  It ignores text/plain and
        // text/html MIME parts.
        cal.addDescription(desc, null);
        // ///////
        // TEXT part (add me first!)
        MimeBodyPart textPart = new ZMimeBodyPart();
        textPart.setText(desc, MimeConstants.P_CHARSET_UTF8);
        mpAlternatives.addBodyPart(textPart);
        // HTML part is needed to keep Outlook happy as it doesn't know
        // how to deal with a message with only text/plain but no HTML.
        MimeBodyPart htmlPart = new ZMimeBodyPart();
        if (descHtml != null) {
            ContentType ct = new ContentType(MimeConstants.CT_TEXT_HTML);
            ct.setParameter(MimeConstants.P_CHARSET, MimeConstants.P_CHARSET_UTF8);
            htmlPart.setText(descHtml, MimeConstants.P_CHARSET_UTF8);
            htmlPart.setHeader("Content-Type", ct.toString());
        } else {
            htmlPart.setDataHandler(new DataHandler(new HtmlPartDataSource(desc)));
        }
        mpAlternatives.addBodyPart(htmlPart);
        // ///////
        // CALENDAR part
        MimeBodyPart icalPart = makeICalIntoMimePart(cal);
        mpAlternatives.addBodyPart(icalPart);
        // MESSAGE HEADERS
        if (subject != null) {
            mm.setSubject(subject, MimeConstants.P_CHARSET_UTF8);
        }
        if (toAddrs != null) {
            Address[] addrs = new Address[toAddrs.size()];
            toAddrs.toArray(addrs);
            mm.addRecipients(javax.mail.Message.RecipientType.TO, addrs);
        }
        if (fromAddr != null)
            mm.setFrom(fromAddr);
        if (senderAddr != null) {
            mm.setSender(senderAddr);
            if (replyToSender) {
                mm.setReplyTo(new Address[] { senderAddr });
            }
        }
        mm.setSentDate(new Date());
        mm.saveChanges();
        return mm;
    } catch (MessagingException e) {
        throw ServiceException.FAILURE("Messaging Exception while building MimeMessage from invite", e);
    }
}
Also used : ContentType(javax.mail.internet.ContentType) Address(javax.mail.Address) InternetAddress(javax.mail.internet.InternetAddress) JavaMailInternetAddress(com.zimbra.common.mime.shim.JavaMailInternetAddress) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MessagingException(javax.mail.MessagingException) Attach(com.zimbra.common.calendar.Attach) DataHandler(javax.activation.DataHandler) Date(java.util.Date) ContentDisposition(com.zimbra.common.mime.ContentDisposition) ZMimeMessage(com.zimbra.common.zmime.ZMimeMessage) MimeMessage(javax.mail.internet.MimeMessage) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) MimeMultipart(javax.mail.internet.MimeMultipart) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MimeBodyPart(javax.mail.internet.MimeBodyPart) ByteArrayDataSource(javax.mail.util.ByteArrayDataSource)

Aggregations

ZMimeMultipart (com.zimbra.common.zmime.ZMimeMultipart)22 MimeMultipart (javax.mail.internet.MimeMultipart)19 ZMimeBodyPart (com.zimbra.common.zmime.ZMimeBodyPart)18 MimeBodyPart (javax.mail.internet.MimeBodyPart)17 MimeMessage (javax.mail.internet.MimeMessage)17 MessagingException (javax.mail.MessagingException)14 ZMimeMessage (com.zimbra.common.zmime.ZMimeMessage)9 JavaMailInternetAddress (com.zimbra.common.mime.shim.JavaMailInternetAddress)7 IOException (java.io.IOException)7 Date (java.util.Date)7 DataHandler (javax.activation.DataHandler)7 SMTPMessage (com.sun.mail.smtp.SMTPMessage)5 Account (com.zimbra.cs.account.Account)5 InternetAddress (javax.mail.internet.InternetAddress)5 ContentDisposition (com.zimbra.common.mime.ContentDisposition)4 Locale (java.util.Locale)4 ByteArrayDataSource (javax.mail.util.ByteArrayDataSource)4 Element (com.zimbra.common.soap.Element)3 Message (com.zimbra.cs.mailbox.Message)3 Mountpoint (com.zimbra.cs.mailbox.Mountpoint)3