You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by ro...@apache.org on 2017/01/11 16:45:40 UTC
[13/22] james-project git commit: JAMES-1894 Push GetMessageList
sorting and limit to the back-end
JAMES-1894 Push GetMessageList sorting and limit to the back-end
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/299addd9
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/299addd9
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/299addd9
Branch: refs/heads/master
Commit: 299addd9415e3744702c44c61bebe3d15e0e5e77
Parents: 7a893c4
Author: Benoit Tellier <bt...@linagora.com>
Authored: Thu Dec 22 18:40:05 2016 +0700
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Mon Jan 9 22:01:01 2017 +0700
----------------------------------------------------------------------
.../apache/james/mailbox/MailboxManager.java | 7 +-
...lasticSearchListeningMessageSearchIndex.java | 18 +-
.../search/ElasticSearchSearcher.java | 38 +--
.../ElasticSearchIntegrationTest.java | 5 +-
.../lucene/search/LuceneMessageSearchIndex.java | 65 +++--
.../LuceneMailboxMessageSearchIndexTest.java | 68 +++--
.../search/LuceneMessageSearchIndexTest.java | 6 +-
.../mailbox/store/StoreMailboxManager.java | 9 +-
.../store/search/LazyMessageSearchIndex.java | 5 +-
.../store/search/MessageSearchIndex.java | 31 ++-
.../mailbox/store/search/MessageSearches.java | 25 +-
.../store/search/SimpleMessageSearchIndex.java | 77 ++++--
.../james/mailbox/store/MessageBuilder.java | 7 +-
.../search/AbstractMessageSearchIndexTest.java | 255 ++++++++++---------
.../host/ElasticSearchHostSystem.java | 7 +-
.../host/LuceneSearchHostSystem.java | 2 +-
.../base/MailboxEventAnalyserTest.java | 2 +-
.../jmap/methods/GetMessageListMethod.java | 83 +-----
.../jmap/utils/SortToComparatorConvertor.java | 85 -------
.../FirstUserConnectionFilterThreadTest.java | 6 +-
.../utils/SortToComparatorConvertorTest.java | 146 -----------
21 files changed, 396 insertions(+), 551 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/299addd9/mailbox/api/src/main/java/org/apache/james/mailbox/MailboxManager.java
----------------------------------------------------------------------
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/MailboxManager.java b/mailbox/api/src/main/java/org/apache/james/mailbox/MailboxManager.java
index 44d1df5..d152466 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/MailboxManager.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/MailboxManager.java
@@ -19,10 +19,8 @@
package org.apache.james.mailbox;
-import java.util.Collection;
import java.util.EnumSet;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import org.apache.james.mailbox.exception.AnnotationException;
@@ -33,11 +31,12 @@ import org.apache.james.mailbox.exception.MailboxNotFoundException;
import org.apache.james.mailbox.exception.UnsupportedRightException;
import org.apache.james.mailbox.model.MailboxACL;
import org.apache.james.mailbox.model.MailboxAnnotation;
-import org.apache.james.mailbox.model.MailboxId;
import org.apache.james.mailbox.model.MailboxAnnotationKey;
+import org.apache.james.mailbox.model.MailboxId;
import org.apache.james.mailbox.model.MailboxMetaData;
import org.apache.james.mailbox.model.MailboxPath;
import org.apache.james.mailbox.model.MailboxQuery;
+import org.apache.james.mailbox.model.MessageId;
import org.apache.james.mailbox.model.MessageRange;
import org.apache.james.mailbox.model.MultimailboxesSearchQuery;
import org.apache.james.mailbox.model.SimpleMailboxACL;
@@ -239,7 +238,7 @@ public interface MailboxManager extends RequestAware, MailboxListenerSupport {
* the context for this call, not null
* @throws MailboxException
*/
- Map<MailboxId, Collection<MessageUid>> search(MultimailboxesSearchQuery expression, MailboxSession session) throws MailboxException;
+ List<MessageId> search(MultimailboxesSearchQuery expression, MailboxSession session, long limit) throws MailboxException;
/**
* Does the given mailbox exist?
http://git-wip-us.apache.org/repos/asf/james-project/blob/299addd9/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndex.java
----------------------------------------------------------------------
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndex.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndex.java
index f4c60f8..281f429 100644
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndex.java
+++ b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndex.java
@@ -20,11 +20,10 @@ package org.apache.james.mailbox.elasticsearch.events;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
-import java.util.Collection;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.List;
-import java.util.Map;
+import java.util.Optional;
import java.util.stream.Collectors;
import javax.inject.Inject;
@@ -38,6 +37,7 @@ import org.apache.james.mailbox.elasticsearch.json.MessageToElasticSearchJson;
import org.apache.james.mailbox.elasticsearch.search.ElasticSearchSearcher;
import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.model.MailboxId;
+import org.apache.james.mailbox.model.MessageId;
import org.apache.james.mailbox.model.MultimailboxesSearchQuery;
import org.apache.james.mailbox.model.SearchQuery;
import org.apache.james.mailbox.model.UpdatedFlags;
@@ -49,6 +49,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.core.JsonProcessingException;
+import com.github.steveash.guavate.Guavate;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
@@ -85,17 +86,20 @@ public class ElasticSearchListeningMessageSearchIndex extends ListeningMessageSe
Preconditions.checkArgument(session != null, "'session' is mandatory");
MailboxId mailboxId = mailbox.getMailboxId();
MultimailboxesSearchQuery query = MultimailboxesSearchQuery.from(searchQuery).inMailboxes(mailboxId).build();
+ Optional<Long> noLimit = Optional.empty();
return searcher
- .search(ImmutableList.of(session.getUser()), query)
- .get(mailboxId)
+ .search(ImmutableList.of(session.getUser()), query, noLimit)
+ .map(SearchResult::getMessageUid)
.iterator();
}
@Override
- public Map<MailboxId, Collection<MessageUid>> search(MailboxSession session, MultimailboxesSearchQuery searchQuery)
+ public List<MessageId> search(MailboxSession session, MultimailboxesSearchQuery searchQuery, long limit)
throws MailboxException {
Preconditions.checkArgument(session != null, "'session' is mandatory");
- return searcher.search(ImmutableList.of(session.getUser()), searchQuery).asMap();
+ return searcher.search(ImmutableList.of(session.getUser()), searchQuery, Optional.of(limit))
+ .map(SearchResult::getMessageId)
+ .collect(Guavate.toImmutableList());
}
@Override
@@ -156,5 +160,5 @@ public class ElasticSearchListeningMessageSearchIndex extends ListeningMessageSe
private String indexIdFor(Mailbox mailbox, MessageUid uid) {
return String.join(ID_SEPARATOR, mailbox.getMailboxId().serialize(), String.valueOf(uid.asLong()));
}
-
+
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/299addd9/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcher.java
----------------------------------------------------------------------
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcher.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcher.java
index 1a5cd1e..e508e7d 100644
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcher.java
+++ b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/search/ElasticSearchSearcher.java
@@ -26,7 +26,6 @@ import java.util.stream.StreamSupport;
import javax.inject.Inject;
-import org.apache.commons.lang3.tuple.Pair;
import org.apache.james.mailbox.MailboxSession.User;
import org.apache.james.mailbox.MessageUid;
import org.apache.james.mailbox.elasticsearch.ElasticSearchIndexer;
@@ -36,7 +35,10 @@ import org.apache.james.mailbox.elasticsearch.query.SortConverter;
import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.model.MailboxId;
import org.apache.james.mailbox.model.MailboxId.Factory;
+import org.apache.james.mailbox.model.MessageId;
import org.apache.james.mailbox.model.MultimailboxesSearchQuery;
+import org.apache.james.mailbox.store.search.MessageSearchIndex;
+import org.apache.james.mailbox.store.search.SimpleMessageSearchIndex;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
@@ -46,9 +48,6 @@ import org.elasticsearch.search.SearchHitField;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.github.steveash.guavate.Guavate;
-import com.google.common.collect.Multimap;
-
public class ElasticSearchSearcher {
private static final Logger LOGGER = LoggerFactory.getLogger(ElasticSearchSearcher.class);
@@ -59,23 +58,26 @@ public class ElasticSearchSearcher {
private final QueryConverter queryConverter;
private final int size;
private final Factory mailboxIdFactory;
+ private final MessageId.Factory messageIdFactory;
@Inject
- public ElasticSearchSearcher(Client client, QueryConverter queryConverter, MailboxId.Factory mailboxIdFactory) {
- this(client, queryConverter, DEFAULT_SIZE, mailboxIdFactory);
+ public ElasticSearchSearcher(Client client, QueryConverter queryConverter, MailboxId.Factory mailboxIdFactory, MessageId.Factory messageIdFactory) {
+ this(client, queryConverter, DEFAULT_SIZE, mailboxIdFactory, messageIdFactory);
}
- public ElasticSearchSearcher(Client client, QueryConverter queryConverter, int size, MailboxId.Factory mailboxIdFactory) {
+ public ElasticSearchSearcher(Client client, QueryConverter queryConverter, int size, Factory mailboxIdFactory, MessageId.Factory messageIdFactory) {
this.client = client;
this.queryConverter = queryConverter;
this.size = size;
this.mailboxIdFactory = mailboxIdFactory;
+ this.messageIdFactory = messageIdFactory;
}
- public Multimap<MailboxId, MessageUid> search(List<User> users, MultimailboxesSearchQuery query) throws MailboxException {
- return new ScrollIterable(client, getSearchRequestBuilder(client, users, query)).stream()
- .flatMap(this::transformResponseToUidStream)
- .collect(Guavate.toImmutableListMultimap(Pair::getLeft, Pair::getRight));
+ public Stream<MessageSearchIndex.SearchResult> search(List<User> users, MultimailboxesSearchQuery query, Optional<Long> limit) throws MailboxException {
+ Stream<MessageSearchIndex.SearchResult> pairStream = new ScrollIterable(client, getSearchRequestBuilder(client, users, query)).stream()
+ .flatMap(this::transformResponseToUidStream);
+ return limit.map(pairStream::limit)
+ .orElse(pairStream);
}
private SearchRequestBuilder getSearchRequestBuilder(Client client, List<User> users, MultimailboxesSearchQuery query) {
@@ -92,21 +94,25 @@ public class ElasticSearchSearcher {
(partialResult1, partialResult2) -> partialResult1);
}
- private Stream<Pair<MailboxId, MessageUid>> transformResponseToUidStream(SearchResponse searchResponse) {
+ private Stream<MessageSearchIndex.SearchResult> transformResponseToUidStream(SearchResponse searchResponse) {
return StreamSupport.stream(searchResponse.getHits().spliterator(), false)
.map(this::extractContentFromHit)
.filter(Optional::isPresent)
.map(Optional::get);
}
- private Optional<Pair<MailboxId, MessageUid>> extractContentFromHit(SearchHit hit) {
+ private Optional<MessageSearchIndex.SearchResult> extractContentFromHit(SearchHit hit) {
SearchHitField mailboxId = hit.field(JsonMessageConstants.MAILBOX_ID);
SearchHitField uid = hit.field(JsonMessageConstants.UID);
- if (mailboxId != null && uid != null) {
+ SearchHitField id = hit.field(JsonMessageConstants.ID);
+ if (mailboxId != null && uid != null && id != null) {
Number uidAsNumber = uid.getValue();
- return Optional.of(Pair.of(mailboxIdFactory.fromString(mailboxId.getValue()), MessageUid.of(uidAsNumber.longValue())));
+ return Optional.of(
+ new MessageSearchIndex.SearchResult(messageIdFactory.fromString(id.getValue()),
+ mailboxIdFactory.fromString(mailboxId.getValue()),
+ MessageUid.of(uidAsNumber.longValue())));
} else {
- LOGGER.warn("Can not extract UID and/or MailboxId for search result " + hit.getId());
+ LOGGER.warn("Can not extract UID, MessageID and/or MailboxId for search result " + hit.getId());
return Optional.empty();
}
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/299addd9/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java
----------------------------------------------------------------------
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java
index e633bb4..749f11b 100644
--- a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java
+++ b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/ElasticSearchIntegrationTest.java
@@ -67,9 +67,10 @@ public class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest
IndexCreationFactory.createIndex(new TestingClientProvider(embeddedElasticSearch.getNode()).get())
);
MailboxSessionMapperFactory mapperFactory = new InMemoryMailboxSessionMapperFactory();
+ InMemoryMessageId.Factory messageIdFactory = new InMemoryMessageId.Factory();
messageSearchIndex = new ElasticSearchListeningMessageSearchIndex(mapperFactory,
new ElasticSearchIndexer(client, new DeleteByQueryPerformer(client, Executors.newSingleThreadExecutor(), BATCH_SIZE)),
- new ElasticSearchSearcher(client, new QueryConverter(new CriterionConverter()), SEARCH_SIZE, new InMemoryId.Factory()),
+ new ElasticSearchSearcher(client, new QueryConverter(new CriterionConverter()), SEARCH_SIZE, new InMemoryId.Factory(), messageIdFactory),
new MessageToElasticSearchJson(new DefaultTextExtractor(), ZoneId.of("Europe/Paris"), IndexAttachments.YES));
storeMailboxManager = new InMemoryMailboxManager(
mapperFactory,
@@ -78,7 +79,7 @@ public class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest
new UnionMailboxACLResolver(),
new SimpleGroupMembershipResolver(),
new MessageParser(),
- new InMemoryMessageId.Factory());
+ messageIdFactory);
storeMailboxManager.setMessageSearchIndex(messageSearchIndex);
storeMailboxManager.init();
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/299addd9/mailbox/lucene/src/main/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndex.java
----------------------------------------------------------------------
diff --git a/mailbox/lucene/src/main/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndex.java b/mailbox/lucene/src/main/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndex.java
index 8a683d9..7dee3cf 100644
--- a/mailbox/lucene/src/main/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndex.java
+++ b/mailbox/lucene/src/main/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndex.java
@@ -33,7 +33,6 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
-import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
@@ -48,6 +47,7 @@ import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.exception.UnsupportedSearchException;
import org.apache.james.mailbox.model.MailboxId;
import org.apache.james.mailbox.model.MailboxId.Factory;
+import org.apache.james.mailbox.model.MessageId;
import org.apache.james.mailbox.model.MessageRange;
import org.apache.james.mailbox.model.MultimailboxesSearchQuery;
import org.apache.james.mailbox.model.SearchQuery;
@@ -117,10 +117,11 @@ import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.util.IOUtils;
import org.apache.lucene.util.Version;
+import com.google.common.base.Function;
import com.google.common.base.Preconditions;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.LinkedHashMultimap;
-import com.google.common.collect.Multimap;
/**
* Lucene based {@link ListeningMessageSearchIndex} which offers message searching via a Lucene index
@@ -264,6 +265,11 @@ public class LuceneMessageSearchIndex extends ListeningMessageSearchIndex {
public final static String MAILBOX_ID_FIELD ="mailboxid";
/**
+ * {@link Field} which will contain the id of the {@link MessageId}
+ */
+ public final static String MESSAGE_ID_FIELD ="messageid";
+
+ /**
* {@link Field} which contain the Date header of the message with YEAR-Resolution
*/
public final static String SENT_DATE_FIELD_YEAR_RESOLUTION ="sentdateYearResolution";
@@ -341,6 +347,7 @@ public class LuceneMessageSearchIndex extends ListeningMessageSearchIndex {
private final static SortField FIRST_FROM_MAILBOX_DISPLAY_SORT_REVERSE = new SortField(FIRST_FROM_MAILBOX_DISPLAY_FIELD, SortField.STRING, true);
private final Factory mailboxIdFactory;
+ private final MessageId.Factory messageIdFactory;
private final IndexWriter writer;
private int maxQueryResults = DEFAULT_MAX_QUERY_RESULTS;
@@ -348,21 +355,23 @@ public class LuceneMessageSearchIndex extends ListeningMessageSearchIndex {
private boolean suffixMatch = false;
@Inject
- public LuceneMessageSearchIndex(MessageMapperFactory factory, MailboxId.Factory mailboxIdFactory, Directory directory) throws CorruptIndexException, LockObtainFailedException, IOException {
- this(factory, mailboxIdFactory, directory, false, true);
+ public LuceneMessageSearchIndex(MessageMapperFactory factory, Factory mailboxIdFactory, Directory directory, MessageId.Factory messageIdFactory) throws CorruptIndexException, LockObtainFailedException, IOException {
+ this(factory, mailboxIdFactory, directory, false, true, messageIdFactory);
}
- public LuceneMessageSearchIndex(MessageMapperFactory factory, MailboxId.Factory mailboxIdFactory, Directory directory, boolean dropIndexOnStart, boolean lenient) throws CorruptIndexException, LockObtainFailedException, IOException {
+ public LuceneMessageSearchIndex(MessageMapperFactory factory, Factory mailboxIdFactory, Directory directory, boolean dropIndexOnStart, boolean lenient, MessageId.Factory messageIdFactory) throws CorruptIndexException, LockObtainFailedException, IOException {
super(factory);
this.mailboxIdFactory = mailboxIdFactory;
+ this.messageIdFactory = messageIdFactory;
this.writer = new IndexWriter(directory, createConfig(createAnalyzer(lenient), dropIndexOnStart));
}
- public LuceneMessageSearchIndex(MessageMapperFactory factory, MailboxId.Factory mailboxIdFactory, IndexWriter writer) {
+ public LuceneMessageSearchIndex(MessageMapperFactory factory, Factory mailboxIdFactory, MessageId.Factory messageIdFactory, IndexWriter writer) {
super(factory);
this.mailboxIdFactory = mailboxIdFactory;
+ this.messageIdFactory = messageIdFactory;
this.writer = writer;
}
@@ -431,24 +440,36 @@ public class LuceneMessageSearchIndex extends ListeningMessageSearchIndex {
public Iterator<MessageUid> search(MailboxSession session, Mailbox mailbox, SearchQuery searchQuery) throws MailboxException {
Preconditions.checkArgument(session != null, "'session' is mandatory");
MailboxId mailboxId = mailbox.getMailboxId();
- Multimap<MailboxId, MessageUid> results =
- searchMultimap(
- session,
- MultimailboxesSearchQuery
- .from(searchQuery)
- .inMailboxes(mailboxId)
- .build());
- return results.get(mailboxId).iterator();
+ return FluentIterable.from(searchMultimap(
+ MultimailboxesSearchQuery
+ .from(searchQuery)
+ .inMailboxes(mailboxId)
+ .build()))
+ .transform(new Function<SearchResult, MessageUid>() {
+ @Override
+ public MessageUid apply(SearchResult input) {
+ return input.getMessageUid();
+ }
+ })
+ .iterator();
}
@Override
- public Map<MailboxId, Collection<MessageUid>> search(MailboxSession session, MultimailboxesSearchQuery searchQuery) throws MailboxException {
+ public List<MessageId> search(MailboxSession session, MultimailboxesSearchQuery searchQuery, long limit) throws MailboxException {
Preconditions.checkArgument(session != null, "'session' is mandatory");
- return searchMultimap(session, searchQuery).asMap();
+ return FluentIterable.from(searchMultimap(searchQuery))
+ .transform(new Function<SearchResult, MessageId>() {
+ @Override
+ public MessageId apply(SearchResult input) {
+ return input.getMessageId();
+ }
+ })
+ .limit(Long.valueOf(limit).intValue())
+ .toList();
}
- private Multimap<MailboxId, MessageUid> searchMultimap(MailboxSession session, MultimailboxesSearchQuery searchQuery) throws MailboxException {
- Multimap<MailboxId, MessageUid> results = LinkedHashMultimap.create();
+ private List<SearchResult> searchMultimap(MultimailboxesSearchQuery searchQuery) throws MailboxException {
+ ImmutableList.Builder<SearchResult> results = ImmutableList.builder();
IndexSearcher searcher = null;
Query inMailboxes = buildQueryFromMailboxes(searchQuery.getInMailboxes());
@@ -471,7 +492,8 @@ public class LuceneMessageSearchIndex extends ListeningMessageSearchIndex {
Document doc = searcher.doc(sDoc.doc);
MessageUid uid = MessageUid.of(Long.valueOf(doc.get(UID_FIELD)));
MailboxId mailboxId = mailboxIdFactory.fromString(doc.get(MAILBOX_ID_FIELD));
- results.put(mailboxId, uid);
+ MessageId messageId = messageIdFactory.fromString(doc.get(MESSAGE_ID_FIELD));
+ results.add(new SearchResult(messageId, mailboxId, uid));
}
} catch (IOException e) {
throw new MailboxException("Unable to search the mailbox", e);
@@ -484,7 +506,7 @@ public class LuceneMessageSearchIndex extends ListeningMessageSearchIndex {
}
}
}
- return results;
+ return results.build();
}
private Query buildQueryFromMailboxes(ImmutableSet<MailboxId> mailboxIds) {
@@ -513,6 +535,7 @@ public class LuceneMessageSearchIndex extends ListeningMessageSearchIndex {
// TODO: Better handling
doc.add(new Field(MAILBOX_ID_FIELD, membership.getMailboxId().serialize().toUpperCase(Locale.ENGLISH), Store.YES, Index.NOT_ANALYZED));
doc.add(new NumericField(UID_FIELD,Store.YES, true).setLongValue(membership.getUid().asLong()));
+ doc.add(new Field(MESSAGE_ID_FIELD, membership.getMessageId().serialize(), Store.YES, Index.NOT_ANALYZED));
// create an unqiue key for the document which can be used later on updates to find the document
doc.add(new Field(ID_FIELD, membership.getMailboxId().serialize().toUpperCase(Locale.ENGLISH) +"-" + Long.toString(membership.getUid().asLong()), Store.YES, Index.NOT_ANALYZED));
http://git-wip-us.apache.org/repos/asf/james-project/blob/299addd9/mailbox/lucene/src/test/java/org/apache/james/mailbox/lucene/search/LuceneMailboxMessageSearchIndexTest.java
----------------------------------------------------------------------
diff --git a/mailbox/lucene/src/test/java/org/apache/james/mailbox/lucene/search/LuceneMailboxMessageSearchIndexTest.java b/mailbox/lucene/src/test/java/org/apache/james/mailbox/lucene/search/LuceneMailboxMessageSearchIndexTest.java
index 6bf144c..82d8cba 100644
--- a/mailbox/lucene/src/test/java/org/apache/james/mailbox/lucene/search/LuceneMailboxMessageSearchIndexTest.java
+++ b/mailbox/lucene/src/test/java/org/apache/james/mailbox/lucene/search/LuceneMailboxMessageSearchIndexTest.java
@@ -23,10 +23,10 @@ import static org.assertj.core.api.Assertions.assertThat;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Calendar;
-import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -38,6 +38,7 @@ import org.apache.james.mailbox.MessageUid;
import org.apache.james.mailbox.mock.MockMailboxSession;
import org.apache.james.mailbox.model.MailboxACL;
import org.apache.james.mailbox.model.MailboxId;
+import org.apache.james.mailbox.model.MessageId;
import org.apache.james.mailbox.model.MultimailboxesSearchQuery;
import org.apache.james.mailbox.model.SearchQuery;
import org.apache.james.mailbox.model.SearchQuery.AddressType;
@@ -45,9 +46,9 @@ import org.apache.james.mailbox.model.SearchQuery.DateResolution;
import org.apache.james.mailbox.model.SearchQuery.Sort.SortClause;
import org.apache.james.mailbox.model.SimpleMailboxACL;
import org.apache.james.mailbox.model.TestId;
+import org.apache.james.mailbox.model.TestMessageId;
import org.apache.james.mailbox.store.MessageBuilder;
import org.apache.james.mailbox.store.SimpleMailboxMembership;
-import org.apache.james.mailbox.store.mail.model.DefaultMessageId;
import org.apache.james.mailbox.store.mail.model.Mailbox;
import org.apache.lucene.store.RAMDirectory;
import org.junit.Before;
@@ -55,7 +56,8 @@ import org.junit.Test;
public class LuceneMailboxMessageSearchIndexTest {
- private LuceneMessageSearchIndex index;
+ public static final long LIMIT = 100L;
+ private LuceneMessageSearchIndex index;
private SimpleMailbox mailbox = new SimpleMailbox(0);
private SimpleMailbox mailbox2 = new SimpleMailbox(1);
@@ -79,6 +81,11 @@ public class LuceneMailboxMessageSearchIndexTest {
private MessageUid uid3;
private MessageUid uid4;
private MessageUid uid5;
+ private MessageId id1;
+ private MessageId id2;
+ private MessageId id3;
+ private MessageId id4;
+ private MessageId id5;
protected boolean useLenient() {
return true;
@@ -86,7 +93,13 @@ public class LuceneMailboxMessageSearchIndexTest {
@Before
public void setUp() throws Exception {
- index = new LuceneMessageSearchIndex(null, new TestId.Factory(), new RAMDirectory(), true, useLenient());
+ TestMessageId.Factory factory = new TestMessageId.Factory();
+ id1 = factory.generate();
+ id2 = factory.generate();
+ id3 = factory.generate();
+ id4 = factory.generate();
+ id5 = factory.generate();
+ index = new LuceneMessageSearchIndex(null, new TestId.Factory(), new RAMDirectory(), true, useLenient(), factory);
index.setEnableSuffixMatch(true);
Map<String, String> headersSubject = new HashMap<String, String>();
headersSubject.put("Subject", "test (fwd)");
@@ -107,23 +120,23 @@ public class LuceneMailboxMessageSearchIndexTest {
headersTestSubject.put("Cc", "test211 <te...@localhost>, test6 <te...@foobar>");
uid1 = MessageUid.of(1);
- SimpleMailboxMembership m = new SimpleMailboxMembership(new DefaultMessageId(), mailbox.getMailboxId(), uid1, 0, new Date(), 200, new Flags(Flag.ANSWERED), "My Body".getBytes(), headersSubject);
+ SimpleMailboxMembership m = new SimpleMailboxMembership(id1, mailbox.getMailboxId(), uid1, 0, new Date(), 200, new Flags(Flag.ANSWERED), "My Body".getBytes(), headersSubject);
index.add(null, mailbox, m);
uid2 = MessageUid.of(1);
- SimpleMailboxMembership m2 = new SimpleMailboxMembership(new DefaultMessageId(), mailbox2.getMailboxId(), uid2, 0, new Date(), 20, new Flags(Flag.ANSWERED), "My Body".getBytes(), headersSubject);
+ SimpleMailboxMembership m2 = new SimpleMailboxMembership(id2, mailbox2.getMailboxId(), uid2, 0, new Date(), 20, new Flags(Flag.ANSWERED), "My Body".getBytes(), headersSubject);
index.add(null, mailbox2, m2);
uid3 = MessageUid.of(2);
Calendar cal = Calendar.getInstance();
cal.set(1980, 2, 10);
- SimpleMailboxMembership m3 = new SimpleMailboxMembership(new DefaultMessageId(), mailbox.getMailboxId(), uid3, 0, cal.getTime(), 20, new Flags(Flag.DELETED), "My Otherbody".getBytes(), headersTest);
+ SimpleMailboxMembership m3 = new SimpleMailboxMembership(id3, mailbox.getMailboxId(), uid3, 0, cal.getTime(), 20, new Flags(Flag.DELETED), "My Otherbody".getBytes(), headersTest);
index.add(null, mailbox, m3);
uid4 = MessageUid.of(3);
Calendar cal2 = Calendar.getInstance();
cal2.set(8000, 2, 10);
- SimpleMailboxMembership m4 = new SimpleMailboxMembership(new DefaultMessageId(), mailbox.getMailboxId(), uid4, 0, cal2.getTime(), 20, new Flags(Flag.DELETED), "My Otherbody2".getBytes(), headersTestSubject);
+ SimpleMailboxMembership m4 = new SimpleMailboxMembership(id4, mailbox.getMailboxId(), uid4, 0, cal2.getTime(), 20, new Flags(Flag.DELETED), "My Otherbody2".getBytes(), headersTestSubject);
index.add(null, mailbox, m4);
uid5 = MessageUid.of(10);
@@ -136,7 +149,7 @@ public class LuceneMailboxMessageSearchIndexTest {
builder.uid = uid5;
builder.mailboxId = mailbox3.getMailboxId();
- index.add(null, mailbox3, builder.build());
+ index.add(null, mailbox3, builder.build(id5));
session = new MockMailboxSession("username");
}
@@ -267,29 +280,44 @@ public class LuceneMailboxMessageSearchIndexTest {
public void searchBodyInAllMailboxesShouldMatch() throws Exception {
SearchQuery query = new SearchQuery();
query.andCriteria(SearchQuery.bodyContains("My Body"));
- Map<MailboxId, Collection<MessageUid>> result = index.search(session, MultimailboxesSearchQuery.from(query).build());
- assertThat(result).hasSize(2);
- assertThat(result.get(mailbox.id)).containsExactly(uid1);
- assertThat(result.get(mailbox2.id)).containsExactly(uid2);
+
+ List<MessageId> result = index.search(session, MultimailboxesSearchQuery.from(query).build(), LIMIT);
+
+ assertThat(result).containsOnly(id1, id2);
}
@Test
public void searchBodyInSpecificMailboxesShouldMatch() throws Exception {
SearchQuery query = new SearchQuery();
query.andCriteria(SearchQuery.bodyContains("My Body"));
- Map<MailboxId, Collection<MessageUid>> result = index.search(session,
- MultimailboxesSearchQuery.from(query).inMailboxes(mailbox.id, mailbox3.id).build());
- assertThat(result).hasSize(1);
- assertThat(result.get(mailbox.id)).containsExactly(uid1);
- }
+ List<MessageId> result = index.search(session,
+ MultimailboxesSearchQuery.from(query).inMailboxes(mailbox.id, mailbox3.id).build(),
+ LIMIT);
+
+ assertThat(result).containsOnly(id1);
+ }
@Test
public void searchAllShouldMatchAllUserEmails() throws Exception {
SearchQuery query = new SearchQuery();
query.andCriteria(SearchQuery.all());
- Map<MailboxId, Collection<MessageUid>> result = index.search(session, MultimailboxesSearchQuery.from(query).build());
- assertThat(result).hasSize(3);
+
+ List<MessageId> result = index.search(session, MultimailboxesSearchQuery.from(query).build(), LIMIT);
+
+ // The query is not limited to one mailbox and we have 5 indexed messages
+ assertThat(result).hasSize(5);
+ }
+
+ @Test
+ public void searchAllShouldLimitTheSize() throws Exception {
+ SearchQuery query = new SearchQuery();
+ query.andCriteria(SearchQuery.all());
+
+ int limit = 1;
+ List<MessageId> result = index.search(session, MultimailboxesSearchQuery.from(query).build(), limit);
+
+ assertThat(result).hasSize(limit);
}
@Test
http://git-wip-us.apache.org/repos/asf/james-project/blob/299addd9/mailbox/lucene/src/test/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndexTest.java
----------------------------------------------------------------------
diff --git a/mailbox/lucene/src/test/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndexTest.java b/mailbox/lucene/src/test/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndexTest.java
index 0270e40..864a7a0 100644
--- a/mailbox/lucene/src/test/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndexTest.java
+++ b/mailbox/lucene/src/test/java/org/apache/james/mailbox/lucene/search/LuceneMessageSearchIndexTest.java
@@ -26,6 +26,7 @@ import org.apache.james.mailbox.inmemory.InMemoryId;
import org.apache.james.mailbox.inmemory.InMemoryMailboxManager;
import org.apache.james.mailbox.inmemory.InMemoryMailboxSessionMapperFactory;
import org.apache.james.mailbox.inmemory.InMemoryMessageId;
+import org.apache.james.mailbox.model.TestMessageId;
import org.apache.james.mailbox.store.FakeAuthenticator;
import org.apache.james.mailbox.store.JVMMailboxPathLocker;
import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
@@ -42,8 +43,9 @@ public class LuceneMessageSearchIndexTest extends AbstractMessageSearchIndexTest
@Override
protected void initializeMailboxManager() throws Exception {
+ TestMessageId.Factory messageIdFactory = new TestMessageId.Factory();
MailboxSessionMapperFactory mapperFactory = new InMemoryMailboxSessionMapperFactory();
- messageSearchIndex = new LuceneMessageSearchIndex(mapperFactory, new InMemoryId.Factory(), new RAMDirectory());
+ messageSearchIndex = new LuceneMessageSearchIndex(mapperFactory, new InMemoryId.Factory(), new RAMDirectory(), messageIdFactory);
storeMailboxManager = new InMemoryMailboxManager(
mapperFactory,
new FakeAuthenticator(),
@@ -51,7 +53,7 @@ public class LuceneMessageSearchIndexTest extends AbstractMessageSearchIndexTest
new UnionMailboxACLResolver(),
new SimpleGroupMembershipResolver(),
new MessageParser(),
- new InMemoryMessageId.Factory());
+ messageIdFactory);
storeMailboxManager.setMessageSearchIndex(messageSearchIndex);
storeMailboxManager.init();
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/299addd9/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
index 8bee086..5f83734 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
@@ -20,12 +20,10 @@
package org.apache.james.mailbox.store;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Locale;
-import java.util.Map;
import java.util.Random;
import java.util.Set;
@@ -40,7 +38,6 @@ import org.apache.james.mailbox.MailboxSession;
import org.apache.james.mailbox.MailboxSession.SessionType;
import org.apache.james.mailbox.MailboxSessionIdGenerator;
import org.apache.james.mailbox.MessageManager;
-import org.apache.james.mailbox.MessageUid;
import org.apache.james.mailbox.RequestAware;
import org.apache.james.mailbox.StandardMailboxMetaDataComparator;
import org.apache.james.mailbox.acl.GroupMembershipResolver;
@@ -85,6 +82,8 @@ import org.apache.james.mailbox.store.transaction.Mapper;
import org.apache.james.mailbox.store.transaction.TransactionalMapper;
import org.slf4j.Logger;
+import com.google.common.base.Optional;
+
/**
* This base class of an {@link MailboxManager} implementation provides a high-level api for writing your own
* {@link MailboxManager} implementation. If you plan to write your own {@link MailboxManager} its most times so easiest
@@ -699,8 +698,8 @@ public class StoreMailboxManager implements MailboxManager {
}
@Override
- public Map<MailboxId, Collection<MessageUid>> search(MultimailboxesSearchQuery expression, MailboxSession session) throws MailboxException {
- return index.search(session, expression);
+ public List<MessageId> search(MultimailboxesSearchQuery expression, MailboxSession session, long limit) throws MailboxException {
+ return index.search(session, expression, limit);
}
public boolean belongsToNamespaceAndUser(MailboxPath base, Mailbox mailbox) {
http://git-wip-us.apache.org/repos/asf/james-project/blob/299addd9/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/LazyMessageSearchIndex.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/LazyMessageSearchIndex.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/LazyMessageSearchIndex.java
index a1c9275..07c6188 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/LazyMessageSearchIndex.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/LazyMessageSearchIndex.java
@@ -18,11 +18,9 @@
****************************************************************/
package org.apache.james.mailbox.store.search;
-import java.util.Collection;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.List;
-import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.james.mailbox.MailboxManager.SearchCapabilities;
@@ -31,6 +29,7 @@ import org.apache.james.mailbox.MessageUid;
import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.exception.UnsupportedSearchException;
import org.apache.james.mailbox.model.MailboxId;
+import org.apache.james.mailbox.model.MessageId;
import org.apache.james.mailbox.model.MessageRange;
import org.apache.james.mailbox.model.MultimailboxesSearchQuery;
import org.apache.james.mailbox.model.SearchQuery;
@@ -128,7 +127,7 @@ public class LazyMessageSearchIndex extends ListeningMessageSearchIndex {
@Override
- public Map<MailboxId, Collection<MessageUid>> search(MailboxSession session, MultimailboxesSearchQuery searchQuery) throws MailboxException {
+ public List<MessageId> search(MailboxSession session, MultimailboxesSearchQuery searchQuery, long limit) throws MailboxException {
throw new UnsupportedSearchException();
}
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/299addd9/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearchIndex.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearchIndex.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearchIndex.java
index 6324898..3df16bd 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearchIndex.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearchIndex.java
@@ -19,21 +19,20 @@
package org.apache.james.mailbox.store.search;
-import java.util.Collection;
import java.util.EnumSet;
import java.util.Iterator;
-import java.util.Map;
+import java.util.List;
import org.apache.james.mailbox.MailboxManager;
import org.apache.james.mailbox.MailboxSession;
import org.apache.james.mailbox.MessageUid;
import org.apache.james.mailbox.exception.MailboxException;
import org.apache.james.mailbox.model.MailboxId;
+import org.apache.james.mailbox.model.MessageId;
import org.apache.james.mailbox.model.MultimailboxesSearchQuery;
import org.apache.james.mailbox.model.SearchQuery;
import org.apache.james.mailbox.store.mail.model.Mailbox;
-
/**
* An index which can be used to search for MailboxMessage UID's that match a {@link SearchQuery}.
*
@@ -50,8 +49,32 @@ public interface MessageSearchIndex {
/**
* Return all uids of all {@link Mailbox}'s the current user has access to which match the {@link SearchQuery}
*/
- Map<MailboxId, Collection<MessageUid>> search(MailboxSession session, MultimailboxesSearchQuery searchQuery) throws MailboxException;
+ List<MessageId> search(MailboxSession session, MultimailboxesSearchQuery searchQuery, long limit) throws MailboxException;
EnumSet<MailboxManager.SearchCapabilities> getSupportedCapabilities();
+ class SearchResult {
+ private final MessageId messageId;
+ private final MailboxId mailboxId;
+ private final MessageUid messageUid;
+
+ public SearchResult(MessageId messageId, MailboxId mailboxId, MessageUid messageUid) {
+ this.messageId = messageId;
+ this.mailboxId = mailboxId;
+ this.messageUid = messageUid;
+ }
+
+ public MessageId getMessageId() {
+ return messageId;
+ }
+
+ public MailboxId getMailboxId() {
+ return mailboxId;
+ }
+
+ public MessageUid getMessageUid() {
+ return messageUid;
+ }
+ }
+
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/299addd9/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java
index f90c144..c2126f1 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/MessageSearches.java
@@ -29,7 +29,6 @@ import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
@@ -70,12 +69,14 @@ import org.apache.james.mime4j.message.DefaultMessageWriter;
import org.apache.james.mime4j.message.HeaderImpl;
import org.apache.james.mime4j.utils.search.MessageMatcher;
+import com.google.common.base.Function;
+import com.google.common.collect.FluentIterable;
import com.google.common.collect.Lists;
/**
* Utility methods to help perform search operations.
*/
-public class MessageSearches implements Iterable<MessageUid> {
+public class MessageSearches implements Iterable<SimpleMessageSearchIndex.SearchResult> {
private Iterator<MailboxMessage> messages;
private SearchQuery query;
@@ -93,7 +94,7 @@ public class MessageSearches implements Iterable<MessageUid> {
public MessageSearches() {
}
- private Set<MessageUid> search() {
+ private Set<SimpleMessageSearchIndex.SearchResult> search() {
TreeSet<MailboxMessage> matched = new TreeSet<MailboxMessage>(CombinedComparator.create(query.getSorts()));
while (messages.hasNext()) {
MailboxMessage m = messages.next();
@@ -107,12 +108,16 @@ public class MessageSearches implements Iterable<MessageUid> {
}
}
}
- Set<MessageUid> uids = new HashSet<MessageUid>();
- Iterator<MailboxMessage> matchedIt = matched.iterator();
- while (matchedIt.hasNext()) {
- uids.add(matchedIt.next().getUid());
- }
- return uids;
+ return FluentIterable.from(matched)
+ .transform(new Function<MailboxMessage, SimpleMessageSearchIndex.SearchResult>() {
+ @Override
+ public SimpleMessageSearchIndex.SearchResult apply(MailboxMessage input) {
+ return new SimpleMessageSearchIndex.SearchResult(
+ input.getMessageId(),
+ input.getMailboxId(),
+ input.getUid());
+ }
+ }).toSet();
}
/**
@@ -631,7 +636,7 @@ public class MessageSearches implements Iterable<MessageUid> {
* according to the SearchQuery
*
*/
- public Iterator<MessageUid> iterator() {
+ public Iterator<SimpleMessageSearchIndex.SearchResult> iterator() {
return search().iterator();
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/299addd9/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndex.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndex.java b/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndex.java
index 18ea774..537164e 100644
--- a/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndex.java
+++ b/mailbox/store/src/main/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndex.java
@@ -19,11 +19,9 @@
package org.apache.james.mailbox.store.search;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.List;
-import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
@@ -33,8 +31,8 @@ import org.apache.james.mailbox.MailboxManager.SearchCapabilities;
import org.apache.james.mailbox.MailboxSession;
import org.apache.james.mailbox.MessageUid;
import org.apache.james.mailbox.exception.MailboxException;
-import org.apache.james.mailbox.model.MailboxId;
import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.model.MessageId;
import org.apache.james.mailbox.model.MessageRange;
import org.apache.james.mailbox.model.MultimailboxesSearchQuery;
import org.apache.james.mailbox.model.SearchQuery;
@@ -49,13 +47,11 @@ import org.apache.james.mailbox.store.mail.MessageMapperFactory;
import org.apache.james.mailbox.store.mail.model.Mailbox;
import org.apache.james.mailbox.store.mail.model.MailboxMessage;
+import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMultimap;
-import com.google.common.collect.ImmutableMultimap.Builder;
-import com.google.common.collect.Multimap;
/**
* {@link MessageSearchIndex} which just fetch {@link MailboxMessage}'s from the {@link MessageMapper} and use {@link MessageSearcher}
@@ -102,25 +98,26 @@ public class SimpleMessageSearchIndex implements MessageSearchIndex {
}
@Override
- public Iterator<MessageUid> search(MailboxSession session, Mailbox mailbox, SearchQuery query) throws MailboxException {
+ public Iterator<MessageUid> search(MailboxSession session, final Mailbox mailbox, SearchQuery query) throws MailboxException {
Preconditions.checkArgument(session != null, "'session' is mandatory");
- return searchMultimap(session, ImmutableList.of(mailbox), query)
- .get(mailbox.getMailboxId())
+ return FluentIterable.from(searchResults(session, ImmutableList.of(mailbox), query))
+ .filter(isInMailbox(mailbox))
+ .transform(toMessageUid())
.iterator();
}
-
- private Multimap<MailboxId, MessageUid> searchMultimap(MailboxSession session, Iterable<Mailbox> mailboxes, SearchQuery query) throws MailboxException {
- Builder<MailboxId, MessageUid> multimap = ImmutableMultimap.builder();
+
+ private List<SearchResult> searchResults(MailboxSession session, Iterable<Mailbox> mailboxes, SearchQuery query) throws MailboxException {
+ ImmutableList.Builder<SearchResult> builder = ImmutableList.builder();
for (Mailbox mailbox: mailboxes) {
- multimap.putAll(searchMultimap(session, mailbox, query));
+ builder.addAll(searchResults(session, mailbox, query));
}
- return multimap.build();
+ return builder.build();
}
- private Multimap<MailboxId, MessageUid> searchMultimap(MailboxSession session, Mailbox mailbox, SearchQuery query) throws MailboxException {
+ private List<SearchResult> searchResults(MailboxSession session, Mailbox mailbox, SearchQuery query) throws MailboxException {
if (!isMatchingUser(session, mailbox)) {
- return ImmutableMultimap.of();
+ return ImmutableList.of();
}
MessageMapper mapper = messageMapperFactory.getMessageMapper(session);
@@ -145,11 +142,7 @@ public class SimpleMessageSearchIndex implements MessageSearchIndex {
hitSet.add(m);
}
}
-
- // MessageSearches does the filtering for us
- return ImmutableMultimap.<MailboxId, MessageUid>builder()
- .putAll(mailbox.getMailboxId(), ImmutableList.copyOf(new MessageSearches(hitSet.iterator(), query, session).iterator()))
- .build();
+ return ImmutableList.copyOf(new MessageSearches(hitSet.iterator(), query, session).iterator());
}
private boolean isMatchingUser(MailboxSession session, Mailbox mailbox) {
@@ -157,7 +150,7 @@ public class SimpleMessageSearchIndex implements MessageSearchIndex {
}
@Override
- public Map<MailboxId, Collection<MessageUid>> search(MailboxSession session, final MultimailboxesSearchQuery searchQuery) throws MailboxException {
+ public List<MessageId> search(MailboxSession session, final MultimailboxesSearchQuery searchQuery, long limit) throws MailboxException {
List<Mailbox> allUserMailboxes = mailboxMapperFactory.getMailboxMapper(session)
.findMailboxWithPathLike(new MailboxPath(session.getPersonalSpace(), session.getUser().getUserName(), WILDCARD));
FluentIterable<Mailbox> filteredMailboxes = FluentIterable.from(allUserMailboxes).filter(new Predicate<Mailbox>() {
@@ -167,8 +160,7 @@ public class SimpleMessageSearchIndex implements MessageSearchIndex {
}
});
if (searchQuery.getInMailboxes().isEmpty()) {
- return searchMultimap(session, filteredMailboxes, searchQuery.getSearchQuery())
- .asMap();
+ return getAsMessageIds(searchResults(session, filteredMailboxes, searchQuery.getSearchQuery()), limit);
}
List<Mailbox> queriedMailboxes = new ArrayList<Mailbox>();
for (Mailbox mailbox: filteredMailboxes) {
@@ -176,8 +168,41 @@ public class SimpleMessageSearchIndex implements MessageSearchIndex {
queriedMailboxes.add(mailbox);
}
}
- return searchMultimap(session, queriedMailboxes, searchQuery.getSearchQuery())
- .asMap();
+ return getAsMessageIds(searchResults(session, queriedMailboxes, searchQuery.getSearchQuery()), limit);
+ }
+
+ private List<MessageId> getAsMessageIds(List<SearchResult> temp, long limit) {
+ return FluentIterable.from(temp)
+ .transform(toMessageId())
+ .limit(Long.valueOf(limit).intValue())
+ .toList();
+ }
+
+ private Function<SearchResult, MessageId> toMessageId() {
+ return new Function<SearchResult, MessageId>() {
+ @Override
+ public MessageId apply(SearchResult input) {
+ return input.getMessageId();
+ }
+ };
+ }
+
+ private Function<SearchResult, MessageUid> toMessageUid() {
+ return new Function<SearchResult, MessageUid>() {
+ @Override
+ public MessageUid apply(SearchResult input) {
+ return input.getMessageUid();
+ }
+ };
+ }
+
+ private Predicate<SearchResult> isInMailbox(final Mailbox mailbox) {
+ return new Predicate<SearchResult>() {
+ @Override
+ public boolean apply(SearchResult input) {
+ return input.getMailboxId().equals(mailbox.getMailboxId());
+ }
+ };
}
}
http://git-wip-us.apache.org/repos/asf/james-project/blob/299addd9/mailbox/store/src/test/java/org/apache/james/mailbox/store/MessageBuilder.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/MessageBuilder.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/MessageBuilder.java
index c1cee99..59ec33b 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/MessageBuilder.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/MessageBuilder.java
@@ -25,6 +25,7 @@ import java.util.Map;
import javax.mail.Flags;
import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.model.MessageId;
import org.apache.james.mailbox.model.TestId;
import org.apache.james.mailbox.store.mail.model.DefaultMessageId;
import org.apache.james.mailbox.store.mail.model.MailboxMessage;
@@ -41,7 +42,11 @@ public class MessageBuilder {
public int lineNumber = 0;
public MailboxMessage build() throws Exception {
- return new SimpleMailboxMembership(new DefaultMessageId(), mailboxId, uid, -1, internalDate, size, flags, body, headers);
+ return build(new DefaultMessageId());
+ }
+
+ public MailboxMessage build(MessageId messageId) throws Exception {
+ return new SimpleMailboxMembership(messageId, mailboxId, uid, -1, internalDate, size, flags, body, headers);
}
public void header(String field, String value) {
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org