private void preload(Mailbox mbox, List<ZimbraHit> hits) throws ServiceException { int unloadedIds[] = new int[hits.size()]; int numToLoad = 0; for (int i = 0; i < hits.size(); i++) { ZimbraHit cur = hits.get(i); if (!cur.itemIsLoaded()) { numToLoad++; unloadedIds[i] = cur.getItemId(); } else { unloadedIds[i] = Mailbox.ID_AUTO_INCREMENT; } } if (numToLoad > 0) { MailItem[] items = mbox.getItemById(opContext, unloadedIds, MailItem.Type.UNKNOWN, inDumpster); for (int i = 0; i < hits.size(); ++i) { if (items[i] != null) { hits.get(i).setItem(items[i]); } } } }
/** Parse the query string. */ public ZimbraQuery(OperationContext octxt, SoapProtocol proto, Mailbox mbox, SearchParams params) throws ServiceException { this.octxt = octxt; this.protocol = proto; this.params = params; this.mailbox = mbox; // Parse the text using the JavaCC parser. try { QueryParser parser = new QueryParser(mbox, mbox.index.getAnalyzer()); parser.setDefaultField(params.getDefaultField()); parser.setTypes(params.getTypes()); parser.setTimeZone(params.getTimeZone()); parser.setLocale(params.getLocale()); parser.setQuick(params.isQuick()); clauses = parser.parse(params.getQueryString()); if (parser.getSortBy() != null) { SortBy sort = SortBy.of(parser.getSortBy()); if (sort == null) { throw ServiceException.PARSE_ERROR("INVALID_SORTBY: " + sort, null); } params.setSortBy(sort); } } catch (Error e) { throw ServiceException.PARSE_ERROR("PARSER_ERROR", e); } ZimbraLog.search.debug("%s,types=%s,sort=%s", this, params.getTypes(), params.getSortBy()); // Build a parse tree and push all the "NOT's" down to the bottom level. // This is because we cannot invert result sets. parseTree = ParseTree.build(clauses).simplify(); parseTree.pushNotsDown(); // Check sort compatibility. switch (params.getSortBy().getKey()) { case RCPT: case ATTACHMENT: case FLAG: case PRIORITY: // We don't store these in Lucene. if (hasTextOperation()) { throw ServiceException.INVALID_REQUEST( "Sort '" + params.getSortBy().name() + "' can't be used with text query.", null); } break; default: break; } SearchParams.Cursor cursor = params.getCursor(); if (cursor != null) { // Check cursor compatibility if (params.getCursor().isIncludeOffset() && hasTextOperation()) { throw ServiceException.INVALID_REQUEST( "cursor.includeOffset can't be used with text query.", null); } // Supplement sortValue if (cursor.getSortValue() == null) { ZimbraLog.search.debug( "Supplementing sortValue sort=%s,id=%s", params.getSortBy(), cursor.getItemId()); try { MailItem item = mailbox.getItemById(null, cursor.getItemId().getId(), MailItem.Type.UNKNOWN); switch (params.getSortBy().getKey()) { case NAME: cursor.setSortValue(item.getName()); break; case RCPT: cursor.setSortValue(item.getSortRecipients()); break; case SENDER: cursor.setSortValue(item.getSortSender()); break; case SIZE: cursor.setSortValue(String.valueOf(item.getSize())); break; case SUBJECT: cursor.setSortValue(item.getSortSubject()); break; case DATE: default: cursor.setSortValue(String.valueOf(item.getDate())); break; } } catch (NoSuchItemException e) { params.setCursor(null); // clear cursor } } } }