Search in sources :

Example 31 with ZVCalendar

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;
}
Also used : ParsedMessage(com.zimbra.cs.mime.ParsedMessage) Element(com.zimbra.common.soap.Element) CalendarPartInfo(com.zimbra.cs.mime.ParsedMessage.CalendarPartInfo) SetCalendarItemData(com.zimbra.cs.mailbox.Mailbox.SetCalendarItemData) ZVCalendar(com.zimbra.common.calendar.ZCalendar.ZVCalendar) InviteParserResult(com.zimbra.cs.service.mail.ParseMimeMessage.InviteParserResult) MimeMessage(javax.mail.internet.MimeMessage) Invite(com.zimbra.cs.mailbox.calendar.Invite)

Example 32 with ZVCalendar

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);
    }
}
Also used : ContentType(javax.mail.internet.ContentType) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MessagingException(javax.mail.MessagingException) DataHandler(javax.activation.DataHandler) IOException(java.io.IOException) ZVCalendar(com.zimbra.common.calendar.ZCalendar.ZVCalendar) ServiceException(com.zimbra.common.service.ServiceException) 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) MimeBodyPart(javax.mail.internet.MimeBodyPart) Invite(com.zimbra.cs.mailbox.calendar.Invite)

Example 33 with ZVCalendar

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);
}
Also used : Locale(java.util.Locale) ZVCalendar(com.zimbra.common.calendar.ZCalendar.ZVCalendar) Address(javax.mail.Address) InternetAddress(javax.mail.internet.InternetAddress) JavaMailInternetAddress(com.zimbra.common.mime.shim.JavaMailInternetAddress) ArrayList(java.util.ArrayList) ParsedDateTime(com.zimbra.common.calendar.ParsedDateTime) Identity(com.zimbra.cs.account.Identity)

Example 34 with ZVCalendar

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);
}
Also used : ZVCalendar(com.zimbra.common.calendar.ZCalendar.ZVCalendar)

Example 35 with ZVCalendar

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;
}
Also used : ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MimeBodyPart(javax.mail.internet.MimeBodyPart) BodyPart(javax.mail.BodyPart) ContentType(com.zimbra.common.mime.ContentType) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MessagingException(javax.mail.MessagingException) TNEFInputStream(net.freeutils.tnef.TNEFInputStream) InputStream(java.io.InputStream) TNEFInputStream(net.freeutils.tnef.TNEFInputStream) DefaultTnefToICalendar(com.zimbra.cs.util.tnef.DefaultTnefToICalendar) ICalTok(com.zimbra.common.calendar.ZCalendar.ICalTok) ZCalendar(com.zimbra.common.calendar.ZCalendar) ZVCalendar(com.zimbra.common.calendar.ZCalendar.ZVCalendar) StringWriter(java.io.StringWriter) ServiceException(com.zimbra.common.service.ServiceException) MimeMessage(javax.mail.internet.MimeMessage) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) MimeMultipart(javax.mail.internet.MimeMultipart) TnefToICalendar(com.zimbra.cs.util.tnef.TnefToICalendar) DefaultTnefToICalendar(com.zimbra.cs.util.tnef.DefaultTnefToICalendar) ZMimeMultipart(com.zimbra.common.zmime.ZMimeMultipart) ZMimeBodyPart(com.zimbra.common.zmime.ZMimeBodyPart) MimeBodyPart(javax.mail.internet.MimeBodyPart) StringWriter(java.io.StringWriter) Writer(java.io.Writer)

Aggregations

ZVCalendar (com.zimbra.common.calendar.ZCalendar.ZVCalendar)47 Invite (com.zimbra.cs.mailbox.calendar.Invite)21 ZComponent (com.zimbra.common.calendar.ZCalendar.ZComponent)16 Account (com.zimbra.cs.account.Account)12 ICalTimeZone (com.zimbra.common.calendar.ICalTimeZone)10 ZProperty (com.zimbra.common.calendar.ZCalendar.ZProperty)10 IOException (java.io.IOException)10 MimeMessage (javax.mail.internet.MimeMessage)10 ParsedDateTime (com.zimbra.common.calendar.ParsedDateTime)9 ItemId (com.zimbra.cs.service.util.ItemId)9 TimeZoneMap (com.zimbra.common.calendar.TimeZoneMap)8 InputStream (java.io.InputStream)8 ArrayList (java.util.ArrayList)8 ServiceException (com.zimbra.common.service.ServiceException)7 Mailbox (com.zimbra.cs.mailbox.Mailbox)7 ByteArrayInputStream (java.io.ByteArrayInputStream)7 Locale (java.util.Locale)7 Test (org.junit.Test)7 Element (com.zimbra.common.soap.Element)6 Date (java.util.Date)6