Search in sources :

Example 6 with Instance

use of com.zimbra.cs.mailbox.CalendarItem.Instance in project zm-mailbox by Zimbra.

the class CheckRecurConflicts method getConflicts.

private static UserConflicts getConflicts(FreeBusy fb, List<Instance> instances) throws ServiceException {
    UserConflicts conflicts = new UserConflicts(fb.getName());
    Iterator<Interval> ivalIter = fb.iterator();
    Iterator<Instance> instIter = instances.iterator();
    Interval ival = ivalIter.hasNext() ? ivalIter.next() : null;
    Instance inst = instIter.hasNext() ? instIter.next() : null;
    // f/b status of the previous overlap between instance and interval, if previous and current overlaps
    // are with the same instance
    String prevStatus = null;
    while (ival != null && inst != null) {
        String status = ival.getStatus();
        if (IcalXmlStrMap.FBTYPE_FREE.equals(status)) {
            ival = ivalIter.hasNext() ? ivalIter.next() : null;
            continue;
        }
        if (!inst.hasStart() || !inst.hasEnd()) {
            inst = instIter.hasNext() ? instIter.next() : null;
            prevStatus = null;
            continue;
        }
        long instStart = inst.getStart();
        long instEnd = inst.getEnd();
        long ivalStart = ival.getStart();
        long ivalEnd = ival.getEnd();
        // If instance is before interval, go to next instance.
        if (instEnd <= ivalStart) {
            inst = instIter.hasNext() ? instIter.next() : null;
            prevStatus = null;
            continue;
        }
        // If interval is before instance, go to next interval.
        if (ivalEnd <= instStart) {
            ival = ivalIter.hasNext() ? ivalIter.next() : null;
            prevStatus = null;
            continue;
        }
        // We have an overlap!
        if (prevStatus != null)
            status = FreeBusy.chooseBusier(status, prevStatus);
        conflicts.put(inst, status);
        prevStatus = status;
        // Advance to the next interval or instance.
        if (ivalEnd < instEnd) {
            // Go to the next interval if its end time is earlier than the instance end time, because
            // the next interval may still overlap the same instance.
            ival = ivalIter.hasNext() ? ivalIter.next() : null;
        } else {
            // instEnd >= ivalEnd
            // If instance end time is at or earlier than interval end time, go to the next
            // instance.  Clear prevStatus because we're changing instance.
            inst = instIter.hasNext() ? instIter.next() : null;
            prevStatus = null;
        }
    }
    return conflicts;
}
Also used : Instance(com.zimbra.cs.mailbox.CalendarItem.Instance) Interval(com.zimbra.cs.fb.FreeBusy.Interval)

Example 7 with Instance

use of com.zimbra.cs.mailbox.CalendarItem.Instance in project zm-mailbox by Zimbra.

the class CompleteTaskInstance method handle.

@Override
public Element handle(Element request, Map<String, Object> context) throws ServiceException {
    ZimbraSoapContext zsc = getZimbraSoapContext(context);
    Mailbox mbox = getRequestedMailbox(zsc);
    OperationContext octxt = getOperationContext(zsc, context);
    ItemId iid = new ItemId(request.getAttribute(MailConstants.A_ID), zsc);
    Element exceptElem = request.getElement(MailConstants.E_CAL_EXCEPTION_ID);
    mbox.lock.lock();
    try {
        CalendarItem calItem = mbox.getCalendarItemById(octxt, iid.getId());
        if (calItem == null) {
            throw MailServiceException.NO_SUCH_CALITEM(iid.toString(), "Could not find calendar item");
        }
        if (!(calItem instanceof Task)) {
            throw MailServiceException.NO_SUCH_CALITEM(iid.toString(), "Calendar item is not a task");
        }
        Invite inv = calItem.getDefaultInviteOrNull();
        if (inv == null) {
            throw MailServiceException.NO_SUCH_CALITEM(iid.toString(), "No default invite found");
        }
        if (!inv.isRecurrence()) {
            throw ServiceException.INVALID_REQUEST("Task is not a recurring task", null);
        }
        ParsedDateTime recurStart = inv.getStartTime();
        if (recurStart == null) {
            throw ServiceException.INVALID_REQUEST("Recurring task is missing start time", null);
        }
        // the instance being marked complete
        TimeZoneMap tzmap = inv.getTimeZoneMap();
        Element tzElem = request.getOptionalElement(MailConstants.E_CAL_TZ);
        ICalTimeZone tz = null;
        if (tzElem != null) {
            tz = CalendarUtils.parseTzElement(tzElem);
            tzmap.add(tz);
        }
        ParsedDateTime exceptDt = CalendarUtils.parseDateTime(exceptElem, tzmap);
        if (exceptDt.getUtcTime() != recurStart.getUtcTime()) {
            throw MailServiceException.INVITE_OUT_OF_DATE(iid.toString());
        }
        // Create a new single-instance task for completed date.
        Invite completed = createCompletedInstanceInvite(inv, exceptDt);
        mbox.addInvite(octxt, completed, calItem.getFolderId());
        // Update recurrence's start date to the next instance start date.
        long oldStart = recurStart.getUtcTime();
        long newStart = -1;
        Collection<Instance> instances = calItem.expandInstances(oldStart, Long.MAX_VALUE, false);
        for (Instance inst : instances) {
            if (inst.getStart() > oldStart) {
                newStart = inst.getStart();
                break;
            }
        }
        if (newStart != -1) {
            // Update DTSTART to newStart.
            ParsedDateTime newStartDt = ParsedDateTime.fromUTCTime(newStart);
            newStartDt.toTimeZone(inv.getStartTime().getTimeZone());
            newStartDt.setHasTime(recurStart.hasTime());
            // Update DUE.
            ParsedDuration dur = inv.getEffectiveDuration();
            if (dur != null) {
                ParsedDateTime due = newStartDt.add(dur);
                inv.setDtEnd(due);
            }
            inv.setDtStart(newStartDt);
            inv.setSeqNo(inv.getSeqNo() + 1);
            inv.setDtStamp(System.currentTimeMillis());
            mbox.addInvite(octxt, inv, calItem.getFolderId());
        } else {
            // No more instance left.  Delete the recurring task.
            mbox.delete(octxt, calItem.getId(), calItem.getType());
        }
    } finally {
        mbox.lock.release();
    }
    // response
    Element response = getResponseElement(zsc);
    return response;
}
Also used : OperationContext(com.zimbra.cs.mailbox.OperationContext) Task(com.zimbra.cs.mailbox.Task) Instance(com.zimbra.cs.mailbox.CalendarItem.Instance) ParsedDuration(com.zimbra.common.calendar.ParsedDuration) Element(com.zimbra.common.soap.Element) ItemId(com.zimbra.cs.service.util.ItemId) CalendarItem(com.zimbra.cs.mailbox.CalendarItem) Mailbox(com.zimbra.cs.mailbox.Mailbox) ZimbraSoapContext(com.zimbra.soap.ZimbraSoapContext) TimeZoneMap(com.zimbra.common.calendar.TimeZoneMap) ParsedDateTime(com.zimbra.common.calendar.ParsedDateTime) Invite(com.zimbra.cs.mailbox.calendar.Invite) ICalTimeZone(com.zimbra.common.calendar.ICalTimeZone)

Example 8 with Instance

use of com.zimbra.cs.mailbox.CalendarItem.Instance in project zm-mailbox by Zimbra.

the class XmlFormatter method formatCallback.

@Override
public void formatCallback(UserServletContext context) throws ServiceException, IOException {
    Element elt = getFactory().createElement("items");
    ItemIdFormatter ifmt = new ItemIdFormatter(context.getAuthAccount(), context.targetMailbox, false);
    Iterator<? extends MailItem> iterator = null;
    try {
        long start = context.getStartTime();
        long end = context.getEndTime();
        boolean hasTimeRange = start != TIME_UNSPECIFIED && end != TIME_UNSPECIFIED;
        iterator = getMailItems(context, start, end, Integer.MAX_VALUE);
        // this is lame
        while (iterator.hasNext()) {
            MailItem item = iterator.next();
            if (item instanceof CalendarItem && hasTimeRange) {
                // Skip appointments that have no instance in the time range.
                CalendarItem calItem = (CalendarItem) item;
                Collection<Instance> instances = calItem.expandInstances(start, end, false);
                if (instances.isEmpty())
                    continue;
            }
            ToXML.encodeItem(elt, ifmt, context.opContext, item, ToXML.NOTIFY_FIELDS);
        }
        context.resp.getOutputStream().write(elt.toUTF8());
    } finally {
        if (iterator instanceof QueryResultIterator)
            ((QueryResultIterator) iterator).finished();
    }
}
Also used : CalendarItem(com.zimbra.cs.mailbox.CalendarItem) MailItem(com.zimbra.cs.mailbox.MailItem) ItemIdFormatter(com.zimbra.cs.service.util.ItemIdFormatter) Instance(com.zimbra.cs.mailbox.CalendarItem.Instance) Element(com.zimbra.common.soap.Element)

Example 9 with Instance

use of com.zimbra.cs.mailbox.CalendarItem.Instance in project zm-mailbox by Zimbra.

the class Invite method getExdates.

public List<Instance> getExdates() {
    List<Instance> exdates = Lists.newArrayList();
    IRecurrence recurrence = getRecurrence();
    if (recurrence == null) {
        return exdates;
    }
    for (Iterator<?> iter = recurrence.subRulesIterator(); iter != null && iter.hasNext(); ) {
        IRecurrence cur = (IRecurrence) iter.next();
        switch(cur.getType()) {
            case Recurrence.TYPE_SINGLE_DATES:
                Recurrence.SingleDates sd = (Recurrence.SingleDates) cur;
                RdateExdate exdate = sd.getRdateExdate();
                if (exdate.isEXDATE()) {
                    exdates.addAll(sd.expandInstances(getMailItemId()));
                } else {
                    ZimbraLog.calendar.debug("RDATE '%s' ignored", exdate);
                }
                break;
            case Recurrence.TYPE_REPEATING:
                // See http://tools.ietf.org/html/rfc5545 A.3. Deprecated Features
                // 1.  The "EXRULE" property can no longer be specified in a component.
                ZimbraLog.calendar.debug("EXRULE ignored - no longer supported in rfc5545");
                break;
        }
    }
    return exdates;
}
Also used : IRecurrence(com.zimbra.cs.mailbox.calendar.Recurrence.IRecurrence) IRecurrence(com.zimbra.cs.mailbox.calendar.Recurrence.IRecurrence) Instance(com.zimbra.cs.mailbox.CalendarItem.Instance)

Example 10 with Instance

use of com.zimbra.cs.mailbox.CalendarItem.Instance in project zm-mailbox by Zimbra.

the class OrganizerInviteChanges method getExdatesOnlyInFirst.

public List<Instance> getExdatesOnlyInFirst(List<Instance> first, List<Instance> second) {
    List<Instance> newList = Lists.newArrayList(first);
    Iterator<Instance> iter = newList.iterator();
    while (iter.hasNext()) {
        Instance curr = iter.next();
        for (Instance fromSecond : second) {
            if (fromSecond.sameTime(curr)) {
                iter.remove();
                break;
            }
        }
    }
    return newList;
}
Also used : Instance(com.zimbra.cs.mailbox.CalendarItem.Instance)

Aggregations

Instance (com.zimbra.cs.mailbox.CalendarItem.Instance)15 Element (com.zimbra.common.soap.Element)7 CalendarItem (com.zimbra.cs.mailbox.CalendarItem)6 TimeZoneMap (com.zimbra.common.calendar.TimeZoneMap)5 ArrayList (java.util.ArrayList)5 ICalTimeZone (com.zimbra.common.calendar.ICalTimeZone)3 ParsedDateTime (com.zimbra.common.calendar.ParsedDateTime)3 ParsedDuration (com.zimbra.common.calendar.ParsedDuration)3 MailItem (com.zimbra.cs.mailbox.MailItem)3 OperationContext (com.zimbra.cs.mailbox.OperationContext)3 Invite (com.zimbra.cs.mailbox.calendar.Invite)3 IRecurrence (com.zimbra.cs.mailbox.calendar.Recurrence.IRecurrence)3 ItemId (com.zimbra.cs.service.util.ItemId)3 ZimbraSoapContext (com.zimbra.soap.ZimbraSoapContext)3 Browser (com.zimbra.common.util.HttpUtil.Browser)2 Account (com.zimbra.cs.account.Account)2 Interval (com.zimbra.cs.fb.FreeBusy.Interval)2 Appointment (com.zimbra.cs.mailbox.Appointment)2 Folder (com.zimbra.cs.mailbox.Folder)2 Task (com.zimbra.cs.mailbox.Task)2