Search in sources :

Example 1 with IntervalList

use of com.zimbra.cs.fb.FreeBusy.IntervalList in project zm-mailbox by Zimbra.

the class LocalFreeBusyProvider method main.

public static void main(String[] args) {
    IntervalList l = new IntervalList(0, 100);
    Interval toAdd;
    System.out.println("List: " + l.toString());
    toAdd = new Interval(50, 60, IcalXmlStrMap.FBTYPE_BUSY);
    l.addInterval(toAdd);
    System.out.println("Added: " + toAdd + l.toString());
    toAdd = new Interval(10, 20, IcalXmlStrMap.FBTYPE_BUSY_TENTATIVE);
    l.addInterval(toAdd);
    System.out.println("Added: " + toAdd + l.toString());
    toAdd = new Interval(20, 30, IcalXmlStrMap.FBTYPE_BUSY_UNAVAILABLE);
    l.addInterval(toAdd);
    System.out.println("Added: " + toAdd + l.toString());
    toAdd = new Interval(15, 35, IcalXmlStrMap.FBTYPE_BUSY);
    l.addInterval(toAdd);
    System.out.println("Added: " + toAdd + l.toString());
    try {
        Mailbox mbox = MailboxManager.getInstance().getMailboxById(1);
        FreeBusy fb = getFreeBusyList(mbox.getAccount(), false, mbox, mbox.getAccount().getName(), 0, Long.MAX_VALUE, FreeBusyQuery.CALENDAR_FOLDER_ALL, null);
        System.out.println(fb.toString());
    } catch (ServiceException e) {
        System.out.println("EXCEPTION: " + e);
        e.printStackTrace();
    }
}
Also used : Mailbox(com.zimbra.cs.mailbox.Mailbox) ServiceException(com.zimbra.common.service.ServiceException) IntervalList(com.zimbra.cs.fb.FreeBusy.IntervalList) Interval(com.zimbra.cs.fb.FreeBusy.Interval)

Example 2 with IntervalList

use of com.zimbra.cs.fb.FreeBusy.IntervalList in project zm-mailbox by Zimbra.

the class LocalFreeBusyProvider method getFreeBusyList.

/**
 * @param mbox
 * @param start
 * @param end
 * @param folder folder to run free/busy search on; FreeBusyQuery.CALENDAR_FOLDER_ALL (-1) for all folders
 * @param exAppt appointment to exclude; calculate free/busy assuming
 *               the specified appointment wasn't there
 * @return
 * @throws ServiceException
 */
public static FreeBusy getFreeBusyList(Account authAcct, boolean asAdmin, Mailbox mbox, String name, long start, long end, int folder, Appointment exAppt) throws ServiceException {
    AccessManager accessMgr = AccessManager.getInstance();
    boolean accountAceAllowed = accessMgr.canDo(authAcct, mbox.getAccount(), User.R_viewFreeBusy, asAdmin);
    int numAllowedFolders = 0;
    int exApptId = exAppt == null ? -1 : exAppt.getId();
    IntervalList intervals = new IntervalList(start, end);
    List<CalendarDataResult> calDataResultList;
    if (folder == FreeBusyQuery.CALENDAR_FOLDER_ALL) {
        calDataResultList = mbox.getAllCalendarsSummaryForRange(null, MailItem.Type.APPOINTMENT, start, end);
    } else {
        calDataResultList = new ArrayList<CalendarDataResult>(1);
        calDataResultList.add(mbox.getCalendarSummaryForRange(null, folder, MailItem.Type.APPOINTMENT, start, end));
    }
    for (CalendarDataResult result : calDataResultList) {
        int folderId = result.data.getFolderId();
        Folder f = mbox.getFolderById(null, folderId);
        if ((f.getFlagBitmask() & Flag.BITMASK_EXCLUDE_FREEBUSY) != 0) {
            ZimbraLog.fb.debug("Calendar '%s' id=%s ignored - has EXCLUDE_FREEBUSY flag set", f.getName(), folderId);
            continue;
        }
        // Free/busy must be allowed by folder or at account-level.
        boolean folderFBAllowed = CalendarItem.allowFreeBusyAccess(f, authAcct, asAdmin);
        if (folderFBAllowed)
            ++numAllowedFolders;
        if (!folderFBAllowed && !accountAceAllowed) {
            ZimbraLog.fb.debug("Calendar '%s' id=%s ignored - folderFBAllowed=%s accountAceAllowed=%s", f.getName(), folderId, folderFBAllowed, accountAceAllowed);
            continue;
        }
        for (Iterator<CalendarItemData> iter = result.data.calendarItemIterator(); iter.hasNext(); ) {
            CalendarItemData appt = iter.next();
            int apptId = appt.getCalItemId();
            if (apptId == exApptId)
                continue;
            FullInstanceData defaultInstance = appt.getDefaultData();
            if (defaultInstance == null)
                continue;
            boolean isTransparent = false;
            String transp = defaultInstance.getTransparency();
            isTransparent = IcalXmlStrMap.TRANSP_TRANSPARENT.equals(transp);
            long defaultDuration = 0;
            if (defaultInstance.getDuration() != null)
                defaultDuration = defaultInstance.getDuration().longValue();
            String defaultFreeBusy = defaultInstance.getFreeBusyActual();
            for (Iterator<InstanceData> instIter = appt.instanceIterator(); instIter.hasNext(); ) {
                InstanceData instance = instIter.next();
                long instStart = instance.getDtStart() != null ? instance.getDtStart().longValue() : 0;
                // Skip instances that are outside the time range but were returned due to alarm being in range.
                if (instStart >= end)
                    continue;
                long dur = defaultDuration;
                if (instance.getDuration() != null)
                    dur = instance.getDuration().longValue();
                if (// Only consider instances with non-zero, positive duration.
                dur <= 0)
                    continue;
                long instEnd = instStart + dur;
                long recurIdDt = 0;
                // Skip if instance is TRANSPARENT to free/busy searches.
                if (instance instanceof FullInstanceData) {
                    FullInstanceData fullInst = (FullInstanceData) instance;
                    String transpInst = fullInst.getTransparency();
                    recurIdDt = fullInst.getRecurrenceId();
                    if (IcalXmlStrMap.TRANSP_TRANSPARENT.equals(transpInst))
                        continue;
                } else if (isTransparent) {
                    continue;
                }
                String freeBusy = instance.getFreeBusyActual();
                if (freeBusy == null)
                    freeBusy = defaultFreeBusy;
                if (!IcalXmlStrMap.FBTYPE_FREE.equals(freeBusy)) {
                    FBInstance fbInst = new FBInstance(freeBusy, instStart, instEnd, apptId, recurIdDt);
                    Interval ival = new Interval(instStart, instEnd, freeBusy, fbInst);
                    intervals.addInterval(ival);
                }
            }
        }
    }
    if (!accountAceAllowed && numAllowedFolders == 0 && !LC.freebusy_disable_nodata_status.booleanValue()) {
        Interval nodata = new Interval(start, end, IcalXmlStrMap.FBTYPE_NODATA);
        intervals.addInterval(nodata);
    }
    return new FreeBusy(name, intervals, start, end);
}
Also used : AccessManager(com.zimbra.cs.account.AccessManager) FullInstanceData(com.zimbra.cs.mailbox.calendar.cache.FullInstanceData) CalendarDataResult(com.zimbra.cs.mailbox.calendar.cache.CalSummaryCache.CalendarDataResult) Folder(com.zimbra.cs.mailbox.Folder) InstanceData(com.zimbra.cs.mailbox.calendar.cache.InstanceData) FullInstanceData(com.zimbra.cs.mailbox.calendar.cache.FullInstanceData) IntervalList(com.zimbra.cs.fb.FreeBusy.IntervalList) CalendarItemData(com.zimbra.cs.mailbox.calendar.cache.CalendarItemData) FBInstance(com.zimbra.cs.fb.FreeBusy.FBInstance) Interval(com.zimbra.cs.fb.FreeBusy.Interval)

Example 3 with IntervalList

use of com.zimbra.cs.fb.FreeBusy.IntervalList in project zm-mailbox by Zimbra.

the class ExchangeMessage method createRequest.

public Document createRequest(FreeBusy fb) {
    Element root = DocumentHelper.createElement(EL_PROPERTYUPDATE);
    root.add(NS_XML);
    root.add(NS_MSFT);
    root.add(NS_WEB_FOLDERS);
    Element prop = root.addElement(EL_SET).addElement(EL_PROP);
    addElement(prop, PR_SUBJECT_A, PUBURL_SECOND_PART + getRcpt(LC.freebusy_exchange_cn2) + mCn);
    addElement(prop, PR_FREEBUSY_START_RANGE, minutesSinceMsEpoch(fb.getStartTime()));
    addElement(prop, PR_FREEBUSY_END_RANGE, minutesSinceMsEpoch(fb.getEndTime()));
    addElement(prop, PR_FREEBUSY_EMAIL_ADDRESS, mOu + getRcpt(LC.freebusy_exchange_cn3) + mCn);
    Element allMonths = addElement(prop, PR_FREEBUSY_ALL_MONTHS, null, ATTR_DT, MV_INT);
    Element allEvents = addElement(prop, PR_FREEBUSY_ALL_EVENTS, null, ATTR_DT, MV_BIN);
    Element busyMonths = addElement(prop, PR_FREEBUSY_BUSY_MONTHS, null, ATTR_DT, MV_INT);
    Element busyEvents = addElement(prop, PR_FREEBUSY_BUSY_EVENTS, null, ATTR_DT, MV_BIN);
    Element tentativeMonths = addElement(prop, PR_FREEBUSY_TENTATIVE_MONTHS, null, ATTR_DT, MV_INT);
    Element tentativeEvents = addElement(prop, PR_FREEBUSY_TENTATIVE_EVENTS, null, ATTR_DT, MV_BIN);
    Element oofMonths = addElement(prop, PR_FREEBUSY_OOF_MONTHS, null, ATTR_DT, MV_INT);
    Element oofEvents = addElement(prop, PR_FREEBUSY_OOF_EVENTS, null, ATTR_DT, MV_BIN);
    // XXX
    // some/all of these properties may not be necessary.
    // because we aren't sure about the purpose of these
    // properties, and the sample codes included them,
    // we'll just keep them in here.
    addElement(prop, PR_68410003, "0");
    addElement(prop, PR_6842000B, "1");
    addElement(prop, PR_6843000B, "1");
    addElement(prop, PR_6846000B, "1");
    addElement(prop, PR_684B000B, "1");
    addElement(prop, PR_PROCESS_MEETING_REQUESTS, "0");
    addElement(prop, PR_DECLINE_RECURRING_MEETING_REQUESTS, "0");
    addElement(prop, PR_DECLINE_CONFLICTING_MEETING_REQUESTS, "0");
    long startMonth, endMonth;
    startMonth = millisToMonths(fb.getStartTime());
    endMonth = millisToMonths(fb.getEndTime());
    IntervalList consolidated = new IntervalList(fb.getStartTime(), fb.getEndTime());
    encodeIntervals(fb, startMonth, endMonth, IcalXmlStrMap.FBTYPE_BUSY, busyMonths, busyEvents, consolidated);
    encodeIntervals(fb, startMonth, endMonth, IcalXmlStrMap.FBTYPE_BUSY_TENTATIVE, tentativeMonths, tentativeEvents, consolidated);
    encodeIntervals(fb, startMonth, endMonth, IcalXmlStrMap.FBTYPE_BUSY_UNAVAILABLE, oofMonths, oofEvents, consolidated);
    encodeIntervals(consolidated, startMonth, endMonth, IcalXmlStrMap.FBTYPE_BUSY, allMonths, allEvents, null);
    return new DefaultDocument(root);
}
Also used : IntervalList(com.zimbra.cs.fb.FreeBusy.IntervalList) Element(org.dom4j.Element) DefaultDocument(org.dom4j.tree.DefaultDocument)

Example 4 with IntervalList

use of com.zimbra.cs.fb.FreeBusy.IntervalList in project zm-mailbox by Zimbra.

the class WorkingHours method getWorkingHours.

public static FreeBusy getWorkingHours(Account authAcct, boolean asAdmin, Account account, String name, long start, long end) throws ServiceException {
    // If free/busy viewing is blocked, so is viewing working hours.
    AccessManager accessMgr = AccessManager.getInstance();
    boolean accountAceAllowed = accessMgr.canDo(authAcct, account, User.R_viewFreeBusy, asAdmin);
    if (!accountAceAllowed)
        return FreeBusy.nodataFreeBusy(account.getName(), start, end);
    // Get the working hours preference and parse it.
    String workingHoursPref = account.getPrefCalendarWorkingHours();
    HoursByDay workingHoursByDay = new HoursByDay(workingHoursPref);
    // Build a recurrence rule for each day of the week and expand over the time range.
    IntervalList intervals = new IntervalList(start, end);
    ICalTimeZone tz = Util.getAccountTimeZone(account);
    TimeZoneMap tzmap = new TimeZoneMap(tz);
    StartSpec startSpec = new StartSpec(start, tz);
    for (int day = 1; day <= 7; ++day) {
        TimeRange timeRange = workingHoursByDay.getHoursForDay(day);
        if (timeRange.enabled) {
            IRecurrence rrule = getRecurrenceForDay(day, startSpec, timeRange, tz, tzmap);
            List<Instance> instances = rrule.expandInstances(0, start, end);
            for (Instance inst : instances) {
                Interval ival = new Interval(inst.getStart(), inst.getEnd(), IcalXmlStrMap.FBTYPE_BUSY_UNAVAILABLE);
                intervals.addInterval(ival);
            }
        }
    }
    // hours are shown as out-of-office.
    for (Iterator<Interval> iter = intervals.iterator(); iter.hasNext(); ) {
        Interval interval = iter.next();
        String status = interval.getStatus();
        interval.setStatus(invertStatus(status));
    }
    return new FreeBusy(name, intervals, start, end);
}
Also used : AccessManager(com.zimbra.cs.account.AccessManager) Instance(com.zimbra.cs.mailbox.CalendarItem.Instance) IRecurrence(com.zimbra.cs.mailbox.calendar.Recurrence.IRecurrence) IntervalList(com.zimbra.cs.fb.FreeBusy.IntervalList) TimeZoneMap(com.zimbra.common.calendar.TimeZoneMap) ICalTimeZone(com.zimbra.common.calendar.ICalTimeZone) Interval(com.zimbra.cs.fb.FreeBusy.Interval)

Example 5 with IntervalList

use of com.zimbra.cs.fb.FreeBusy.IntervalList in project zm-mailbox by Zimbra.

the class ExchangeEWSMessage method GetFreeBusyProperties.

Map<PathToExtendedFieldType, NonEmptyArrayOfPropertyValuesType> GetFreeBusyProperties(FreeBusy fb) {
    Map<PathToExtendedFieldType, NonEmptyArrayOfPropertyValuesType> ret = new HashMap<PathToExtendedFieldType, NonEmptyArrayOfPropertyValuesType>();
    long startMonth, endMonth;
    startMonth = millisToMonths(fb.getStartTime());
    endMonth = millisToMonths(fb.getEndTime());
    IntervalList consolidated = // TEMP
    new IntervalList(fb.getStartTime(), fb.getEndTime());
    ArrayList<String> busyMonths = new ArrayList<String>();
    ArrayList<byte[]> busyEvents = new ArrayList<byte[]>();
    ArrayList<String> tentativeMonths = new ArrayList<String>();
    ArrayList<byte[]> tentativeEvents = new ArrayList<byte[]>();
    ArrayList<String> oofMonths = new ArrayList<String>();
    ArrayList<byte[]> oofEvents = new ArrayList<byte[]>();
    ArrayList<String> allMonths = new ArrayList<String>();
    ArrayList<byte[]> allEvents = new ArrayList<byte[]>();
    encodeIntervals(fb, startMonth, endMonth, IcalXmlStrMap.FBTYPE_BUSY, busyMonths, busyEvents, consolidated);
    encodeIntervals(fb, startMonth, endMonth, IcalXmlStrMap.FBTYPE_BUSY_TENTATIVE, tentativeMonths, tentativeEvents, consolidated);
    encodeIntervals(fb, startMonth, endMonth, IcalXmlStrMap.FBTYPE_BUSY_UNAVAILABLE, oofMonths, oofEvents, consolidated);
    encodeIntervals(consolidated, startMonth, endMonth, IcalXmlStrMap.FBTYPE_BUSY, allMonths, allEvents, null);
    if (tentativeMonths.size() > 0 && tentativeEvents.size() > 0) {
        NonEmptyArrayOfPropertyValuesType nonEmptyTentativeMonths = new NonEmptyArrayOfPropertyValuesType();
        nonEmptyTentativeMonths.getValue().addAll(tentativeMonths);
        ret.put(PidTagScheduleInfoMonthsTentative, nonEmptyTentativeMonths);
        NonEmptyArrayOfPropertyValuesType nonEmptyTentativeEvents = new NonEmptyArrayOfPropertyValuesType();
        for (byte[] buf : tentativeEvents) {
            nonEmptyTentativeEvents.getValue().add(encodeBase64LittleEndian(buf));
        }
        ret.put(PidTagScheduleInfoFreeBusyTentative, nonEmptyTentativeEvents);
    }
    if (busyMonths.size() > 0 && busyEvents.size() > 0) {
        NonEmptyArrayOfPropertyValuesType nonEmptyBusyMonths = new NonEmptyArrayOfPropertyValuesType();
        nonEmptyBusyMonths.getValue().addAll(busyMonths);
        ret.put(PidTagScheduleInfoMonthsBusy, nonEmptyBusyMonths);
        NonEmptyArrayOfPropertyValuesType nonEmptyBusyEvents = new NonEmptyArrayOfPropertyValuesType();
        for (byte[] buf : busyEvents) {
            nonEmptyBusyEvents.getValue().add(encodeBase64LittleEndian(buf));
        }
        ret.put(PidTagScheduleInfoFreeBusyBusy, nonEmptyBusyEvents);
    }
    if (oofMonths.size() > 0 && oofEvents.size() > 0) {
        NonEmptyArrayOfPropertyValuesType nonEmptyOofMonths = new NonEmptyArrayOfPropertyValuesType();
        nonEmptyOofMonths.getValue().addAll(oofMonths);
        ret.put(PidTagScheduleInfoMonthsAway, nonEmptyOofMonths);
        NonEmptyArrayOfPropertyValuesType nonEmptyOofEvents = new NonEmptyArrayOfPropertyValuesType();
        for (byte[] buf : oofEvents) {
            nonEmptyOofEvents.getValue().add(encodeBase64LittleEndian(buf));
        }
        ret.put(PidTagScheduleInfoFreeBusyAway, nonEmptyOofEvents);
    }
    if (allMonths.size() > 0 && allEvents.size() > 0) {
        NonEmptyArrayOfPropertyValuesType nonEmptyAllMonths = new NonEmptyArrayOfPropertyValuesType();
        nonEmptyAllMonths.getValue().addAll(allMonths);
        ret.put(PidTagScheduleInfoMonthsMerged, nonEmptyAllMonths);
        NonEmptyArrayOfPropertyValuesType nonEmptyAllEvents = new NonEmptyArrayOfPropertyValuesType();
        for (byte[] buf : allEvents) {
            nonEmptyAllEvents.getValue().add(encodeBase64LittleEndian(buf));
        }
        ret.put(PidTagScheduleInfoFreeBusyMerged, nonEmptyAllEvents);
    }
    NonEmptyArrayOfPropertyValuesType fbStartTime = new NonEmptyArrayOfPropertyValuesType();
    fbStartTime.getValue().add(String.valueOf(lMinutesSinceMsEpoch(fb.getStartTime())));
    ret.put(PidTagFreeBusyPublishStart, fbStartTime);
    NonEmptyArrayOfPropertyValuesType fbEndTime = new NonEmptyArrayOfPropertyValuesType();
    fbEndTime.getValue().add(String.valueOf(lMinutesSinceMsEpoch(fb.getEndTime())));
    ret.put(PidTagFreeBusyPublishEnd, fbEndTime);
    NonEmptyArrayOfPropertyValuesType nonEmptyEmailAddress = new NonEmptyArrayOfPropertyValuesType();
    nonEmptyEmailAddress.getValue().add(mOu + getRcpt(LC.freebusy_exchange_cn3) + mCn);
    ret.put(PidTagFreeBusyMessageEmailAddress, nonEmptyEmailAddress);
    return ret;
}
Also used : HashMap(java.util.HashMap) IntervalList(com.zimbra.cs.fb.FreeBusy.IntervalList) ArrayList(java.util.ArrayList) PathToExtendedFieldType(com.microsoft.schemas.exchange.services._2006.types.PathToExtendedFieldType) NonEmptyArrayOfPropertyValuesType(com.microsoft.schemas.exchange.services._2006.types.NonEmptyArrayOfPropertyValuesType)

Aggregations

IntervalList (com.zimbra.cs.fb.FreeBusy.IntervalList)5 Interval (com.zimbra.cs.fb.FreeBusy.Interval)3 AccessManager (com.zimbra.cs.account.AccessManager)2 NonEmptyArrayOfPropertyValuesType (com.microsoft.schemas.exchange.services._2006.types.NonEmptyArrayOfPropertyValuesType)1 PathToExtendedFieldType (com.microsoft.schemas.exchange.services._2006.types.PathToExtendedFieldType)1 ICalTimeZone (com.zimbra.common.calendar.ICalTimeZone)1 TimeZoneMap (com.zimbra.common.calendar.TimeZoneMap)1 ServiceException (com.zimbra.common.service.ServiceException)1 FBInstance (com.zimbra.cs.fb.FreeBusy.FBInstance)1 Instance (com.zimbra.cs.mailbox.CalendarItem.Instance)1 Folder (com.zimbra.cs.mailbox.Folder)1 Mailbox (com.zimbra.cs.mailbox.Mailbox)1 IRecurrence (com.zimbra.cs.mailbox.calendar.Recurrence.IRecurrence)1 CalendarDataResult (com.zimbra.cs.mailbox.calendar.cache.CalSummaryCache.CalendarDataResult)1 CalendarItemData (com.zimbra.cs.mailbox.calendar.cache.CalendarItemData)1 FullInstanceData (com.zimbra.cs.mailbox.calendar.cache.FullInstanceData)1 InstanceData (com.zimbra.cs.mailbox.calendar.cache.InstanceData)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 Element (org.dom4j.Element)1