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