Search in sources :

Example 1 with InviteInfo

use of com.zimbra.cs.mailbox.calendar.InviteInfo 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 2 with InviteInfo

use of com.zimbra.cs.mailbox.calendar.InviteInfo in project zm-mailbox by Zimbra.

the class CalendarItem method getNextAlarmHelper.

private AlarmData getNextAlarmHelper(long atOrAfter, long snoozeUntil, Collection<Instance> instances, long rangeStart, boolean forEmailAction) {
    // Find the two nearest alarms that surround atOrAfter such that t(alarm1) <= atOrAfter < t(alarm2).
    Alarm alarm1 = null, alarm2 = null;
    // trigger times for alarm1 and alarm2
    long trigger1 = Long.MIN_VALUE, trigger2 = Long.MAX_VALUE;
    // instance start time for alarm1 and alarm2
    long instStart1 = 0, instStart2 = 0;
    // invId and compNum for inst1 and inst2
    int invId1 = 0, compNum1 = 0, invId2 = 0, compNum2 = 0;
    for (Instance inst : instances) {
        long instStart = inst.getStart();
        long instEnd = inst.getEnd();
        if (inst.hasStart() && inst.hasEnd()) {
            // Ignore instances that ended already.
            if (instEnd <= rangeStart)
                continue;
            // For appointments (but not tasks), ignore instances whose start time has come and gone.
            if (instStart < rangeStart && (this instanceof Appointment))
                continue;
        }
        InviteInfo invId = inst.getInviteInfo();
        Invite inv = getInvite(invId.getMsgId(), invId.getComponentId());
        assert (inv != null);
        // The instance can have multiple alarms.
        for (Iterator<Alarm> alarms = inv.alarmsIterator(); alarms.hasNext(); ) {
            Alarm alarm = alarms.next();
            if (Action.EMAIL.equals(alarm.getAction()) == forEmailAction) {
                long trg = alarm.getTriggerTime(instStart, instEnd);
                if (trg <= atOrAfter) {
                    if (trg > trigger1) {
                        trigger1 = trg;
                        alarm1 = alarm;
                        instStart1 = instStart;
                        invId1 = invId.getMsgId();
                        compNum1 = invId.getComponentId();
                    }
                } else {
                    // trg > atOrAfter
                    if (trg < trigger2) {
                        trigger2 = trg;
                        alarm2 = alarm;
                        instStart2 = instStart;
                        invId2 = invId.getMsgId();
                        compNum2 = invId.getComponentId();
                    }
                }
            }
        }
        if (alarm1 != null && alarm2 != null) {
            break;
        }
    }
    AlarmData ad1 = alarm1 != null ? new AlarmData(trigger1, snoozeUntil, instStart1, invId1, compNum1, alarm1) : null;
    AlarmData ad2 = alarm2 != null ? new AlarmData(trigger2, AlarmData.NO_SNOOZE, instStart2, invId2, compNum2, alarm2) : null;
    return chooseNextAlarm(atOrAfter, snoozeUntil, ad1, ad2);
}
Also used : InviteInfo(com.zimbra.cs.mailbox.calendar.InviteInfo) Alarm(com.zimbra.cs.mailbox.calendar.Alarm) Invite(com.zimbra.cs.mailbox.calendar.Invite)

Example 3 with InviteInfo

use of com.zimbra.cs.mailbox.calendar.InviteInfo in project zm-mailbox by Zimbra.

the class GetCalendarItemSummaries method encodeCalendarItemInstances.

/**
     * Encodes a calendar item
     *
     * @param parent
     * @param elementName
     *         name of element to add (MailConstants .E_APPOINTMENT or MailConstants.E_TASK)
     * @param rangeStart
     *         start period to expand instances (or -1 for no start time constraint)
     * @param rangeEnd
     *         end period to expand instances (or -1 for no end time constraint)
     * @param newFormat
     *         temporary HACK - true: SearchRequest, false: GetAppointmentSummaries
     * @return
     */
static EncodeCalendarItemResult encodeCalendarItemInstances(ZimbraSoapContext lc, OperationContext octxt, CalendarItem calItem, Account acct, long rangeStart, long rangeEnd, boolean newFormat) throws ServiceException {
    EncodeCalendarItemResult toRet = new EncodeCalendarItemResult();
    ItemIdFormatter ifmt = new ItemIdFormatter(lc);
    Account authAccount = getAuthenticatedAccount(lc);
    boolean hidePrivate = !calItem.allowPrivateAccess(authAccount, lc.isUsingAdminPrivileges());
    try {
        boolean expandRanges;
        if (calItem instanceof Task) {
            expandRanges = true;
            if (rangeStart == -1 && rangeEnd == -1) {
                rangeStart = Long.MIN_VALUE;
                rangeEnd = Long.MAX_VALUE;
            }
        } else {
            expandRanges = (rangeStart != -1 && rangeEnd != -1 && rangeStart < rangeEnd);
        }
        boolean isAppointment = calItem instanceof Appointment;
        // Use the marshalling code in calendar summary cache for uniform output, when we can.
        if (isAppointment && expandRanges) {
            CalendarItemData calItemData = CalSummaryCache.reloadCalendarItemOverRange(calItem, rangeStart, rangeEnd);
            if (calItemData != null) {
                int numInstances = calItemData.getNumInstances();
                if (numInstances > 0) {
                    Element calItemElem = CacheToXML.encodeCalendarItemData(lc, ifmt, calItemData, !hidePrivate, !newFormat);
                    toRet.element = calItemElem;
                    toRet.numInstancesExpanded = numInstances;
                }
            }
            return toRet;
        }
        // But there are other cases (e.g. tasks, no time range) that require the legacy code below.
        // don't initialize until we find at least one valid instance
        Element calItemElem = null;
        Invite defaultInvite = calItem.getDefaultInviteOrNull();
        if (defaultInvite == null) {
            mLog.info("Could not load defaultinfo for calendar item with id=" + calItem.getId() + " SKIPPING");
            return toRet;
        }
        ParsedDuration defDuration = defaultInvite.getEffectiveDuration();
        // events and 1 second for non all-day.  (bug 28615)
        if (defDuration == null && !defaultInvite.isTodo()) {
            if (defaultInvite.isAllDayEvent()) {
                defDuration = ParsedDuration.ONE_DAY;
            } else {
                defDuration = ParsedDuration.ONE_SECOND;
            }
        }
        long defDurationMsecs = 0;
        if (defaultInvite.getStartTime() != null && defDuration != null) {
            ParsedDateTime s = defaultInvite.getStartTime();
            long et = s.add(defDuration).getUtcTime();
            defDurationMsecs = et - s.getUtcTime();
        }
        String defaultFba = null;
        if (calItem instanceof Appointment) {
            defaultFba = ((Appointment) calItem).getEffectiveFreeBusyActual(defaultInvite, null);
        }
        String defaultPtSt = calItem.getEffectivePartStat(defaultInvite, null);
        AlarmData alarmData = calItem.getAlarmData();
        // add all the instances:
        int numInRange = 0;
        if (expandRanges) {
            Collection<CalendarItem.Instance> instances = calItem.expandInstances(rangeStart, rangeEnd, true);
            long alarmTime = 0;
            long alarmInst = 0;
            if (alarmData != null) {
                alarmTime = alarmData.getNextAt();
                alarmInst = alarmData.getNextInstanceStart();
            }
            for (CalendarItem.Instance inst : instances) {
                try {
                    InviteInfo invId = inst.getInviteInfo();
                    Invite inv = calItem.getInvite(invId.getMsgId(), invId.getComponentId());
                    boolean showAll = !hidePrivate || inv.isPublic();
                    // figure out which fields are different from the default and put their data here...
                    ParsedDuration invDuration = inv.getEffectiveDuration();
                    long instStart = inst.getStart();
                    // For an instance whose alarm time is within the time range, we must
                    // include it even if its start time is after the range.
                    long startOrAlarm = instStart == alarmInst ? alarmTime : instStart;
                    // events and 1 second for non all-day.  (bug 28615)
                    if (invDuration == null) {
                        if (inv.isAllDayEvent())
                            invDuration = ParsedDuration.ONE_DAY;
                        else
                            invDuration = ParsedDuration.ONE_SECOND;
                    }
                    if (!inst.hasStart() || (startOrAlarm < rangeEnd && invDuration.addToTime(instStart) > rangeStart)) {
                        numInRange++;
                    } else {
                        continue;
                    }
                    if (calItemElem == null) {
                        calItemElem = lc.createElement(isAppointment ? MailConstants.E_APPOINTMENT : MailConstants.E_TASK);
                        if (showAll) {
                            // flags and tags
                            ToXML.recordItemTags(calItemElem, calItem, octxt);
                        }
                        // Organizer
                        if (inv.hasOrganizer()) {
                            ZOrganizer org = inv.getOrganizer();
                            org.toXml(calItemElem);
                        }
                        calItemElem.addAttribute("x_uid", calItem.getUid());
                        calItemElem.addAttribute(MailConstants.A_UID, calItem.getUid());
                    }
                    Element instElt = calItemElem.addElement(MailConstants.E_INSTANCE);
                    if (showAll) {
                        if (isAppointment && inv.isEvent()) {
                            String instFba = ((Appointment) calItem).getEffectiveFreeBusyActual(inv, inst);
                            if (instFba != null && (!instFba.equals(defaultFba) || inst.isException()))
                                instElt.addAttribute(MailConstants.A_APPT_FREEBUSY_ACTUAL, instFba);
                        }
                        String instPtSt = calItem.getEffectivePartStat(inv, inst);
                        if (!defaultPtSt.equals(instPtSt) || inst.isException())
                            instElt.addAttribute(MailConstants.A_CAL_PARTSTAT, instPtSt);
                    }
                    if (inst.hasStart()) {
                        instElt.addAttribute(MailConstants.A_CAL_START_TIME, instStart);
                        if (inv.isAllDayEvent())
                            instElt.addAttribute(MailConstants.A_CAL_TZ_OFFSET, inst.getStartTzOffset());
                    }
                    if (inst.isException() && inv.hasRecurId()) {
                        RecurId rid = inv.getRecurId();
                        instElt.addAttribute(MailConstants.A_CAL_RECURRENCE_ID_Z, rid.getDtZ());
                    } else {
                        instElt.addAttribute(MailConstants.A_CAL_RECURRENCE_ID_Z, inst.getRecurIdZ());
                    }
                    if (inst.isException()) {
                        instElt.addAttribute(MailConstants.A_CAL_IS_EXCEPTION, true);
                        instElt.addAttribute(MailConstants.A_CAL_INV_ID, ifmt.formatItemId(calItem, inst.getMailItemId()));
                        instElt.addAttribute(MailConstants.A_CAL_COMPONENT_NUM, inst.getComponentNum());
                        if (showAll) {
                            // fragment has already been sanitized...
                            String frag = inv.getFragment();
                            if (frag != null && !frag.equals(""))
                                instElt.addAttribute(MailConstants.E_FRAG, frag, Element.Disposition.CONTENT);
                            if (inv.getPriority() != null)
                                instElt.addAttribute(MailConstants.A_CAL_PRIORITY, inv.getPriority());
                            if (inv.isEvent()) {
                                if (inv.getFreeBusy() != null)
                                    instElt.addAttribute(MailConstants.A_APPT_FREEBUSY, inv.getFreeBusy());
                                if (inv.getTransparency() != null)
                                    instElt.addAttribute(MailConstants.A_APPT_TRANSPARENCY, inv.getTransparency());
                            }
                            if (inv.isTodo()) {
                                if (inv.getPercentComplete() != null)
                                    instElt.addAttribute(MailConstants.A_TASK_PERCENT_COMPLETE, inv.getPercentComplete());
                            }
                            if (inv.getName() != null)
                                instElt.addAttribute(MailConstants.A_NAME, inv.getName());
                            if (inv.getLocation() != null)
                                instElt.addAttribute(MailConstants.A_CAL_LOCATION, inv.getLocation());
                            List<String> categories = inv.getCategories();
                            if (categories != null) {
                                for (String cat : categories) {
                                    instElt.addElement(MailConstants.E_CAL_CATEGORY).setText(cat);
                                }
                            }
                            Geo geo = inv.getGeo();
                            if (geo != null)
                                geo.toXml(instElt);
                            if (inv.hasOtherAttendees())
                                instElt.addAttribute(MailConstants.A_CAL_OTHER_ATTENDEES, true);
                            if (inv.hasAlarm())
                                instElt.addAttribute(MailConstants.A_CAL_ALARM, true);
                        }
                        instElt.addAttribute(MailConstants.A_CAL_ISORG, inv.isOrganizer());
                        if (inv.isTodo()) {
                            if (inst.hasEnd()) {
                                instElt.addAttribute(MailConstants.A_TASK_DUE_DATE, inst.getEnd());
                                if (inv.isAllDayEvent())
                                    instElt.addAttribute(MailConstants.A_CAL_TZ_OFFSET_DUE, inst.getEndTzOffset());
                            }
                        } else {
                            if (inst.hasStart() && inst.hasEnd()) {
                                instElt.addAttribute(newFormat ? MailConstants.A_CAL_NEW_DURATION : MailConstants.A_CAL_DURATION, inst.getEnd() - inst.getStart());
                            }
                        }
                        if (inv.getStatus() != null)
                            instElt.addAttribute(MailConstants.A_CAL_STATUS, inv.getStatus());
                        if (inv.getClassProp() != null)
                            instElt.addAttribute(MailConstants.A_CAL_CLASS, inv.getClassProp());
                        if (inv.isAllDayEvent())
                            instElt.addAttribute(MailConstants.A_CAL_ALLDAY, true);
                        if (inv.isDraft())
                            instElt.addAttribute(MailConstants.A_CAL_DRAFT, true);
                        if (inv.isNeverSent())
                            instElt.addAttribute(MailConstants.A_CAL_NEVER_SENT, true);
                        if (inv.isRecurrence())
                            instElt.addAttribute(MailConstants.A_CAL_RECUR, true);
                    } else {
                        if (inv.isTodo()) {
                            if (inst.hasEnd()) {
                                instElt.addAttribute(MailConstants.A_TASK_DUE_DATE, inst.getEnd());
                                if (inv.isAllDayEvent())
                                    instElt.addAttribute(MailConstants.A_CAL_TZ_OFFSET_DUE, inst.getEndTzOffset());
                            }
                        } else {
                            // the default duration due to daylight savings time transitions.
                            if (inst.hasStart() && inst.hasEnd() && defDurationMsecs != inst.getEnd() - inst.getStart()) {
                                instElt.addAttribute(newFormat ? MailConstants.A_CAL_NEW_DURATION : MailConstants.A_CAL_DURATION, inst.getEnd() - inst.getStart());
                            }
                        }
                    }
                } catch (MailServiceException.NoSuchItemException e) {
                    mLog.info("Error could not get instance " + inst.getMailItemId() + "-" + inst.getComponentNum() + " for appt " + calItem.getId(), e);
                }
            }
        // iterate all the instances
        }
        if (!expandRanges || numInRange > 0) {
            // if we found any calItems at all, we have to encode the "Default" data here
            boolean showAll = !hidePrivate || defaultInvite.isPublic();
            if (calItemElem == null) {
                calItemElem = lc.createElement(isAppointment ? MailConstants.E_APPOINTMENT : MailConstants.E_TASK);
                calItemElem.addAttribute("x_uid", calItem.getUid());
                calItemElem.addAttribute(MailConstants.A_UID, calItem.getUid());
                if (showAll) {
                    // flags and tags
                    ToXML.recordItemTags(calItemElem, calItem, octxt);
                }
                // Organizer
                if (defaultInvite.hasOrganizer()) {
                    ZOrganizer org = defaultInvite.getOrganizer();
                    org.toXml(calItemElem);
                }
            }
            if (showAll) {
                if (alarmData != null)
                    ToXML.encodeAlarmData(calItemElem, calItem, alarmData);
                String defaultPriority = defaultInvite.getPriority();
                if (defaultPriority != null)
                    calItemElem.addAttribute(MailConstants.A_CAL_PRIORITY, defaultPriority);
                calItemElem.addAttribute(MailConstants.A_CAL_PARTSTAT, defaultPtSt);
                if (defaultInvite.isEvent()) {
                    calItemElem.addAttribute(MailConstants.A_APPT_FREEBUSY, defaultInvite.getFreeBusy());
                    calItemElem.addAttribute(MailConstants.A_APPT_FREEBUSY_ACTUAL, defaultFba);
                    calItemElem.addAttribute(MailConstants.A_APPT_TRANSPARENCY, defaultInvite.getTransparency());
                }
                if (defaultInvite.isTodo()) {
                    String pctComplete = defaultInvite.getPercentComplete();
                    if (pctComplete != null)
                        calItemElem.addAttribute(MailConstants.A_TASK_PERCENT_COMPLETE, pctComplete);
                }
                calItemElem.addAttribute(MailConstants.A_NAME, defaultInvite.getName());
                calItemElem.addAttribute(MailConstants.A_CAL_LOCATION, defaultInvite.getLocation());
                List<String> categories = defaultInvite.getCategories();
                if (categories != null) {
                    for (String cat : categories) {
                        calItemElem.addElement(MailConstants.E_CAL_CATEGORY).setText(cat);
                    }
                }
                Geo geo = defaultInvite.getGeo();
                if (geo != null)
                    geo.toXml(calItemElem);
                // fragment has already been sanitized...
                String fragment = defaultInvite.getFragment();
                if (!fragment.equals(""))
                    calItemElem.addAttribute(MailConstants.E_FRAG, fragment, Element.Disposition.CONTENT);
                if (defaultInvite.hasOtherAttendees()) {
                    calItemElem.addAttribute(MailConstants.A_CAL_OTHER_ATTENDEES, defaultInvite.hasOtherAttendees());
                }
                if (defaultInvite.hasAlarm()) {
                    calItemElem.addAttribute(MailConstants.A_CAL_ALARM, defaultInvite.hasAlarm());
                }
            }
            calItemElem.addAttribute(MailConstants.A_CAL_ISORG, defaultInvite.isOrganizer());
            calItemElem.addAttribute(MailConstants.A_ID, ifmt.formatItemId(calItem));
            calItemElem.addAttribute(MailConstants.A_CAL_INV_ID, ifmt.formatItemId(calItem, defaultInvite.getMailItemId()));
            calItemElem.addAttribute(MailConstants.A_CAL_COMPONENT_NUM, defaultInvite.getComponentNum());
            calItemElem.addAttribute(MailConstants.A_FOLDER, ifmt.formatItemId(new ItemId(calItem.getMailbox().getAccountId(), calItem.getFolderId())));
            calItemElem.addAttribute(MailConstants.A_CAL_STATUS, defaultInvite.getStatus());
            calItemElem.addAttribute(MailConstants.A_CAL_CLASS, defaultInvite.getClassProp());
            if (!defaultInvite.isTodo())
                calItemElem.addAttribute(newFormat ? MailConstants.A_CAL_NEW_DURATION : MailConstants.A_CAL_DURATION, defDurationMsecs);
            if (defaultInvite.isAllDayEvent())
                calItemElem.addAttribute(MailConstants.A_CAL_ALLDAY, defaultInvite.isAllDayEvent());
            if (defaultInvite.isDraft())
                calItemElem.addAttribute(MailConstants.A_CAL_DRAFT, defaultInvite.isDraft());
            if (defaultInvite.isNeverSent())
                calItemElem.addAttribute(MailConstants.A_CAL_NEVER_SENT, defaultInvite.isNeverSent());
            if (defaultInvite.isRecurrence())
                calItemElem.addAttribute(MailConstants.A_CAL_RECUR, defaultInvite.isRecurrence());
            if (calItem.hasExceptions()) {
                calItemElem.addAttribute(MailConstants.A_CAL_HAS_EXCEPTIONS, true);
            }
            toRet.element = calItemElem;
        }
        toRet.numInstancesExpanded = numInRange;
    } catch (MailServiceException.NoSuchItemException e) {
        mLog.info("Error could not get default invite for calendar item: " + calItem.getId(), e);
    } catch (RuntimeException e) {
        mLog.info("Caught Exception " + e + " while getting summary info for calendar item: " + calItem.getId(), e);
    }
    return toRet;
}
Also used : Appointment(com.zimbra.cs.mailbox.Appointment) Account(com.zimbra.cs.account.Account) InviteInfo(com.zimbra.cs.mailbox.calendar.InviteInfo) Task(com.zimbra.cs.mailbox.Task) ItemIdFormatter(com.zimbra.cs.service.util.ItemIdFormatter) ParsedDuration(com.zimbra.common.calendar.ParsedDuration) Element(com.zimbra.common.soap.Element) RecurId(com.zimbra.cs.mailbox.calendar.RecurId) ItemId(com.zimbra.cs.service.util.ItemId) CalendarItem(com.zimbra.cs.mailbox.CalendarItem) CalendarItemData(com.zimbra.cs.mailbox.calendar.cache.CalendarItemData) ParsedDateTime(com.zimbra.common.calendar.ParsedDateTime) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) ZOrganizer(com.zimbra.cs.mailbox.calendar.ZOrganizer) Geo(com.zimbra.common.calendar.Geo) Invite(com.zimbra.cs.mailbox.calendar.Invite) AlarmData(com.zimbra.cs.mailbox.CalendarItem.AlarmData)

Example 4 with InviteInfo

use of com.zimbra.cs.mailbox.calendar.InviteInfo in project zm-mailbox by Zimbra.

the class CalSummaryCache method reloadCalendarItemOverRange.

// mSummaryCache
//
// key = "accountId:folderId"
// value = CalendarData type
//
// CalendarData = {
//   folderId, range start, range end,
//   // list of CalendarItemData objects (one for each appointment in range)
//   [
//     CalendarItemData {
//       calItemId, folderId, flags, tags, item type,
//       last modified,
//       actual range start, actual range end,
//       uid, isRecurring, isPublic, alarm,
//       default instance data (FullInstanceData type),
//       // list of instances (FullInstanceData if an exception, InstanceData if not)
//       [
//         InstanceData/FullInstanceData, ...
//       ]
//     },
//     CalendarItemData, ...
//   ]
public static CalendarItemData reloadCalendarItemOverRange(CalendarItem calItem, long rangeStart, long rangeEnd) throws ServiceException {
    CalendarItemData calItemData = null;
    try {
        boolean rangeValid = (rangeStart >= CalendarUtils.MICROSOFT_EPOC_START_MS_SINCE_EPOC && rangeEnd > CalendarUtils.MICROSOFT_EPOC_START_MS_SINCE_EPOC && rangeStart < rangeEnd);
        if (!rangeValid) {
            return null;
        }
        Invite defaultInvite = calItem.getDefaultInviteOrNull();
        if (defaultInvite == null) {
            ZimbraLog.calendar.info("Could not load defaultinfo for calendar item with id=" + calItem.getId() + "; SKIPPING");
            return null;
        }
        String defaultFba = null;
        if (calItem instanceof Appointment)
            defaultFba = ((Appointment) calItem).getEffectiveFreeBusyActual(defaultInvite, null);
        AlarmData alarm = null;
        CalendarItem.AlarmData calItemAlarmData = calItem.getAlarmData();
        long alarmTime = 0;
        long alarmInst = 0;
        if (calItemAlarmData != null) {
            alarmTime = calItemAlarmData.getNextAt();
            alarmInst = calItemAlarmData.getNextInstanceStart();
            int alarmInvId = calItemAlarmData.getInvId();
            int alarmCompNum = calItemAlarmData.getCompNum();
            String summary = null, location = null;
            Invite alarmInv = calItem.getInvite(alarmInvId, alarmCompNum);
            if (alarmInv != null) {
                summary = alarmInv.getName();
                location = alarmInv.getLocation();
            }
            alarm = new AlarmData(calItemAlarmData.getNextAt(), calItemAlarmData.getNextInstanceStart(), alarmInvId, alarmCompNum, summary, location, calItemAlarmData.getAlarm());
        }
        Long defDtStartLong = null;
        Long defDurationLong = null;
        ParsedDateTime defDtStart = defaultInvite.getStartTime();
        if (defDtStart != null) {
            defDtStartLong = Long.valueOf(defDtStart.getUtcTime());
            ParsedDateTime defDtEnd = defaultInvite.getEffectiveEndTime();
            if (defDtEnd != null)
                defDurationLong = Long.valueOf(defDtEnd.getUtcTime() - defDtStartLong.longValue());
        }
        String defaultEffectivePartStat = calItem.getEffectivePartStat(defaultInvite, null);
        FullInstanceData defaultData = new FullInstanceData(defaultInvite, null, defDtStartLong, defDurationLong, defaultEffectivePartStat, defaultFba, null);
        calItemData = new CalendarItemData(calItem.getType(), calItem.getFolderId(), calItem.getId(), calItem.getFlagString(), calItem.getTags(), TagUtil.getTagIdString(calItem), calItem.getModifiedSequence(), calItem.getSavedSequence(), calItem.getDate(), calItem.getChangeDate(), calItem.getSize(), defaultInvite.getUid(), defaultInvite.isRecurrence(), calItem.hasExceptions(), calItem.isPublic(), alarm, defaultData);
        long actualRangeStart = 0;
        long actualRangeEnd = 0;
        int numInstances = 0;
        Collection<CalendarItem.Instance> instances = calItem.expandInstances(rangeStart, rangeEnd, true);
        for (CalendarItem.Instance inst : instances) {
            try {
                long instStart = inst.getStart();
                long duration = inst.getEnd() - instStart;
                // 0 means "no DTSTART", however, note that negative numbers are valid
                Long instStartLong = instStart != 0 ? Long.valueOf(instStart) : null;
                Long durationLong = duration > 0 ? Long.valueOf(duration) : null;
                // For an instance whose alarm time is within the time range, we must
                // include it even if its start time is after the range.
                long startOrAlarm = instStart == alarmInst ? alarmTime : instStart;
                boolean hasTimes = inst.hasStart() && inst.hasEnd();
                if (hasTimes && (startOrAlarm >= rangeEnd || inst.getEnd() <= rangeStart)) {
                    continue;
                }
                numInstances++;
                if (hasTimes) {
                    if (actualRangeStart == 0 || startOrAlarm < actualRangeStart)
                        actualRangeStart = startOrAlarm;
                    if (inst.getEnd() > actualRangeEnd)
                        actualRangeEnd = inst.getEnd();
                }
                InviteInfo invId = inst.getInviteInfo();
                Invite inv = calItem.getInvite(invId.getMsgId(), invId.getComponentId());
                Long alarmAt = instStart == alarmInst ? Long.valueOf(alarmTime) : null;
                String fba = inv.getFreeBusyActual();
                if (calItem instanceof Appointment)
                    fba = ((Appointment) calItem).getEffectiveFreeBusyActual(inv, inst);
                String effectivePartStat = calItem.getEffectivePartStat(inv, inst);
                InstanceData instData;
                if (!inst.isException()) {
                    String ridZ = inst.getRecurIdZ();
                    Long tzOffset = instStartLong != null && inst.isAllDay() ? Long.valueOf(inst.getStartTzOffset()) : null;
                    instData = new InstanceData(ridZ, instStartLong, durationLong, alarmAt, tzOffset, effectivePartStat, fba, inv.getPercentComplete(), defaultData);
                } else {
                    String ridZ = null;
                    if (inv.hasRecurId())
                        ridZ = inv.getRecurId().getDtZ();
                    instData = new FullInstanceData(inv, ridZ, instStartLong, durationLong, effectivePartStat, fba, alarmAt);
                }
                calItemData.addInstance(instData);
            } catch (MailServiceException.NoSuchItemException e) {
                ZimbraLog.calendar.info("Error could not get instance " + inst.getMailItemId() + "-" + inst.getComponentNum() + " for appt " + calItem.getId(), e);
            }
        }
        if (numInstances < 1)
            return null;
        calItemData.setActualRange(actualRangeStart, actualRangeEnd);
    } catch (MailServiceException.NoSuchItemException e) {
        ZimbraLog.calendar.info("Error could not get default invite for calendar item: " + calItem.getId(), e);
    } catch (RuntimeException e) {
        ZimbraLog.calendar.info("Caught Exception " + e + " while getting summary info for calendar item: " + calItem.getId(), e);
    }
    return calItemData;
}
Also used : Appointment(com.zimbra.cs.mailbox.Appointment) InviteInfo(com.zimbra.cs.mailbox.calendar.InviteInfo) CalendarItem(com.zimbra.cs.mailbox.CalendarItem) ParsedDateTime(com.zimbra.common.calendar.ParsedDateTime) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) Invite(com.zimbra.cs.mailbox.calendar.Invite)

Example 5 with InviteInfo

use of com.zimbra.cs.mailbox.calendar.InviteInfo in project zm-mailbox by Zimbra.

the class RssFormatter method addCalendarItem.

private void addCalendarItem(CalendarItem calItem, Element channel, UserServletContext context) throws ServiceException {
    Collection<Instance> instances = calItem.expandInstances(context.getStartTime(), context.getEndTime(), false);
    for (Iterator<Instance> instIt = instances.iterator(); instIt.hasNext(); ) {
        CalendarItem.Instance inst = instIt.next();
        InviteInfo invId = inst.getInviteInfo();
        Invite inv = calItem.getInvite(invId.getMsgId(), invId.getComponentId());
        Element rssItem = channel.addElement("item");
        rssItem.addElement("title").setText(inv.getName());
        rssItem.addElement("pubDate").setText(mDateFormat.format(new Date(inst.getStart())));
        /*
            StringBuffer desc = new StringBuffer();
            sb.append("Start: ").append(sdf.format(new Date(inst.getStart()))).append("\n");
            sb.append("End: ").append(sdf.format(new Date(inst.getEnd()))).append("\n");
            sb.append("Location: ").append(inv.getLocation()).append("\n");
            sb.append("Notes: ").append(inv.getFragment()).append("\n");
            item.addElement("description").setText(sb.toString());
            */
        rssItem.addElement("description").setText(inv.getFragment());
        if (inv.hasOrganizer())
            rssItem.addElement("author").setText(inv.getOrganizer().getAddress());
    }
}
Also used : CalendarItem(com.zimbra.cs.mailbox.CalendarItem) InviteInfo(com.zimbra.cs.mailbox.calendar.InviteInfo) Instance(com.zimbra.cs.mailbox.CalendarItem.Instance) Instance(com.zimbra.cs.mailbox.CalendarItem.Instance) Element(com.zimbra.common.soap.Element) Invite(com.zimbra.cs.mailbox.calendar.Invite) Date(java.util.Date)

Aggregations

Invite (com.zimbra.cs.mailbox.calendar.Invite)10 InviteInfo (com.zimbra.cs.mailbox.calendar.InviteInfo)10 ParsedDateTime (com.zimbra.common.calendar.ParsedDateTime)5 CalendarItem (com.zimbra.cs.mailbox.CalendarItem)4 Element (com.zimbra.common.soap.Element)3 Account (com.zimbra.cs.account.Account)2 Appointment (com.zimbra.cs.mailbox.Appointment)2 Instance (com.zimbra.cs.mailbox.CalendarItem.Instance)2 MailServiceException (com.zimbra.cs.mailbox.MailServiceException)2 Alarm (com.zimbra.cs.mailbox.calendar.Alarm)2 RecurId (com.zimbra.cs.mailbox.calendar.RecurId)2 Recurrence (com.zimbra.cs.mailbox.calendar.Recurrence)2 IRecurrence (com.zimbra.cs.mailbox.calendar.Recurrence.IRecurrence)2 RecurrenceRule (com.zimbra.cs.mailbox.calendar.Recurrence.RecurrenceRule)2 ArrayList (java.util.ArrayList)2 Date (java.util.Date)2 Geo (com.zimbra.common.calendar.Geo)1 ICalTimeZone (com.zimbra.common.calendar.ICalTimeZone)1 ParsedDuration (com.zimbra.common.calendar.ParsedDuration)1 CalendarResource (com.zimbra.cs.account.CalendarResource)1