Search in sources :

Example 6 with ZMimeMultipart

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

the class CalendarItem method createBlob.

/**
     * The Blob for the appointment/task is currently single Mime multipart/digest which has
     * each invite's MimeMessage stored as a part.
     *
     * @param invPm
     * @param firstInvite
     * @throws ServiceException
     */
private MailboxBlob createBlob(ParsedMessage invPm, Invite firstInvite) throws ServiceException {
    // Create blob only if there's an attachment or DESCRIPTION is too big to be stored in metadata.
    if (!firstInvite.hasAttachment() && (invPm == null || firstInvite.descInMeta())) {
        // If we're not going to create a blob after all, we must at least save the metadata to db.
        // It's weird that the db update is implicitly required of this method, but that's the way
        // it is, unfortunately.  If we're creating a blob, the implicit db update is done by
        // storeUpdatedBlob() call.  (see below)
        saveMetadata();
        return null;
    }
    try {
        // create the toplevel multipart/digest...
        MimeMessage mm = new Mime.FixedMimeMessage(JMSession.getSession());
        MimeMultipart mmp = new ZMimeMultipart("digest");
        mm.setContent(mmp);
        // add the invite
        MimeBodyPart mbp = new ZMimeBodyPart();
        mbp.setDataHandler(new DataHandler(new PMDataSource(invPm)));
        mbp.addHeader("invId", Integer.toString(firstInvite.getMailItemId()));
        mmp.addBodyPart(mbp);
        mm.saveChanges();
        return storeUpdatedBlob(mm);
    } catch (MessagingException e) {
        throw ServiceException.FAILURE("MessagingException " + e, e);
    } catch (IOException e) {
        throw ServiceException.FAILURE("IOException " + e, e);
    }
}
Also used : MimeMessage(javax.mail.internet.MimeMessage) FixedMimeMessage(com.zimbra.cs.mime.Mime.FixedMimeMessage) 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) FixedMimeMessage(com.zimbra.cs.mime.Mime.FixedMimeMessage) DataHandler(javax.activation.DataHandler) IOException(java.io.IOException) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MimeBodyPart(javax.mail.internet.MimeBodyPart)

Example 7 with ZMimeMultipart

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

the class ParsedContact method generateMimeMessage.

private static MimeMessage generateMimeMessage(List<Attachment> attachments) throws MessagingException {
    MimeMessage mm = new Mime.FixedMimeMessage(JMSession.getSession());
    MimeMultipart multi = new ZMimeMultipart("mixed");
    int part = 1;
    for (Attachment attach : attachments) {
        ContentDisposition cdisp = new ContentDisposition(Part.ATTACHMENT);
        cdisp.setParameter("filename", attach.getFilename()).setParameter("field", attach.getName());
        MimeBodyPart bp = new ZMimeBodyPart();
        // it gets called before setting Content-Type and CTE headers.
        try {
            bp.setDataHandler(new DataHandler(new ByteArrayDataSource(attach.getContent(), attach.getContentType())));
        } catch (IOException e) {
            throw new MessagingException("could not generate mime part content", e);
        }
        bp.addHeader("Content-Disposition", cdisp.toString());
        bp.addHeader("Content-Type", attach.getContentType());
        bp.addHeader("Content-Transfer-Encoding", MimeConstants.ET_8BIT);
        multi.addBodyPart(bp);
        attach.setPartName(Integer.toString(part++));
    }
    mm.setContent(multi);
    mm.saveChanges();
    return mm;
}
Also used : ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MessagingException(javax.mail.MessagingException) Attachment(com.zimbra.cs.mailbox.Contact.Attachment) DataHandler(javax.activation.DataHandler) IOException(java.io.IOException) ContentDisposition(com.zimbra.common.mime.ContentDisposition) 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)

Example 8 with ZMimeMultipart

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

the class SpamHandler method sendReport.

private void sendReport(SpamReport sr) throws ServiceException, MessagingException {
    Config config = Provisioning.getInstance().getConfig();
    String isSpamString = sr.isSpam ? config.getSpamReportTypeSpam() : config.getSpamReportTypeHam();
    SMTPMessage out = new SMTPMessage(JMSession.getSmtpSession());
    Mailbox mbox = MailboxManager.getInstance().getMailboxById(sr.mailboxId);
    Message msg = mbox.getMessageById(null, sr.messageId);
    MimeMultipart mmp = new ZMimeMultipart("mixed");
    MimeBodyPart infoPart = new ZMimeBodyPart();
    infoPart.setHeader("Content-Description", "Zimbra spam classification report");
    String body = String.format("Classified-By: %s\r\n" + "Classified-As: %s\r\n" + "Action: %s\r\n" + "Source-Folder: %s\r\n" + "Destination-Folder: %s\r\n" + "Destination-Mailbox: %s\r\n", Strings.nullToEmpty(sr.accountName), isSpamString, Strings.nullToEmpty(sr.action), Strings.nullToEmpty(sr.sourceFolder), Strings.nullToEmpty(sr.destFolder), Strings.nullToEmpty(sr.destAccountName));
    infoPart.setText(body);
    mmp.addBodyPart(infoPart);
    MailboxBlob blob = msg.getBlob();
    MimeBodyPart mbp = new ZMimeBodyPart();
    mbp.setDataHandler(new DataHandler(new MailboxBlobDataSource(blob)));
    mbp.setHeader("Content-Type", MimeConstants.CT_MESSAGE_RFC822);
    mbp.setHeader("Content-Disposition", Part.ATTACHMENT);
    mmp.addBodyPart(mbp);
    out.setContent(mmp);
    out.addHeader(config.getSpamReportSenderHeader(), sr.accountName);
    out.addHeader(config.getSpamReportTypeHeader(), isSpamString);
    if (config.isSmtpSendAddOriginatingIP() && sr.origIp != null)
        out.addHeader(MailSender.X_ORIGINATING_IP, MailSender.formatXOrigIpHeader(sr.origIp));
    out.setRecipient(javax.mail.Message.RecipientType.TO, sr.reportRecipient);
    out.setEnvelopeFrom(config.getSpamReportEnvelopeFrom());
    out.setSubject(config.getSpamTrainingSubjectPrefix() + " " + sr.accountName + ": " + isSpamString);
    Transport.send(out);
    ZimbraLog.misc.info("Sent " + sr);
}
Also used : SMTPMessage(com.sun.mail.smtp.SMTPMessage) Mailbox(com.zimbra.cs.mailbox.Mailbox) Message(com.zimbra.cs.mailbox.Message) SMTPMessage(com.sun.mail.smtp.SMTPMessage) MimeMessage(javax.mail.internet.MimeMessage) MailboxBlob(com.zimbra.cs.store.MailboxBlob) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) MimeMultipart(javax.mail.internet.MimeMultipart) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MailboxBlobDataSource(com.zimbra.cs.mime.MailboxBlobDataSource) Config(com.zimbra.cs.account.Config) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) DataHandler(javax.activation.DataHandler) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MimeBodyPart(javax.mail.internet.MimeBodyPart)

Example 9 with ZMimeMultipart

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

the class UUEncodeConverter method visitMessage.

@Override
protected boolean visitMessage(MimeMessage mm, VisitPhase visitKind) throws MessagingException {
    // do the decode in the exit phase
    if (visitKind != VisitPhase.VISIT_END)
        return false;
    MimeMultipart mmp = null;
    try {
        // only check "text/plain" parts for uudecodeable attachments
        if (!mm.isMimeType(MimeConstants.CT_TEXT_PLAIN))
            return false;
        // don't check transfer-encoded parts for uudecodeable attachments
        String cte = mm.getHeader("Content-Transfer-Encoding", null);
        if (cte != null) {
            cte = cte.trim().toLowerCase();
            if (!cte.equals(MimeConstants.ET_7BIT) && !cte.equals(MimeConstants.ET_8BIT) && !cte.equals(MimeConstants.ET_BINARY))
                return false;
        }
        List<UUDecodedFile> uufiles = null;
        // go through top-level text/plain part and extract uuencoded files
        PositionInputStream is = null;
        long size;
        try {
            is = new PositionInputStream(new BufferedInputStream(mm.getInputStream()));
            for (int c = is.read(); c != -1; ) {
                long start = is.getPosition() - 1;
                // check for uuencode header: "begin NNN filename"
                if (c == 'b' && (c = is.read()) == 'e' && (c = is.read()) == 'g' && (c = is.read()) == 'i' && (c = is.read()) == 'n' && ((c = is.read()) == ' ' || c == '\t') && Character.isDigit((c = is.read())) && Character.isDigit(c = is.read()) && Character.isDigit(c = is.read()) && ((c = is.read()) == ' ' || c == '\t')) {
                    StringBuilder sb = new StringBuilder();
                    while ((c = is.read()) != '\r' && c != '\n' && c != -1) sb.append((char) c);
                    String filename = FileUtil.trimFilename(sb.toString().trim());
                    if (c != -1 && filename.length() > 0) {
                        if (uufiles == null)
                            uufiles = new ArrayList<UUDecodedFile>(3);
                        try {
                            uufiles.add(new UUDecodedFile(is, filename, start));
                            // check to make sure that the caller's OK with altering the message
                            if (uufiles.size() == 1 && mCallback != null && !mCallback.onModification())
                                return false;
                        } catch (IOException ioe) {
                        }
                    }
                }
                // skip to the beginning of the next line
                while (c != '\r' && c != '\n' && c != -1) c = is.read();
                while (c == '\r' || c == '\n') c = is.read();
            }
            size = is.getPosition();
        } finally {
            ByteUtil.closeStream(is);
        }
        if (uufiles == null || uufiles.isEmpty())
            return false;
        // create MimeParts for the extracted files
        mmp = new ZMimeMultipart("mixed");
        for (UUDecodedFile uu : uufiles) {
            MimeBodyPart mbp = new ZMimeBodyPart();
            mbp.setHeader("Content-Type", uu.getContentType());
            mbp.setHeader("Content-Disposition", new ContentDisposition(Part.ATTACHMENT).setParameter("filename", uu.getFilename()).toString());
            mbp.setDataHandler(new DataHandler(uu.getDataSource()));
            mmp.addBodyPart(mbp);
            size -= uu.getEndOffset() - uu.getStartOffset();
        }
        // take the remaining text and put it in as the first "related" part
        InputStream isOrig = null;
        try {
            isOrig = mm.getInputStream();
            long offset = 0;
            ByteArrayOutputStream baos = new ByteArrayOutputStream((int) size);
            byte[] buffer = new byte[8192];
            for (UUDecodedFile uu : uufiles) {
                long count = uu.getStartOffset() - offset, numRead;
                while (count > 0 && (numRead = isOrig.read(buffer, 0, (int) Math.min(count, 8192))) >= 0) {
                    baos.write(buffer, 0, (int) numRead);
                    count -= numRead;
                }
                isOrig.skip(uu.getEndOffset() - uu.getStartOffset());
                offset = uu.getEndOffset();
            }
            ByteUtil.copy(isOrig, true, baos, true);
            MimeBodyPart mbp = new ZMimeBodyPart();
            mbp.setDataHandler(new DataHandler(new ByteArrayDataSource(baos.toByteArray(), MimeConstants.CT_TEXT_PLAIN)));
            mmp.addBodyPart(mbp, 0);
        } finally {
            ByteUtil.closeStream(isOrig);
        }
    } catch (MessagingException e) {
        ZimbraLog.extensions.warn("exception while uudecoding message part; skipping part", e);
        return false;
    } catch (IOException e) {
        ZimbraLog.extensions.warn("exception while uudecoding message part; skipping part", e);
        return false;
    }
    // replace the top-level part with a new multipart/related
    mm.setContent(mmp);
    mm.setHeader("Content-Type", mmp.getContentType() + "; generated=true");
    return true;
}
Also used : ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MessagingException(javax.mail.MessagingException) BufferedInputStream(java.io.BufferedInputStream) PositionInputStream(com.zimbra.common.util.ByteUtil.PositionInputStream) InputStream(java.io.InputStream) ArrayList(java.util.ArrayList) IOException(java.io.IOException) DataHandler(javax.activation.DataHandler) ByteArrayOutputStream(java.io.ByteArrayOutputStream) ContentDisposition(com.zimbra.common.mime.ContentDisposition) MimeMultipart(javax.mail.internet.MimeMultipart) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) BufferedInputStream(java.io.BufferedInputStream) PositionInputStream(com.zimbra.common.util.ByteUtil.PositionInputStream) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MimeBodyPart(javax.mail.internet.MimeBodyPart) ByteArrayDataSource(javax.mail.util.ByteArrayDataSource)

Example 10 with ZMimeMultipart

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

the class ParseMimeMessage method parseMimeMsgSoap.

/**
     * Given an {@code <m>} element from SOAP, return us a parsed {@link MimeMessage}, and also fill in the
     * {@link MimeMessageData} structure with information we parsed out of it (e.g. contained Invite, msgids, etc etc)
     *
     * @param msgElem the {@code <m>} element
     * @param additionalParts MimeBodyParts that we want to have added to the {@link MimeMessage} (ie things the server
     * is adding onto the message)
     * @param inviteParser Callback which handles {@code <inv>} embedded invite components
     * @param out Holds info about things we parsed out of the message that the caller might want to know about
     */
public static MimeMessage parseMimeMsgSoap(ZimbraSoapContext zsc, OperationContext octxt, Mailbox mbox, Element msgElem, MimeBodyPart[] additionalParts, InviteParser inviteParser, MimeMessageData out, boolean attachMessageFromCache) throws ServiceException {
    // msgElem == "<m>" E_MSG
    assert (msgElem.getName().equals(MailConstants.E_MSG));
    Account target = DocumentHandler.getRequestedAccount(zsc);
    ParseMessageContext ctxt = new ParseMessageContext();
    ctxt.out = out;
    ctxt.zsc = zsc;
    ctxt.octxt = octxt;
    ctxt.mbox = mbox;
    ctxt.use2231 = target.isPrefUseRfc2231();
    ctxt.defaultCharset = target.getPrefMailDefaultCharset();
    if (Strings.isNullOrEmpty(ctxt.defaultCharset)) {
        ctxt.defaultCharset = MimeConstants.P_CHARSET_UTF8;
    }
    try {
        MimeMessage mm = new Mime.FixedMimeMessage(JMSession.getSmtpSession(target));
        MimeMultipart mmp = null;
        Element partElem = msgElem.getOptionalElement(MailConstants.E_MIMEPART);
        Element attachElem = msgElem.getOptionalElement(MailConstants.E_ATTACH);
        Element inviteElem = msgElem.getOptionalElement(MailConstants.E_INVITE);
        boolean hasContent = (partElem != null || inviteElem != null || additionalParts != null);
        // || inviteElem != null || additionalParts!=null);
        boolean isMultipart = (attachElem != null);
        if (isMultipart) {
            // may need to change to "digest" later
            mmp = new ZMimeMultipart("mixed");
            mm.setContent(mmp);
        }
        // Grab the <inv> part now so we can stick it in a multipart/alternative if necessary
        MimeBodyPart[] alternatives = null;
        if (inviteElem != null) {
            int additionalLen = 0;
            if (additionalParts != null) {
                additionalLen += additionalParts.length;
            }
            alternatives = new MimeBodyPart[additionalLen + 1];
            int curAltPart = 0;
            // goes into the "content" subpart
            InviteParserResult result = inviteParser.parse(zsc, octxt, mbox.getAccount(), inviteElem);
            if (partElem != null && result.mCal != null) {
                // If textual content is provided and there's an invite,
                // set the text as DESCRIPTION of the iCalendar.  This helps
                // clients that ignore alternative text content and only
                // displays the DESCRIPTION specified in the iCalendar part.
                // (e.g. MS Entourage for Mac)
                String desc = getTextPlainContent(partElem);
                String html = getTextHtmlContent(partElem);
                result.mCal.addDescription(desc, html);
                if (result.mInvite != null) {
                    // It's possible the notes were given in <inv> node only, with no corresponding MIME parts.
                    if ((desc != null && desc.length() > 0) || (html != null && html.length() > 0)) {
                        result.mInvite.setDescription(desc, html);
                        if (desc != null && desc.length() > 0) {
                            result.mInvite.setFragment(Fragment.getFragment(desc, true));
                        }
                    }
                }
            }
            MimeBodyPart mbp = CalendarMailSender.makeICalIntoMimePart(result.mCal);
            alternatives[curAltPart++] = mbp;
            if (additionalParts != null) {
                for (int i = 0; i < additionalParts.length; i++) {
                    alternatives[curAltPart++] = additionalParts[i];
                }
            }
        } else {
            alternatives = additionalParts;
        }
        // handle the content from the client, if any
        if (hasContent) {
            setContent(mm, mmp, partElem != null ? partElem : inviteElem, alternatives, ctxt);
        }
        // attachments go into the toplevel "mixed" part
        if (isMultipart && attachElem != null) {
            handleAttachments(attachElem, mmp, ctxt, null, Part.ATTACHMENT, attachMessageFromCache);
        }
        // <m> attributes: id, f[lags], s[ize], d[ate], cid(conv-id), l(parent folder)
        // <m> child elements: <e> (email), <s> (subject), <f> (fragment), <mp>, <attach>
        MessageAddresses maddrs = new MessageAddresses();
        Set<String> headerNames = ImmutableSet.copyOf(Provisioning.getInstance().getConfig().getCustomMimeHeaderNameAllowed());
        for (Element elem : msgElem.listElements()) {
            String eName = elem.getName();
            if (eName.equals(MailConstants.E_ATTACH)) {
            // ignore it...
            } else if (eName.equals(MailConstants.E_MIMEPART)) {
            /* <mp> */
            // processMessagePart(mm, elem);
            } else if (eName.equals(MailConstants.E_EMAIL)) {
                /* <e> */
                maddrs.add(elem, ctxt.defaultCharset);
            } else if (eName.equals(MailConstants.E_IN_REPLY_TO)) {
            /* <irt> */
            // mm.setHeader("In-Reply-To", elem.getText());
            } else if (eName.equals(MailConstants.E_SUBJECT)) {
            /* <su> */
            // mm.setSubject(elem.getText(), "utf-8");
            } else if (eName.equals(MailConstants.E_FRAG)) {
                /* <f> */
                ZimbraLog.soap.debug("Ignoring message fragment data");
            } else if (eName.equals(MailConstants.E_INVITE)) {
            /* <inv> */
            // Already processed above.  Ignore it.
            } else if (eName.equals(MailConstants.E_CAL_TZ)) {
            /* <tz> */
            // Ignore as a special case.
            } else if (eName.equals(MailConstants.E_HEADER)) {
                // <h>
                String name = elem.getAttribute(MailConstants.A_NAME);
                if (headerNames.contains(name)) {
                    mm.addHeader(name, MimeHeader.escape(elem.getText(), Charsets.UTF_8, true));
                } else {
                    throw ServiceException.INVALID_REQUEST("header '" + name + "' not allowed", null);
                }
            } else {
                ZimbraLog.soap.warn("unsupported child element '%s' under parent %s", elem.getName(), msgElem.getName());
            }
        }
        // deal with things that can be either <m> attributes or subelements
        String subject = msgElem.getAttribute(MailConstants.E_SUBJECT, "");
        mm.setSubject(subject, CharsetUtil.checkCharset(subject, ctxt.defaultCharset));
        String irt = cleanReference(msgElem.getAttribute(MailConstants.E_IN_REPLY_TO, null));
        if (irt != null) {
            mm.setHeader("In-Reply-To", irt);
        }
        // can have no addresses specified if it's a draft...
        if (!maddrs.isEmpty()) {
            addAddressHeaders(mm, maddrs);
        }
        if (!hasContent && !isMultipart) {
            mm.setText("", MimeConstants.P_CHARSET_DEFAULT);
        }
        String flagStr = msgElem.getAttribute(MailConstants.A_FLAGS, "");
        if (flagStr.indexOf(Flag.toChar(Flag.ID_HIGH_PRIORITY)) != -1) {
            mm.addHeader("X-Priority", "1");
            mm.addHeader("Importance", "high");
        } else if (flagStr.indexOf(Flag.toChar(Flag.ID_LOW_PRIORITY)) != -1) {
            mm.addHeader("X-Priority", "5");
            mm.addHeader("Importance", "low");
        }
        // JavaMail tip: don't forget to call this, it is REALLY confusing.
        mm.saveChanges();
        return mm;
    } catch (UnsupportedEncodingException e) {
        throw ServiceException.FAILURE("UnsupportedEncodingExecption", e);
    } catch (SendFailedException e) {
        SafeSendFailedException ssfe = new SafeSendFailedException(e);
        throw ServiceException.FAILURE("SendFailure", ssfe);
    } catch (MessagingException e) {
        throw ServiceException.FAILURE("MessagingExecption", e);
    } catch (IOException e) {
        throw ServiceException.FAILURE("IOExecption", e);
    }
}
Also used : Account(com.zimbra.cs.account.Account) SendFailedException(javax.mail.SendFailedException) SafeSendFailedException(com.zimbra.cs.mailbox.MailSender.SafeSendFailedException) MessagingException(javax.mail.MessagingException) Element(com.zimbra.common.soap.Element) UnsupportedEncodingException(java.io.UnsupportedEncodingException) SafeSendFailedException(com.zimbra.cs.mailbox.MailSender.SafeSendFailedException) IOException(java.io.IOException) Mountpoint(com.zimbra.cs.mailbox.Mountpoint) 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)

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