use of javax.mail.internet.MimeMultipart 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);
}
}
use of javax.mail.internet.MimeMultipart in project zm-mailbox by Zimbra.
the class SendShareNotification method generateShareNotification.
protected MimeMessage generateShareNotification(Account authAccount, Account ownerAccount, ShareInfoData sid, String notes, Action action, Collection<String> internlaRecipients, String externalRecipient) throws ServiceException, MessagingException {
Locale locale = authAccount.getLocale();
String charset = authAccount.getAttr(Provisioning.A_zimbraPrefMailDefaultCharset, MimeConstants.P_CHARSET_UTF8);
MimeMessage mm = new Mime.FixedMimeMessage(JMSession.getSmtpSession(authAccount));
MsgKey subjectKey;
if (action == null) {
subjectKey = MsgKey.shareNotifSubject;
} else {
switch(action) {
case edit:
subjectKey = MsgKey.shareModifySubject;
break;
case revoke:
subjectKey = MsgKey.shareRevokeSubject;
break;
case expire:
subjectKey = MsgKey.shareExpireSubject;
break;
default:
subjectKey = MsgKey.shareNotifSubject;
}
}
String subject = L10nUtil.getMessage(subjectKey, locale);
String ownerAcctDisplayName = ownerAccount.getDisplayName();
if (ownerAcctDisplayName == null) {
ownerAcctDisplayName = ownerAccount.getName();
}
subject += L10nUtil.getMessage(MsgKey.sharedBySubject, locale, sid.getName(), ownerAcctDisplayName);
mm.setSubject(subject, CharsetUtil.checkCharset(subject, charset));
mm.setSentDate(new Date());
// from the owner
mm.setFrom(AccountUtil.getFriendlyEmailAddress(ownerAccount));
// sent by auth account
mm.setSender(AccountUtil.getFriendlyEmailAddress(authAccount));
// to the grantee
if (internlaRecipients != null) {
assert (externalRecipient == null);
for (String recipient : internlaRecipients) {
try {
mm.addRecipient(javax.mail.Message.RecipientType.TO, new JavaMailInternetAddress(recipient));
} catch (AddressException e) {
sLog.warn("Ignoring error while sending share notification to " + recipient, e);
}
}
} else if (externalRecipient != null) {
mm.setRecipient(javax.mail.Message.RecipientType.TO, new JavaMailInternetAddress(externalRecipient));
} else {
String recipient = sid.getGranteeName();
mm.setRecipient(javax.mail.Message.RecipientType.TO, new JavaMailInternetAddress(recipient));
}
MimeMultipart mmp = ShareInfo.NotificationSender.genNotifBody(sid, notes, locale, action, externalRecipient);
mm.setContent(mmp);
mm.saveChanges();
if (sLog.isDebugEnabled()) {
// log4j.logger.com.zimbra.cs.service.mail=DEBUG
try {
ByteArrayOutputStream buf = new ByteArrayOutputStream();
mm.writeTo(buf);
String mmDump = new String(buf.toByteArray());
sLog.debug("********\n" + mmDump);
} catch (MessagingException e) {
sLog.debug("failed log debug share notification message", e);
} catch (IOException e) {
sLog.debug("failed log debug share notification message", e);
}
}
return mm;
}
use of javax.mail.internet.MimeMultipart 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);
}
use of javax.mail.internet.MimeMultipart 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;
}
use of javax.mail.internet.MimeMultipart in project zm-mailbox by Zimbra.
the class TnefConverter method visitMessage.
@Override
protected boolean visitMessage(MimeMessage msg, VisitPhase visitKind) throws MessagingException {
// do the decode in the exit phase
if (visitKind == VisitPhase.VISIT_BEGIN) {
mMimeMessage = msg;
return false;
}
try {
// we only care about "application/ms-tnef" content
if (!TNEFUtils.isTNEFMimeType(msg.getContentType()))
return false;
// check to make sure that the caller's OK with altering the message
if (mCallback != null && !mCallback.onModification())
return false;
} catch (MessagingException e) {
ZimbraLog.extensions.warn("exception while checking message for TNEF content; skipping part");
return false;
}
MimeMultipart multi = null;
MimeBodyPart tnefPart = null;
try {
Object content = msg.getContent();
if (!(content instanceof MimeBodyPart))
return false;
tnefPart = (MimeBodyPart) content;
// try to expand the TNEF into a suitable multipart
multi = expandTNEF(tnefPart);
if (multi == null)
return false;
// add the TNEF to the expanded multipart
multi.addBodyPart(tnefPart, 0);
} catch (MessagingException e) {
ZimbraLog.extensions.warn("exception while decoding TNEF message content; skipping part", e);
return false;
} catch (IOException e) {
ZimbraLog.extensions.warn("exception while decoding TNEF message content; skipping part", e);
return false;
}
// and put the new multipart/alternative where the TNEF used to be
msg.setContent(multi);
msg.setHeader("Content-Type", multi.getContentType() + "; generated=true");
return true;
}
Aggregations