Search in sources :

Example 1 with ZimbraQueryResults

use of com.zimbra.cs.index.ZimbraQueryResults 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 ZimbraQueryResults

use of com.zimbra.cs.index.ZimbraQueryResults 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 ZimbraQueryResults

use of com.zimbra.cs.index.ZimbraQueryResults 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 ZimbraQueryResults

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

the class MailboxIndex method search.

private ZimbraQueryResults search(ZimbraQuery zq) throws ServiceException {
    SearchParams params = zq.getParams();
    ZimbraLog.search.debug("query: %s", params.getQueryString());
    ZimbraLog.searchstat.debug("query: %s", zq.toSanitizedtring());
    // handle special-case Task-only sorts: convert them to a "normal sort" and then re-sort them at the end
    // TODO: this hack (converting the sort) should be able to go away w/ the new SortBy implementation, if the
    // lower-level code was modified to use the SortBy.Criterion and SortBy.Direction data (instead of switching on
    // the SortBy itself). We still will need this switch so that we can wrap the results in ReSortingQueryResults.
    boolean isTaskSort = false;
    boolean isLocalizedSort = false;
    SortBy originalSort = params.getSortBy();
    switch(originalSort) {
        case TASK_DUE_ASC:
            isTaskSort = true;
            params.setSortBy(SortBy.DATE_DESC);
            break;
        case TASK_DUE_DESC:
            isTaskSort = true;
            params.setSortBy(SortBy.DATE_DESC);
            break;
        case TASK_STATUS_ASC:
            isTaskSort = true;
            params.setSortBy(SortBy.DATE_DESC);
            break;
        case TASK_STATUS_DESC:
            isTaskSort = true;
            params.setSortBy(SortBy.DATE_DESC);
            break;
        case TASK_PERCENT_COMPLETE_ASC:
            isTaskSort = true;
            params.setSortBy(SortBy.DATE_DESC);
            break;
        case TASK_PERCENT_COMPLETE_DESC:
            isTaskSort = true;
            params.setSortBy(SortBy.DATE_DESC);
            break;
        case NAME_LOCALIZED_ASC:
        case NAME_LOCALIZED_DESC:
            isLocalizedSort = true;
            break;
    }
    ZimbraQueryResults results = zq.execute();
    if (isTaskSort) {
        results = new ReSortingQueryResults(results, originalSort, null);
    }
    if (isLocalizedSort) {
        results = new ReSortingQueryResults(results, originalSort, params);
    }
    return results;
}
Also used : SearchParams(com.zimbra.cs.index.SearchParams) SortBy(com.zimbra.cs.index.SortBy) ZimbraQueryResults(com.zimbra.cs.index.ZimbraQueryResults) ReSortingQueryResults(com.zimbra.cs.index.ReSortingQueryResults)

Example 5 with ZimbraQueryResults

use of com.zimbra.cs.index.ZimbraQueryResults 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)

Aggregations

ZimbraQueryResults (com.zimbra.cs.index.ZimbraQueryResults)22 Mailbox (com.zimbra.cs.mailbox.Mailbox)13 ZimbraHit (com.zimbra.cs.index.ZimbraHit)11 OperationContext (com.zimbra.cs.mailbox.OperationContext)11 ServiceException (com.zimbra.common.service.ServiceException)9 ArrayList (java.util.ArrayList)9 SearchParams (com.zimbra.cs.index.SearchParams)8 Element (com.zimbra.common.soap.Element)6 Account (com.zimbra.cs.account.Account)5 IOException (java.io.IOException)5 Test (org.junit.Test)5 MailServiceException (com.zimbra.cs.mailbox.MailServiceException)4 ZimbraSoapContext (com.zimbra.soap.ZimbraSoapContext)4 HashMap (java.util.HashMap)4 MessageHit (com.zimbra.cs.index.MessageHit)3 SortBy (com.zimbra.cs.index.SortBy)3 Contact (com.zimbra.cs.mailbox.Contact)3 Message (com.zimbra.cs.mailbox.Message)3 Mountpoint (com.zimbra.cs.mailbox.Mountpoint)3 ZMailbox (com.zimbra.client.ZMailbox)2