Search in sources :

Example 6 with InviteInfo

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

the class Appointment method processPartStat.

@Override
protected String processPartStat(Invite invite, MimeMessage mmInv, boolean forCreate, String defaultPartStat) throws ServiceException {
    Mailbox mbox = getMailbox();
    OperationContext octxt = mbox.getOperationContext();
    CreateCalendarItemPlayer player = octxt != null ? (CreateCalendarItemPlayer) octxt.getPlayer() : null;
    long opTime = octxt != null ? octxt.getTimestamp() : System.currentTimeMillis();
    Account account = getMailbox().getAccount();
    boolean onBehalfOf = false;
    Account authAcct = account;
    if (octxt != null) {
        Account authuser = octxt.getAuthenticatedUser();
        if (authuser != null) {
            onBehalfOf = !account.getId().equalsIgnoreCase(authuser.getId());
            if (onBehalfOf)
                authAcct = authuser;
        }
    }
    boolean asAdmin = octxt != null ? octxt.isUsingAdminPrivileges() : false;
    boolean allowPrivateAccess = allowPrivateAccess(authAcct, asAdmin);
    String partStat = defaultPartStat;
    if (player != null) {
        String p = player.getCalendarItemPartStat();
        if (p != null)
            partStat = p;
    }
    // See if we have RSVP=FALSE for the attendee.  Let's assume RSVP was requested unless it is
    // explicitly set to FALSE.
    boolean rsvpRequested = true;
    ZAttendee attendee = invite.getMatchingAttendee(account);
    if (attendee != null) {
        Boolean rsvp = attendee.getRsvp();
        if (rsvp != null)
            rsvpRequested = rsvp.booleanValue();
    }
    RedoLogProvider redoProvider = RedoLogProvider.getInstance();
    // Don't send reply emails if we're not on master (in redo-driven master/replica setup).
    // Don't send reply emails if we're replaying redo for reasons other than crash recovery.
    // In other words, we DO want to send emails during crash recovery, because we're completing
    // an interrupted transaction.  But we don't send emails during redo reply phase of restore.
    // Also don't send emails for cancel invites.  (Organizer doesn't expect reply for cancels.)
    // And don't send emails for task requests.
    // Don't send reply emails from a system account. (e.g. archiving, galsync, ham/spam)
    boolean needReplyEmail = rsvpRequested && redoProvider.isMaster() && (player == null || redoProvider.getRedoLogManager().getInCrashRecovery()) && invite.hasOrganizer() && !invite.isCancel() && !invite.isTodo() && !account.isIsSystemResource();
    if (invite.isOrganizer()) {
        // Organizer always accepts.
        partStat = IcalXmlStrMap.PARTSTAT_ACCEPTED;
    } else if (account instanceof CalendarResource && octxt == null) {
        // Auto accept/decline processing should only occur during email delivery.  In particular,
        // don't do it if we're here during ics import.  We're in email delivery if octxt == null.
        // (There needs to be a better way to determine that...)
        boolean replySent = false;
        CalendarResource resource = (CalendarResource) account;
        Locale lc;
        Account organizer = invite.getOrganizerAccount();
        if (organizer != null)
            lc = organizer.getLocale();
        else
            lc = resource.getLocale();
        if (resource.autoAcceptDecline() || resource.autoDeclineIfBusy() || resource.autoDeclineRecurring()) {
            boolean replyListUpdated = false;
            // If auto-accept is enabled, assume it'll be accepted until it gets declined.
            if (resource.autoAcceptDecline())
                partStat = IcalXmlStrMap.PARTSTAT_ACCEPTED;
            if (isRecurring() && resource.autoDeclineRecurring()) {
                // Decline because resource is configured to decline all recurring appointments.
                partStat = IcalXmlStrMap.PARTSTAT_DECLINED;
                if (needReplyEmail) {
                    String reason = L10nUtil.getMessage(MsgKey.calendarResourceDeclineReasonRecurring, lc);
                    Invite replyInv = makeReplyInvite(account, authAcct, lc, onBehalfOf, allowPrivateAccess, invite, invite.getRecurId(), CalendarMailSender.VERB_DECLINE);
                    CalendarMailSender.sendResourceAutoReply(octxt, mbox, true, CalendarMailSender.VERB_DECLINE, false, reason + "\r\n", this, invite, new Invite[] { replyInv }, mmInv);
                    replySent = true;
                }
            } else if (resource.autoDeclineIfBusy()) {
                // Auto decline is enabled.  Let's check for conflicts.
                int maxNumConflicts = resource.getMaxNumConflictsAllowed();
                int maxPctConflicts = resource.getMaxPercentConflictsAllowed();
                ConflictCheckResult checkResult = checkAvailability(opTime, invite, maxNumConflicts, maxPctConflicts);
                if (checkResult != null) {
                    List<Conflict> conflicts = checkResult.getConflicts();
                    if (conflicts.size() > 0) {
                        if (invite.isRecurrence() && !checkResult.tooManyConflicts()) {
                            // There are some conflicts, but within resource's allowed limit.
                            if (resource.autoAcceptDecline()) {
                                // Let's accept partially.  (Accept the series and decline conflicting instances.)
                                List<Invite> replyInvites = new ArrayList<Invite>();
                                // the REPLY for the ACCEPT of recurrence series
                                Invite acceptInv = makeReplyInvite(account, authAcct, lc, onBehalfOf, allowPrivateAccess, invite, invite.getRecurId(), CalendarMailSender.VERB_ACCEPT);
                                for (Conflict conflict : conflicts) {
                                    Instance inst = conflict.getInstance();
                                    InviteInfo invInfo = inst.getInviteInfo();
                                    Invite inv = getInvite(invInfo.getMsgId(), invInfo.getComponentId());
                                    RecurId rid = inst.makeRecurId(inv);
                                    // Record the decline status in reply list.
                                    getReplyList().modifyPartStat(resource, rid, null, resource.getName(), null, null, IcalXmlStrMap.PARTSTAT_DECLINED, false, invite.getSeqNo(), opTime);
                                    replyListUpdated = true;
                                    // Make REPLY VEVENT for the declined instance.
                                    Invite replyInv = makeReplyInvite(account, authAcct, lc, onBehalfOf, allowPrivateAccess, inv, rid, CalendarMailSender.VERB_DECLINE);
                                    replyInvites.add(replyInv);
                                }
                                if (needReplyEmail) {
                                    ICalTimeZone tz = chooseReplyTZ(invite);
                                    // Send one email to accept the series.
                                    String declinedInstances = getDeclinedTimesString(octxt, mbox, conflicts, invite.isAllDayEvent(), tz, lc);
                                    String msg = L10nUtil.getMessage(MsgKey.calendarResourceDeclinedInstances, lc) + "\r\n\r\n" + declinedInstances;
                                    CalendarMailSender.sendResourceAutoReply(octxt, mbox, true, CalendarMailSender.VERB_ACCEPT, true, msg, this, invite, new Invite[] { acceptInv }, mmInv);
                                    // Send another email to decline instances, all in one email.
                                    String conflictingTimes = getBusyTimesString(octxt, mbox, conflicts, tz, lc, false);
                                    msg = L10nUtil.getMessage(MsgKey.calendarResourceDeclinedInstances, lc) + "\r\n\r\n" + declinedInstances + "\r\n" + L10nUtil.getMessage(MsgKey.calendarResourceDeclineReasonConflict, lc) + "\r\n\r\n" + conflictingTimes;
                                    CalendarMailSender.sendResourceAutoReply(octxt, mbox, true, CalendarMailSender.VERB_DECLINE, true, msg, this, invite, replyInvites.toArray(new Invite[0]), mmInv);
                                    replySent = true;
                                }
                            } else {
                            // Auto-accept is not enabled.  Auto-decline is enabled, but there weren't
                            // enough conflicting instances to decline outright.  So we just stay
                            // silent and let the human admin deal with it.  This case is rather
                            // ambiguous, and can be avoided by configuring the resource to allow
                            // zero conflicting instance.
                            }
                        } else {
                            // Too many conflicts.  Decline outright.
                            partStat = IcalXmlStrMap.PARTSTAT_DECLINED;
                            if (needReplyEmail) {
                                ICalTimeZone tz = chooseReplyTZ(invite);
                                String msg = L10nUtil.getMessage(MsgKey.calendarResourceDeclineReasonConflict, lc) + "\r\n\r\n" + getBusyTimesString(octxt, mbox, conflicts, tz, lc, checkResult.hasMoreConflicts());
                                Invite replyInv = makeReplyInvite(account, authAcct, lc, onBehalfOf, allowPrivateAccess, invite, invite.getRecurId(), CalendarMailSender.VERB_DECLINE);
                                CalendarMailSender.sendResourceAutoReply(octxt, mbox, true, CalendarMailSender.VERB_DECLINE, false, msg, this, invite, new Invite[] { replyInv }, mmInv);
                                replySent = true;
                            }
                        }
                    }
                }
            }
            if (!replySent && IcalXmlStrMap.PARTSTAT_ACCEPTED.equals(partStat)) {
                if (needReplyEmail) {
                    Invite replyInv = makeReplyInvite(account, authAcct, lc, onBehalfOf, allowPrivateAccess, invite, invite.getRecurId(), CalendarMailSender.VERB_ACCEPT);
                    CalendarMailSender.sendResourceAutoReply(octxt, mbox, true, CalendarMailSender.VERB_ACCEPT, false, null, this, invite, new Invite[] { replyInv }, mmInv);
                }
            }
            // Record the final outcome in the replies list.
            if (IcalXmlStrMap.PARTSTAT_NEEDS_ACTION.equals(partStat)) {
                getReplyList().modifyPartStat(resource, invite.getRecurId(), null, resource.getName(), null, null, partStat, false, invite.getSeqNo(), opTime);
                replyListUpdated = true;
            }
            if (forCreate && replyListUpdated)
                saveMetadata();
        }
    }
    CreateCalendarItemRecorder recorder = (CreateCalendarItemRecorder) mbox.getRedoRecorder();
    recorder.setCalendarItemPartStat(partStat);
    invite.updateMyPartStat(account, partStat);
    if (forCreate) {
        Invite defaultInvite = getDefaultInviteOrNull();
        if (defaultInvite != null && !defaultInvite.equals(invite) && !partStat.equals(defaultInvite.getPartStat())) {
            defaultInvite.updateMyPartStat(account, partStat);
            saveMetadata();
        }
    }
    return partStat;
}
Also used : Locale(java.util.Locale) Account(com.zimbra.cs.account.Account) InviteInfo(com.zimbra.cs.mailbox.calendar.InviteInfo) FBInstance(com.zimbra.cs.fb.FreeBusy.FBInstance) ArrayList(java.util.ArrayList) RecurId(com.zimbra.cs.mailbox.calendar.RecurId) CreateCalendarItemPlayer(com.zimbra.cs.redolog.op.CreateCalendarItemPlayer) CreateCalendarItemRecorder(com.zimbra.cs.redolog.op.CreateCalendarItemRecorder) RedoLogProvider(com.zimbra.cs.redolog.RedoLogProvider) ZAttendee(com.zimbra.cs.mailbox.calendar.ZAttendee) CalendarResource(com.zimbra.cs.account.CalendarResource) Invite(com.zimbra.cs.mailbox.calendar.Invite) ICalTimeZone(com.zimbra.common.calendar.ICalTimeZone)

Example 7 with InviteInfo

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

the class CalendarItem method expandInstances.

/**
     * Expand all the instances for the time period from start to end
     *
     * @param start
     * @param end
     * @param includeAlarmOnlyInstances
     * @return list of Instances for the specified time period
     */
public Collection<Instance> expandInstances(long start, long end, boolean includeAlarmOnlyInstances) throws ServiceException {
    long endAdjusted = end;
    long alarmInstStart = 0;
    if (includeAlarmOnlyInstances) {
        // range.
        if (mAlarmData != null) {
            alarmInstStart = mAlarmData.getNextInstanceStart();
            long nextAlarm = mAlarmData.getNextAtBase();
            if (nextAlarm >= start && nextAlarm < end) {
                if (alarmInstStart >= end)
                    endAdjusted = alarmInstStart + 1;
            }
        }
    }
    List<Instance> instances = new ArrayList<Instance>();
    if (mRecurrence != null) {
        long startTime = System.currentTimeMillis();
        instances = Recurrence.expandInstances(mRecurrence, getId(), start, endAdjusted);
        if (ZimbraLog.calendar.isDebugEnabled()) {
            long elapsed = System.currentTimeMillis() - startTime;
            ZimbraLog.calendar.debug("RECURRENCE EXPANSION for appt/task %s: start=%s, end=%s; took %sms.  %s instances", getId(), start, end, elapsed, instances.size());
        }
    } else {
        // organizer.
        if (mInvites != null) {
            for (Invite inv : mInvites) {
                if (// Skip canceled instances.
                inv.isCancel())
                    continue;
                ParsedDateTime dtStart = inv.getStartTime();
                long invStart = dtStart != null ? dtStart.getUtcTime() : 0;
                ParsedDateTime dtEnd = inv.getEffectiveEndTime();
                long invEnd = dtEnd != null ? dtEnd.getUtcTime() : 0;
                if ((invStart < endAdjusted && invEnd > start) || (dtStart == null)) {
                    Instance inst = new Instance(getId(), new InviteInfo(inv), dtStart != null, dtEnd != null, invStart, invEnd, inv.isAllDayEvent(), dtStart != null ? dtStart.getOffset() : 0, dtEnd != null ? dtEnd.getOffset() : 0, inv.hasRecurId(), false);
                    instances.add(inst);
                }
            }
        }
    }
    // Remove instances that aren't in the actual range.
    for (Iterator<Instance> iter = instances.iterator(); iter.hasNext(); ) {
        Instance inst = iter.next();
        if (inst.hasStart() && inst.hasEnd()) {
            long instStart = inst.getStart();
            long instEnd = inst.getEnd();
            // or instance starts after range end. (i.e. instance does not overlap range)
            if (instStart != alarmInstStart && (instEnd <= start || instStart >= end))
                iter.remove();
        }
    }
    return instances;
}
Also used : InviteInfo(com.zimbra.cs.mailbox.calendar.InviteInfo) ArrayList(java.util.ArrayList) ParsedDateTime(com.zimbra.common.calendar.ParsedDateTime) Invite(com.zimbra.cs.mailbox.calendar.Invite)

Example 8 with InviteInfo

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

the class CalendarItem method updateRecurrence.

private boolean updateRecurrence(long nextAlarm) throws ServiceException {
    long startTime, endTime;
    // update our recurrence rule, start with the initial rule
    Invite firstInv = getDefaultInviteOrNull();
    if (firstInv == null) {
        return false;
    }
    IRecurrence recur = firstInv.getRecurrence();
    if (recur instanceof Recurrence.RecurrenceRule) {
        mRecurrence = (IRecurrence) recur.clone();
        // now, go through the list of invites and find all the exceptions
        for (Invite cur : mInvites) {
            if (cur != firstInv) {
                String method = cur.getMethod();
                if (cur.isCancel()) {
                    assert (cur.hasRecurId());
                    if (cur.hasRecurId()) {
                        checkExdateIsSensible(cur.getRecurId());
                        Recurrence.CancellationRule cancelRule = new Recurrence.CancellationRule(cur.getRecurId());
                        ((Recurrence.RecurrenceRule) mRecurrence).addException(cancelRule);
                    }
                } else if (method.equals(ICalTok.REQUEST.toString()) || method.equals(ICalTok.PUBLISH.toString())) {
                    assert (cur.hasRecurId());
                    if (cur.hasRecurId() && cur.getStartTime() != null) {
                        checkRecurIdIsSensible(cur.getRecurId());
                        Recurrence.ExceptionRule exceptRule = null;
                        IRecurrence curRule = cur.getRecurrence();
                        if (curRule != null && curRule instanceof Recurrence.ExceptionRule) {
                            exceptRule = (Recurrence.ExceptionRule) curRule.clone();
                        } else {
                            // create a fake ExceptionRule wrapper around the single-instance
                            exceptRule = new Recurrence.ExceptionRule(cur.getRecurId(), cur.getStartTime(), cur.getEffectiveDuration(), new InviteInfo(cur));
                        }
                        ((Recurrence.RecurrenceRule) mRecurrence).addException(exceptRule);
                    } else {
                        sLog.debug("Got second invite with no RecurID: " + cur.toString());
                    }
                }
            }
        }
        // Find the earliest DTSTART and latest DTEND.  We're just looking for the bounds, so we won't worry
        // about cancelled instances.
        ParsedDateTime earliestStart = null;
        ParsedDateTime latestEnd = null;
        for (Invite cur : mInvites) {
            if (!cur.isCancel()) {
                ParsedDateTime start = cur.getStartTime();
                if (earliestStart == null)
                    earliestStart = start;
                else if (start != null && start.compareTo(earliestStart) < 0)
                    earliestStart = start;
                ParsedDateTime end = cur.getEffectiveEndTime();
                if (latestEnd == null)
                    latestEnd = end;
                else if (end != null && end.compareTo(latestEnd) > 0)
                    latestEnd = end;
            }
        }
        // Take the later of latestEnd and recurrence's end time.
        ParsedDateTime recurEnd = mRecurrence.getEndTime();
        if (latestEnd == null)
            latestEnd = recurEnd;
        else if (recurEnd != null && recurEnd.compareTo(latestEnd) > 0)
            latestEnd = recurEnd;
        // update the start and end time in the CalendarItem table if
        // necessary
        startTime = earliestStart != null ? earliestStart.getUtcTime() : 0;
        endTime = latestEnd != null ? latestEnd.getUtcTime() : 0;
    } else {
        mRecurrence = null;
        startTime = 0;
        endTime = 0;
        for (Invite inv : mInvites) {
            if (!inv.isCancel()) {
                ParsedDateTime dtStart = inv.getStartTime();
                long st = dtStart != null ? dtStart.getUtcTime() : 0;
                if (st != 0 && (st < startTime || startTime == 0))
                    startTime = st;
                ParsedDateTime dtEnd = inv.getEffectiveEndTime();
                long et = dtEnd != null ? dtEnd.getUtcTime() : 0;
                if (et != 0 && et > endTime)
                    endTime = et;
            }
        }
    }
    // Adjust start/end times before recomputing alarm because alarm computation depends on those times.
    boolean timesChanged = false;
    if (mStartTime != startTime || mEndTime != endTime) {
        timesChanged = true;
        mStartTime = startTime;
        mEndTime = endTime;
    }
    // Recompute next alarm.  Bring appointment start time forward to the alarm time,
    // if the next alarm is before the first instance.
    recomputeNextAlarm(nextAlarm, false, false);
    if (mAlarmData != null) {
        long newNextAlarm = mAlarmData.getNextAtBase();
        if (newNextAlarm > 0 && newNextAlarm < startTime && mStartTime != startTime) {
            timesChanged = true;
            mStartTime = newNextAlarm;
        }
    }
    if (timesChanged) {
        if (ZimbraLog.calendar.isDebugEnabled()) {
            ZimbraLog.calendar.debug("Updating recurrence for %s.  nextAlarm=%d.", getMailopContext(this), nextAlarm);
        }
        DbMailItem.updateInCalendarItemTable(this);
    }
    return true;
}
Also used : RecurrenceRule(com.zimbra.cs.mailbox.calendar.Recurrence.RecurrenceRule) IRecurrence(com.zimbra.cs.mailbox.calendar.Recurrence.IRecurrence) IRecurrence(com.zimbra.cs.mailbox.calendar.Recurrence.IRecurrence) Recurrence(com.zimbra.cs.mailbox.calendar.Recurrence) InviteInfo(com.zimbra.cs.mailbox.calendar.InviteInfo) ParsedDateTime(com.zimbra.common.calendar.ParsedDateTime) Invite(com.zimbra.cs.mailbox.calendar.Invite)

Example 9 with InviteInfo

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

the class CalendarItem method getNextAlarm.

private AlarmData getNextAlarm(long nextAlarm, boolean skipAlarmDefChangeCheck, AlarmData currentNextAlarmData, boolean dismissed, boolean forEmailAction) throws ServiceException {
    if (nextAlarm == NEXT_ALARM_ALL_DISMISSED || !hasAlarm()) {
        return null;
    }
    long now = getMailbox().getOperationTimestampMillis();
    // Chosen alarm must be at or after this time.
    long atOrAfter;
    long snoozeUntil;
    if (nextAlarm == NEXT_ALARM_KEEP_CURRENT) {
        // special case to preserve current next alarm trigger time
        if (currentNextAlarmData != null) {
            atOrAfter = currentNextAlarmData.getNextAtBase();
            snoozeUntil = currentNextAlarmData.getSnoozeUntil();
        } else {
            // no existing alarm; pick the first alarm in the future
            atOrAfter = snoozeUntil = now;
        }
    } else if (nextAlarm == NEXT_ALARM_FROM_NOW) {
        // another special case to mean starting from "now"; pick the first alarm in the future
        atOrAfter = snoozeUntil = now;
    } else if (!dismissed && currentNextAlarmData != null) {
        // if not dismissing previous alarm, keep it as the base trigger time.  nextAlarm has snoozed re-trigger time
        atOrAfter = currentNextAlarmData.getNextAtBase();
        snoozeUntil = nextAlarm;
    } else {
        // else we just use the nextAlarm value that was passed in
        atOrAfter = snoozeUntil = nextAlarm;
    }
    if (atOrAfter <= 0) {
        // sanity check
        atOrAfter = snoozeUntil = now;
    }
    if (snoozeUntil != AlarmData.NO_SNOOZE && snoozeUntil < atOrAfter) {
        snoozeUntil = atOrAfter;
    }
    // startTime and endTime limit the time range for meeting instances to be examined.
    // All instances that ended before startTime are ignored, and by extension the alarms for them.
    // endTime limit is set to avoid examining too many instances, for performance reason.
    long startTime = atOrAfter;
    if (startTime > now) {
        // Handle the case when appointment is brought back in time such that the new start time
        // is earlier than previously set alarm trigger time.
        startTime = now;
    }
    long endTime = getNextAlarmRecurrenceExpansionLimit();
    Collection<Instance> instances = expandInstances(startTime, endTime, false);
    // Special handling for modified alarm definition
    if (atOrAfter > 0 && !skipAlarmDefChangeCheck) {
        // Let's see if alarm definition has changed.  It changed if there is no alarm to go off at
        // previously saved nextAlarm time.
        boolean alarmDefChanged = true;
        long savedNextInstStart = currentNextAlarmData != null ? currentNextAlarmData.getNextInstanceStart() : 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 <= startTime)
                    continue;
                // For appointments (but not tasks), ignore instances whose start time has come and gone.
                if (instStart < startTime && (this instanceof Appointment))
                    continue;
                // definition.
                if (instStart > savedNextInstStart)
                    break;
            }
            InviteInfo invId = inst.getInviteInfo();
            Invite inv = getInvite(invId.getMsgId(), invId.getComponentId());
            Iterator<Alarm> alarmsIter = inv.alarmsIterator();
            for (; alarmsIter.hasNext(); ) {
                Alarm alarm = alarmsIter.next();
                long currTrigger = alarm.getTriggerTime(instStart, instEnd);
                if (currTrigger == atOrAfter) {
                    // Detected alarm definition change.  Reset atOrAfter to 0 to force the next loop
                    // to choose the earliest alarm from an earliest instance at or after old nextAlarm time.
                    alarmDefChanged = false;
                    break;
                }
            }
            // no need to look at later instances
            break;
        }
        if (alarmDefChanged) {
            // If alarm definition changed, just pick the earliest alarm from now.  Without this,
            // we can't change alarm definition to an earlier trigger time, e.g. from 5 minutes before
            // to 10 minutes before. (bug 28630)
            atOrAfter = snoozeUntil = now;
        }
    }
    AlarmData alarmData = getNextAlarmHelper(atOrAfter, snoozeUntil, instances, startTime, forEmailAction);
    if (alarmData == null && this instanceof Task) {
        // special handling for Tasks
        return getNextAlarmHelperForTasks(atOrAfter, snoozeUntil, forEmailAction);
    } else {
        return alarmData;
    }
}
Also used : InviteInfo(com.zimbra.cs.mailbox.calendar.InviteInfo) Alarm(com.zimbra.cs.mailbox.calendar.Alarm) Invite(com.zimbra.cs.mailbox.calendar.Invite)

Example 10 with InviteInfo

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

the class AtomFormatter method addCalendarItem.

private void addCalendarItem(CalendarItem calItem, Element feed, 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 entry = feed.addElement("entry");
        entry.addElement("title").setText(inv.getName());
        entry.addElement("updated").setText(DateUtil.toISO8601(new Date(inst.getStart())));
        entry.addElement("summary").setText(inv.getFragment());
        // TODO: only personal part in name
        if (inv.hasOrganizer()) {
            Element author = entry.addElement("author");
            author.addElement("name").setText(inv.getOrganizer().getCn());
            author.addElement("email").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