use of com.zimbra.common.calendar.ZCalendar.ZVCalendar in project zm-mailbox by Zimbra.
the class SetCalendarItem method getSetCalendarItemData.
static SetCalendarItemData getSetCalendarItemData(ZimbraSoapContext zsc, OperationContext octxt, Account acct, Mailbox mbox, Element e, ParseMimeMessage.InviteParser parser) throws ServiceException {
String partStatStr = e.getAttribute(MailConstants.A_CAL_PARTSTAT, IcalXmlStrMap.PARTSTAT_NEEDS_ACTION);
// <M>
Element msgElem = e.getElement(MailConstants.E_MSG);
// check to see whether the entire message has been uploaded under separate cover
String attachmentId = msgElem.getAttribute(MailConstants.A_ATTACHMENT_ID, null);
Element contentElement = msgElem.getOptionalElement(MailConstants.E_CONTENT);
InviteParserResult ipr = null;
MimeMessage mm = null;
if (attachmentId != null) {
ParseMimeMessage.MimeMessageData mimeData = new ParseMimeMessage.MimeMessageData();
mm = SendMsg.parseUploadedMessage(zsc, attachmentId, mimeData);
} else if (contentElement != null) {
mm = ParseMimeMessage.importMsgSoap(msgElem);
} else {
CalSendData dat = handleMsgElement(zsc, octxt, msgElem, acct, mbox, parser);
mm = dat.mMm;
ipr = parser.getResult();
}
if (ipr == null && msgElem.getOptionalElement(MailConstants.E_INVITE) != null) {
ipr = parser.parse(zsc, octxt, mbox.getAccount(), msgElem.getElement(MailConstants.E_INVITE));
// in the <inv> but not in mime parts.
if (ipr != null && ipr.mInvite != null && mm != null) {
String desc = Invite.getDescription(mm, MimeConstants.CT_TEXT_PLAIN);
String descHtml = Invite.getDescription(mm, MimeConstants.CT_TEXT_HTML);
if ((desc != null && desc.length() > 0) || (descHtml != null && descHtml.length() > 0)) {
ipr.mInvite.setDescription(desc, descHtml);
}
}
}
ParsedMessage pm = new ParsedMessage(mm, mbox.attachmentsIndexingEnabled());
Invite inv = (ipr == null ? null : ipr.mInvite);
if (inv == null || inv.getDTStamp() == -1) {
//zdsync if -1 for 4.5 back compat
CalendarPartInfo cpi = pm.getCalendarPartInfo();
ZVCalendar cal = null;
if (cpi != null && CalendarItem.isAcceptableInvite(mbox.getAccount(), cpi)) {
cal = cpi.cal;
}
if (cal == null) {
throw ServiceException.FAILURE("SetCalendarItem could not build an iCalendar object", null);
}
// not applicable in the SetCalendarItem case
boolean sentByMe = false;
Invite iCalInv = Invite.createFromCalendar(acct, pm.getFragment(acct.getLocale()), cal, sentByMe).get(0);
if (inv == null) {
inv = iCalInv;
} else {
//zdsync
inv.setDtStamp(iCalInv.getDTStamp());
//zdsync
inv.setFragment(iCalInv.getFragment());
}
}
inv.setPartStat(partStatStr);
SetCalendarItemData sadata = new SetCalendarItemData();
sadata.invite = inv;
sadata.message = pm;
return sadata;
}
use of com.zimbra.common.calendar.ZCalendar.ZVCalendar 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.calendar.ZCalendar.ZVCalendar in project zm-mailbox by Zimbra.
the class CalendarMailSender method createCalendarInviteDeniedMessage.
private static MimeMessage createCalendarInviteDeniedMessage(Account fromAccount, Account senderAccount, boolean onBehalfOf, boolean allowPrivateAccess, Address toAddr, Invite inv, MsgKey bodyTextKey) throws ServiceException {
Locale locale = !onBehalfOf ? fromAccount.getLocale() : senderAccount.getLocale();
Identity fromIdentity = getTargetedIdentity(fromAccount, inv);
StringBuilder replyText = new StringBuilder();
String sigText = getSignatureText(fromAccount, fromIdentity, Provisioning.A_zimbraPrefCalendarAutoDenySignatureId);
if (sigText == null || sigText.length() < 1)
sigText = L10nUtil.getMessage(bodyTextKey, locale);
if (sigText != null && sigText.length() > 0)
replyText.append(sigText).append("\r\n");
attachInviteSummary(replyText, inv, null, locale);
String subject = L10nUtil.getMessage(MsgKey.calendarReplySubjectDecline, locale) + ": " + inv.getName();
String uid = inv.getUid();
ParsedDateTime exceptDt = null;
if (inv.hasRecurId())
exceptDt = inv.getRecurId().getDt();
Invite replyInv = replyToInvite(fromAccount, senderAccount, onBehalfOf, allowPrivateAccess, inv, VERB_DECLINE, subject, exceptDt);
ZVCalendar iCal = replyInv.newToICalendar(true);
Address fromAddr = fromIdentity.getFriendlyEmailAddress();
Address senderAddr = null;
if (onBehalfOf)
senderAddr = AccountUtil.getFriendlyEmailAddress(senderAccount);
List<Address> toAddrs = new ArrayList<Address>(1);
toAddrs.add(toAddr);
return createCalendarMessage(senderAccount, fromAddr, senderAddr, toAddrs, subject, replyText.toString(), null, uid, iCal);
}
use of com.zimbra.common.calendar.ZCalendar.ZVCalendar in project zm-mailbox by Zimbra.
the class CalendarMailSender method createCalendarMessage.
public static MimeMessage createCalendarMessage(Invite inv) throws ServiceException {
String subject = inv.getName();
String desc = inv.getDescription();
String descHtml = inv.getDescriptionHtml();
String uid = inv.getUid();
ZVCalendar cal = inv.newToICalendar(true);
return createCalendarMessage(null, null, null, null, subject, desc, descHtml, uid, cal, inv.getIcalendarAttaches(), true);
}
use of com.zimbra.common.calendar.ZCalendar.ZVCalendar in project zm-mailbox by Zimbra.
the class TnefConverter method expandTNEF.
/**
* Performs the TNEF->MIME conversion on any TNEF body parts that
* make up the given message.
* @throws ServiceException
*/
private MimeMultipart expandTNEF(MimeBodyPart bp) throws MessagingException, IOException {
if (!TNEFUtils.isTNEFMimeType(bp.getContentType()))
return null;
MimeMessage converted = null;
// convert TNEF to a MimeMessage and remove it from the parent
InputStream is = null;
try {
TNEFInputStream tnefis = new TNEFInputStream(is = bp.getInputStream());
converted = TNEFMime.convert(JMSession.getSession(), tnefis);
// XXX bburtin: nasty hack. Don't handle OOME since JTNEF can allocate a huge byte
// array when the TNEF file is malformed. See bug 42649.
// } catch (OutOfMemoryError e) {
// Zimbra.halt("Ran out of memory while expanding TNEF attachment", e);
} catch (Throwable t) {
ZimbraLog.extensions.warn("Conversion failed. TNEF attachment will not be expanded.", t);
return null;
} finally {
ByteUtil.closeStream(is);
}
Object convertedContent = converted.getContent();
if (!(convertedContent instanceof MimeMultipart)) {
ZimbraLog.extensions.debug("TNEF attachment doesn't contain valid MimeMultiPart");
return null;
}
MimeMultipart convertedMulti = (MimeMultipart) convertedContent;
// make sure that all the attachments are marked as attachments
for (int i = 0; i < convertedMulti.getCount(); i++) {
BodyPart subpart = convertedMulti.getBodyPart(i);
if (subpart.getHeader("Content-Disposition") == null)
subpart.setHeader("Content-Disposition", Part.ATTACHMENT);
}
// Create a MimeBodyPart for the converted data. Currently we're throwing
// away the top-level message because its content shows up as blank after
// the conversion.
MimeBodyPart convertedPart = new ZMimeBodyPart();
convertedPart.setContent(convertedMulti);
// If the TNEF object contains calendar data, create an iCalendar version.
MimeBodyPart icalPart = null;
if (DebugConfig.enableTnefToICalendarConversion) {
try {
TnefToICalendar calConverter = new DefaultTnefToICalendar();
ZCalendar.DefaultContentHandler icalHandler = new ZCalendar.DefaultContentHandler();
if (calConverter.convert(mMimeMessage, bp.getInputStream(), icalHandler)) {
if (icalHandler.getNumCals() > 0) {
List<ZVCalendar> cals = icalHandler.getCals();
Writer writer = new StringWriter(1024);
ICalTok method = null;
for (ZVCalendar cal : cals) {
cal.toICalendar(writer);
if (method == null)
method = cal.getMethod();
}
writer.close();
icalPart = new ZMimeBodyPart();
icalPart.setText(writer.toString());
ContentType ct = new ContentType(MimeConstants.CT_TEXT_CALENDAR);
ct.setCharset(MimeConstants.P_CHARSET_UTF8);
if (method != null)
ct.setParameter("method", method.toString());
icalPart.setHeader("Content-Type", ct.toString());
}
}
} catch (ServiceException e) {
throw new MessagingException("TNEF to iCalendar conversion failure: " + e.getMessage(), e);
} catch (Throwable t) {
//don't allow TNEF errors to crash server
ZimbraLog.extensions.warn("Failed to convert TNEF to iCal", t);
throw new MessagingException("TNEF to iCalendar conversion failure");
}
}
// create a multipart/alternative for the TNEF and its MIME version
MimeMultipart altMulti = new ZMimeMultipart("alternative");
// altMulti.addBodyPart(bp);
altMulti.addBodyPart(convertedPart);
if (icalPart != null)
altMulti.addBodyPart(icalPart);
return altMulti;
}
Aggregations