Search in sources :

Example 1 with CalendarDataResult

use of com.zimbra.cs.mailbox.calendar.cache.CalSummaryCache.CalendarDataResult 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 2 with CalendarDataResult

use of com.zimbra.cs.mailbox.calendar.cache.CalSummaryCache.CalendarDataResult in project zm-mailbox by Zimbra.

the class Search method runSimpleAppointmentQuery.

private static void runSimpleAppointmentQuery(Element parent, SearchParams params, OperationContext octxt, ZimbraSoapContext zsc, Account authAcct, Mailbox mbox, List<String> folderIdStrs) throws ServiceException {
    Set<MailItem.Type> types = params.getTypes();
    MailItem.Type type = types.size() == 1 ? Iterables.getOnlyElement(types) : MailItem.Type.APPOINTMENT;
    if (params.getSortBy() != null) {
        parent.addAttribute(MailConstants.A_SORTBY, params.getSortBy().toString());
    }
    parent.addAttribute(MailConstants.A_QUERY_OFFSET, params.getOffset());
    parent.addAttribute(MailConstants.A_QUERY_MORE, false);
    List<ItemId> folderIids = new ArrayList<ItemId>(folderIdStrs.size());
    for (String folderIdStr : folderIdStrs) {
        folderIids.add(new ItemId(folderIdStr, zsc));
    }
    Provisioning prov = Provisioning.getInstance();
    MailboxManager mboxMgr = MailboxManager.getInstance();
    Server localServer = prov.getLocalServer();
    Map<Server, Map<String, List<Integer>>> /* folder ids */
    groupedByServer = groupByServer(ItemId.groupFoldersByAccount(octxt, mbox, folderIids));
    // Look up in calendar cache first.
    if (LC.calendar_cache_enabled.booleanValue()) {
        CalSummaryCache calCache = CalendarCacheManager.getInstance().getSummaryCache();
        long rangeStart = params.getCalItemExpandStart();
        long rangeEnd = params.getCalItemExpandEnd();
        for (Iterator<Map.Entry<Server, Map<String, List<Integer>>>> serverIter = groupedByServer.entrySet().iterator(); serverIter.hasNext(); ) {
            Map.Entry<Server, Map<String, List<Integer>>> serverMapEntry = serverIter.next();
            Map<String, List<Integer>> accountFolders = serverMapEntry.getValue();
            // for each account
            for (Iterator<Map.Entry<String, List<Integer>>> acctIter = accountFolders.entrySet().iterator(); acctIter.hasNext(); ) {
                Map.Entry<String, List<Integer>> acctEntry = acctIter.next();
                String acctId = acctEntry.getKey();
                List<Integer> folderIds = acctEntry.getValue();
                // Setup ItemIdFormatter appropriate for this folder which might not be in the authed account
                // but also take note of presense of <noqualify/> in SOAP context
                ItemIdFormatter ifmt = new ItemIdFormatter(authAcct.getId(), acctId, zsc.wantsUnqualifiedIds());
                // for each folder
                for (Iterator<Integer> iterFolderId = folderIds.iterator(); iterFolderId.hasNext(); ) {
                    int folderId = iterFolderId.next();
                    try {
                        CalendarDataResult result = calCache.getCalendarSummary(octxt, acctId, folderId, type, rangeStart, rangeEnd, true);
                        if (result != null) {
                            // Found data in cache.
                            iterFolderId.remove();
                            addCalendarDataToResponse(parent, zsc, ifmt, result.data, result.allowPrivateAccess);
                        }
                    } catch (ServiceException e) {
                        String ecode = e.getCode();
                        if (ecode.equals(ServiceException.PERM_DENIED)) {
                            // share permission was revoked
                            ZimbraLog.calendar.warn("Ignoring permission error during calendar search of folder %s", ifmt.formatItemId(folderId), e);
                        } else if (ecode.equals(MailServiceException.NO_SUCH_FOLDER)) {
                            // shared calendar folder was deleted by the owner
                            ZimbraLog.calendar.warn("Ignoring deleted calendar folder %s", ifmt.formatItemId(folderId));
                        } else {
                            throw e;
                        }
                        iterFolderId.remove();
                    }
                }
                if (folderIds.isEmpty())
                    acctIter.remove();
            }
            if (accountFolders.isEmpty())
                serverIter.remove();
        }
    }
    // For any remaining calendars, we have to get the data the hard way.
    for (Map.Entry<Server, Map<String, List<Integer>>> serverMapEntry : groupedByServer.entrySet()) {
        Server server = serverMapEntry.getKey();
        Map<String, List<Integer>> accountFolders = serverMapEntry.getValue();
        if (server.equals(localServer)) {
            // local server
            for (Map.Entry<String, List<Integer>> entry : accountFolders.entrySet()) {
                String acctId = entry.getKey();
                List<Integer> folderIds = entry.getValue();
                if (folderIds.isEmpty())
                    continue;
                Account targetAcct = prov.get(AccountBy.id, acctId);
                if (targetAcct == null) {
                    ZimbraLog.calendar.warn("Skipping unknown account " + acctId + " during calendar search");
                    continue;
                }
                Mailbox targetMbox = mboxMgr.getMailboxByAccount(targetAcct);
                searchLocalAccountCalendars(parent, params, octxt, zsc, authAcct, targetMbox, folderIds, type);
            }
        } else {
            // remote server
            searchRemoteAccountCalendars(parent, params, zsc, authAcct, accountFolders);
        }
    }
}
Also used : Account(com.zimbra.cs.account.Account) Server(com.zimbra.cs.account.Server) ItemIdFormatter(com.zimbra.cs.service.util.ItemIdFormatter) ArrayList(java.util.ArrayList) CalendarDataResult(com.zimbra.cs.mailbox.calendar.cache.CalSummaryCache.CalendarDataResult) ItemId(com.zimbra.cs.service.util.ItemId) Provisioning(com.zimbra.cs.account.Provisioning) Mailbox(com.zimbra.cs.mailbox.Mailbox) ZMailbox(com.zimbra.client.ZMailbox) ArrayList(java.util.ArrayList) List(java.util.List) MailItem(com.zimbra.cs.mailbox.MailItem) MailboxManager(com.zimbra.cs.mailbox.MailboxManager) ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) HashMap(java.util.HashMap) Map(java.util.Map) ContactMemberOfMap(com.zimbra.cs.mailbox.ContactMemberOfMap) CalSummaryCache(com.zimbra.cs.mailbox.calendar.cache.CalSummaryCache)

Example 3 with CalendarDataResult

use of com.zimbra.cs.mailbox.calendar.cache.CalSummaryCache.CalendarDataResult in project zm-mailbox by Zimbra.

the class Search method searchLocalAccountCalendars.

private static void searchLocalAccountCalendars(Element parent, SearchParams params, OperationContext octxt, ZimbraSoapContext zsc, Account authAcct, Mailbox targetMbox, List<Integer> folderIds, MailItem.Type type) throws ServiceException {
    ItemIdFormatter ifmt = new ItemIdFormatter(authAcct.getId(), targetMbox.getAccountId(), false);
    long rangeStart = params.getCalItemExpandStart();
    long rangeEnd = params.getCalItemExpandEnd();
    for (int folderId : folderIds) {
        try {
            CalendarDataResult result = targetMbox.getCalendarSummaryForRange(octxt, folderId, type, rangeStart, rangeEnd);
            if (result != null) {
                addCalendarDataToResponse(parent, zsc, ifmt, result.data, result.allowPrivateAccess);
            }
        } catch (ServiceException e) {
            String ecode = e.getCode();
            if (ecode.equals(ServiceException.PERM_DENIED)) {
                // share permission was revoked
                ZimbraLog.calendar.warn("Ignoring permission error during calendar search of folder " + ifmt.formatItemId(folderId), e);
            } else if (ecode.equals(MailServiceException.NO_SUCH_FOLDER)) {
                // shared calendar folder was deleted by the owner
                ZimbraLog.calendar.warn("Ignoring deleted calendar folder " + ifmt.formatItemId(folderId));
            } else {
                throw e;
            }
        }
    }
}
Also used : ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) ItemIdFormatter(com.zimbra.cs.service.util.ItemIdFormatter) CalendarDataResult(com.zimbra.cs.mailbox.calendar.cache.CalSummaryCache.CalendarDataResult)

Example 4 with CalendarDataResult

use of com.zimbra.cs.mailbox.calendar.cache.CalSummaryCache.CalendarDataResult in project zm-mailbox by Zimbra.

the class GetMiniCal method doLocalFolder.

private static void doLocalFolder(OperationContext octxt, ICalTimeZone tz, Mailbox mbox, int folderId, long rangeStart, long rangeEnd, Set<String> busyDates) throws ServiceException {
    Calendar cal = new GregorianCalendar(tz);
    CalendarDataResult result = mbox.getCalendarSummaryForRange(octxt, folderId, MailItem.Type.APPOINTMENT, rangeStart, rangeEnd);
    if (result != null) {
        addBusyDates(cal, result.data, rangeStart, rangeEnd, busyDates);
    }
}
Also used : Calendar(java.util.Calendar) GregorianCalendar(java.util.GregorianCalendar) GregorianCalendar(java.util.GregorianCalendar) CalendarDataResult(com.zimbra.cs.mailbox.calendar.cache.CalSummaryCache.CalendarDataResult)

Example 5 with CalendarDataResult

use of com.zimbra.cs.mailbox.calendar.cache.CalSummaryCache.CalendarDataResult in project zm-mailbox by Zimbra.

the class Mailbox method getAllCalendarsSummaryForRange.

public List<CalendarDataResult> getAllCalendarsSummaryForRange(OperationContext octxt, MailItem.Type type, long start, long end) throws ServiceException {
    boolean success = false;
    try {
        // folder cache is populated in beginTransaction...
        beginReadTransaction("getAllCalendarsSummaryForRange", octxt);
        success = true;
        List<CalendarDataResult> list = new ArrayList<CalendarDataResult>();
        for (Folder folder : listAllFolders()) {
            if (folder.inTrash() || folder.inSpam()) {
                continue;
            }
            // any calendar items.
            if (folder.getDefaultView() != type) {
                continue;
            }
            try {
                if (!folder.canAccess(ACL.RIGHT_READ)) {
                    continue;
                }
                CalendarDataResult result = CalendarCacheManager.getInstance().getSummaryCache().getCalendarSummary(octxt, getAccountId(), folder.getId(), type, start, end, true);
                if (result != null) {
                    list.add(result);
                }
            } catch (ServiceException se) {
                ZimbraLog.fb.info("Problem getting calendar summary cache for folder '%s' - ignoring", folder.getName(), se);
                throw se;
            }
        }
        return list;
    } finally {
        endTransaction(success);
    }
}
Also used : AccountServiceException(com.zimbra.cs.account.AccountServiceException) ServiceException(com.zimbra.common.service.ServiceException) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) CalendarDataResult(com.zimbra.cs.mailbox.calendar.cache.CalSummaryCache.CalendarDataResult) CreateFolder(com.zimbra.cs.redolog.op.CreateFolder) ZFolder(com.zimbra.client.ZFolder)

Aggregations

CalendarDataResult (com.zimbra.cs.mailbox.calendar.cache.CalSummaryCache.CalendarDataResult)7 ServiceException (com.zimbra.common.service.ServiceException)4 ItemIdFormatter (com.zimbra.cs.service.util.ItemIdFormatter)4 Account (com.zimbra.cs.account.Account)3 MailServiceException (com.zimbra.cs.mailbox.MailServiceException)3 Mailbox (com.zimbra.cs.mailbox.Mailbox)3 ItemId (com.zimbra.cs.service.util.ItemId)3 ArrayList (java.util.ArrayList)3 ZMailbox (com.zimbra.client.ZMailbox)2 Element (com.zimbra.common.soap.Element)2 AccountServiceException (com.zimbra.cs.account.AccountServiceException)2 Provisioning (com.zimbra.cs.account.Provisioning)2 Server (com.zimbra.cs.account.Server)2 MailboxManager (com.zimbra.cs.mailbox.MailboxManager)2 OperationContext (com.zimbra.cs.mailbox.OperationContext)2 CalSummaryCache (com.zimbra.cs.mailbox.calendar.cache.CalSummaryCache)2 CalendarItemData (com.zimbra.cs.mailbox.calendar.cache.CalendarItemData)2 ZimbraSoapContext (com.zimbra.soap.ZimbraSoapContext)2 Calendar (java.util.Calendar)2 GregorianCalendar (java.util.GregorianCalendar)2