use of com.zimbra.cs.session.PendingModifications.ModificationKey in project zm-mailbox by Zimbra.
the class CalListCache method notifyCommittedChanges.
void notifyCommittedChanges(PendingModifications mods, int changeId) {
ChangeMap changeMap = new ChangeMap(1);
if (mods.created != null) {
for (Map.Entry<ModificationKey, MailItem> entry : mods.created.entrySet()) {
MailItem item = entry.getValue();
if (item instanceof Folder) {
Folder folder = (Folder) item;
MailItem.Type viewType = folder.getDefaultView();
if (viewType == MailItem.Type.APPOINTMENT || viewType == MailItem.Type.TASK) {
ChangedFolders changedFolders = changeMap.getAccount(entry.getKey().getAccountId());
changedFolders.created.add(folder.getId());
}
}
}
}
if (mods.modified != null) {
for (Map.Entry<ModificationKey, Change> entry : mods.modified.entrySet()) {
Change change = entry.getValue();
Object whatChanged = change.what;
if (whatChanged instanceof Folder) {
Folder folder = (Folder) whatChanged;
MailItem.Type viewType = folder.getDefaultView();
if (viewType == MailItem.Type.APPOINTMENT || viewType == MailItem.Type.TASK) {
ChangedFolders changedFolders = changeMap.getAccount(entry.getKey().getAccountId());
int folderId = folder.getId();
if ((change.why & Change.FOLDER) != 0) {
// moving the calendar folder to another parent folder
int parentFolder = folder.getFolderId();
changedFolders.created.add(folderId);
if (parentFolder == Mailbox.ID_FOLDER_TRASH) {
changedFolders.deleted.add(folderId);
} else {
changedFolders.created.add(folderId);
}
} else {
// not a folder move, but something else changed, either calendar's metadata
// or a child item (appointment/task)
changedFolders.modified.add(folderId);
}
}
} else if (whatChanged instanceof Message) {
Message msg = (Message) whatChanged;
if (msg.hasCalendarItemInfos()) {
if (msg.getFolderId() == Mailbox.ID_FOLDER_INBOX || (change.why & Change.FOLDER) != 0) {
// If message was moved, we don't know which folder it was moved from.
// Just invalidate the Inbox because that's the only message folder we care
// about in calendaring.
ChangedFolders changedFolders = changeMap.getAccount(entry.getKey().getAccountId());
changedFolders.modified.add(Mailbox.ID_FOLDER_INBOX);
}
}
}
}
}
if (mods.deleted != null) {
for (Map.Entry<ModificationKey, Change> entry : mods.deleted.entrySet()) {
MailItem.Type type = (MailItem.Type) entry.getValue().what;
if (type == MailItem.Type.FOLDER) {
// We only have item id. Let's just assume it's a calendar folder id and check
// against the cached list.
ChangedFolders changedFolders = changeMap.getAccount(entry.getKey().getAccountId());
changedFolders.deleted.add(entry.getKey().getItemId());
}
// Let's not worry about hard deletes of invite/reply emails. It has no practical benefit.
}
}
try {
for (Map.Entry<String, ChangedFolders> entry : changeMap.entrySet()) {
ChangedFolders changedFolders = entry.getValue();
if (changedFolders.isEmpty())
continue;
String accountId = entry.getKey();
AccountKey key = new AccountKey(accountId);
CalList list = mMemcachedLookup.get(key);
if (list != null) {
boolean updated = false;
CalList newList = new CalList(list);
for (Integer folderId : changedFolders.created) {
if (!list.contains(folderId)) {
updated = true;
newList.add(folderId);
}
}
for (Integer folderId : changedFolders.modified) {
if (list.contains(folderId))
updated = true;
}
for (Integer folderId : changedFolders.deleted) {
if (list.contains(folderId)) {
updated = true;
newList.remove(folderId);
}
}
// There was a change. Increment the version and put back to cache.
if (updated) {
newList.incrementSeq();
mMemcachedLookup.put(key, newList);
}
}
}
} catch (ServiceException e) {
ZimbraLog.calendar.warn("Unable to notify calendar list cache. Some cached data may become stale.", e);
}
}
use of com.zimbra.cs.session.PendingModifications.ModificationKey in project zm-mailbox by Zimbra.
the class CtagInfoCache method notifyCommittedChanges.
void notifyCommittedChanges(PendingModifications mods, int changeId) {
int inboxFolder = Mailbox.ID_FOLDER_INBOX;
Set<CalendarKey> keysToInvalidate = new HashSet<CalendarKey>();
if (mods.created != null) {
for (Map.Entry<ModificationKey, MailItem> entry : mods.created.entrySet()) {
MailItem item = entry.getValue();
if (item instanceof Message) {
Message msg = (Message) item;
if (msg.hasCalendarItemInfos() && msg.getFolderId() == inboxFolder) {
CalendarKey key = new CalendarKey(msg.getMailbox().getAccountId(), inboxFolder);
keysToInvalidate.add(key);
}
}
}
}
if (mods.modified != null) {
for (Map.Entry<ModificationKey, Change> entry : mods.modified.entrySet()) {
Change change = entry.getValue();
Object whatChanged = change.what;
if (whatChanged instanceof Folder) {
Folder folder = (Folder) whatChanged;
MailItem.Type viewType = folder.getDefaultView();
if (viewType == MailItem.Type.APPOINTMENT || viewType == MailItem.Type.TASK) {
CalendarKey key = new CalendarKey(folder.getMailbox().getAccountId(), folder.getId());
keysToInvalidate.add(key);
}
} else if (whatChanged instanceof Message) {
Message msg = (Message) whatChanged;
if (msg.hasCalendarItemInfos()) {
if (msg.getFolderId() == inboxFolder || (change.why & Change.FOLDER) != 0) {
// If message was moved, we don't know which folder it was moved from.
// Just invalidate the Inbox because that's the only message folder we care
// about in calendaring.
CalendarKey key = new CalendarKey(msg.getMailbox().getAccountId(), inboxFolder);
keysToInvalidate.add(key);
}
}
}
}
}
if (mods.deleted != null) {
for (Entry<ModificationKey, Change> entry : mods.deleted.entrySet()) {
Type type = (Type) entry.getValue().what;
if (type == MailItem.Type.FOLDER) {
// We only have item id. Assume it's a folder id and issue a delete.
String acctId = entry.getKey().getAccountId();
if (acctId == null)
// just to be safe
continue;
CalendarKey key = new CalendarKey(acctId, entry.getKey().getItemId());
keysToInvalidate.add(key);
}
// Let's not worry about hard deletes of invite/reply emails. It has no practical benefit.
}
}
try {
mMemcachedLookup.removeMulti(keysToInvalidate);
} catch (ServiceException e) {
ZimbraLog.calendar.warn("Unable to notify ctag info cache. Some cached data may become stale.", e);
}
}
use of com.zimbra.cs.session.PendingModifications.ModificationKey in project zm-mailbox by Zimbra.
the class ImapListener method notifyPendingChanges.
@SuppressWarnings("rawtypes")
@Override
public void notifyPendingChanges(PendingModifications pnsIn, int changeId, Session source) {
if (!pnsIn.hasNotifications()) {
return;
}
if (changeId < lastChangeId) {
ZimbraLog.imap.debug("ImapListener :: change %d is not higher than last change %d. Ignoring", changeId, lastChangeId);
return;
}
ImapHandler i4handler = handler;
try {
synchronized (this) {
AddedItems added = new AddedItems();
if (pnsIn.deleted != null) {
@SuppressWarnings("unchecked") Map<ModificationKey, Change> deleted = pnsIn.deleted;
for (Map.Entry<ModificationKey, Change> entry : deleted.entrySet()) {
handleDelete(changeId, entry.getKey().getItemId(), entry.getValue());
}
}
notifyPendingCreates(pnsIn, changeId, added);
if (pnsIn.modified != null) {
@SuppressWarnings("unchecked") Map<ModificationKey, Change> modified = pnsIn.modified;
for (Change chg : modified.values()) {
handleModify(changeId, chg, added);
}
}
// add new messages to the currently selected mailbox
if (!added.isEmpty()) {
mFolder.handleAddedMessages(changeId, added);
}
mFolder.finishNotification(changeId);
}
if (i4handler != null && i4handler.isIdle()) {
i4handler.sendNotifications(true, true);
}
} catch (IOException e) {
// which calls Session.doCleanup, which calls Mailbox.removeListener
if (ZimbraLog.imap.isDebugEnabled()) {
// with stack trace
ZimbraLog.imap.debug("Failed to notify, closing %s", this, e);
} else {
// without stack trace
ZimbraLog.imap.info("Failed to notify (%s), closing %s", e.toString(), this);
}
if (i4handler != null) {
i4handler.close();
}
} finally {
lastChangeId = changeId;
}
}
use of com.zimbra.cs.session.PendingModifications.ModificationKey in project zm-mailbox by Zimbra.
the class CalItemReminderService method notify.
@Override
public void notify(ChangeNotification notification) {
Account account = notification.mailboxAccount;
if (notification.mods.created != null) {
for (Map.Entry<ModificationKey, BaseItemInfo> entry : notification.mods.created.entrySet()) {
BaseItemInfo item = entry.getValue();
if (item instanceof CalendarItem) {
CalendarItem calItem = (CalendarItem) item;
ZimbraLog.scheduler.debug("Handling creation of calendar item (id=%s,mailboxId=%s)", calItem.getId(), calItem.getMailboxId());
scheduleNextReminders((CalendarItem) item, true, true);
}
}
}
if (notification.mods.modified != null) {
for (Map.Entry<ModificationKey, Change> entry : notification.mods.modified.entrySet()) {
Change change = entry.getValue();
if (change.what instanceof CalendarItem) {
CalendarItem calItem = (CalendarItem) change.what;
ZimbraLog.scheduler.debug("Handling modification of calendar item (id=%s,mailboxId=%s)", calItem.getId(), calItem.getMailboxId());
boolean calItemCanceled = false;
try {
if ((change.why & Change.FOLDER) != 0 && calItem.inTrash()) {
calItemCanceled = true;
}
} catch (ServiceException e) {
ZimbraLog.scheduler.error("Error in fetching calendar item's folder", e);
}
// cancel any existing reminders and schedule new ones if cal item not canceled
if (cancelExistingReminders(calItem) && !calItemCanceled)
scheduleNextReminders(calItem, true, true);
}
}
}
if (notification.mods.deleted != null) {
for (Map.Entry<ModificationKey, Change> entry : notification.mods.deleted.entrySet()) {
MailItem.Type type = (MailItem.Type) entry.getValue().what;
if (type == MailItem.Type.APPOINTMENT || type == MailItem.Type.TASK) {
Mailbox mbox = null;
try {
mbox = MailboxManager.getInstance().getMailboxByAccount(account, MailboxManager.FetchMode.DO_NOT_AUTOCREATE);
} catch (ServiceException e) {
ZimbraLog.scheduler.error("Error looking up the mailbox of account %s", account.getId(), e);
}
if (mbox != null) {
cancelExistingReminders(entry.getKey().getItemId(), mbox.getId());
}
}
}
}
}
use of com.zimbra.cs.session.PendingModifications.ModificationKey in project zm-mailbox by Zimbra.
the class CalSummaryMemcachedCache method notifyCommittedChanges.
void notifyCommittedChanges(PendingLocalModifications mods, int changeId) {
Set<CalSummaryKey> keysToInvalidate = new HashSet<CalSummaryKey>();
if (mods.modified != null) {
for (Map.Entry<ModificationKey, Change> entry : mods.modified.entrySet()) {
Change change = entry.getValue();
Object whatChanged = change.what;
if (whatChanged instanceof Folder) {
Folder folder = (Folder) whatChanged;
MailItem.Type viewType = folder.getDefaultView();
if (viewType == MailItem.Type.APPOINTMENT || viewType == MailItem.Type.TASK) {
CalSummaryKey key = new CalSummaryKey(folder.getMailbox().getAccountId(), folder.getId());
keysToInvalidate.add(key);
}
}
}
}
if (mods.deleted != null) {
for (Map.Entry<ModificationKey, Change> entry : mods.deleted.entrySet()) {
MailItem.Type type = (MailItem.Type) entry.getValue().what;
if (type == MailItem.Type.FOLDER) {
// We only have item id. Assume it's a folder id and issue a delete.
String acctId = entry.getKey().getAccountId();
if (acctId == null)
// just to be safe
continue;
CalSummaryKey key = new CalSummaryKey(acctId, entry.getKey().getItemId());
keysToInvalidate.add(key);
}
// Let's not worry about hard deletes of invite/reply emails. It has no practical benefit.
}
}
try {
mMemcachedLookup.removeMulti(keysToInvalidate);
} catch (ServiceException e) {
ZimbraLog.calendar.warn("Unable to notify ctag info cache. Some cached data may become stale.", e);
}
}
Aggregations