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;
}
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);
}
}
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;
}
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;
}
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;
}
Aggregations