Search in sources :

Example 1 with ParsedDateTime

use of com.zimbra.common.calendar.ParsedDateTime in project zm-mailbox by Zimbra.

the class ScheduleOutbox method handleFreebusyRequest.

private void handleFreebusyRequest(DavContext ctxt, ZComponent vfreebusy, String originator, String rcpt, Element resp) throws DavException, ServiceException {
    ZProperty dtstartProp = vfreebusy.getProperty(ICalTok.DTSTART);
    ZProperty dtendProp = vfreebusy.getProperty(ICalTok.DTEND);
    ZProperty durationProp = vfreebusy.getProperty(ICalTok.DURATION);
    if (dtstartProp == null || dtendProp == null && durationProp == null)
        throw new DavException("missing dtstart or dtend/duration in the schedule request", HttpServletResponse.SC_BAD_REQUEST, null);
    long start, end;
    try {
        ParsedDateTime startTime = ParsedDateTime.parseUtcOnly(dtstartProp.getValue());
        start = startTime.getUtcTime();
        if (dtendProp != null) {
            end = ParsedDateTime.parseUtcOnly(dtendProp.getValue()).getUtcTime();
        } else {
            ParsedDuration dur = ParsedDuration.parse(durationProp.getValue());
            ParsedDateTime endTime = startTime.add(dur);
            end = endTime.getUtcTime();
        }
    } catch (ParseException pe) {
        throw new DavException("can't parse date", HttpServletResponse.SC_BAD_REQUEST, pe);
    }
    ZimbraLog.dav.debug("rcpt: " + rcpt + ", start: " + new Date(start) + ", end: " + new Date(end));
    FreeBusy fb = null;
    if (ctxt.isFreebusyEnabled()) {
        FreeBusyQuery fbQuery = new FreeBusyQuery(ctxt.getRequest(), ctxt.getAuthAccount(), start, end, null);
        fbQuery.addEmailAddress(getAddressFromPrincipalURL(rcpt), FreeBusyQuery.CALENDAR_FOLDER_ALL);
        java.util.Collection<FreeBusy> fbResult = fbQuery.getResults();
        if (fbResult.size() > 0)
            fb = fbResult.iterator().next();
    }
    if (fb != null) {
        String fbMsg = fb.toVCalendar(FreeBusy.Method.REPLY, originator, rcpt, null);
        resp.addElement(DavElements.E_RECIPIENT).addElement(DavElements.E_HREF).setText(rcpt);
        resp.addElement(DavElements.E_REQUEST_STATUS).setText("2.0;Success");
        resp.addElement(DavElements.E_CALENDAR_DATA).setText(fbMsg);
    } else {
        resp.addElement(DavElements.E_RECIPIENT).addElement(DavElements.E_HREF).setText(rcpt);
        resp.addElement(DavElements.E_REQUEST_STATUS).setText("5.3;No f/b for the user");
    }
}
Also used : FreeBusy(com.zimbra.cs.fb.FreeBusy) DavException(com.zimbra.cs.dav.DavException) ParsedDuration(com.zimbra.common.calendar.ParsedDuration) FreeBusyQuery(com.zimbra.cs.fb.FreeBusyQuery) ZProperty(com.zimbra.common.calendar.ZCalendar.ZProperty) ParsedDateTime(com.zimbra.common.calendar.ParsedDateTime) ParseException(java.text.ParseException) Date(java.util.Date)

Example 2 with ParsedDateTime

use of com.zimbra.common.calendar.ParsedDateTime in project zm-mailbox by Zimbra.

the class CalendarItem method decodeMetadata.

@Override
void decodeMetadata(Metadata meta) throws ServiceException {
    super.decodeMetadata(meta);
    mUid = Invite.fixupIfOutlookUid(meta.get(Metadata.FN_UID, null));
    mInvites = new ArrayList<Invite>();
    ICalTimeZone accountTZ = Util.getAccountTimeZone(getMailbox().getAccount());
    if (meta.containsKey(Metadata.FN_TZMAP)) {
        try {
            Set<String> tzids = new HashSet<String>();
            mTzMap = Util.decodeFromMetadata(meta.getMap(Metadata.FN_TZMAP), accountTZ);
            // appointment/task start and end
            mStartTime = meta.getLong(Metadata.FN_CALITEM_START, 0);
            mEndTime = meta.getLong(Metadata.FN_CALITEM_END, 0);
            // invite ID's
            long numComp = meta.getLong(Metadata.FN_NUM_COMPONENTS);
            for (int i = 0; i < numComp; i++) {
                Metadata md = meta.getMap(Metadata.FN_INV + i);
                Invite inv = Invite.decodeMetadata(getMailboxId(), md, this, accountTZ);
                mInvites.add(inv);
                tzids.addAll(inv.getReferencedTZIDs());
                mTzMap.add(inv.getTimeZoneMap());
            }
            Metadata metaRecur = meta.getMap(FN_CALITEM_RECURRENCE, true);
            if (metaRecur != null) {
                mRecurrence = Recurrence.decodeMetadata(metaRecur, mTzMap);
                if (mRecurrence != null) {
                    tzids.addAll(Recurrence.getReferencedTZIDs(mRecurrence));
                }
            }
            if (meta.containsKey(Metadata.FN_REPLY_LIST)) {
                mReplyList = ReplyList.decodeFromMetadata(meta.getMap(Metadata.FN_REPLY_LIST), mTzMap);
                // Get all TZIDs referenced by replies.
                for (ReplyInfo ri : mReplyList.mReplies) {
                    if (ri.mRecurId != null) {
                        ParsedDateTime dt = ri.mRecurId.getDt();
                        if (dt != null && dt.hasTime()) {
                            ICalTimeZone tz = dt.getTimeZone();
                            if (tz != null)
                                tzids.add(tz.getID());
                        }
                    }
                }
            } else {
                mReplyList = new ReplyList();
            }
            Metadata metaAlarmData = meta.getMap(Metadata.FN_ALARM_DATA, true);
            if (metaAlarmData != null)
                mAlarmData = AlarmData.decodeMetadata(metaAlarmData);
            // Reduce tzmap to minimal set of TZIDs referenced by invites, recurrence, and replies.
            mTzMap.reduceTo(tzids);
        } catch (ServiceException se) {
            if (ServiceException.INVALID_REQUEST.equals(se.getCode()) && this.getChangeDate() < new GregorianCalendar(2006, 0, 1).getTimeInMillis()) {
                //could have been metadata version 3, 4 or 5.
                //All of those versions have FN_TZMAP, but different format for other fields
                //these are edge cases that should only appear in dev/df/cf
                mStartTime = 0;
                mEndTime = 0;
            } else {
                throw se;
            }
        }
    } else {
        //version 2 or earlier
        mStartTime = 0;
        mEndTime = 0;
    }
}
Also used : GregorianCalendar(java.util.GregorianCalendar) ServiceException(com.zimbra.common.service.ServiceException) ParsedDateTime(com.zimbra.common.calendar.ParsedDateTime) Invite(com.zimbra.cs.mailbox.calendar.Invite) ICalTimeZone(com.zimbra.common.calendar.ICalTimeZone) HashSet(java.util.HashSet)

Example 3 with ParsedDateTime

use of com.zimbra.common.calendar.ParsedDateTime in project zm-mailbox by Zimbra.

the class CalendarItem method instancesNear.

/**
     * Find instances within 24 hours either side.  Assumption is that any timezone related problems
     * causing {@code recurId} to be incorrect will only be relevant to times within that window.
     * @param recurId
     * @return
     * @throws ServiceException
     */
private Collection<Instance> instancesNear(RecurId recurId) throws ServiceException {
    if (recurId == null) {
        return Collections.emptyList();
    }
    ParsedDateTime dt = recurId.getDt();
    if (dt == null) {
        return Collections.emptyList();
    }
    long utcTime = dt.getUtcTime();
    return this.expandInstances(utcTime - MILLIS_IN_DAY, utcTime + MILLIS_IN_DAY, false);
}
Also used : ParsedDateTime(com.zimbra.common.calendar.ParsedDateTime)

Example 4 with ParsedDateTime

use of com.zimbra.common.calendar.ParsedDateTime in project zm-mailbox by Zimbra.

the class CalendarItem method createPseudoExceptionForSingleInstanceReplyIfNecessary.

/**
     * Bug 94018 - Need an exception to represent a reply to a single instance of an exception, otherwise a decline
     * to a single instance gets forgotten in some cases where the series partstat is used instead.
     * Assumption - already checked that there isn't a matching exception instance already
     * Caller is responsible for ensuring changed MetaData is written through to SQL sending notification of change.
     */
private void createPseudoExceptionForSingleInstanceReplyIfNecessary(Invite reply) throws ServiceException {
    if ((reply == null) || reply.getRecurId() == null) {
        // reply isn't to a single instance
        return;
    }
    Recurrence.RecurrenceRule recurrenceRule = null;
    if ((mRecurrence == null) || !(mRecurrence instanceof Recurrence.RecurrenceRule)) {
        return;
    }
    recurrenceRule = (Recurrence.RecurrenceRule) mRecurrence;
    Collection<Instance> instancesNear = instancesNear(reply.getRecurId());
    if (!instancesNear.isEmpty()) {
        /* we need a new exception to handle the difference in attendee status */
        for (int i = 0; i < numInvites(); i++) {
            Invite cur = getInvite(i);
            if (cur.getRecurId() == null) {
                try {
                    ParsedDateTime pdt = ParsedDateTime.parseUtcOnly(reply.getRecurId().getDtZ());
                    Invite localException = cur.makeInstanceInvite(pdt);
                    localException.setDtStamp(System.currentTimeMillis());
                    localException.updateMatchingAttendeesFromReply(reply);
                    // flag as organizer change
                    localException.setClassPropSetByMe(true);
                    mInvites.add(localException);
                    // create a fake ExceptionRule wrapper around the single-instance
                    recurrenceRule.addException(new Recurrence.ExceptionRule(reply.getRecurId(), localException.getStartTime(), localException.getEffectiveDuration(), new InviteInfo(localException)));
                } catch (ParseException e) {
                    sLog.debug("Unexpected exception - not updating calendar invite with pseudo exception", e);
                }
                break;
            }
        }
    }
}
Also used : IRecurrence(com.zimbra.cs.mailbox.calendar.Recurrence.IRecurrence) Recurrence(com.zimbra.cs.mailbox.calendar.Recurrence) InviteInfo(com.zimbra.cs.mailbox.calendar.InviteInfo) RecurrenceRule(com.zimbra.cs.mailbox.calendar.Recurrence.RecurrenceRule) ParsedDateTime(com.zimbra.common.calendar.ParsedDateTime) ParseException(java.text.ParseException) Invite(com.zimbra.cs.mailbox.calendar.Invite)

Example 5 with ParsedDateTime

use of com.zimbra.common.calendar.ParsedDateTime in project zm-mailbox by Zimbra.

the class Appointment method makeReplyInvite.

private Invite makeReplyInvite(Account account, Account authAccount, Locale lc, boolean onBehalfOf, boolean allowPrivateAccess, Invite inv, RecurId rid, Verb verb) throws ServiceException {
    boolean hidePrivate = !inv.isPublic() && !allowPrivateAccess;
    String subject;
    if (hidePrivate)
        subject = L10nUtil.getMessage(MsgKey.calendarSubjectWithheld, lc);
    else
        subject = inv.getName();
    String replySubject = CalendarMailSender.getReplySubject(verb, subject, lc);
    ParsedDateTime ridDt = rid != null ? rid.getDt() : null;
    Invite replyInv = CalendarMailSender.replyToInvite(account, authAccount, onBehalfOf, allowPrivateAccess, inv, verb, replySubject, ridDt);
    return replyInv;
}
Also used : ParsedDateTime(com.zimbra.common.calendar.ParsedDateTime) Invite(com.zimbra.cs.mailbox.calendar.Invite)

Aggregations

ParsedDateTime (com.zimbra.common.calendar.ParsedDateTime)66 ParsedDuration (com.zimbra.common.calendar.ParsedDuration)23 Invite (com.zimbra.cs.mailbox.calendar.Invite)20 ICalTimeZone (com.zimbra.common.calendar.ICalTimeZone)18 ParseException (java.text.ParseException)16 ArrayList (java.util.ArrayList)16 IRecurrence (com.zimbra.cs.mailbox.calendar.Recurrence.IRecurrence)15 ZProperty (com.zimbra.common.calendar.ZCalendar.ZProperty)14 Element (com.zimbra.common.soap.Element)13 RecurId (com.zimbra.cs.mailbox.calendar.RecurId)11 TimeZoneMap (com.zimbra.common.calendar.TimeZoneMap)10 Account (com.zimbra.cs.account.Account)10 ZOrganizer (com.zimbra.cs.mailbox.calendar.ZOrganizer)10 ZVCalendar (com.zimbra.common.calendar.ZCalendar.ZVCalendar)9 ICalTok (com.zimbra.common.calendar.ZCalendar.ICalTok)8 ZAttendee (com.zimbra.cs.mailbox.calendar.ZAttendee)8 ZComponent (com.zimbra.common.calendar.ZCalendar.ZComponent)7 ZParameter (com.zimbra.common.calendar.ZCalendar.ZParameter)7 ServiceException (com.zimbra.common.service.ServiceException)7 CalendarItem (com.zimbra.cs.mailbox.CalendarItem)7