use of com.zimbra.cs.index.ZimbraHit in project zm-mailbox by Zimbra.
the class TestTags method testRemoteTagSearch.
/**
* Bug 79576 was seeing extra (wrong) hits from shared folder when click on a tag.
*/
public void testRemoteTagSearch() throws Exception {
Account remoteAcct = TestUtil.createAccount(remoteUser);
remoteAcct = TestUtil.getAccount(remoteUser);
Mailbox remoteMbox = MailboxManager.getInstance().getMailboxByAccount(remoteAcct);
remoteMbox.grantAccess(null, Mailbox.ID_FOLDER_INBOX, mAccount.getId(), ACL.GRANTEE_USER, (short) (ACL.RIGHT_READ | ACL.RIGHT_WRITE | ACL.RIGHT_INSERT), null);
mountpoint = mMbox.createMountpoint(null, Mailbox.ID_FOLDER_USER_ROOT, "remoteInbox", remoteAcct.getId(), Mailbox.ID_FOLDER_INBOX, null, MailItem.Type.MESSAGE, Flag.ID_CHECKED, (byte) 2, false);
Message remoteMsg1 = TestUtil.addMessage(remoteMbox, MSG_SUBJECT + " in shared inbox tagged with shared TAG");
Message remoteMsg2 = TestUtil.addMessage(remoteMbox, MSG_SUBJECT + " in shared inbox tagged remOnly");
Tag[] remoteTags = new Tag[2];
remoteTags[0] = remoteMbox.createTag(null, TAG_PREFIX + 1, (byte) 0);
remoteTags[1] = remoteMbox.createTag(null, TAG_PREFIX + "remOnly", (byte) 0);
mTags = new Tag[2];
for (int i = 0; i < mTags.length; i++) {
mTags[i] = mMbox.createTag(null, TAG_PREFIX + (i + 1), (byte) 0);
}
refresh();
remoteMbox.alterTag(null, remoteMsg1.getId(), remoteMsg1.getType(), remoteTags[0].getName(), true, null);
remoteMbox.alterTag(null, remoteMsg2.getId(), remoteMsg2.getType(), remoteTags[1].getName(), true, null);
mMbox.alterTag(null, mMessage2.getId(), mMessage2.getType(), mTags[0].getName(), true, null);
mMbox.alterTag(null, mMessage3.getId(), mMessage3.getType(), mTags[1].getName(), true, null);
Folder sharedFolder = mMbox.getFolderByName(null, Mailbox.ID_FOLDER_USER_ROOT, "remoteInbox");
sharedFolder.getId();
List<ZimbraHit> hits = TestUtil.searchForHits(mMbox, String.format("tag:\"%s\" (inid:%d OR is:local)", mTags[0].getName(), sharedFolder.getId()), MailItem.Type.MESSAGE);
assertEquals("Search for tag present in both local and remote mboxes. Number of hits returned", 2, hits.size());
boolean gotLocalHit = false;
boolean gotRemoteHit = false;
ZimbraLog.test.setLevel(Level.trace);
for (ZimbraHit hit : hits) {
ZimbraLog.test.info("HIT %s", hit.getParsedItemID());
ItemId parsedId = hit.getParsedItemID();
if (parsedId.belongsTo(mAccount) && hit.getItemId() == mMessage2.getId()) {
gotLocalHit = true;
}
if (parsedId.belongsTo(remoteAcct) && hit.getItemId() == remoteMsg1.getId()) {
gotRemoteHit = true;
}
}
assertTrue("1st search should return one local hit", gotLocalHit);
assertTrue("1st search should return one remote hit", gotRemoteHit);
Set<Integer> ids = search(String.format("tag:\"%s\" (inid:%d OR is:local)", mTags[1].getName(), sharedFolder.getId()), MailItem.Type.MESSAGE);
assertEquals("Search for tag not present in remote mbox. Number of ids returned", 1, ids.size());
assertTrue("2nd search should contain message 3", ids.contains(new Integer(mMessage3.getId())));
}
use of com.zimbra.cs.index.ZimbraHit in project zm-mailbox by Zimbra.
the class GalSearchControl method doLocalGalAccountSearch.
private boolean doLocalGalAccountSearch(Account galAcct) {
ZimbraQueryResults zqr = null;
try {
Mailbox mbox = MailboxManager.getInstance().getMailboxByAccount(galAcct);
SearchParams searchParams = mParams.getSearchParams();
zqr = mbox.index.search(SoapProtocol.Soap12, new OperationContext(mbox), searchParams);
ResultsPager pager = ResultsPager.create(zqr, searchParams);
GalSearchResultCallback callback = mParams.getResultCallback();
int num = 0;
while (pager.hasNext()) {
ZimbraHit hit = pager.getNextHit();
if (hit instanceof ContactHit) {
Element contactElem = callback.handleContact(((ContactHit) hit).getContact());
if (contactElem != null)
contactElem.addAttribute(MailConstants.A_SORT_FIELD, hit.getSortField(pager.getSortOrder()).toString());
}
num++;
if (num == mParams.getLimit())
break;
}
callback.setSortBy(zqr.getSortBy().toString());
callback.setQueryOffset(searchParams.getOffset());
callback.setHasMoreResult(pager.hasNext());
} catch (Exception e) {
ZimbraLog.gal.warn("search on GalSync account failed for %s", galAcct.getId(), e);
return false;
} finally {
Closeables.closeQuietly(zqr);
}
return true;
}
use of com.zimbra.cs.index.ZimbraHit in project zm-mailbox by Zimbra.
the class ImapSessionManager method loadVirtualFolder.
/** Fetches the messages contained within a search folder. When a search
* folder is IMAP-visible, it appears in folder listings, is SELECTable
* READ-ONLY, and appears to have all matching messages as its contents.
* If it is not visible, it will be completely hidden from all IMAP
* commands.
* @param octxt Encapsulation of the authenticated user.
* @param search The search folder being exposed. */
private static List<ImapMessage> loadVirtualFolder(OperationContext octxt, SearchFolder search) throws ServiceException {
List<ImapMessage> i4list = new ArrayList<ImapMessage>();
Set<MailItem.Type> types = ImapFolder.getTypeConstraint(search);
if (types.isEmpty()) {
return i4list;
}
SearchParams params = new SearchParams();
params.setQueryString(search.getQuery());
params.setIncludeTagDeleted(true);
params.setTypes(types);
params.setSortBy(SortBy.DATE_ASC);
params.setChunkSize(1000);
params.setFetchMode(SearchParams.Fetch.IMAP);
Mailbox mbox = search.getMailbox();
try {
ZimbraQueryResults zqr = mbox.index.search(SoapProtocol.Soap12, octxt, params);
try {
for (ZimbraHit hit = zqr.getNext(); hit != null; hit = zqr.getNext()) {
i4list.add(hit.getImapMessage());
}
} finally {
zqr.close();
}
} catch (ServiceException e) {
throw e;
} catch (Exception e) {
throw ServiceException.FAILURE("failure opening search folder", e);
}
return i4list;
}
use of com.zimbra.cs.index.ZimbraHit in project zm-mailbox by Zimbra.
the class GetShareNotifications method handle.
@Override
public Element handle(Element request, Map<String, Object> context) throws ServiceException {
ZimbraSoapContext zsc = getZimbraSoapContext(context);
Mailbox mbox = getRequestedMailbox(zsc);
OperationContext octxt = getOperationContext(zsc, context);
Element response = zsc.createElement(MailConstants.GET_SHARE_NOTIFICATIONS_RESPONSE);
HashSet<String> shares = new HashSet<String>();
ZimbraQueryResults zqr = null;
try {
zqr = mbox.index.search(octxt, query, SEARCH_TYPES, SortBy.DATE_DESC, 10);
while (zqr.hasNext()) {
ZimbraHit hit = zqr.getNext();
if (hit instanceof MessageHit) {
Message message = ((MessageHit) hit).getMessage();
try {
for (MPartInfo part : Mime.getParts(message.getMimeMessage())) {
String ctype = StringUtil.stripControlCharacters(part.getContentType());
if (MimeConstants.CT_XML_ZIMBRA_SHARE.equals(ctype)) {
ShareNotification sn = ShareNotification.fromMimePart(part.getMimePart());
String shareItemId = sn.getGrantorId() + ":" + sn.getItemId();
if (shares.contains(shareItemId)) {
// this notification is stale as there is
// a new one for the same share. delete
// this notification and skip to the next one.
sLog.info("deleting stale notification %s", message.getId());
mbox.delete(octxt, message.getId(), Type.MESSAGE);
continue;
}
shares.add(shareItemId);
Element share = response.addElement(sn.isRevoke() || sn.isExpire() ? MailConstants.E_REVOKE : MailConstants.E_SHARE);
if (sn.isExpire()) {
share.addAttribute(MailConstants.A_EXPIRE, true);
}
Element g = share.addUniqueElement(MailConstants.E_GRANTOR);
g.addAttribute(MailConstants.A_ID, sn.getGrantorId());
g.addAttribute(MailConstants.A_EMAIL, sn.getGrantorEmail());
g.addAttribute(MailConstants.A_NAME, sn.getGrantorName());
Element l = share.addUniqueElement(MailConstants.E_MOUNT);
l.addAttribute(MailConstants.A_ID, sn.getItemId());
l.addAttribute(MailConstants.A_NAME, sn.getItemName());
l.addAttribute(MailConstants.A_DEFAULT_VIEW, sn.getView());
l.addAttribute(MailConstants.A_RIGHTS, sn.getPermissions());
String status = (message.isUnread() ? "new" : "seen");
share.addAttribute(MailConstants.A_STATUS, status);
share.addAttribute(MailConstants.A_ID, "" + message.getId());
share.addAttribute(MailConstants.A_DATE, message.getDate());
if (sn.isRevoke() || sn.isExpire()) {
// purge revoke/expire notification upon receipt
mbox.delete(octxt, message.getId(), Type.MESSAGE);
}
}
}
} catch (IOException e) {
ZimbraLog.misc.warn("can't parse share notification", e);
} catch (MessagingException e) {
ZimbraLog.misc.warn("can't parse share notification", e);
}
}
}
} finally {
Closeables.closeQuietly(zqr);
}
return response;
}
use of com.zimbra.cs.index.ZimbraHit in project zm-mailbox by Zimbra.
the class AddressObject method getMatchingHit.
/**
* There could be multiple contacts with the same UID from different collections.
* Due to an old CardDAV bug, it is also possible there may be more than one contact with the same UID in
* the same collection. Using "preferredBaseName" ensures that CardDAV clients can still do an
* update in that case.
*
* @param zqr
* @param folderId
* @param preferredBaseName If more than one item matches, prefer one matching this name - can be null
* Ignored if folderId < 0
* @return
* @throws ServiceException
*/
private static Contact getMatchingHit(ZimbraQueryResults zqr, int folderId, String preferredBaseName) throws ServiceException {
Contact item = null;
Contact firstMatchingItem = null;
while (zqr.hasNext()) {
ZimbraHit hit = zqr.getNext();
if (hit instanceof ContactHit) {
item = ((ContactHit) hit).getContact();
if (folderId < 0) {
break;
}
if (item.getFolderId() == folderId) {
if (firstMatchingItem == null) {
firstMatchingItem = item;
}
if (preferredBaseName != null) {
String contactBaseName = VCard.getUrl(item) + AddressObject.VCARD_EXTENSION;
if (!preferredBaseName.equals(contactBaseName)) {
item = null;
continue;
}
}
break;
}
item = null;
}
}
return item != null ? item : firstMatchingItem;
}
Aggregations