use of com.zimbra.common.zmime.ZMimeBodyPart in project zm-mailbox by Zimbra.
the class Notification method interceptIfNecessary.
/**
* If <tt>zimbraInterceptAddress</tt> is specified, sends a message to that
* address with the given message attached.
*
* @param operation name of the operation being performed (send, add message, save draft, etc.)
* @param folder the folder that the message was filed into, or <tt>null</tt>
*/
void interceptIfNecessary(Mailbox mbox, MimeMessage msg, String operation, Folder folder) throws ServiceException {
// Don't do anything if intercept is turned off.
Account account = mbox.getAccount();
String[] interceptAddresses = account.getMultiAttr(Provisioning.A_zimbraInterceptAddress);
if (interceptAddresses.length == 0) {
return;
}
for (String interceptAddress : interceptAddresses) {
try {
ZimbraLog.mailbox.info("Sending intercept of message %s to %s.", msg.getMessageID(), interceptAddress);
// Fill templates
String folderName = "none";
String folderId = "none";
if (folder != null) {
folderName = folder.getName();
folderId = Integer.toString(folder.getId());
}
Map<String, String> vars = new HashMap<String, String>();
vars.put("ACCOUNT_DOMAIN", getDomain(account.getName()));
vars.put("ACCOUNT_ADDRESS", account.getName());
vars.put("MESSAGE_SUBJECT", Mime.getSubject(msg));
vars.put("OPERATION", operation);
vars.put("FOLDER_NAME", folderName);
vars.put("FOLDER_ID", folderId);
vars.put("NEWLINE", "\r\n");
String from = StringUtil.fillTemplate(account.getAttr(Provisioning.A_zimbraInterceptFrom), vars);
String subject = StringUtil.fillTemplate(account.getAttr(Provisioning.A_zimbraInterceptSubject), vars);
String bodyText = StringUtil.fillTemplate(account.getAttr(Provisioning.A_zimbraInterceptBody), vars);
// Assemble outgoing message
MimeMessage attached = msg;
boolean headersOnly = account.getBooleanAttr(Provisioning.A_zimbraInterceptSendHeadersOnly, false);
if (headersOnly) {
attached = new MimeMessageWithId(msg.getMessageID());
Enumeration e = msg.getAllHeaderLines();
while (e.hasMoreElements()) {
attached.addHeaderLine((String) e.nextElement());
}
attached.setContent("", msg.getContentType());
attached.saveChanges();
}
SMTPMessage out = new SMTPMessage(JMSession.getSmtpSession());
out.setHeader("Auto-Submitted", "auto-replied (zimbra; intercept)");
InternetAddress address = new JavaMailInternetAddress(from);
out.setFrom(address);
address = new JavaMailInternetAddress(interceptAddress);
out.setRecipient(javax.mail.Message.RecipientType.TO, address);
String charset = getCharset(account, subject);
out.setSubject(subject, charset);
charset = getCharset(account, bodyText);
MimeMultipart multi = new ZMimeMultipart();
// Add message body
MimeBodyPart part = new ZMimeBodyPart();
part.setText(bodyText, charset);
multi.addBodyPart(part);
// Add original message
MimeBodyPart part2 = new ZMimeBodyPart();
part2.setContent(attached, MimeConstants.CT_MESSAGE_RFC822);
multi.addBodyPart(part2);
out.setContent(multi);
String envFrom = "<>";
out.setEnvelopeFrom(envFrom);
out.saveChanges();
Transport.send(out);
// clean up after ourselves...
multi.removeBodyPart(part2);
} catch (MessagingException e) {
ZimbraLog.lmtp.warn("Unable to send intercept message to %s.", interceptAddress, e);
}
}
}
use of com.zimbra.common.zmime.ZMimeBodyPart in project zm-mailbox by Zimbra.
the class FeedManager method generateMessage.
private static ParsedMessage generateMessage(String title, String content, String ctype, InternetAddress addr, Date date, List<Enclosure> attach) throws ServiceException {
// cull out invalid enclosures
if (attach != null) {
for (Iterator<Enclosure> it = attach.iterator(); it.hasNext(); ) {
if (it.next().getLocation() == null) {
it.remove();
}
}
}
boolean hasAttachments = attach != null && !attach.isEmpty();
// clean up whitespace in the title
if (title != null) {
title = title.replaceAll("\\s+", " ");
}
// create the MIME message and wrap it
try {
MimeMessage mm = new Mime.FixedMimeMessage(JMSession.getSession());
MimePart body = hasAttachments ? new ZMimeBodyPart() : (MimePart) mm;
body.setText(content, "utf-8");
body.setHeader("Content-Type", ctype);
if (hasAttachments) {
// encode each enclosure as an attachment with Content-Location set
MimeMultipart mmp = new ZMimeMultipart("mixed");
mmp.addBodyPart((BodyPart) body);
for (Enclosure enc : attach) {
MimeBodyPart part = new ZMimeBodyPart();
part.setText("");
part.addHeader("Content-Location", enc.getLocation());
part.addHeader("Content-Type", enc.getContentType());
if (enc.getDescription() != null) {
part.addHeader("Content-Description", enc.getDescription());
}
part.addHeader("Content-Disposition", "attachment");
mmp.addBodyPart(part);
}
mm.setContent(mmp);
}
mm.setSentDate(date);
mm.addFrom(new InternetAddress[] { addr });
mm.setSubject(title, "utf-8");
// more stuff here!
mm.saveChanges();
return new ParsedMessage(mm, date.getTime(), false);
} catch (MessagingException e) {
throw ServiceException.PARSE_ERROR("error wrapping feed item in MimeMessage", e);
}
}
use of com.zimbra.common.zmime.ZMimeBodyPart in project zm-mailbox by Zimbra.
the class MessageBuilder method create.
public String create() throws MessagingException, ServiceException, IOException {
if (toRecipient == null) {
toRecipient = "user1";
}
if (from == null) {
from = "jspiccoli";
}
if (date == null) {
date = new Date();
}
if (contentType == null) {
contentType = MimeConstants.CT_TEXT_PLAIN;
}
if (body == null) {
body = MessageBuilder.DEFAULT_MESSAGE_BODY;
}
from = TestUtil.addDomainIfNecessary(from);
toRecipient = TestUtil.addDomainIfNecessary(toRecipient);
sender = TestUtil.addDomainIfNecessary(sender);
MimeMessage msg = addMessageIdHeader ? new ZMimeMessage(JMSession.getSession()) : new MimeMessageWithNoId();
msg.setRecipient(RecipientType.TO, new JavaMailInternetAddress(toRecipient));
if (ccRecipient != null) {
ccRecipient = TestUtil.addDomainIfNecessary(ccRecipient);
msg.setRecipient(RecipientType.CC, new JavaMailInternetAddress(ccRecipient));
}
msg.setFrom(new JavaMailInternetAddress(from));
if (sender != null) {
msg.setSender(new JavaMailInternetAddress(sender));
}
msg.setSentDate(date);
msg.setSubject(subject);
if (attachment == null) {
// Need to specify the data handler explicitly because JavaMail
// doesn't know what to do with text/enriched.
msg.setDataHandler(new DataHandler(new ByteArrayDataSource(body.getBytes(), contentType)));
} else {
MimeMultipart multi = new ZMimeMultipart("mixed");
MimeBodyPart body = new ZMimeBodyPart();
body.setDataHandler(new DataHandler(new ByteArrayDataSource(this.body.getBytes(), contentType)));
multi.addBodyPart(body);
MimeBodyPart attachment = new ZMimeBodyPart();
attachment.setContent(this.attachment, attachmentContentType);
attachment.setHeader("Content-Disposition", "attachment; filename=" + attachmentFilename);
multi.addBodyPart(attachment);
msg.setContent(multi);
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
msg.writeTo(out);
return new String(out.toByteArray());
}
use of com.zimbra.common.zmime.ZMimeBodyPart in project zm-mailbox by Zimbra.
the class CalendarItem method modifyBlob.
/**
* Upate the Blob for this CalendarItem object: possibly remove one or more entries from it,
* possibly add an entry to it.
*
* It IS okay to have newInv != null and invPm==null....this would mean an invite-add where the
* new invite had no ParsedMessage: IE because it didn't actually come in via an RFC822 msg
*
* @param toRemove
* @param removeAllExistingInvites if true, all existing invites are removed regardless of
* what's passed in toRemove list
* @param toUpdate
* @param invPm
* @param newInv
* @param isCancel if the method is being called while processing a cancel request
* @param allowPrivateAccess
* @param forceSave if TRUE then this call is guaranteed to save the current metadata state
* @param replaceExceptionBodyWithSeriesBody if TRUE bodies of exceptions are replaced with series body
* for invites in toUpdate list
* @throws ServiceException
*/
private void modifyBlob(List<Invite> toRemove, boolean removeAllExistingInvites, List<Invite> toUpdate, ParsedMessage invPm, Invite newInv, boolean isCancel, boolean allowPrivateAccess, boolean forceSave, boolean replaceExceptionBodyWithSeriesBody) throws ServiceException {
// if a single incoming Message has multiple invites in it, all for this CalendarItem)
try {
// now, make sure the message is in our blob already...
MimeMessage mm = null;
if (getSize() > 0) {
try {
mm = getMimeMessage();
} catch (ServiceException e) {
ZimbraLog.calendar.warn("Error reading blob for calendar item " + getId() + " in mailbox " + getMailboxId(), e);
}
}
if (mm == null) {
if (newInv != null && invPm != null) {
// if the blob isn't already there, and we're going to add one, then
// just go into create
createBlob(invPm, newInv);
} else {
if (forceSave)
saveMetadata();
}
return;
}
// It should be a multipart/digest.
MimeMultipart mmp;
Object obj = mm.getContent();
if (obj instanceof MimeMultipart)
mmp = (MimeMultipart) obj;
else
throw ServiceException.FAILURE("Expected MimeMultipart, but got " + obj.getClass().getName() + ": id=" + mId + ", content=" + obj.toString(), null);
boolean updated = false;
// remove invites
if (removeAllExistingInvites) {
int numParts = mmp.getCount();
if (numParts > 0) {
for (int i = numParts - 1; i >= 0; i--) {
mmp.removeBodyPart(i);
}
updated = true;
}
} else {
// Remove specific invites.
for (Invite inv : toRemove) {
int matchedIdx;
do {
// find the matching parts...
int numParts = mmp.getCount();
matchedIdx = -1;
for (int i = 0; i < numParts; i++) {
MimeBodyPart mbp = (MimeBodyPart) mmp.getBodyPart(i);
String[] hdrs = mbp.getHeader("invId");
if (hdrs == null || hdrs.length == 0) {
matchedIdx = i;
break;
}
if (hdrs != null && hdrs.length > 0 && (Integer.parseInt(hdrs[0]) == inv.getMailItemId())) {
matchedIdx = i;
break;
}
}
if (matchedIdx > -1) {
mmp.removeBodyPart(matchedIdx);
updated = true;
}
} while (matchedIdx > -1);
}
}
// Update some invites.
for (Invite inv : toUpdate) {
MimeBodyPart mbpInv = null;
int numParts = mmp.getCount();
for (int i = 0; i < numParts; i++) {
MimeBodyPart mbp = (MimeBodyPart) mmp.getBodyPart(i);
String[] hdrs = mbp.getHeader("invId");
if (hdrs != null && hdrs.length > 0 && (Integer.parseInt(hdrs[0]) == inv.getMailItemId())) {
mbpInv = mbp;
break;
}
}
if (mbpInv == null)
continue;
if (replaceExceptionBodyWithSeriesBody) {
// Throw away the existing part. Replace it with body from new invite.
mmp.removeBodyPart(mbpInv);
mbpInv = new ZMimeBodyPart();
mbpInv.setDataHandler(new DataHandler(new PMDataSource(invPm)));
mbpInv.addHeader("invId", Integer.toString(inv.getMailItemId()));
mmp.addBodyPart(mbpInv);
// required by JavaMail for some magical reason
mm.saveChanges();
}
// Find the text/calendar part and replace it.
String mbpInvCt = mbpInv.getContentType();
Object objInv = mbpInv.getContent();
if (!(objInv instanceof MimeMessage))
continue;
MimeMessage mmInv = (MimeMessage) objInv;
Object objMulti = mmInv.getContent();
if (!(objMulti instanceof MimeMultipart))
continue;
MimeMultipart multi = (MimeMultipart) objMulti;
int numSubParts = multi.getCount();
int icalPartNum = -1;
for (int j = 0; j < numSubParts; j++) {
MimeBodyPart part = (MimeBodyPart) multi.getBodyPart(j);
ContentType ct = new ContentType(part.getContentType());
if (ct.match(MimeConstants.CT_TEXT_CALENDAR)) {
icalPartNum = j;
break;
}
}
if (icalPartNum != -1) {
updated = true;
multi.removeBodyPart(icalPartNum);
ZVCalendar cal = inv.newToICalendar(allowPrivateAccess);
MimeBodyPart icalPart = CalendarMailSender.makeICalIntoMimePart(cal);
multi.addBodyPart(icalPart, icalPartNum);
// Courtesy of JavaMail. All three lines are necessary.
// Reasons unclear from JavaMail docs.
mmInv.setContent(multi);
mmInv.saveChanges();
mbpInv.setContent(mmInv, mbpInvCt);
// End of courtesy of JavaMail
}
}
if (newInv != null) {
MimeBodyPart mbp = new ZMimeBodyPart();
mbp.setDataHandler(new DataHandler(new PMDataSource(invPm)));
mmp.addBodyPart(mbp);
mbp.addHeader("invId", Integer.toString(newInv.getMailItemId()));
updated = true;
}
if (!updated) {
if (forceSave)
saveMetadata();
return;
}
if (mmp.getCount() == 0) {
markBlobForDeletion();
setContent(null, null);
if (forceSave)
saveMetadata();
} else {
// must call this explicitly or else new part won't be added...
mm.setContent(mmp);
mm.saveChanges();
storeUpdatedBlob(mm);
}
} catch (MessagingException e) {
throw ServiceException.FAILURE("MessagingException", e);
} catch (IOException e) {
throw ServiceException.FAILURE("IOException", e);
}
}
use of com.zimbra.common.zmime.ZMimeBodyPart in project zm-mailbox by Zimbra.
the class CalItemEmailReminderTask method sendReminder.
@Override
protected void sendReminder(CalendarItem calItem, Invite invite) throws Exception {
Account account = calItem.getAccount();
Locale locale = account.getLocale();
TimeZone tz = Util.getAccountTimeZone(account);
MimeMessage mm = new Mime.FixedMimeMessage(JMSession.getSmtpSession(account));
String to = account.getAttr(Provisioning.A_zimbraPrefCalendarReminderEmail);
if (to == null) {
ZimbraLog.scheduler.info("Unable to send calendar reminder email since %s is not set", Provisioning.A_zimbraPrefCalendarReminderEmail);
return;
}
mm.setRecipient(javax.mail.Message.RecipientType.TO, new JavaMailInternetAddress(to));
mm.setSubject(L10nUtil.getMessage(calItem.getType() == MailItem.Type.APPOINTMENT ? L10nUtil.MsgKey.apptReminderEmailSubject : L10nUtil.MsgKey.taskReminderEmailSubject, locale, calItem.getSubject()), MimeConstants.P_CHARSET_UTF8);
if (invite.getDescriptionHtml() == null) {
mm.setText(getBody(calItem, invite, false, locale, tz), MimeConstants.P_CHARSET_UTF8);
} else {
MimeMultipart mmp = new ZMimeMultipart("alternative");
mm.setContent(mmp);
MimeBodyPart textPart = new ZMimeBodyPart();
textPart.setText(getBody(calItem, invite, false, locale, tz), MimeConstants.P_CHARSET_UTF8);
mmp.addBodyPart(textPart);
MimeBodyPart htmlPart = new ZMimeBodyPart();
htmlPart.setContent(getBody(calItem, invite, true, locale, tz), MimeConstants.CT_TEXT_HTML + "; " + MimeConstants.P_CHARSET + "=" + MimeConstants.P_CHARSET_UTF8);
mmp.addBodyPart(htmlPart);
}
mm.setSentDate(new Date());
mm.saveChanges();
MailSender mailSender = calItem.getMailbox().getMailSender();
mailSender.sendMimeMessage(null, calItem.getMailbox(), mm);
}
Aggregations