Search in sources :

Example 1 with ContainerException

use of com.zimbra.common.soap.Element.ContainerException in project zm-mailbox by Zimbra.

the class SoapSession method putQueuedNotifications.

/**
 * Write a single instance of the PendingLocalModifications structure into the
 *  passed-in <ctxt> block.
 */
protected void putQueuedNotifications(Mailbox mbox, QueuedNotifications ntfn, Element parent, ZimbraSoapContext zsc) {
    // create the base "notify" block:  <notify seq="6"/>
    Element eNotify = parent.addNonUniqueElement(ZimbraNamespace.E_NOTIFY);
    if (ntfn.getSequence() > 0) {
        eNotify.addAttribute(HeaderConstants.A_SEQNO, ntfn.getSequence());
    }
    OperationContext octxt = null;
    try {
        octxt = DocumentHandler.getOperationContext(zsc, this);
    } catch (ServiceException e) {
        ZimbraLog.session.warn("error fetching operation context for: " + zsc.getAuthtokenAccountId(), e);
        return;
    }
    boolean debug = ZimbraLog.session.isDebugEnabled();
    PendingLocalModifications pms = ntfn.mMailboxChanges;
    RemoteNotifications rns = ntfn.mRemoteChanges;
    Element eDeleted = eNotify.addUniqueElement(ZimbraNamespace.E_DELETED);
    StringBuilder deletedIds = new StringBuilder();
    if (pms != null && pms.deleted != null && pms.deleted.size() > 0) {
        for (ModificationKey mkey : pms.deleted.keySet()) {
            addDeletedNotification(mkey, deletedIds);
        }
    }
    if (rns != null && rns.deleted != null) {
        deletedIds.append(deletedIds.length() == 0 ? "" : ",").append(rns.deleted);
    }
    boolean hasLocalCreates = pms != null && pms.created != null && !pms.created.isEmpty();
    boolean hasRemoteCreates = rns != null && rns.created != null && !rns.created.isEmpty();
    boolean hasLocalModifies = pms != null && pms.modified != null && !pms.modified.isEmpty();
    boolean hasRemoteModifies = rns != null && rns.modified != null && !rns.modified.isEmpty();
    if (SoapTransport.NotificationFormat.valueOf(zsc.getNotificationFormat()) == SoapTransport.NotificationFormat.IMAP) {
        try {
            AccountWithModifications info = new AccountWithModifications(zsc.getAuthtokenAccountId(), mbox.getLastChangeID());
            Map<Integer, PendingFolderModifications> folderMods = PendingModifications.encodeIMAPFolderModifications(pms);
            info.setPendingFolderModifications(folderMods.values());
            eNotify.addUniqueElement(JaxbUtil.jaxbToElement(info, eNotify.getFactory()));
        } catch (ContainerException | ServiceException e) {
            ZimbraLog.session.error("Failed to encode IMAP notifications for a SOAP session ", e);
        }
    }
    if (hasLocalCreates || hasRemoteCreates) {
        Element eCreated = eNotify.addUniqueElement(ZimbraNamespace.E_CREATED);
        if (hasLocalCreates) {
            for (BaseItemInfo item : pms.created.values()) {
                if (item instanceof MailItem) {
                    MailItem mi = (MailItem) item;
                    ItemIdFormatter ifmt = new ItemIdFormatter(mAuthenticatedAccountId, mi.getMailbox(), false);
                    try {
                        Element elem = ToXML.encodeItem(eCreated, ifmt, octxt, mi, ToXML.NOTIFY_FIELDS);
                        // special-case notifications for new mountpoints in the authenticated user's mailbox
                        if (item instanceof Mountpoint && mbox == mi.getMailbox()) {
                            Map<ItemId, Pair<Boolean, Element>> mountpoints = new HashMap<ItemId, Pair<Boolean, Element>>(2);
                            expandLocalMountpoint(octxt, (Mountpoint) mi, eCreated.getFactory(), mountpoints);
                            expandRemoteMountpoints(octxt, zsc, mountpoints);
                            transferMountpointContents(elem, octxt, mountpoints);
                        }
                    } catch (ServiceException e) {
                        ZimbraLog.session.warn("error encoding item " + mi.getId(), e);
                        return;
                    }
                }
            }
            // sanity-check the returned element
            if (!eCreated.hasChildren() && debug) {
                ZimbraLog.session.debug("no serialied creates for item set: %s", pms.created.keySet());
            }
        }
        if (hasRemoteCreates) {
            if (debug) {
                ZimbraLog.session.debug("adding %d proxied creates", rns.created.size());
            }
            for (Element elt : rns.created) {
                if (encodingMatches(parent, elt)) {
                    eCreated.addElement(elt.clone().detach());
                } else {
                    ZimbraLog.session.warn("unable to add remote notification due to mismatched SOAP protocol");
                }
            }
        }
    }
    ItemIdFormatter ifmt = new ItemIdFormatter(zsc);
    if (hasLocalModifies || hasRemoteModifies) {
        Element eModified = eNotify.addUniqueElement(ZimbraNamespace.E_MODIFIED);
        if (hasLocalModifies) {
            for (Change chg : pms.modified.values()) {
                if (chg.why != 0 && chg.what instanceof MailItem) {
                    MailItem item = (MailItem) chg.what;
                    try {
                        Element elt = ToXML.encodeItem(eModified, ifmt, octxt, item, chg.why);
                        if (elt == null) {
                            ModificationKey mkey = new PendingLocalModifications.ModificationKey(item);
                            addDeletedNotification(mkey, deletedIds);
                            if (debug) {
                                ZimbraLog.session.debug("marking nonserialized item as a delete: %s", mkey);
                            }
                        }
                    } catch (ServiceException e) {
                        ZimbraLog.session.warn("error encoding item " + item.getId(), e);
                        return;
                    }
                } else if (chg.why != 0 && chg.what instanceof Mailbox) {
                    ToXML.encodeMailbox(eModified, octxt, (Mailbox) chg.what, chg.why);
                }
            }
            // sanity-check the returned element
            if (!eModified.hasChildren() && debug) {
                ZimbraLog.session.debug("no serialied modifies for item set: %s", pms.modified.keySet());
            }
        }
        if (hasRemoteModifies) {
            if (debug) {
                ZimbraLog.session.debug("adding %d proxied modifies", rns.modified.size());
            }
            for (Element elt : rns.modified) {
                if (encodingMatches(parent, elt)) {
                    eModified.addElement(elt.clone().detach());
                } else {
                    ZimbraLog.session.warn("unable to add remote notification due to mismatched SOAP protocol");
                }
            }
        }
    }
    if (rns != null && rns.activities != null && !rns.activities.isEmpty()) {
        for (Element elt : rns.activities) {
            if (encodingMatches(parent, elt)) {
                eNotify.addElement(elt.clone().detach());
            } else {
                ZimbraLog.session.warn("unable to add remote notification due to mismatched SOAP protocol");
            }
        }
    }
    putExtraNotifications(ntfn, eNotify, ifmt);
    if (deletedIds == null || deletedIds.length() == 0) {
        eDeleted.detach();
    } else {
        eDeleted.addAttribute(A_ID, deletedIds.toString());
    }
}
Also used : AccountWithModifications(com.zimbra.soap.type.AccountWithModifications) BaseItemInfo(com.zimbra.common.mailbox.BaseItemInfo) ItemIdFormatter(com.zimbra.cs.service.util.ItemIdFormatter) HashMap(java.util.HashMap) Element(com.zimbra.common.soap.Element) ModificationKey(com.zimbra.cs.session.PendingModifications.ModificationKey) ItemId(com.zimbra.cs.service.util.ItemId) Mailbox(com.zimbra.cs.mailbox.Mailbox) ContainerException(com.zimbra.common.soap.Element.ContainerException) Mountpoint(com.zimbra.cs.mailbox.Mountpoint) Pair(com.zimbra.common.util.Pair) OperationContext(com.zimbra.cs.mailbox.OperationContext) Change(com.zimbra.cs.session.PendingModifications.Change) MailItem(com.zimbra.cs.mailbox.MailItem) ServiceException(com.zimbra.common.service.ServiceException) PendingFolderModifications(com.zimbra.soap.mail.type.PendingFolderModifications)

Aggregations

BaseItemInfo (com.zimbra.common.mailbox.BaseItemInfo)1 ServiceException (com.zimbra.common.service.ServiceException)1 Element (com.zimbra.common.soap.Element)1 ContainerException (com.zimbra.common.soap.Element.ContainerException)1 Pair (com.zimbra.common.util.Pair)1 MailItem (com.zimbra.cs.mailbox.MailItem)1 Mailbox (com.zimbra.cs.mailbox.Mailbox)1 Mountpoint (com.zimbra.cs.mailbox.Mountpoint)1 OperationContext (com.zimbra.cs.mailbox.OperationContext)1 ItemId (com.zimbra.cs.service.util.ItemId)1 ItemIdFormatter (com.zimbra.cs.service.util.ItemIdFormatter)1 Change (com.zimbra.cs.session.PendingModifications.Change)1 ModificationKey (com.zimbra.cs.session.PendingModifications.ModificationKey)1 PendingFolderModifications (com.zimbra.soap.mail.type.PendingFolderModifications)1 AccountWithModifications (com.zimbra.soap.type.AccountWithModifications)1 HashMap (java.util.HashMap)1