use of com.zimbra.common.mailbox.BaseItemInfo in project zm-mailbox by Zimbra.
the class TagTest method notifications.
@Test
public void notifications() throws Exception {
Mailbox mbox = MailboxManager.getInstance().getMailboxByAccountId(MockProvisioning.DEFAULT_ACCOUNT_ID);
MockListener ml = new MockListener();
MailboxListener.register(ml);
try {
// new implicit tags should not be included in notifications
DeliveryOptions dopt = new DeliveryOptions().setFolderId(Mailbox.ID_FOLDER_INBOX).setFlags(Flag.BITMASK_UNREAD).setTags(new String[] { tag2 });
mbox.addMessage(null, ThreaderTest.getRootMessage(), dopt, null);
for (BaseItemInfo item : ml.pms.created.values()) {
Assert.assertFalse("implicit tags should not be notified", item instanceof Tag);
}
ml.clear();
// new real tags *should* be included in notifications
mbox.createTag(null, tag1, (byte) 0);
Assert.assertFalse("explicit tag create must produce notifications", ml.pms.created.isEmpty());
Assert.assertTrue("explicit tags must be notified", ml.pms.created.values().iterator().next() instanceof Tag);
ml.clear();
// changes to implicit tags should not be included in notifications
int msgId = mbox.addMessage(null, ThreaderTest.getRootMessage(), dopt, null).getId();
for (Change chg : ml.pms.modified.values()) {
Assert.assertFalse("implicit tag changes should not be notified", chg.what instanceof Tag);
}
ml.clear();
// changes to real tags *should* be included in notifications
mbox.alterTag(null, msgId, MailItem.Type.MESSAGE, tag1, true, null);
Assert.assertFalse("explicit tag apply must produce notifications", ml.pms.modified == null || ml.pms.modified.isEmpty());
boolean found = false;
for (Change chg : ml.pms.modified.values()) {
found |= chg.what instanceof Tag;
}
Assert.assertTrue("explicit tag apply must be notified", found);
} finally {
MailboxListener.unregister(ml);
}
}
use of com.zimbra.common.mailbox.BaseItemInfo in project zm-mailbox by Zimbra.
the class ImapListener method handleModify.
protected void handleModify(int changeId, Change chg, AddedItems added) {
if (chg.what instanceof ZimbraTag && (chg.why & Change.NAME) != 0) {
mFolder.handleTagRename(changeId, (ZimbraTag) chg.what, chg);
} else {
boolean isFolder = (chg.what instanceof BaseItemInfo && ((BaseItemInfo) chg.what).getMailItemType() == MailItemType.FOLDER);
boolean isMsgOrContact = false;
BaseItemInfo item = null;
if (chg.what instanceof BaseItemInfo) {
item = (BaseItemInfo) chg.what;
isMsgOrContact = (item.getMailItemType() == MailItemType.MESSAGE || item.getMailItemType() == MailItemType.CONTACT);
}
try {
if (isFolder && ((BaseFolderInfo) chg.what).getFolderIdInOwnerMailbox() == folderId.id) {
FolderStore folder = (FolderStore) chg.what;
// here we assume that the FolderStore object also implements BaseItemInfo
if ((chg.why & Change.FLAGS) != 0 && (((BaseItemInfo) folder).getFlagBitmask() & Flag.BITMASK_DELETED) != 0) {
// mailbox accessed by sending a untagged BYE response."
if (handler != null) {
handler.close();
}
} else if ((chg.why & (Change.FOLDER | Change.NAME)) != 0) {
mFolder.handleFolderRename(changeId, folder, chg);
}
} else if (isMsgOrContact) {
boolean inFolder = mIsVirtual || item.getFolderIdInMailbox() == folderId.id;
if (!inFolder && (chg.why & Change.FOLDER) == 0) {
return;
}
mFolder.handleItemUpdate(changeId, chg, added);
}
} catch (ServiceException e) {
ZimbraLog.imap.warn("error handling modified items for changeId %s", changeId, e);
return;
}
}
}
use of com.zimbra.common.mailbox.BaseItemInfo 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.common.mailbox.BaseItemInfo in project zm-mailbox by Zimbra.
the class CtagInfoCache method notifyCommittedChanges.
void notifyCommittedChanges(PendingLocalModifications mods, int changeId) {
int inboxFolder = Mailbox.ID_FOLDER_INBOX;
Set<CalendarKey> keysToInvalidate = new HashSet<CalendarKey>();
if (mods.created != null) {
for (Map.Entry<ModificationKey, BaseItemInfo> entry : mods.created.entrySet()) {
BaseItemInfo 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.common.mailbox.BaseItemInfo in project zm-mailbox by Zimbra.
the class CalListCache method notifyCommittedChanges.
void notifyCommittedChanges(PendingLocalModifications mods, int changeId) {
ChangeMap changeMap = new ChangeMap(1);
if (mods.created != null) {
for (Map.Entry<ModificationKey, BaseItemInfo> entry : mods.created.entrySet()) {
BaseItemInfo 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);
}
}
Aggregations