use of com.zimbra.common.calendar.ParsedDateTime in project zm-mailbox by Zimbra.
the class CalendarItem method computeNextAlarms.
/**
* Returns the next trigger times for alarms defined on the given Invite.
* @param inv
* @param lastAlarmsAt Map key is the 0-based alarm position and value is the last trigger time
* for that alarm.
* @return NextAlarms object that tells trigger time and instance start time by alarm position.
* It will not contain alarm position if that alarm doesn't have next trigger time later
* than its last trigger time.
*/
public NextAlarms computeNextAlarms(Invite inv, Map<Integer, Long> lastAlarmsAt) throws ServiceException {
NextAlarms result = new NextAlarms();
if (inv.getRecurrence() == null) {
// non-recurring appointment or exception instance
long instStart = 0, instEnd = 0;
ParsedDateTime dtstart = inv.getStartTime();
if (dtstart != null)
instStart = dtstart.getUtcTime();
ParsedDateTime dtend = inv.getEffectiveEndTime();
if (dtend != null)
instEnd = dtend.getUtcTime();
List<Alarm> alarms = inv.getAlarms();
int index = 0;
for (Iterator<Alarm> iter = alarms.iterator(); iter.hasNext(); index++) {
Alarm alarm = iter.next();
Long lastAtLong = lastAlarmsAt.get(index);
if (lastAtLong != null) {
long lastAt = lastAtLong.longValue();
long triggerAt = alarm.getTriggerTime(instStart, instEnd);
if (lastAt < triggerAt)
result.add(index, triggerAt, instStart);
}
}
} else {
// series invite of recurring appointment
long oldest;
oldest = Long.MAX_VALUE;
for (long lastAt : lastAlarmsAt.values()) {
oldest = Math.min(oldest, lastAt);
}
long endTime = getNextAlarmRecurrenceExpansionLimit();
Collection<Instance> instances = expandInstances(oldest, endTime, false);
List<Alarm> alarms = inv.getAlarms();
int index = 0;
for (Iterator<Alarm> iter = alarms.iterator(); iter.hasNext(); index++) {
Alarm alarm = iter.next();
Long lastAtLong = lastAlarmsAt.get(index);
if (lastAtLong != null) {
long lastAt = lastAtLong.longValue();
for (Instance inst : instances) {
if (// only look at non-exception instances
inst.isException())
continue;
long instStart = inst.getStart();
if (instStart < lastAt && inst.hasStart())
continue;
long triggerAt = alarm.getTriggerTime(instStart, inst.getEnd());
if (lastAt < triggerAt) {
result.add(index, triggerAt, instStart);
// We can break now because we know alarms on later instances are even later.
break;
}
}
}
}
}
return result;
}
use of com.zimbra.common.calendar.ParsedDateTime in project zm-mailbox by Zimbra.
the class CalendarRequest method inviteIsAfterTime.
// Check if invite is relevant after the given time. Invite is relevant if its DTSTART
// or RECURRENCE-ID comes after the reference time. For all-day appointment, look back
// 24 hours to account for possible TZ difference.
protected static boolean inviteIsAfterTime(Invite inv, long time) {
long startUtc = 0;
ParsedDateTime dtStart = inv.getStartTime();
if (dtStart != null)
startUtc = dtStart.getUtcTime();
long ridUtc = 0;
RecurId rid = inv.getRecurId();
if (rid != null) {
ParsedDateTime ridDt = rid.getDt();
if (ridDt != null)
ridUtc = ridDt.getUtcTime();
}
long invTime = Math.max(startUtc, ridUtc);
if (inv.isAllDayEvent())
time -= MSECS_PER_DAY;
return invTime >= time;
}
use of com.zimbra.common.calendar.ParsedDateTime in project zm-mailbox by Zimbra.
the class CalendarUtils method parseInviteForCounter.
static ParseMimeMessage.InviteParserResult parseInviteForCounter(Account account, Invite oldInvite, MailItem.Type type, Element inviteElem) throws ServiceException {
TimeZoneMap tzMap = new TimeZoneMap(Util.getAccountTimeZone(account));
Invite inv = new Invite(ICalTok.COUNTER.toString(), tzMap, false);
CalendarUtils.parseInviteElementCommon(account, type, inviteElem, inv, true, true);
// Get the existing invite to populate X-MS-OLK-ORIGINALSTART and X-MS-OLK-ORIGINALEND
if (oldInvite == null) {
Mailbox mbox = MailboxManager.getInstance().getMailboxByAccount(account);
CalendarItem calItem = mbox.getCalendarItemByUid(null, inv.getUid());
if (calItem != null)
oldInvite = calItem.getInvite(inv.getRecurId());
}
if (oldInvite != null) {
// Add TZIDs from oldInvite to inv
inv.getTimeZoneMap().add(oldInvite.getTimeZoneMap());
// Add ORIGINALSTART x-prop
ParsedDateTime dt = oldInvite.getStartTime();
if (dt != null) {
ZCalendar.ZProperty prop = new ZCalendar.ZProperty("X-MS-OLK-ORIGINALSTART");
prop.setValue(dt.getDateTimePartString());
if (dt.getTZName() != null)
prop.addParameter(new ZParameter(ICalTok.TZID, dt.getTZName()));
inv.addXProp(prop);
}
// Add ORIGINALEND x-prop
dt = oldInvite.getEffectiveEndTime();
if (dt != null) {
ZCalendar.ZProperty prop = new ZCalendar.ZProperty("X-MS-OLK-ORIGINALEND");
prop.setValue(dt.getDateTimePartString());
if (dt.getTZName() != null)
prop.addParameter(new ZParameter(ICalTok.TZID, dt.getTZName()));
inv.addXProp(prop);
}
// Add LOCATION if not already exist.
if (inv.getLocation() == null || inv.getLocation().isEmpty())
inv.setLocation(oldInvite.getLocation());
}
// UID
String uid = inv.getUid();
if (uid == null || uid.length() == 0)
throw ServiceException.INVALID_REQUEST("Missing uid in a counter invite", null);
// ORGANIZER
if (!inv.hasOrganizer())
throw ServiceException.INVALID_REQUEST("Missing organizer in a counter invite", null);
// DTSTAMP
if (inv.getDTStamp() == 0) {
//zdsync
inv.setDtStamp(new Date().getTime());
}
// DTSTART
if (inv.getStartTime() == null)
throw ServiceException.INVALID_REQUEST("Missing dtstart in a counter invite", null);
// iCalendar object doesn't have an ATTENDEE property. RFC2446 doesn't require one.
if (!inv.hasOtherAttendees()) {
ZAttendee at = new ZAttendee(account.getMail());
at.setPartStat(IcalXmlStrMap.PARTSTAT_TENTATIVE);
inv.addAttendee(at);
}
inv.setLocalOnly(false);
ZVCalendar iCal = inv.newToICalendar(true);
String summaryStr = inv.getName() != null ? inv.getName() : "";
ParseMimeMessage.InviteParserResult toRet = new ParseMimeMessage.InviteParserResult();
toRet.mCal = iCal;
toRet.mUid = inv.getUid();
toRet.mSummary = summaryStr;
toRet.mInvite = inv;
return toRet;
}
use of com.zimbra.common.calendar.ParsedDateTime in project zm-mailbox by Zimbra.
the class CalendarUtils method cancelInvite.
private static Invite cancelInvite(Account acct, Account senderAcct, boolean allowPrivateAccess, boolean onBehalfOf, Invite inv, String comment, List<ZAttendee> forAttendees, RecurId recurId, boolean incrementSeq) throws ServiceException {
Invite cancel = new Invite(inv.getItemType(), ICalTok.CANCEL.toString(), inv.getTimeZoneMap(), inv.isOrganizer());
// ORGANIZER
if (inv.hasOrganizer()) {
ZOrganizer org = new ZOrganizer(inv.getOrganizer());
if (onBehalfOf && senderAcct != null)
org.setSentBy(senderAcct.getName());
cancel.setOrganizer(org);
}
// ATTENDEEs
List<ZAttendee> attendees = forAttendees != null ? forAttendees : inv.getAttendees();
for (ZAttendee a : attendees) cancel.addAttendee(a);
cancel.setClassProp(inv.getClassProp());
boolean showAll = inv.isPublic() || allowPrivateAccess;
Locale locale = acct.getLocale();
if (!showAll) {
// SUMMARY
String sbj = L10nUtil.getMessage(MsgKey.calendarSubjectWithheld, locale);
cancel.setName(CalendarMailSender.getCancelSubject(sbj, locale));
} else {
// SUMMARY
cancel.setName(CalendarMailSender.getCancelSubject(inv.getName(), locale));
// COMMENT
if (comment != null && !comment.equals(""))
cancel.addComment(comment);
}
// UID
cancel.setUid(inv.getUid());
// RECURRENCE-ID
if (inv.hasRecurId()) {
// FIXME: if RECURRENCE-ID can be a range (THISANDFUTURE) then we'll
// need to be smarter here
cancel.setRecurId(inv.getRecurId());
} else {
if (recurId != null) {
cancel.setRecurId(recurId);
}
}
// all-day
// bug 30121
cancel.setIsAllDayEvent(inv.isAllDayEvent());
// DTSTART, DTEND, and LOCATION (Outlook seems to require these, even
// though they are optional according to RFC2446.)
ParsedDateTime dtStart = recurId == null ? inv.getStartTime() : recurId.getDt();
if (dtStart != null) {
cancel.setDtStart(dtStart);
ParsedDuration dur = inv.getEffectiveDuration();
if (dur != null)
cancel.setDtEnd(dtStart.add(dur));
}
// LOCATION
cancel.setLocation(inv.getLocation());
// SEQUENCE
int seq = inv.getSeqNo();
if (incrementSeq) {
// present value. (bug 8465)
if (acct != null && inv.isOrganizer())
seq++;
}
cancel.setSeqNo(seq);
// STATUS
cancel.setStatus(IcalXmlStrMap.STATUS_CANCELLED);
// DTSTAMP
cancel.setDtStamp(new Date().getTime());
return cancel;
}
use of com.zimbra.common.calendar.ParsedDateTime in project zm-mailbox by Zimbra.
the class CalendarUtils method parseRecurId.
static RecurId parseRecurId(Element e, TimeZoneMap tzmap) throws ServiceException {
String range = e.getAttribute(MailConstants.A_CAL_RANGE, null);
ParsedDateTime dt = parseDateTime(e, tzmap);
return new RecurId(dt, range);
}
Aggregations