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);
}
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);
}
}
}
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;
}
}
}
}
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);
}
}
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);
}
}
Aggregations