use of com.zimbra.cs.mailbox.calendar.Alarm 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;
}
}
Aggregations