Search in sources :

Example 11 with BaseItemInfo

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);
    }
}
Also used : BaseItemInfo(com.zimbra.common.mailbox.BaseItemInfo) DbTag(com.zimbra.cs.db.DbTag) Change(com.zimbra.cs.session.PendingModifications.Change) MockListener(com.zimbra.cs.mailbox.MailboxTest.MockListener) Test(org.junit.Test)

Example 12 with BaseItemInfo

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;
        }
    }
}
Also used : BaseFolderInfo(com.zimbra.common.mailbox.BaseFolderInfo) BaseItemInfo(com.zimbra.common.mailbox.BaseItemInfo) ServiceException(com.zimbra.common.service.ServiceException) ZimbraTag(com.zimbra.common.mailbox.ZimbraTag) FolderStore(com.zimbra.common.mailbox.FolderStore)

Example 13 with BaseItemInfo

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());
                }
            }
        }
    }
}
Also used : Account(com.zimbra.cs.account.Account) BaseItemInfo(com.zimbra.common.mailbox.BaseItemInfo) ModificationKey(com.zimbra.cs.session.PendingModifications.ModificationKey) Change(com.zimbra.cs.session.PendingModifications.Change) CalendarItem(com.zimbra.cs.mailbox.CalendarItem) MailItem(com.zimbra.cs.mailbox.MailItem) ServiceException(com.zimbra.common.service.ServiceException) Mailbox(com.zimbra.cs.mailbox.Mailbox) Map(java.util.Map)

Example 14 with BaseItemInfo

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);
    }
}
Also used : BaseItemInfo(com.zimbra.common.mailbox.BaseItemInfo) Message(com.zimbra.cs.mailbox.Message) ModificationKey(com.zimbra.cs.session.PendingModifications.ModificationKey) Change(com.zimbra.cs.session.PendingModifications.Change) ZFolder(com.zimbra.client.ZFolder) Folder(com.zimbra.cs.mailbox.Folder) Type(com.zimbra.cs.mailbox.MailItem.Type) MailItem(com.zimbra.cs.mailbox.MailItem) Type(com.zimbra.cs.mailbox.MailItem.Type) ServiceException(com.zimbra.common.service.ServiceException) HashMap(java.util.HashMap) Map(java.util.Map) MemcachedMap(com.zimbra.common.util.memcached.MemcachedMap) HashSet(java.util.HashSet)

Example 15 with BaseItemInfo

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);
    }
}
Also used : BaseItemInfo(com.zimbra.common.mailbox.BaseItemInfo) Message(com.zimbra.cs.mailbox.Message) ModificationKey(com.zimbra.cs.session.PendingModifications.ModificationKey) Change(com.zimbra.cs.session.PendingModifications.Change) Folder(com.zimbra.cs.mailbox.Folder) MailItem(com.zimbra.cs.mailbox.MailItem) ServiceException(com.zimbra.common.service.ServiceException) HashMap(java.util.HashMap) Map(java.util.Map) MemcachedMap(com.zimbra.common.util.memcached.MemcachedMap)

Aggregations

BaseItemInfo (com.zimbra.common.mailbox.BaseItemInfo)17 Change (com.zimbra.cs.session.PendingModifications.Change)10 MailItem (com.zimbra.cs.mailbox.MailItem)8 HashMap (java.util.HashMap)8 Map (java.util.Map)8 ServiceException (com.zimbra.common.service.ServiceException)7 ZimbraMailItem (com.zimbra.common.mailbox.ZimbraMailItem)6 ModificationKey (com.zimbra.cs.session.PendingModifications.ModificationKey)6 Mailbox (com.zimbra.cs.mailbox.Mailbox)5 Folder (com.zimbra.cs.mailbox.Folder)4 Type (com.zimbra.cs.mailbox.MailItem.Type)4 LinkedHashMap (java.util.LinkedHashMap)4 ZFolder (com.zimbra.client.ZFolder)3 ZimbraTag (com.zimbra.common.mailbox.ZimbraTag)3 DbTag (com.zimbra.cs.db.DbTag)3 Message (com.zimbra.cs.mailbox.Message)3 MemcachedMap (com.zimbra.common.util.memcached.MemcachedMap)2 DbMailItem (com.zimbra.cs.db.DbMailItem)2 CalendarItem (com.zimbra.cs.mailbox.CalendarItem)2 AlterItemTag (com.zimbra.cs.redolog.op.AlterItemTag)2