Search in sources :

Example 16 with ZimbraQueryResults

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

the class AddressObject method getContactByUID.

/**
     * @param preferredBaseName If more than one item matches the UID, prefer one matching this name - can be null
     */
private static Contact getContactByUID(DavContext ctxt, String uid, Account account, int folderId, String preferredBaseName) throws ServiceException {
    Contact item = null;
    Mailbox mbox = MailboxManager.getInstance().getMailboxByAccount(account);
    if (uid.endsWith(AddressObject.VCARD_EXTENSION)) {
        uid = uid.substring(0, uid.length() - AddressObject.VCARD_EXTENSION.length());
        // Unescape the name (It was encoded in DavContext intentionally)
        uid = HttpUtil.urlUnescape(uid);
    }
    // first check whether the UID is an encoding of the Contact ID
    int id = 0;
    int index = uid.indexOf(':');
    if (index > 0) {
        String accountId = uid.substring(0, index);
        try {
            if (accountId.equals(account.getId()))
                id = Integer.parseInt(uid.substring(index + 1));
        } catch (NumberFormatException e) {
        }
    }
    if (id > 0) {
        item = mbox.getContactById(ctxt.getOperationContext(), Integer.parseInt(uid.substring(index + 1)));
    } else {
        ZimbraQueryResults zqr = null;
        StringBuilder query = new StringBuilder();
        query.append("#").append(ContactConstants.A_vCardUID).append(":");
        // escape the double quotes in uid and surround with double quotes
        query.append("\"").append(uid.replace("\"", "\\\"")).append("\"");
        query.append(" OR ").append("#").append(ContactConstants.A_vCardURL).append(":");
        query.append("\"").append(uid.replace("\"", "\\\"")).append("\"");
        ZimbraLog.dav.debug("query %s", query.toString());
        try {
            zqr = mbox.index.search(ctxt.getOperationContext(), query.toString(), EnumSet.of(MailItem.Type.CONTACT), SortBy.NAME_ASC, 10);
            // There could be multiple contacts with the same UID from different collections.
            item = getMatchingHit(zqr, folderId, preferredBaseName);
        } catch (Exception e) {
            ZimbraLog.dav.error("can't search for: uid=%s", uid, e);
        } finally {
            Closeables.closeQuietly(zqr);
        }
    }
    if ((item != null) && (folderId >= 0) && (item.getFolderId() != folderId))
        item = null;
    return item;
}
Also used : Mailbox(com.zimbra.cs.mailbox.Mailbox) ZimbraQueryResults(com.zimbra.cs.index.ZimbraQueryResults) ServiceException(com.zimbra.common.service.ServiceException) IOException(java.io.IOException) DavException(com.zimbra.cs.dav.DavException) Contact(com.zimbra.cs.mailbox.Contact)

Example 17 with ZimbraQueryResults

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

the class ImapHandler method search.

boolean search(String tag, String command, ImapSearch i4search, boolean byUID, Integer options, List<SortBy> order) 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 SEARCH MODSEQ in this mailbox", true);
    }
    // only supporting one level of sorting sort at this point
    SortBy sort = SortBy.NONE;
    if (order != null && !order.isEmpty()) {
        for (SortBy level : order) {
            if ((sort = level) != SortBy.NONE) {
                break;
            }
        }
    }
    boolean saveResults = (options != null && (options & RETURN_SAVE) != 0);
    boolean unsorted = sort == SortBy.NONE;
    Collection<ImapMessage> hits;
    int modseq = 0;
    try {
        Mailbox mbox = i4folder.getMailbox();
        if (unsorted && i4search.canBeRunLocally()) {
            mbox.lock.lock(false);
            try {
                hits = i4search.evaluate(i4folder);
                hits.remove(null);
            } finally {
                mbox.lock.release();
            }
        } else {
            ZimbraQueryResults zqr = runSearch(i4search, i4folder, sort, requiresMODSEQ ? SearchParams.Fetch.MODSEQ : SearchParams.Fetch.IDS);
            hits = unsorted ? new ImapMessageSet() : new ArrayList<ImapMessage>();
            try {
                for (ZimbraHit hit = zqr.getNext(); hit != null; hit = zqr.getNext()) {
                    ImapMessage i4msg = i4folder.getById(hit.getItemId());
                    if (i4msg == null || i4msg.isExpunged()) {
                        continue;
                    }
                    hits.add(i4msg);
                    if (requiresMODSEQ)
                        modseq = Math.max(modseq, hit.getModifiedSequence());
                }
            } finally {
                Closeables.closeQuietly(zqr);
            }
        }
    } catch (ServiceException e) {
        //              variable to the empty sequence."
        if (saveResults) {
            i4folder.saveSearchResults(new ImapMessageSet());
        }
        ZimbraLog.imap.warn(command + " failed", e);
        sendNO(tag, command + " failed");
        return true;
    }
    int size = hits.size();
    ImapMessage first = null, last = null;
    if (size != 0 && options != null && (options & (RETURN_MIN | RETURN_MAX)) != 0) {
        if (unsorted) {
            first = ((ImapMessageSet) hits).first();
            last = ((ImapMessageSet) hits).last();
        } else {
            first = ((List<ImapMessage>) hits).get(0);
            last = ((List<ImapMessage>) hits).get(size - 1);
        }
    }
    StringBuilder result = null;
    if (options == null) {
        result = new StringBuilder(command);
        for (ImapMessage i4msg : hits) {
            result.append(' ').append(getMessageId(i4msg, byUID));
        }
    } else if (options != RETURN_SAVE) {
        // Note: rfc5267's ESORT reuses the ESEARCH response i.e. response result starts with "ESEARCH" NOT "ESORT"
        //       This is slightly inconsistent as rfc5256's SORT response result starts with "SORT"...
        result = new StringBuilder("ESEARCH (TAG \"").append(tag).append("\")");
        if (byUID) {
            result.append(" UID");
        }
        if (first != null && (options & RETURN_MIN) != 0) {
            result.append(" MIN ").append(getMessageId(first, byUID));
        }
        if (last != null && (options & RETURN_MAX) != 0) {
            result.append(" MAX ").append(getMessageId(last, byUID));
        }
        if ((options & RETURN_COUNT) != 0) {
            result.append(" COUNT ").append(size);
        }
        if (size != 0 && (options & RETURN_ALL) != 0) {
            result.append(" ALL ").append(ImapFolder.encodeSubsequence(hits, byUID));
        }
    }
    if (modseq > 0 && result != null) {
        result.append(" (MODSEQ ").append(modseq).append(')');
    }
    if (saveResults) {
        if (size == 0 || options == RETURN_SAVE || (options & (RETURN_COUNT | RETURN_ALL)) != 0) {
            i4folder.saveSearchResults(unsorted ? (ImapMessageSet) hits : new ImapMessageSet(hits));
        } else {
            ImapMessageSet saved = new ImapMessageSet();
            if (first != null && (options & RETURN_MIN) != 0) {
                saved.add(first);
            }
            if (last != null && (options & RETURN_MAX) != 0) {
                saved.add(last);
            }
            i4folder.saveSearchResults(saved);
        }
    }
    if (result != null) {
        sendUntagged(result.toString());
    }
    sendNotifications(byUID, false);
    sendOK(tag, (byUID ? "UID " : "") + command + " completed");
    return true;
}
Also used : ZimbraHit(com.zimbra.cs.index.ZimbraHit) SortBy(com.zimbra.cs.index.SortBy) ArrayList(java.util.ArrayList) Mountpoint(com.zimbra.cs.mailbox.Mountpoint) Mailbox(com.zimbra.cs.mailbox.Mailbox) ZMailbox(com.zimbra.client.ZMailbox) AccountServiceException(com.zimbra.cs.account.AccountServiceException) ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) ZimbraQueryResults(com.zimbra.cs.index.ZimbraQueryResults) ImapMessageSet(com.zimbra.cs.imap.ImapMessage.ImapMessageSet)

Example 18 with ZimbraQueryResults

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

the class TestUtil method searchForHits.

public static List<ZimbraHit> searchForHits(Mailbox mbox, String query, Set<MailItem.Type> types) throws Exception {
    List<ZimbraHit> hits = Lists.newArrayList();
    ZimbraQueryResults r = mbox.index.search(new OperationContext(mbox), query, types, SortBy.DATE_DESC, 100);
    while (r.hasNext()) {
        hits.add(r.getNext());
    }
    Closeables.closeQuietly(r);
    return hits;
}
Also used : ZimbraHit(com.zimbra.cs.index.ZimbraHit) OperationContext(com.zimbra.cs.mailbox.OperationContext) ZimbraQueryResults(com.zimbra.cs.index.ZimbraQueryResults)

Example 19 with ZimbraQueryResults

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

the class ScheduleInbox method getAppointmentsByUids.

@Override
public java.util.Collection<DavResource> getAppointmentsByUids(DavContext ctxt, List<String> hrefs) throws ServiceException, DavException {
    List<DavResource> result = new ArrayList<DavResource>();
    if (!DavResource.isSchedulingEnabled()) {
        return result;
    }
    Account target = null;
    Provisioning prov = Provisioning.getInstance();
    if (ctxt.getActingAsDelegateFor() != null) {
        target = prov.getAccountByName(ctxt.getActingAsDelegateFor());
    }
    String query = "is:invite is:unread inid:" + getId() + " after:\"-1month\" ";
    Mailbox mbox = getMailbox(ctxt);
    ZimbraQueryResults zqr = null;
    try {
        zqr = mbox.index.search(ctxt.getOperationContext(), query, SEARCH_TYPES, SortBy.DATE_ASC, 100);
        while (zqr.hasNext()) {
            ZimbraHit hit = zqr.getNext();
            if (hit instanceof MessageHit) {
                Message msg = ((MessageHit) hit).getMessage();
                if (target == null && msg.getCalendarIntendedFor() != null) {
                    continue;
                }
                if (!msg.isInvite() || !msg.hasCalendarItemInfos()) {
                    continue;
                }
                /* Bug 40567.  hide replies to avoid them being deleted by CalDAV clients.
                     * TODO: An alternative approach would be to show them but when they are "deleted", flag them as
                     * absent from the scheduling inbox.
                     */
                if ("REPLY".equals(msg.getCalendarItemInfo(0).getInvite().getMethod())) {
                    continue;
                }
                if (target != null) {
                    if (msg.getCalendarIntendedFor() == null) {
                        continue;
                    }
                    Account apptRcpt = prov.getAccountByName(msg.getCalendarIntendedFor());
                    if (apptRcpt == null || !apptRcpt.getId().equals(target.getId())) {
                        continue;
                    }
                }
                DavResource rs = UrlNamespace.getResourceFromMailItem(ctxt, msg);
                if (rs != null) {
                    String href = UrlNamespace.getRawResourceUrl(rs);
                    if (hrefs == null)
                        result.add(rs);
                    else {
                        boolean found = false;
                        for (String ref : hrefs) {
                            if (HttpUtil.urlUnescape(ref).equals(href)) {
                                result.add(rs);
                                found = true;
                                break;
                            }
                        }
                        if (!found)
                            result.add(new DavResource.InvalidResource(href, getOwner()));
                    }
                }
            }
        }
    } catch (Exception e) {
        ZimbraLog.dav.error("can't search: uri=" + getUri(), e);
    } finally {
        Closeables.closeQuietly(zqr);
    }
    return result;
}
Also used : ZimbraHit(com.zimbra.cs.index.ZimbraHit) Account(com.zimbra.cs.account.Account) Message(com.zimbra.cs.mailbox.Message) MessageHit(com.zimbra.cs.index.MessageHit) ArrayList(java.util.ArrayList) Provisioning(com.zimbra.cs.account.Provisioning) ServiceException(com.zimbra.common.service.ServiceException) IOException(java.io.IOException) DavException(com.zimbra.cs.dav.DavException) Mailbox(com.zimbra.cs.mailbox.Mailbox) ZimbraQueryResults(com.zimbra.cs.index.ZimbraQueryResults)

Example 20 with ZimbraQueryResults

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

the class Search method handle.

@Override
public Element handle(Element request, Map<String, Object> context) throws ServiceException {
    ZimbraSoapContext zsc = getZimbraSoapContext(context);
    Mailbox mbox = getRequestedMailbox(zsc);
    Account account = getRequestedAccount(zsc);
    OperationContext octxt = getOperationContext(zsc, context);
    fixBooleanRecipients(request);
    SearchRequest req = JaxbUtil.elementToJaxb(request);
    if (Objects.firstNonNull(req.getWarmup(), false)) {
        mbox.index.getIndexStore().warmup();
        return zsc.createElement(MailConstants.SEARCH_RESPONSE);
    }
    SearchParams params = SearchParams.parse(req, zsc, account.getPrefMailInitialSearch());
    if (params.getLocale() == null) {
        params.setLocale(mbox.getAccount().getLocale());
    }
    if (params.inDumpster() && params.getTypes().contains(MailItem.Type.CONVERSATION)) {
        throw ServiceException.INVALID_REQUEST("cannot search for conversations in dumpster", null);
    }
    if (LC.calendar_cache_enabled.booleanValue()) {
        List<String> apptFolderIds = getFolderIdListIfSimpleAppointmentsQuery(params, zsc);
        if (apptFolderIds != null) {
            Account authAcct = getAuthenticatedAccount(zsc);
            Element response = zsc.createElement(MailConstants.SEARCH_RESPONSE);
            runSimpleAppointmentQuery(response, params, octxt, zsc, authAcct, mbox, apptFolderIds);
            return response;
        }
    }
    ZimbraQueryResults results = mbox.index.search(zsc.getResponseProtocol(), octxt, params);
    try {
        // create the XML response Element
        Element response = zsc.createElement(MailConstants.SEARCH_RESPONSE);
        // must use results.getSortBy() because the results might have ignored our sortBy
        // request and used something else...
        response.addAttribute(MailConstants.A_SORTBY, results.getSortBy().toString());
        putHits(zsc, octxt, response, results, params);
        return response;
    } finally {
        Closeables.closeQuietly(results);
    }
}
Also used : OperationContext(com.zimbra.cs.mailbox.OperationContext) Account(com.zimbra.cs.account.Account) SearchRequest(com.zimbra.soap.mail.message.SearchRequest) SearchParams(com.zimbra.cs.index.SearchParams) Mailbox(com.zimbra.cs.mailbox.Mailbox) ZMailbox(com.zimbra.client.ZMailbox) ZimbraSoapContext(com.zimbra.soap.ZimbraSoapContext) Element(com.zimbra.common.soap.Element) ZimbraQueryResults(com.zimbra.cs.index.ZimbraQueryResults)

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