Search in sources :

Example 1 with ZimbraHit

use of com.zimbra.cs.index.ZimbraHit in project zm-mailbox by Zimbra.

the class SearchWrapper method getChildren.

@Override
public Collection<DavResource> getChildren(DavContext ctxt) {
    ArrayList<DavResource> children = new ArrayList<DavResource>();
    String user = ctxt.getUser();
    Provisioning prov = Provisioning.getInstance();
    ZimbraQueryResults zqr = null;
    try {
        Account account = prov.get(AccountBy.name, user);
        Mailbox mbox = MailboxManager.getInstance().getMailboxByAccount(account);
        SearchParams params = new SearchParams();
        params.setQueryString(mQuery.toString());
        params.setTypes(SEARCH_TYPES);
        params.setSortBy(SortBy.NAME_ASC);
        params.setFetchMode(SearchParams.Fetch.NORMAL);
        params.setPrefetch(true);
        params.setChunkSize(SEARCH_LIMIT);
        zqr = mbox.index.search(SoapProtocol.Soap12, ctxt.getOperationContext(), params);
        while (zqr.hasNext()) {
            ZimbraHit hit = zqr.getNext();
            if (hit instanceof MessageHit)
                addAttachmentResources((MessageHit) hit, children);
        }
    } catch (Exception e) {
        ZimbraLog.dav.error("can't search: uri=" + getUri(), e);
    } finally {
        Closeables.closeQuietly(zqr);
    }
    return children;
}
Also used : ZimbraHit(com.zimbra.cs.index.ZimbraHit) Account(com.zimbra.cs.account.Account) SearchParams(com.zimbra.cs.index.SearchParams) Mailbox(com.zimbra.cs.mailbox.Mailbox) MessageHit(com.zimbra.cs.index.MessageHit) ArrayList(java.util.ArrayList) ZimbraQueryResults(com.zimbra.cs.index.ZimbraQueryResults) Provisioning(com.zimbra.cs.account.Provisioning)

Example 2 with ZimbraHit

use of com.zimbra.cs.index.ZimbraHit in project zm-mailbox by Zimbra.

the class ContactAutoComplete method queryFolders.

private void queryFolders(String str, String generatedQuery, Map<ItemId, Mountpoint> mountpoints, int limit, AutoCompleteResult result) throws ServiceException {
    ZimbraQueryResults qres = null;
    try {
        Mailbox mbox = MailboxManager.getInstance().getMailboxByAccountId(getRequestedAcctId());
        SearchParams params = new SearchParams();
        params.setQueryString(generatedQuery);
        params.setDefaultField("contact:");
        params.setTypes(CONTACT_TYPES);
        params.setSortBy(SortBy.NONE);
        params.setLimit(limit + 1);
        params.setPrefetch(true);
        params.setFetchMode(SearchParams.Fetch.NORMAL);
        ZimbraLog.gal.debug("querying contact folders: %s", params.getQueryString());
        qres = mbox.index.search(SoapProtocol.Soap12, octxt, params);
        while (qres.hasNext()) {
            ZimbraHit hit = qres.getNext();
            Map<String, String> fields = null;
            ItemId id = null;
            int fid = 0;
            if (hit instanceof ContactHit) {
                Contact c = ((ContactHit) hit).getContact();
                ZimbraLog.gal.debug("hit: %d", c.getId());
                fields = c.getFields();
                id = new ItemId(c);
                fid = c.getFolderId();
                if (returnFullContactData) {
                    List<Attachment> contactAttachments = c.getAttachments();
                    if (contactAttachments != null && contactAttachments.size() != 0) {
                        fields.put("image", c.getId() + "_" + contactAttachments.get(0).getName());
                    }
                }
            } else if (hit instanceof ProxiedHit) {
                fields = new HashMap<String, String>();
                Element top = ((ProxiedHit) hit).getElement();
                id = new ItemId(top.getAttribute(MailConstants.A_ID), (String) null);
                ZimbraLog.gal.debug("hit: %s", id);
                ItemId fiid = new ItemId(top.getAttribute(MailConstants.A_FOLDER), (String) null);
                Mountpoint mp = mountpoints.get(fiid);
                if (mp != null) {
                    // if the hit came from a descendant folder of
                    // the mountpoint, we don't have a peer folder ID.
                    fid = mp.getId();
                } else {
                    fid = FOLDER_ID_MOUNTPOINT_SUBFOLDER;
                }
                for (Element elt : top.listElements(MailConstants.E_ATTRIBUTE)) {
                    try {
                        String name = elt.getAttribute(MailConstants.A_ATTRIBUTE_NAME);
                        fields.put(name, elt.getText());
                    } catch (ServiceException se) {
                        ZimbraLog.gal.warn("error handling proxied query result " + hit);
                    }
                }
                if (returnFullContactData) {
                    if (fields.containsKey("image")) {
                        fields.put("image", id.getAccountId() + "_" + id.getId() + "_image");
                    }
                }
            } else {
                continue;
            }
            addMatchedContacts(str, fields, fid, id, result);
            if (!result.canBeCached) {
                return;
            }
        }
    } finally {
        Closeables.closeQuietly(qres);
    }
}
Also used : ZimbraHit(com.zimbra.cs.index.ZimbraHit) GalSearchParams(com.zimbra.cs.gal.GalSearchParams) SearchParams(com.zimbra.cs.index.SearchParams) HashMap(java.util.HashMap) Element(com.zimbra.common.soap.Element) Attachment(com.zimbra.cs.mailbox.Contact.Attachment) ItemId(com.zimbra.cs.service.util.ItemId) GalContact(com.zimbra.cs.account.GalContact) ProxiedHit(com.zimbra.cs.index.ProxiedHit) ContactHit(com.zimbra.cs.index.ContactHit) ServiceException(com.zimbra.common.service.ServiceException) ZimbraQueryResults(com.zimbra.cs.index.ZimbraQueryResults)

Example 3 with ZimbraHit

use of com.zimbra.cs.index.ZimbraHit in project zm-mailbox by Zimbra.

the class ApplyFilterRules method handle.

@Override
public Element handle(Element request, Map<String, Object> context) throws ServiceException {
    ZimbraSoapContext zsc = getZimbraSoapContext(context);
    Account account = getRequestedAccount(zsc);
    if (!canAccessAccount(zsc, account))
        throw ServiceException.PERM_DENIED("cannot access account");
    // Get rules.
    String fullScript = getRules(account);
    if (StringUtil.isNullOrEmpty(fullScript)) {
        throw ServiceException.INVALID_REQUEST("Account has no filter rules defined.", null);
    }
    List<Element> ruleElements = request.getElement(MailConstants.E_FILTER_RULES).listElements(MailConstants.E_FILTER_RULE);
    if (ruleElements.size() == 0) {
        String msg = String.format("No %s elements specified.", MailConstants.E_FILTER_RULE);
        throw ServiceException.INVALID_REQUEST(msg, null);
    }
    // Concatenate script parts and create a new script to run on existing messages.
    StringBuilder buf = new StringBuilder();
    for (Element ruleEl : ruleElements) {
        String name = ruleEl.getAttribute(MailConstants.A_NAME);
        String singleRule = RuleManager.getRuleByName(fullScript, name);
        if (singleRule == null) {
            String msg = String.format("Could not find a rule named '%s'", name);
            throw ServiceException.INVALID_REQUEST(msg, null);
        }
        buf.append(singleRule).append("\n");
    }
    String partialScript = buf.toString();
    ZimbraLog.filter.debug("Applying partial script to existing messages: %s", partialScript);
    Node node = null;
    try {
        node = RuleManager.parse(partialScript);
    } catch (ParseException e) {
        throw ServiceException.FAILURE("Unable to parse Sieve script: " + partialScript, e);
    }
    // Get the ids of the messages to filter.
    Element msgEl = request.getOptionalElement(MailConstants.E_MSG);
    String query = getElementText(request, MailConstants.E_QUERY);
    if (msgEl != null && query != null) {
        String msg = String.format("Cannot specify both %s and %s elements.", MailConstants.E_MSG, MailConstants.E_QUERY);
        throw ServiceException.INVALID_REQUEST(msg, null);
    }
    Mailbox mbox = getRequestedMailbox(zsc);
    List<Integer> messageIds = new ArrayList<Integer>();
    List<Integer> affectedIds = new ArrayList<Integer>();
    OperationContext octxt = getOperationContext(zsc, context);
    if (msgEl != null) {
        String[] ids = msgEl.getAttribute(MailConstants.A_IDS).split(",");
        for (String id : ids) {
            messageIds.add(Integer.valueOf(id));
        }
    } else if (query != null) {
        ZimbraQueryResults results = null;
        try {
            results = mbox.index.search(octxt, query, EnumSet.of(MailItem.Type.MESSAGE), SortBy.NONE, Integer.MAX_VALUE);
            while (results.hasNext()) {
                ZimbraHit hit = results.getNext();
                messageIds.add(hit.getItemId());
            }
        } catch (Exception e) {
            String msg = String.format("Unable to run search for query: '%s'", query);
            throw ServiceException.INVALID_REQUEST(msg, e);
        } finally {
            Closeables.closeQuietly(results);
        }
    } else {
        String msg = String.format("Must specify either the %s or %s element.", MailConstants.E_MSG, MailConstants.E_QUERY);
        throw ServiceException.INVALID_REQUEST(msg, null);
    }
    int max = account.getFilterBatchSize();
    if (messageIds.size() > max) {
        throw ServiceException.INVALID_REQUEST("Attempted to apply filter rules to " + messageIds.size() + " messages, which exceeded the limit of " + max, null);
    }
    ZimbraLog.filter.info("Applying filter rules to %s existing messages.", messageIds.size());
    long sleepInterval = account.getFilterSleepInterval();
    // Apply filter rules.
    for (int i = 0; i < messageIds.size(); i++) {
        if (i > 0 && sleepInterval > 0) {
            try {
                Thread.sleep(sleepInterval);
            } catch (InterruptedException e) {
            }
        }
        int id = messageIds.get(i);
        try {
            mbox.getMessageById(octxt, id);
            if (RuleManager.applyRulesToExistingMessage(octxt, mbox, id, node)) {
                affectedIds.add(id);
            }
        } catch (NoSuchItemException e) {
            // Message was deleted since the search was done (bug 41609).
            ZimbraLog.filter.info("Skipping message %d: %s.", id, e.toString());
        } catch (ServiceException e) {
            ZimbraLog.filter.warn("Unable to filter message %d.", id, e);
        }
    }
    // Send response.
    Element response = zsc.createElement(getResponseElementName());
    if (affectedIds.size() > 0) {
        response.addElement(MailConstants.E_MSG).addAttribute(MailConstants.A_IDS, StringUtil.join(",", affectedIds));
    }
    return response;
}
Also used : OperationContext(com.zimbra.cs.mailbox.OperationContext) ZimbraHit(com.zimbra.cs.index.ZimbraHit) Account(com.zimbra.cs.account.Account) Element(com.zimbra.common.soap.Element) Node(org.apache.jsieve.parser.generated.Node) ArrayList(java.util.ArrayList) NoSuchItemException(com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException) ServiceException(com.zimbra.common.service.ServiceException) ParseException(org.apache.jsieve.parser.generated.ParseException) NoSuchItemException(com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException) Mailbox(com.zimbra.cs.mailbox.Mailbox) ServiceException(com.zimbra.common.service.ServiceException) ZimbraSoapContext(com.zimbra.soap.ZimbraSoapContext) ZimbraQueryResults(com.zimbra.cs.index.ZimbraQueryResults) ParseException(org.apache.jsieve.parser.generated.ParseException)

Example 4 with ZimbraHit

use of com.zimbra.cs.index.ZimbraHit in project zm-mailbox by Zimbra.

the class ImapHandler method doTHREAD.

boolean doTHREAD(String tag, ImapSearch i4search, boolean byUID) throws IOException, ImapException {
    if (!checkState(tag, State.SELECTED)) {
        return true;
    }
    ImapFolder i4folder = getSelectedFolder();
    if (i4folder == null) {
        throw new ImapSessionClosedException();
    }
    boolean requiresMODSEQ = i4search.requiresMODSEQ();
    if (requiresMODSEQ) {
        activateExtension(ImapExtension.CONDSTORE);
    }
    //                  MUST reject any such command with the tagged BAD response."
    if (requiresMODSEQ && !sessionActivated(ImapExtension.CONDSTORE)) {
        throw new ImapParseException(tag, "NOMODSEQ", "cannot THREAD MODSEQ in this mailbox", true);
    }
    LinkedHashMap<Integer, List<ImapMessage>> threads = new LinkedHashMap<Integer, List<ImapMessage>>();
    try {
        // RFC 5256 3: "The searched messages are sorted by base subject and then
        //              by the sent date.  The messages are then split into separate
        //              threads, with each thread containing messages with the same
        //              base subject text.  Finally, the threads are sorted by the
        //              sent date of the first message in the thread."
        ZimbraQueryResults zqr = runSearch(i4search, i4folder, SortBy.DATE_ASC, SearchParams.Fetch.PARENT);
        try {
            for (ZimbraHit hit = zqr.getNext(); hit != null; hit = zqr.getNext()) {
                ImapMessage i4msg = i4folder.getById(hit.getItemId());
                if (i4msg == null || i4msg.isExpunged()) {
                    continue;
                }
                int parentId = hit.getParentId();
                if (parentId <= 0) {
                    threads.put(-i4msg.msgId, Arrays.asList(i4msg));
                    continue;
                }
                List<ImapMessage> contents = threads.get(parentId);
                if (contents == null) {
                    (contents = new LinkedList<ImapMessage>()).add(i4msg);
                    threads.put(parentId, contents);
                } else {
                    contents.add(i4msg);
                }
            }
        } finally {
            zqr.close();
        }
    } catch (ServiceException e) {
        ZimbraLog.imap.warn("THREAD failed", e);
        sendNO(tag, "THREAD failed");
        return true;
    }
    StringBuilder result = new StringBuilder("THREAD");
    if (!threads.isEmpty()) {
        result.append(' ');
        for (List<ImapMessage> thread : threads.values()) {
            // ORDEREDSUBJECT: "(A)" for singletons, "(A B)" for pairs, "(A (B)(C)(D)(E))" for larger threads
            Iterator<ImapMessage> it = thread.iterator();
            result.append('(').append(getMessageId(it.next(), byUID));
            if (it.hasNext()) {
                result.append(' ');
                if (thread.size() == 2) {
                    result.append(getMessageId(it.next(), byUID));
                } else {
                    while (it.hasNext()) {
                        result.append('(').append(getMessageId(it.next(), byUID)).append(')');
                    }
                }
            }
            result.append(')');
        }
    }
    sendUntagged(result.toString());
    sendNotifications(false, false);
    sendOK(tag, (byUID ? "UID " : "") + "THREAD completed");
    return true;
}
Also used : ZimbraHit(com.zimbra.cs.index.ZimbraHit) Mountpoint(com.zimbra.cs.mailbox.Mountpoint) LinkedHashMap(java.util.LinkedHashMap) AccountServiceException(com.zimbra.cs.account.AccountServiceException) ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) ZimbraQueryResults(com.zimbra.cs.index.ZimbraQueryResults) List(java.util.List) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList)

Example 5 with ZimbraHit

use of com.zimbra.cs.index.ZimbraHit in project zm-mailbox by Zimbra.

the class TestUtil method search.

/**
     * Searches a mailbox and returns the id's of all matching items.
     */
public static List<Integer> search(Mailbox mbox, String query, Set<MailItem.Type> types) throws ServiceException {
    List<Integer> ids = new ArrayList<Integer>();
    ZimbraQueryResults r = mbox.index.search(new OperationContext(mbox), query, types, SortBy.DATE_DESC, 100);
    while (r.hasNext()) {
        ZimbraHit hit = r.getNext();
        ids.add(new Integer(hit.getItemId()));
    }
    Closeables.closeQuietly(r);
    return ids;
}
Also used : OperationContext(com.zimbra.cs.mailbox.OperationContext) ZimbraHit(com.zimbra.cs.index.ZimbraHit) ArrayList(java.util.ArrayList) ZimbraQueryResults(com.zimbra.cs.index.ZimbraQueryResults)

Aggregations

ZimbraHit (com.zimbra.cs.index.ZimbraHit)15 ZimbraQueryResults (com.zimbra.cs.index.ZimbraQueryResults)11 Mailbox (com.zimbra.cs.mailbox.Mailbox)8 ServiceException (com.zimbra.common.service.ServiceException)7 ArrayList (java.util.ArrayList)7 OperationContext (com.zimbra.cs.mailbox.OperationContext)5 Element (com.zimbra.common.soap.Element)4 Account (com.zimbra.cs.account.Account)4 MessageHit (com.zimbra.cs.index.MessageHit)4 SearchParams (com.zimbra.cs.index.SearchParams)4 Message (com.zimbra.cs.mailbox.Message)4 ContactHit (com.zimbra.cs.index.ContactHit)3 MailServiceException (com.zimbra.cs.mailbox.MailServiceException)3 Mountpoint (com.zimbra.cs.mailbox.Mountpoint)3 ItemId (com.zimbra.cs.service.util.ItemId)3 IOException (java.io.IOException)3 AccountServiceException (com.zimbra.cs.account.AccountServiceException)2 Provisioning (com.zimbra.cs.account.Provisioning)2 ResultsPager (com.zimbra.cs.index.ResultsPager)2 ExpandResults (com.zimbra.cs.index.SearchParams.ExpandResults)2