Search in sources :

Example 16 with ItemIdentifier

use of com.zimbra.common.mailbox.ItemIdentifier in project zm-mailbox by Zimbra.

the class ImapHandler method copyItemsBetweenMailboxes.

private void copyItemsBetweenMailboxes(ImapMailboxStore selectedImapMboxStore, List<ImapMessage> batch, ItemIdentifier fromFolderId, ItemIdentifier targetIdentifier, List<Integer> copyUIDs) throws ServiceException {
    List<ItemIdentifier> identList = Lists.newArrayListWithCapacity(batch.size());
    List<Integer> createdList = Lists.newArrayListWithCapacity(batch.size());
    for (ImapMessage i4msg : batch) {
        identList.add(ItemIdentifier.fromAccountIdAndItemId(fromFolderId.accountId, i4msg.msgId));
    }
    MailboxStore selectedStore = selectedImapMboxStore.getMailboxStore();
    List<String> copyIds = selectedStore.copyItemAction(getContext(), targetIdentifier, identList);
    for (String copyId : copyIds) {
        if (copyId.isEmpty()) {
            continue;
        }
        // For newly created items, the UID is the same as the id in the target mailbox
        ItemIdentifier itemIdentifier = new ItemIdentifier(copyId, (String) null);
        createdList.add(itemIdentifier.id);
    }
    if (createdList.size() != identList.size()) {
        throw ServiceException.FAILURE(String.format("mismatch between original (%s) and target (%s) count during IMAP COPY", identList.size(), createdList.size()), null);
    }
    if (copyUIDs != null) {
        copyUIDs.addAll(createdList);
    }
}
Also used : ItemIdentifier(com.zimbra.common.mailbox.ItemIdentifier) MailboxStore(com.zimbra.common.mailbox.MailboxStore)

Example 17 with ItemIdentifier

use of com.zimbra.common.mailbox.ItemIdentifier in project zm-mailbox by Zimbra.

the class ImapSessionManager method openFolder.

protected FolderDetails openFolder(ImapPath path, byte params, ImapHandler handler) throws ServiceException {
    ZimbraLog.imap.debug("opening folder: %s", path);
    if (!path.isSelectable()) {
        throw ServiceException.PERM_DENIED("cannot select folder: " + path);
    }
    if ((params & ImapFolder.SELECT_CONDSTORE) != 0) {
        handler.activateExtension(ImapExtension.CONDSTORE);
    }
    FolderStore folder = path.getFolder();
    String folderIdAsString = folder.getFolderIdAsString();
    int folderId = folder.getFolderIdInOwnerMailbox();
    MailboxStore mbox = folder.getMailboxStore();
    ImapMailboxStore imapStore = ImapMailboxStore.get(mbox);
    // don't have a session when the folder is loaded...
    OperationContext octxt = handler.getCredentials().getContext();
    List<ImapMessage> i4list = null;
    // *always* recalculate the contents of search folders
    if (folder instanceof SearchFolderStore) {
        i4list = loadVirtualFolder(octxt, (SearchFolderStore) folder);
    } else {
        waitForWaitSetNotifications(imapStore, folder);
    }
    mbox.lock(true);
    try {
        // need mInitialRecent to be set *before* loading the folder so we can determine what's \Recent
        if (!(folder instanceof ZSharedFolder)) {
            folder = mbox.getFolderById(octxt, folderIdAsString);
            if (folder == null) {
                throw MailServiceException.NO_SUCH_FOLDER(path.asImapPath());
            }
        }
        int recentCutoff = imapStore.getImapRECENTCutoff(folder);
        if (i4list == null) {
            List<ImapListener> listners = imapStore.getListeners(folder);
            // first option is to duplicate an existing registered session
            // (could try to just activate an inactive session, but this logic is simpler for now)
            i4list = duplicateExistingSession(folderId, listners);
            // no matching session means we next check for serialized folder data
            if (i4list == null) {
                i4list = duplicateSerializedFolder(folder);
            } else if (CONSISTENCY_CHECK) {
                Collections.sort(i4list);
            // sort only if using list from duplicated session which may be out of order
            // if loaded from serialized folder order _should_ already be OK since no changes have occurred
            }
            // do the consistency check, if requested
            if (CONSISTENCY_CHECK) {
                i4list = consistencyCheck(i4list, imapStore, octxt, folder);
            }
            // no matching serialized session means we have to go to the DB to get the messages
            if (i4list == null) {
                ItemIdentifier ident;
                if (folder instanceof MountpointStore) {
                    ident = ((MountpointStore) folder).getTargetItemIdentifier();
                } else {
                    ident = folder.getFolderItemIdentifier();
                }
                i4list = imapStore.openImapFolder(octxt, ident);
            }
        }
        Collections.sort(i4list);
        // check messages for imapUid <= 0 and assign new IMAP IDs if necessary
        renumberMessages(octxt, mbox, i4list);
        ImapFolder i4folder = new ImapFolder(path, params, handler);
        // don't rely on the <code>Folder</code> object being updated in place
        if (!(folder instanceof ZSharedFolder)) {
            folder = mbox.getFolderById(octxt, folderIdAsString);
        }
        // can't set these until *after* loading the folder because UID renumbering affects them
        InitialFolderValues initial = new InitialFolderValues(folder);
        for (ImapMessage i4msg : i4list) {
            i4folder.cache(i4msg, i4msg.imapUid > recentCutoff);
            if (initial.firstUnread == -1 && (i4msg.flags & Flag.BITMASK_UNREAD) != 0) {
                initial.firstUnread = i4msg.sequence;
            }
        }
        i4folder.setInitialSize();
        ZimbraLog.imap.debug("ImapSessionManager.openFolder.  Folder with id=%s added message list %s", folderIdAsString, i4list);
        ImapListener session = null;
        try {
            session = imapStore.createListener(i4folder, handler);
            session.register();
            sessions.put(session, session);
            imapStore.registerWithImapServerListener(session);
            return new FolderDetails(session, initial);
        } catch (ServiceException e) {
            if (session != null) {
                session.unregister();
            }
            throw e;
        }
    } finally {
        mbox.unlock();
    }
}
Also used : OperationContext(com.zimbra.cs.mailbox.OperationContext) MailboxStore(com.zimbra.common.mailbox.MailboxStore) FolderStore(com.zimbra.common.mailbox.FolderStore) SearchFolderStore(com.zimbra.common.mailbox.SearchFolderStore) ZSharedFolder(com.zimbra.client.ZSharedFolder) ItemIdentifier(com.zimbra.common.mailbox.ItemIdentifier) SearchFolderStore(com.zimbra.common.mailbox.SearchFolderStore) ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) MountpointStore(com.zimbra.common.mailbox.MountpointStore)

Example 18 with ItemIdentifier

use of com.zimbra.common.mailbox.ItemIdentifier in project zm-mailbox by Zimbra.

the class ToXML method encodeContact.

/**
 * @param memberOfIds set of IDs of contact groups this contact is a member of
 * @param mRequestedAcct requested account
 * @param mAuthedAcct authenticated account
 */
public static Element encodeContact(Element parent, ItemIdFormatter ifmt, OperationContext octxt, Contact contact, ContactGroup contactGroup, Collection<String> memberAttrFilter, boolean summary, Collection<String> attrFilter, int fields, String migratedDlist, boolean returnHiddenAttrs, long maxMembers, boolean returnCertInfo, Set<String> memberOfIds, Account mRequestedAcct, Account mAuthedAcct) throws ServiceException {
    Element el = parent.addNonUniqueElement(MailConstants.E_CONTACT);
    el.addAttribute(MailConstants.A_ID, ifmt.formatItemId(contact));
    if (needToOutput(fields, Change.FOLDER)) {
        el.addAttribute(MailConstants.A_FOLDER, ifmt.formatItemId(new ItemId(contact.getMailbox().getAccountId(), contact.getFolderId())));
    }
    recordItemTags(el, contact, octxt, fields);
    if (needToOutput(fields, Change.CONFLICT)) {
        el.addAttribute(MailConstants.A_CHANGE_DATE, contact.getChangeDate() / 1000);
        el.addAttribute(MailConstants.A_MODIFIED_SEQUENCE, contact.getModifiedSequence());
        el.addAttribute(MailConstants.A_DATE, contact.getDate());
        el.addAttribute(MailConstants.A_REVISION, contact.getSavedSequence());
    } else {
        if (needToOutput(fields, Change.CONTENT)) {
            el.addAttribute(MailConstants.A_DATE, contact.getDate());
            el.addAttribute(MailConstants.A_REVISION, contact.getSavedSequence());
        }
        if (needToOutput(fields, Change.MODSEQ)) {
            el.addAttribute(MailConstants.A_MODIFIED_SEQUENCE, contact.getModifiedSequence());
        }
    }
    if (needToOutput(fields, Change.IMAP_UID)) {
        el.addAttribute(MailConstants.A_IMAP_UID, contact.getImapUid());
    }
    if (needToOutput(fields, Change.METADATA)) {
        encodeAllCustomMetadata(el, contact, fields);
    }
    if (!needToOutput(fields, Change.CONTENT)) {
        if (summary) {
            try {
                el.addAttribute(MailConstants.A_FILE_AS_STR, contact.getFileAsString());
            } catch (ServiceException e) {
            }
            el.addAttribute(ContactConstants.A_email, contact.get(ContactConstants.A_email));
            el.addAttribute(ContactConstants.A_email2, contact.get(ContactConstants.A_email2));
            el.addAttribute(ContactConstants.A_email3, contact.get(ContactConstants.A_email3));
            String type = contact.get(ContactConstants.A_type);
            el.addAttribute(ContactConstants.A_type, type);
            // send back date with summary via search results
            el.addAttribute(MailConstants.A_CHANGE_DATE, contact.getChangeDate() / 1000);
        }
        // stop here if we're not returning the actual contact content
        return el;
    }
    try {
        el.addAttribute(MailConstants.A_FILE_AS_STR, contact.getFileAsString());
    } catch (ServiceException e) {
    }
    List<Attachment> attachments = contact.getAttachments();
    // encode contact group members (not derefed) if we don't have a
    // already derefed contactGroup, and we don't have a migrated dlist
    boolean encodeContactGroupMembersBasic = (contactGroup == null) && (migratedDlist == null);
    if (attrFilter != null) {
        for (String name : attrFilter) {
            // XXX: How to distinguish between a non-existent attribute and
            // an existing attribute with null or empty string value?
            String value = contact.get(name);
            if (!Strings.isNullOrEmpty(value)) {
                encodeContactAttr(el, name, value, contact, encodeContactGroupMembersBasic, octxt, returnCertInfo);
            } else if (attachments != null) {
                for (Attachment attach : attachments) {
                    if (attach.getName().equals(name)) {
                        encodeContactAttachment(el, attach);
                    }
                }
            }
        }
    } else {
        Map<String, String> contactFields = returnHiddenAttrs ? contact.getAllFields() : contact.getFields();
        for (Map.Entry<String, String> me : contactFields.entrySet()) {
            String name = me.getKey();
            String value = me.getValue();
            // can be configured as a hidden or non-hidden field
            if (ContactConstants.A_member.equals(name)) {
                String email = contactFields.get("email");
                if (!hasDLViewRight(email, mRequestedAcct, mAuthedAcct)) {
                    continue;
                }
                if (maxMembers != GetContacts.NO_LIMIT_MAX_MEMBERS) {
                    // there is a limit on the max number of members to return
                    ContactDLMembers dlMembers = new ContactDLMembers(contact);
                    if (dlMembers.getTotal() > maxMembers) {
                        el.addAttribute(MailConstants.A_TOO_MANY_MEMBERS, true);
                        continue;
                    }
                }
            }
            if (name != null && !name.trim().isEmpty() && !Strings.isNullOrEmpty(value)) {
                encodeContactAttr(el, name, value, contact, encodeContactGroupMembersBasic, octxt, returnCertInfo);
            }
        }
        if (attachments != null) {
            for (Attachment attach : attachments) {
                encodeContactAttachment(el, attach);
            }
        }
    }
    if (migratedDlist != null) {
        encodeContactAttr(el, ContactConstants.A_dlist, migratedDlist, contact, false, octxt, returnCertInfo);
    } else if (contactGroup != null) {
        encodeContactGroup(el, contactGroup, memberAttrFilter, ifmt, octxt, summary, fields);
    }
    if (memberOfIds != null && !memberOfIds.isEmpty()) {
        List<String> memIds = Lists.newArrayListWithExpectedSize(memberOfIds.size());
        String authAcctId = null;
        if ((octxt != null) && (octxt.getmAuthTokenAccountId() != null)) {
            authAcctId = octxt.getmAuthTokenAccountId();
        }
        for (String memberOfId : memberOfIds) {
            ItemIdentifier ident = ItemIdentifier.fromOwnerAndRemoteId(authAcctId, memberOfId);
            memIds.add(ident.toString(authAcctId));
        }
        el.addAttribute(MailConstants.E_CONTACT_MEMBER_OF, Joiner.on(',').join(memIds), Element.Disposition.CONTENT);
    }
    return el;
}
Also used : ContactDLMembers(com.zimbra.cs.gal.GalGroupMembers.ContactDLMembers) Element(com.zimbra.common.soap.Element) Attachment(com.zimbra.cs.mailbox.Contact.Attachment) ItemId(com.zimbra.cs.service.util.ItemId) ItemIdentifier(com.zimbra.common.mailbox.ItemIdentifier) ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) Map(java.util.Map) IcalXmlStrMap(com.zimbra.cs.mailbox.calendar.IcalXmlStrMap) TimeZoneMap(com.zimbra.common.calendar.TimeZoneMap)

Example 19 with ItemIdentifier

use of com.zimbra.common.mailbox.ItemIdentifier in project zm-mailbox by Zimbra.

the class GetIMAPRecent method handle.

@Override
public Element handle(Element request, Map<String, Object> context) throws ServiceException {
    ZimbraSoapContext zsc = getZimbraSoapContext(context);
    Mailbox mbox = getRequestedMailbox(zsc);
    OperationContext octxt = getOperationContext(zsc, context);
    GetIMAPRecentRequest req = zsc.elementToJaxb(request);
    ItemIdentifier itemIdent = ItemIdentifier.fromOwnerAndRemoteId(mbox.getAccountId(), req.getId());
    if (!mbox.getAccountId().equals(itemIdent.accountId)) {
        throw MailServiceException.NO_SUCH_FOLDER(req.getId());
    }
    return zsc.jaxbToElement(new GetIMAPRecentResponse(mbox.getImapRecent(octxt, itemIdent.id)));
}
Also used : OperationContext(com.zimbra.cs.mailbox.OperationContext) GetIMAPRecentRequest(com.zimbra.soap.mail.message.GetIMAPRecentRequest) ItemIdentifier(com.zimbra.common.mailbox.ItemIdentifier) Mailbox(com.zimbra.cs.mailbox.Mailbox) GetIMAPRecentResponse(com.zimbra.soap.mail.message.GetIMAPRecentResponse) ZimbraSoapContext(com.zimbra.soap.ZimbraSoapContext)

Example 20 with ItemIdentifier

use of com.zimbra.common.mailbox.ItemIdentifier in project zm-mailbox by Zimbra.

the class TestZClient method testImapUIDForNonStandardContact.

@Test
public void testImapUIDForNonStandardContact() throws ServiceException {
    Mailbox mbox = TestUtil.getMailbox(USER_NAME);
    ZMailbox zmbox = TestUtil.getZMailbox(USER_NAME);
    Contact contact = TestUtil.createContactInDefaultFolder(mbox, "testzclient@example.com");
    ItemIdentifier contactId = ItemIdentifier.fromAccountIdAndItemId(zmbox.getAccountId(), contact.getId());
    Element reqEl = zmbox.newRequestElement(MailConstants.GET_CONTACTS_REQUEST);
    // Specifically do NOT do reqEl.addAttribute(MailConstants.A_WANT_IMAP_UID, true);
    reqEl.addNonUniqueElement(MailConstants.E_CONTACT).addAttribute(MailConstants.A_ID, contactId.id);
    Element respEl = zmbox.invoke(reqEl);
    ZContact zcontact = new ZContact(respEl.getElement(MailConstants.E_CONTACT), zmbox);
    assertNotNull("ZContact object", zcontact);
    // The IMAP UID should be gotten via a refetch of the contact - asking for the IMAP UID
    assertEquals("Expected=ZContact ID Actual=ZContact IMAP UID", zcontact.getIdInMailbox(), zcontact.getImapUid());
    assertEquals("IMAP UID Expected=Contact Actual=ZContact", contact.getImapUid(), zcontact.getImapUid());
    assertEquals("ModifiedSequence Expected=Contact Actual=ZContact", contact.getModifiedSequence(), zcontact.getModifiedSequence());
}
Also used : ItemIdentifier(com.zimbra.common.mailbox.ItemIdentifier) ZMailbox(com.zimbra.client.ZMailbox) Mailbox(com.zimbra.cs.mailbox.Mailbox) ZMailbox(com.zimbra.client.ZMailbox) Element(com.zimbra.common.soap.Element) ZContact(com.zimbra.client.ZContact) Contact(com.zimbra.cs.mailbox.Contact) ZContact(com.zimbra.client.ZContact) Test(org.junit.Test)

Aggregations

ItemIdentifier (com.zimbra.common.mailbox.ItemIdentifier)26 ZMailbox (com.zimbra.client.ZMailbox)12 Mailbox (com.zimbra.cs.mailbox.Mailbox)12 Test (org.junit.Test)11 ZMessage (com.zimbra.client.ZMessage)6 ServiceException (com.zimbra.common.service.ServiceException)6 ParsedMessage (com.zimbra.cs.mime.ParsedMessage)6 ArrayList (java.util.ArrayList)6 ZMountpoint (com.zimbra.client.ZMountpoint)5 MailboxStore (com.zimbra.common.mailbox.MailboxStore)5 ImapMessage (com.zimbra.cs.imap.ImapMessage)5 MailServiceException (com.zimbra.cs.mailbox.MailServiceException)5 Message (com.zimbra.cs.mailbox.Message)5 ZOutgoingMessage (com.zimbra.client.ZMailbox.ZOutgoingMessage)4 ZimbraMailItem (com.zimbra.common.mailbox.ZimbraMailItem)4 Folder (com.zimbra.cs.mailbox.Folder)4 ZContact (com.zimbra.client.ZContact)3 AccountServiceException (com.zimbra.cs.account.AccountServiceException)3 Contact (com.zimbra.cs.mailbox.Contact)3 OperationContext (com.zimbra.cs.mailbox.OperationContext)3