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 ad...@apache.org on 2017/09/08 20:14:49 UTC

[1/7] james-project git commit: JAMES-2137 Attachment text search capability is mandatory in JMAP

Repository: james-project
Updated Branches:
  refs/heads/master adad8aad9 -> 2c411e8b5


JAMES-2137 Attachment text search capability is mandatory in JMAP


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/f319cd39
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/f319cd39
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/f319cd39

Branch: refs/heads/master
Commit: f319cd39afbe0c60d720d996d91e79a130217e81
Parents: d76f8fc
Author: Antoine Duprat <ad...@linagora.com>
Authored: Tue Sep 5 14:41:15 2017 +0200
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Fri Sep 8 21:53:13 2017 +0200

----------------------------------------------------------------------
 .../apache/james/JamesCapabilitiesServerTest.java    | 15 +++++++++++++++
 .../main/java/org/apache/james/jmap/JMAPModule.java  |  2 ++
 2 files changed, 17 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/f319cd39/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesCapabilitiesServerTest.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesCapabilitiesServerTest.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesCapabilitiesServerTest.java
index 5fee8a5..cedaccb 100644
--- a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesCapabilitiesServerTest.java
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesCapabilitiesServerTest.java
@@ -116,6 +116,21 @@ public class JamesCapabilitiesServerTest {
     }
     
     @Test
+    public void startShouldFailWhenNoAttachmentSearchCapability() throws Exception {
+        MailboxManager mailboxManager = mock(MailboxManager.class);
+        when(mailboxManager.getSupportedMailboxCapabilities())
+            .thenReturn(EnumSet.allOf(MailboxManager.MailboxCapabilities.class));
+        when(mailboxManager.getSupportedMessageCapabilities())
+            .thenReturn(EnumSet.allOf(MailboxManager.MessageCapabilities.class));
+        when(mailboxManager.getSupportedSearchCapabilities())
+            .thenReturn(EnumSet.complementOf(EnumSet.of(MailboxManager.SearchCapabilities.Attachment)));
+
+        server = createCassandraJamesServer(mailboxManager);
+
+        assertThatThrownBy(() -> server.start()).isInstanceOf(IllegalArgumentException.class);
+    }
+    
+    @Test
     public void startShouldFailWhenNoMultimailboxSearchCapability() throws Exception {
         MailboxManager mailboxManager = mock(MailboxManager.class);
         when(mailboxManager.getSupportedMailboxCapabilities())

http://git-wip-us.apache.org/repos/asf/james-project/blob/f319cd39/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java
index a04a866..88de16a 100644
--- a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java
+++ b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java
@@ -153,6 +153,8 @@ public class JMAPModule extends AbstractModule {
                     "Multimailbox search in MailboxManager is required by JMAP Module");
             Preconditions.checkArgument(searchCapabilities.contains(MailboxManager.SearchCapabilities.Text),
                     "Text support in MailboxManager is required by JMAP Module");
+            Preconditions.checkArgument(searchCapabilities.contains(MailboxManager.SearchCapabilities.Attachment),
+                    "Attachment Search support in MailboxManager is required by JMAP Module");
         }
 
         @Override


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[5/7] james-project git commit: JAMES-2137 Introduce FullText search capability

Posted by ad...@apache.org.
JAMES-2137 Introduce FullText search capability


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/ad33cef8
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/ad33cef8
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/ad33cef8

Branch: refs/heads/master
Commit: ad33cef8f4ad0ac0feae8a4a323690871f1e311c
Parents: f319cd3
Author: Antoine Duprat <ad...@linagora.com>
Authored: Wed Sep 6 11:18:40 2017 +0200
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Fri Sep 8 21:56:59 2017 +0200

----------------------------------------------------------------------
 .../apache/james/mailbox/MailboxManager.java    |  1 +
 ...lasticSearchListeningMessageSearchIndex.java |  2 +-
 .../search/SimpleMessageSearchIndexTest.java    |  9 ++---
 .../store/search/SimpleMessageSearchIndex.java  |  2 +-
 .../search/AbstractMessageSearchIndexTest.java  | 41 ++++++++++++++------
 .../james/JamesCapabilitiesServerTest.java      |  4 +-
 .../java/org/apache/james/jmap/JMAPModule.java  |  4 +-
 7 files changed, 40 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/ad33cef8/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 f0b3eb1..0a34607 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
@@ -103,6 +103,7 @@ public interface MailboxManager extends RequestAware, MailboxListenerSupport {
          *  From, To, Cc, Bcc, Subjects, textBody & htmlBody
          */
         Text,
+        FullText,
         Attachment
     }
     

http://git-wip-us.apache.org/repos/asf/james-project/blob/ad33cef8/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 34c0d2b..f36ffdb 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
@@ -78,7 +78,7 @@ public class ElasticSearchListeningMessageSearchIndex extends ListeningMessageSe
 
     @Override
     public EnumSet<SearchCapabilities> getSupportedCapabilities() {
-        return EnumSet.of(SearchCapabilities.MultimailboxSearch, SearchCapabilities.Text, SearchCapabilities.Attachment);
+        return EnumSet.of(SearchCapabilities.MultimailboxSearch, SearchCapabilities.Text, SearchCapabilities.FullText, SearchCapabilities.Attachment);
     }
     
     @Override

http://git-wip-us.apache.org/repos/asf/james-project/blob/ad33cef8/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndexTest.java
----------------------------------------------------------------------
diff --git a/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndexTest.java b/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndexTest.java
index 9d5f2ba..da2c267 100644
--- a/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndexTest.java
+++ b/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndexTest.java
@@ -228,7 +228,7 @@ public class SimpleMessageSearchIndexTest extends AbstractMessageSearchIndexTest
 
     @Ignore
     @Override
-    public void searchWithFullTextShouldReturnMailsWhenTextBodyMatchesAndNonContinuousWords() throws Exception {
+    public void searchWithTextShouldReturnMailsWhenTextBodyMatchesAndNonContinuousWords() throws Exception {
     }
 
     @Ignore
@@ -238,17 +238,16 @@ public class SimpleMessageSearchIndexTest extends AbstractMessageSearchIndexTest
 
     @Ignore
     @Override
-    public void searchWithFullTextShouldReturnMailsWhenHtmlBodyMatchesAndNonContinuousWords() throws Exception {
+    public void searchWithTextShouldReturnMailsWhenHtmlBodyMatchesAndNonContinuousWords() throws Exception {
     }
 
     @Ignore
     @Override
-    public void searchWithFullTextShouldReturnMailsWhenTextBodyWithExtraUnindexedWords() throws Exception {
+    public void searchWithTextShouldReturnMailsWhenTextBodyWithExtraUnindexedWords() throws Exception {
     }
 
     @Ignore
     @Override
-    public void searchWithFullTextShouldReturnMailsWhenHtmlBodyMatchesWithStemming() throws Exception {
+    public void searchWithTextShouldReturnMailsWhenHtmlBodyMatchesWithStemming() throws Exception {
     }
-
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/ad33cef8/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 9a301b4..6388fff 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
@@ -77,7 +77,7 @@ public class SimpleMessageSearchIndex implements MessageSearchIndex {
     
     @Override
     public EnumSet<SearchCapabilities> getSupportedCapabilities() {
-        return EnumSet.of(SearchCapabilities.MultimailboxSearch, SearchCapabilities.Text, SearchCapabilities.Attachment);
+        return EnumSet.of(SearchCapabilities.MultimailboxSearch, SearchCapabilities.Text, SearchCapabilities.FullText, SearchCapabilities.Attachment);
     }
     
     /**

http://git-wip-us.apache.org/repos/asf/james-project/blob/ad33cef8/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/AbstractMessageSearchIndexTest.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/AbstractMessageSearchIndexTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/AbstractMessageSearchIndexTest.java
index a2686f3..9fc2062 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/AbstractMessageSearchIndexTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/AbstractMessageSearchIndexTest.java
@@ -999,7 +999,7 @@ public abstract class AbstractMessageSearchIndexTest {
     }
 
     @Test
-    public void searchWithFullTextShouldReturnNoMailWhenNotMatching() throws Exception {
+    public void searchWithTextShouldReturnNoMailWhenNotMatching() throws Exception {
         Assume.assumeTrue(storeMailboxManager.getSupportedSearchCapabilities().contains(MailboxManager.SearchCapabilities.Text));
         SearchQuery searchQuery = new SearchQuery(SearchQuery.textContains("unmatching"));
 
@@ -1008,7 +1008,7 @@ public abstract class AbstractMessageSearchIndexTest {
     }
 
     @Test
-    public void searchWithFullTextShouldReturnMailsWhenFromMatches() throws Exception {
+    public void searchWithTextShouldReturnMailsWhenFromMatches() throws Exception {
         Assume.assumeTrue(storeMailboxManager.getSupportedSearchCapabilities().contains(MailboxManager.SearchCapabilities.Text));
         SearchQuery searchQuery = new SearchQuery(SearchQuery.textContains("spam.minet.net"));
 
@@ -1017,7 +1017,7 @@ public abstract class AbstractMessageSearchIndexTest {
     }
 
     @Test
-    public void searchWithFullTextShouldReturnMailsWhenToMatches() throws Exception {
+    public void searchWithTextShouldReturnMailsWhenToMatches() throws Exception {
         Assume.assumeTrue(storeMailboxManager.getSupportedSearchCapabilities().contains(MailboxManager.SearchCapabilities.Text));
         SearchQuery searchQuery = new SearchQuery(SearchQuery.textContains("listes.minet.net"));
 
@@ -1026,7 +1026,7 @@ public abstract class AbstractMessageSearchIndexTest {
     }
 
     @Test
-    public void searchWithFullTextShouldReturnMailsWhenCcMatches() throws Exception {
+    public void searchWithTextShouldReturnMailsWhenCcMatches() throws Exception {
         Assume.assumeTrue(storeMailboxManager.getSupportedSearchCapabilities().contains(MailboxManager.SearchCapabilities.Text));
         SearchQuery searchQuery = new SearchQuery(SearchQuery.textContains("abc.org"));
 
@@ -1035,7 +1035,7 @@ public abstract class AbstractMessageSearchIndexTest {
     }
 
     @Test
-    public void searchWithFullTextShouldReturnMailsWhenBccMatches() throws Exception {
+    public void searchWithTextShouldReturnMailsWhenBccMatches() throws Exception {
         Assume.assumeTrue(storeMailboxManager.getSupportedSearchCapabilities().contains(MailboxManager.SearchCapabilities.Text));
         SearchQuery searchQuery = new SearchQuery(SearchQuery.textContains("any.com"));
 
@@ -1044,7 +1044,7 @@ public abstract class AbstractMessageSearchIndexTest {
     }
 
     @Test
-    public void searchWithFullTextShouldReturnMailsWhenTextBodyMatches() throws Exception {
+    public void searchWithTextShouldReturnMailsWhenTextBodyMatches() throws Exception {
         Assume.assumeTrue(storeMailboxManager.getSupportedSearchCapabilities().contains(MailboxManager.SearchCapabilities.Text));
         SearchQuery searchQuery = new SearchQuery(SearchQuery.textContains("reviewing work"));
 
@@ -1054,7 +1054,7 @@ public abstract class AbstractMessageSearchIndexTest {
     }
 
     @Test
-    public void searchWithFullTextShouldReturnMailsWhenTextBodyMatchesAndNonContinuousWords() throws Exception {
+    public void searchWithTextShouldReturnMailsWhenTextBodyMatchesAndNonContinuousWords() throws Exception {
         Assume.assumeTrue(storeMailboxManager.getSupportedSearchCapabilities().contains(MailboxManager.SearchCapabilities.Text));
         SearchQuery searchQuery = new SearchQuery(SearchQuery.textContains("reviewing feature"));
         // 2: text/plain contains: "Issue Type: New Feature"
@@ -1065,7 +1065,7 @@ public abstract class AbstractMessageSearchIndexTest {
     }
 
     @Test
-    public void searchWithFullTextShouldReturnMailsWhenTextBodyMatchesInsensitiveWords() throws Exception {
+    public void searchWithTextShouldReturnMailsWhenTextBodyMatchesInsensitiveWords() throws Exception {
         Assume.assumeTrue(storeMailboxManager.getSupportedSearchCapabilities().contains(MailboxManager.SearchCapabilities.Text));
         SearchQuery searchQuery = new SearchQuery(SearchQuery.textContains("reVieWing"));
         // text/plain contains: "We are reviewing work I did for this feature."
@@ -1075,7 +1075,7 @@ public abstract class AbstractMessageSearchIndexTest {
     }
 
     @Test
-    public void searchWithFullTextShouldReturnMailsWhenTextBodyWithExtraUnindexedWords() throws Exception {
+    public void searchWithTextShouldReturnMailsWhenTextBodyWithExtraUnindexedWords() throws Exception {
         Assume.assumeTrue(storeMailboxManager.getSupportedSearchCapabilities().contains(MailboxManager.SearchCapabilities.Text));
         SearchQuery searchQuery = new SearchQuery(SearchQuery.textContains("a reviewing of the work"));
         // text/plain contains: "We are reviewing work I did for this feature."
@@ -1085,7 +1085,7 @@ public abstract class AbstractMessageSearchIndexTest {
     }
 
     @Test
-    public void searchWithFullTextShouldReturnMailsWhenHtmlBodyMatches() throws Exception {
+    public void searchWithTextShouldReturnMailsWhenHtmlBodyMatches() throws Exception {
         Assume.assumeTrue(storeMailboxManager.getSupportedSearchCapabilities().contains(MailboxManager.SearchCapabilities.Text));
         SearchQuery searchQuery = new SearchQuery(SearchQuery.textContains("contains a banana"));
         // text/html contains: "This is a mail with beautifull html content which contains a banana."
@@ -1095,7 +1095,7 @@ public abstract class AbstractMessageSearchIndexTest {
     }
 
     @Test
-    public void searchWithFullTextShouldReturnMailsWhenHtmlBodyMatchesWithStemming() throws Exception {
+    public void searchWithTextShouldReturnMailsWhenHtmlBodyMatchesWithStemming() throws Exception {
         Assume.assumeTrue(storeMailboxManager.getSupportedSearchCapabilities().contains(MailboxManager.SearchCapabilities.Text));
         SearchQuery searchQuery = new SearchQuery(SearchQuery.textContains("contain banana"));
 
@@ -1104,7 +1104,7 @@ public abstract class AbstractMessageSearchIndexTest {
     }
 
     @Test
-    public void searchWithFullTextShouldReturnMailsWhenHtmlBodyMatchesAndNonContinuousWords() throws Exception {
+    public void searchWithTextShouldReturnMailsWhenHtmlBodyMatchesAndNonContinuousWords() throws Exception {
         Assume.assumeTrue(storeMailboxManager.getSupportedSearchCapabilities().contains(MailboxManager.SearchCapabilities.Text));
         SearchQuery searchQuery = new SearchQuery(SearchQuery.textContains("beautifull banana"));
 
@@ -1113,6 +1113,23 @@ public abstract class AbstractMessageSearchIndexTest {
     }
 
     @Test
+    public void searchWithFulTextShouldReturnMailsWhenToAndBodyAndAttachmentMatches() throws Exception {
+        Assume.assumeTrue(storeMailboxManager.getSupportedSearchCapabilities().contains(MailboxManager.SearchCapabilities.FullText));
+        ComposedMessageId messageWithBeautifulBananaAsTextAttachment = myFolderMessageManager.appendMessage(
+                ClassLoader.getSystemResourceAsStream("eml/emailWithTextAttachment.eml"),
+                new Date(1404252000000L),
+                session,
+                RECENT,
+                new Flags());
+        await();
+
+        SearchQuery searchQuery = new SearchQuery(SearchQuery.mailContains("User message banana"));
+
+        assertThat(messageSearchIndex.search(session, mailbox2, searchQuery))
+            .containsExactly(messageWithBeautifulBananaAsTextAttachment.getUid());
+    }
+
+    @Test
     public void searchWithTextAttachmentShouldReturnMailsWhenAttachmentContentMatches() throws Exception {
         Assume.assumeTrue(storeMailboxManager.getSupportedSearchCapabilities().contains(MailboxManager.SearchCapabilities.Attachment));
         ComposedMessageId messageWithBeautifulBananaAsTextAttachment = myFolderMessageManager.appendMessage(

http://git-wip-us.apache.org/repos/asf/james-project/blob/ad33cef8/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesCapabilitiesServerTest.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesCapabilitiesServerTest.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesCapabilitiesServerTest.java
index cedaccb..e0f447c 100644
--- a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesCapabilitiesServerTest.java
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesCapabilitiesServerTest.java
@@ -101,14 +101,14 @@ public class JamesCapabilitiesServerTest {
     }
     
     @Test
-    public void startShouldFailWhenNoTextCapability() throws Exception {
+    public void startShouldFailWhenNoFullTextCapability() throws Exception {
         MailboxManager mailboxManager = mock(MailboxManager.class);
         when(mailboxManager.getSupportedMailboxCapabilities())
             .thenReturn(EnumSet.allOf(MailboxManager.MailboxCapabilities.class));
         when(mailboxManager.getSupportedMessageCapabilities())
             .thenReturn(EnumSet.allOf(MailboxManager.MessageCapabilities.class));
         when(mailboxManager.getSupportedSearchCapabilities())
-            .thenReturn(EnumSet.complementOf(EnumSet.of(MailboxManager.SearchCapabilities.Text)));
+            .thenReturn(EnumSet.complementOf(EnumSet.of(MailboxManager.SearchCapabilities.FullText)));
 
         server = createCassandraJamesServer(mailboxManager);
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/ad33cef8/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java
index 88de16a..9150680 100644
--- a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java
+++ b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java
@@ -151,8 +151,8 @@ public class JMAPModule extends AbstractModule {
             EnumSet<SearchCapabilities> searchCapabilities = mailboxManager.getSupportedSearchCapabilities();
             Preconditions.checkArgument(searchCapabilities.contains(MailboxManager.SearchCapabilities.MultimailboxSearch),
                     "Multimailbox search in MailboxManager is required by JMAP Module");
-            Preconditions.checkArgument(searchCapabilities.contains(MailboxManager.SearchCapabilities.Text),
-                    "Text support in MailboxManager is required by JMAP Module");
+            Preconditions.checkArgument(searchCapabilities.contains(MailboxManager.SearchCapabilities.FullText),
+                    "FullText support in MailboxManager is required by JMAP Module");
             Preconditions.checkArgument(searchCapabilities.contains(MailboxManager.SearchCapabilities.Attachment),
                     "Attachment Search support in MailboxManager is required by JMAP Module");
         }


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[4/7] james-project git commit: JAMES-2137 Sanitize and test PDFTextExtractor

Posted by ad...@apache.org.
JAMES-2137 Sanitize and test PDFTextExtractor


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/11e336a3
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/11e336a3
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/11e336a3

Branch: refs/heads/master
Commit: 11e336a32c23e7dad43ef4d373d9df04c03c6935
Parents: ad33cef
Author: benwa <bt...@linagora.com>
Authored: Fri Sep 8 10:03:38 2017 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Fri Sep 8 21:56:59 2017 +0200

----------------------------------------------------------------------
 .../mailbox/store/search/PDFTextExtractor.java  |  26 +++----
 .../store/search/PDFTextExtractorTest.java      |  75 +++++++++++++++++++
 .../scanning-search/src/test/resources/pdf.pdf  | Bin 0 -> 14707 bytes
 .../mailbox/store/search/MessageSearches.java   |  21 ++++--
 4 files changed, 101 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/11e336a3/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/PDFTextExtractor.java
----------------------------------------------------------------------
diff --git a/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/PDFTextExtractor.java b/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/PDFTextExtractor.java
index 1a5b5eb..1e21b7e 100644
--- a/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/PDFTextExtractor.java
+++ b/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/PDFTextExtractor.java
@@ -28,36 +28,32 @@ import org.apache.pdfbox.pdmodel.PDDocument;
 import org.apache.pdfbox.text.PDFTextStripper;
 
 import com.google.common.base.Charsets;
+import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableMap;
 
 public class PDFTextExtractor implements TextExtractor {
 
-    private static final String PDF_TYPE = "application/pdf";
+    static final String PDF_TYPE = "application/pdf";
 
     @Override
     public ParsedContent extractContent(InputStream inputStream, String contentType) throws Exception {
+        Preconditions.checkNotNull(inputStream);
+        Preconditions.checkNotNull(contentType);
+
         if (isPDF(contentType)) {
             return extractTextFromPDF(inputStream);
         }
-        try {
-            return new ParsedContent(IOUtils.toString(inputStream, Charsets.UTF_8), ImmutableMap.of());
-        } catch (IOException e) {
-            return new ParsedContent(null, ImmutableMap.of());
-        }
+        return new ParsedContent(IOUtils.toString(inputStream, Charsets.UTF_8), ImmutableMap.of());
     }
 
     private boolean isPDF(String contentType) {
         return contentType.equals(PDF_TYPE);
     }
 
-    private ParsedContent extractTextFromPDF(InputStream inputStream) {
-        try {
-            return new ParsedContent(
-                    new PDFTextStripper().getText(
-                            PDDocument.load(inputStream)),
-                    ImmutableMap.of());
-        } catch (IOException e) {
-            return new ParsedContent(null, ImmutableMap.of());
-        }
+    private ParsedContent extractTextFromPDF(InputStream inputStream) throws IOException {
+        return new ParsedContent(
+            new PDFTextStripper().getText(
+                PDDocument.load(inputStream)),
+            ImmutableMap.of());
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/11e336a3/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/PDFTextExtractorTest.java
----------------------------------------------------------------------
diff --git a/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/PDFTextExtractorTest.java b/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/PDFTextExtractorTest.java
new file mode 100644
index 0000000..df52009
--- /dev/null
+++ b/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/PDFTextExtractorTest.java
@@ -0,0 +1,75 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.store.search;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class PDFTextExtractorTest {
+
+    private PDFTextExtractor testee;
+
+    @Before
+    public void setUp() {
+        testee = new PDFTextExtractor();
+    }
+
+    @Test
+    public void extractContentShouldThrowWhenNullInputStream() throws Exception {
+        assertThatThrownBy(() ->
+            testee.extractContent(null, "any/any"))
+            .isInstanceOf(NullPointerException.class);
+    }
+
+    @Test
+    public void extractContentShouldThrowWhenNullContentType() throws Exception {
+        InputStream inputStream = new ByteArrayInputStream("content".getBytes(StandardCharsets.UTF_8));
+        assertThatThrownBy(() -> testee.extractContent(inputStream, null))
+            .isInstanceOf(NullPointerException.class);
+    }
+
+    @Test
+    public void extractContentShouldExtractPlainText() throws Exception {
+        String content = "content";
+        InputStream inputStream = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8));
+
+        assertThat(testee.extractContent(inputStream, "text/plain")
+            .getTextualContent())
+            .isEqualTo(content);
+    }
+
+    @Test
+    public void extractContentShouldExtractPDF() throws Exception {
+        String content = "Little PDF";
+        InputStream inputStream = ClassLoader.getSystemResourceAsStream("pdf.pdf");
+
+        assertThat(testee.extractContent(inputStream, PDFTextExtractor.PDF_TYPE)
+            .getTextualContent())
+            .contains(content);
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/11e336a3/mailbox/scanning-search/src/test/resources/pdf.pdf
----------------------------------------------------------------------
diff --git a/mailbox/scanning-search/src/test/resources/pdf.pdf b/mailbox/scanning-search/src/test/resources/pdf.pdf
new file mode 100644
index 0000000..5388d4a
Binary files /dev/null and b/mailbox/scanning-search/src/test/resources/pdf.pdf differ

http://git-wip-us.apache.org/repos/asf/james-project/blob/11e336a3/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 d34c522..dc35559 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
@@ -35,13 +35,13 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Optional;
 import java.util.TimeZone;
+import java.util.stream.Stream;
 
 import javax.mail.Flags;
 
 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.extractor.ParsedContent;
 import org.apache.james.mailbox.extractor.TextExtractor;
 import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.MessageAttachment;
@@ -77,9 +77,7 @@ import org.apache.james.mime4j.utils.search.MessageMatcher;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.github.fge.lambdas.Throwing;
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Lists;
 
 /**
@@ -252,12 +250,23 @@ public class MessageSearches implements Iterable<SimpleMessageSearchIndex.Search
     private boolean isInAttachments(String value, List<MessageAttachment> attachments) {
         return attachments.stream()
             .map(MessageAttachment::getAttachment)
-            .map(Throwing.function((Attachment attachment) -> textExtractor.extractContent(attachment.getStream(), attachment.getType()))
-                    .orReturn(new ParsedContent(null, ImmutableMap.of())))
-            .map(ParsedContent::getTextualContent)
+            .flatMap(this::toAttachmentContent)
             .anyMatch(string -> string.contains(value));
     }
 
+    private Stream<String> toAttachmentContent(Attachment attachment) {
+        try {
+            return Stream.of(textExtractor
+                .extractContent(
+                    attachment.getStream(),
+                    attachment.getType())
+                .getTextualContent());
+        } catch (Exception e) {
+            LOGGER.error("Error while parsing attachment content", e);
+            return Stream.of();
+        }
+    }
+
     private InputStream textHeaders(MailboxMessage message) throws MimeIOException, IOException {
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         new DefaultMessageWriter()


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[7/7] james-project git commit: JAMES-2133 Avoid cassandra test containers to cluster together

Posted by ad...@apache.org.
JAMES-2133 Avoid cassandra test containers to cluster together


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/2c411e8b
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/2c411e8b
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/2c411e8b

Branch: refs/heads/master
Commit: 2c411e8b5bb8d304f5b2775f0e28e83e9ccf9859
Parents: 5bd1604
Author: benwa <bt...@linagora.com>
Authored: Thu Sep 7 16:57:17 2017 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Fri Sep 8 21:58:06 2017 +0200

----------------------------------------------------------------------
 .../org/apache/james/backends/cassandra/DockerCassandraRule.java | 4 ++++
 1 file changed, 4 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/2c411e8b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandraRule.java
----------------------------------------------------------------------
diff --git a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandraRule.java b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandraRule.java
index 2579a14..67ce0b4 100644
--- a/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandraRule.java
+++ b/backends-common/cassandra/src/test/java/org/apache/james/backends/cassandra/DockerCassandraRule.java
@@ -19,6 +19,8 @@
 
 package org.apache.james.backends.cassandra;
 
+import java.util.UUID;
+
 import org.apache.commons.lang3.RandomStringUtils;
 import org.junit.rules.TestRule;
 import org.junit.runner.Description;
@@ -80,6 +82,8 @@ public class DockerCassandraRule implements TestRule {
                         .run("echo \"JVM_OPTS=\\\"\\$JVM_OPTS -Dcassandra.skip_wait_for_gossip_to_settle=0\\\"\" >> " + CASSANDRA_ENV)
                         //make sure commit log disk flush won't happen
                         .run("sed -i -e \"s/commitlog_sync_period_in_ms: 10000/commitlog_sync_period_in_ms: 9999999/\" " + CASSANDRA_YAML)
+                        //Cassandra nodes should not cluster together
+                        .run("sed -i -e \"s/cluster_name: 'Test Cluster'/cluster_name: 'Test Cluster " + UUID.randomUUID() + "'/\" " + CASSANDRA_YAML)
                         //auto_bootstrap should be useless when no existing data
                         .run("echo auto_bootstrap: false >> " + CASSANDRA_YAML)
                         .run("echo \"-Xms1500M\" >> " + JVM_OPTIONS)


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[2/7] james-project git commit: JAMES-2137 Provide a method for searching in attachments and associated capability

Posted by ad...@apache.org.
http://git-wip-us.apache.org/repos/asf/james-project/blob/d76f8fc4/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsTest.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsTest.java
index efb6b80..2249dae 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsTest.java
@@ -26,12 +26,14 @@ import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Collection;
 import java.util.Date;
+import java.util.Iterator;
 import java.util.Locale;
 import java.util.TimeZone;
 
 import javax.mail.Flags;
 
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.extractor.TextExtractor;
 import org.apache.james.mailbox.model.SearchQuery;
 import org.apache.james.mailbox.model.SearchQuery.AddressType;
 import org.apache.james.mailbox.model.SearchQuery.DateResolution;
@@ -61,6 +63,8 @@ public class SearchUtilsTest {
     MessageBuilder builder;
 
     Collection<MessageUid> recent;
+
+    private MessageSearches messageSearches;
     
     private Calendar getGMT() {
         return Calendar.getInstance(TimeZone.getTimeZone("GMT"), Locale.UK);
@@ -76,19 +80,24 @@ public class SearchUtilsTest {
         recent = new ArrayList<>();
         builder = new MessageBuilder();
         builder.uid = MessageUid.of(1009);
+        
+        Iterator<MailboxMessage> messages = null;
+        SearchQuery query = null; 
+        TextExtractor textExtractor = null;
+        messageSearches = new MessageSearches(messages, query, textExtractor);
     }
     
     @Test
     public void testMatchSizeLessThan() throws Exception {
         builder.size = SIZE;
         MailboxMessage row = builder.build();
-        assertFalse(new MessageSearches().isMatch(SearchQuery.sizeLessThan(SIZE - 1), row,
+        assertFalse(messageSearches.isMatch(SearchQuery.sizeLessThan(SIZE - 1), row,
                 recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.sizeLessThan(SIZE), row,
+        assertFalse(messageSearches.isMatch(SearchQuery.sizeLessThan(SIZE), row,
                 recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.sizeLessThan(SIZE + 1), row,
+        assertTrue(messageSearches.isMatch(SearchQuery.sizeLessThan(SIZE + 1), row,
                 recent));
-        assertTrue(new MessageSearches().isMatch(
+        assertTrue(messageSearches.isMatch(
                 SearchQuery.sizeLessThan(Integer.MAX_VALUE), row, recent));
     }
 
@@ -96,13 +105,13 @@ public class SearchUtilsTest {
     public void testMatchSizeMoreThan() throws Exception {
         builder.size = SIZE;
         MailboxMessage row = builder.build();
-        assertTrue(new MessageSearches().isMatch(SearchQuery.sizeGreaterThan(SIZE - 1), row,
+        assertTrue(messageSearches.isMatch(SearchQuery.sizeGreaterThan(SIZE - 1), row,
                 recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.sizeGreaterThan(SIZE), row,
+        assertFalse(messageSearches.isMatch(SearchQuery.sizeGreaterThan(SIZE), row,
                 recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.sizeGreaterThan(SIZE + 1),
+        assertFalse(messageSearches.isMatch(SearchQuery.sizeGreaterThan(SIZE + 1),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery
+        assertFalse(messageSearches.isMatch(SearchQuery
                 .sizeGreaterThan(Integer.MAX_VALUE), row, recent));
     }
 
@@ -110,12 +119,12 @@ public class SearchUtilsTest {
     public void testMatchSizeEquals() throws Exception {
         builder.size = SIZE;
         MailboxMessage row = builder.build();
-        assertFalse(new MessageSearches().isMatch(SearchQuery.sizeEquals(SIZE - 1), row,
+        assertFalse(messageSearches.isMatch(SearchQuery.sizeEquals(SIZE - 1), row,
                 recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.sizeEquals(SIZE), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.sizeEquals(SIZE + 1), row,
+        assertTrue(messageSearches.isMatch(SearchQuery.sizeEquals(SIZE), row, recent));
+        assertFalse(messageSearches.isMatch(SearchQuery.sizeEquals(SIZE + 1), row,
                 recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.sizeEquals(Integer.MAX_VALUE),
+        assertFalse(messageSearches.isMatch(SearchQuery.sizeEquals(Integer.MAX_VALUE),
                 row, recent));
     }
 
@@ -123,15 +132,15 @@ public class SearchUtilsTest {
     public void testMatchInternalDateEquals() throws Exception {
         builder.internalDate = SUN_SEP_9TH_2001;
         MailboxMessage row = builder.build();
-        assertFalse(new MessageSearches().isMatch(SearchQuery.internalDateOn(getDate(9, 9, 2000), DateResolution.Day),
+        assertFalse(messageSearches.isMatch(SearchQuery.internalDateOn(getDate(9, 9, 2000), DateResolution.Day),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.internalDateOn(getDate(8, 9, 2001), DateResolution.Day),
+        assertFalse(messageSearches.isMatch(SearchQuery.internalDateOn(getDate(8, 9, 2001), DateResolution.Day),
                 row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.internalDateOn(getDate(9, 9, 2001), DateResolution.Day),
+        assertTrue(messageSearches.isMatch(SearchQuery.internalDateOn(getDate(9, 9, 2001), DateResolution.Day),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.internalDateOn(getDate(10, 9, 2001), DateResolution.Day),
+        assertFalse(messageSearches.isMatch(SearchQuery.internalDateOn(getDate(10, 9, 2001), DateResolution.Day),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.internalDateOn(getDate(9, 9, 2002), DateResolution.Day),
+        assertFalse(messageSearches.isMatch(SearchQuery.internalDateOn(getDate(9, 9, 2002), DateResolution.Day),
                 row, recent));
     }
 
@@ -140,15 +149,15 @@ public class SearchUtilsTest {
     public void testMatchInternalDateBefore() throws Exception {
         builder.internalDate = SUN_SEP_9TH_2001;
         MailboxMessage row = builder.build();
-        assertFalse(new MessageSearches().isMatch(
+        assertFalse(messageSearches.isMatch(
                 SearchQuery.internalDateBefore(getDate(9, 9, 2000), DateResolution.Day), row, recent));
-        assertFalse(new MessageSearches().isMatch(
+        assertFalse(messageSearches.isMatch(
                 SearchQuery.internalDateBefore(getDate(8, 9, 2001), DateResolution.Day), row, recent));
-        assertFalse(new MessageSearches().isMatch(
+        assertFalse(messageSearches.isMatch(
                 SearchQuery.internalDateBefore(getDate(9, 9, 2001), DateResolution.Day), row, recent));
-        assertTrue(new MessageSearches().isMatch(
+        assertTrue(messageSearches.isMatch(
                 SearchQuery.internalDateBefore(getDate(10, 9, 2001), DateResolution.Day), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.internalDateBefore(getDate(9, 9, 2002), DateResolution.Day),
+        assertTrue(messageSearches.isMatch(SearchQuery.internalDateBefore(getDate(9, 9, 2002), DateResolution.Day),
                 row, recent));
     }
 
@@ -156,15 +165,15 @@ public class SearchUtilsTest {
     public void testMatchInternalDateAfter() throws Exception {
         builder.internalDate = SUN_SEP_9TH_2001;
         MailboxMessage row = builder.build();
-        assertTrue(new MessageSearches().isMatch(SearchQuery.internalDateAfter(getDate(9, 9, 2000), DateResolution.Day),
+        assertTrue(messageSearches.isMatch(SearchQuery.internalDateAfter(getDate(9, 9, 2000), DateResolution.Day),
                 row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.internalDateAfter(getDate(8, 9, 2001), DateResolution.Day),
+        assertTrue(messageSearches.isMatch(SearchQuery.internalDateAfter(getDate(8, 9, 2001), DateResolution.Day),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.internalDateAfter(getDate(9, 9, 2001), DateResolution.Day),
+        assertFalse(messageSearches.isMatch(SearchQuery.internalDateAfter(getDate(9, 9, 2001), DateResolution.Day),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(
+        assertFalse(messageSearches.isMatch(
                 SearchQuery.internalDateAfter(getDate(10, 9, 2001), DateResolution.Day), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.internalDateAfter(getDate(9, 9, 2002), DateResolution.Day),
+        assertFalse(messageSearches.isMatch(SearchQuery.internalDateAfter(getDate(9, 9, 2002), DateResolution.Day),
                 row, recent));
     }
 
@@ -172,17 +181,17 @@ public class SearchUtilsTest {
     public void testMatchHeaderDateAfter() throws Exception {
         builder.header(DATE_FIELD, RFC822_SUN_SEP_9TH_2001);
         MailboxMessage row = builder.build();
-        assertTrue(new MessageSearches().isMatch(SearchQuery.headerDateAfter(DATE_FIELD, getDate(9,
+        assertTrue(messageSearches.isMatch(SearchQuery.headerDateAfter(DATE_FIELD, getDate(9,
                 9, 2000), DateResolution.Day), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.headerDateAfter(DATE_FIELD, getDate(8,
+        assertTrue(messageSearches.isMatch(SearchQuery.headerDateAfter(DATE_FIELD, getDate(8,
                 9, 2001), DateResolution.Day), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateAfter(DATE_FIELD, getDate(9,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateAfter(DATE_FIELD, getDate(9,
                 9, 2001), DateResolution.Day), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateAfter(DATE_FIELD,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateAfter(DATE_FIELD,
                 getDate(10, 9, 2001), DateResolution.Day), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateAfter(DATE_FIELD, getDate(9,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateAfter(DATE_FIELD, getDate(9,
                 9, 2002), DateResolution.Day), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateAfter("BOGUS", getDate(9, 9,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateAfter("BOGUS", getDate(9, 9,
                 2001), DateResolution.Day), row, recent));
     }
 
@@ -190,17 +199,17 @@ public class SearchUtilsTest {
     public void testShouldMatchCapsHeaderDateAfter() throws Exception {
         builder.header(DATE_FIELD.toUpperCase(Locale.US), RFC822_SUN_SEP_9TH_2001);
         MailboxMessage row = builder.build();
-        assertTrue(new MessageSearches().isMatch(SearchQuery.headerDateAfter(DATE_FIELD, getDate(9,
+        assertTrue(messageSearches.isMatch(SearchQuery.headerDateAfter(DATE_FIELD, getDate(9,
                 9, 2000), DateResolution.Day), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.headerDateAfter(DATE_FIELD, getDate(8,
+        assertTrue(messageSearches.isMatch(SearchQuery.headerDateAfter(DATE_FIELD, getDate(8,
                 9, 2001), DateResolution.Day), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateAfter(DATE_FIELD, getDate(9,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateAfter(DATE_FIELD, getDate(9,
                 9, 2001), DateResolution.Day), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateAfter(DATE_FIELD,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateAfter(DATE_FIELD,
                 getDate(10, 9, 2001), DateResolution.Day), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateAfter(DATE_FIELD, getDate(9,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateAfter(DATE_FIELD, getDate(9,
                 9, 2002), DateResolution.Day), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateAfter("BOGUS", getDate(9, 9,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateAfter("BOGUS", getDate(9, 9,
                 2001), DateResolution.Day), row, recent));
     }
 
@@ -208,17 +217,17 @@ public class SearchUtilsTest {
     public void testShouldMatchLowersHeaderDateAfter() throws Exception {
         builder.header(DATE_FIELD.toLowerCase(Locale.US), RFC822_SUN_SEP_9TH_2001);
         MailboxMessage row = builder.build();
-        assertTrue(new MessageSearches().isMatch(SearchQuery.headerDateAfter(DATE_FIELD, getDate(9,
+        assertTrue(messageSearches.isMatch(SearchQuery.headerDateAfter(DATE_FIELD, getDate(9,
                 9, 2000), DateResolution.Day), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.headerDateAfter(DATE_FIELD, getDate(8,
+        assertTrue(messageSearches.isMatch(SearchQuery.headerDateAfter(DATE_FIELD, getDate(8,
                 9, 2001),DateResolution.Day), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateAfter(DATE_FIELD, getDate(9,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateAfter(DATE_FIELD, getDate(9,
                 9, 2001), DateResolution.Day),row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateAfter(DATE_FIELD,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateAfter(DATE_FIELD,
                 getDate(10, 9, 2001), DateResolution.Day),row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateAfter(DATE_FIELD, getDate(9,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateAfter(DATE_FIELD, getDate(9,
                 9, 2002), DateResolution.Day),row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateAfter("BOGUS", getDate(9, 9,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateAfter("BOGUS", getDate(9, 9,
                 2001), DateResolution.Day),row, recent));
     }
 
@@ -226,17 +235,17 @@ public class SearchUtilsTest {
     public void testMatchHeaderDateOn() throws Exception {
         builder.header(DATE_FIELD, RFC822_SUN_SEP_9TH_2001);
         MailboxMessage row = builder.build();
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(9, 9,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(9, 9,
                 2000), DateResolution.Day),row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(8, 9,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(8, 9,
                 2001), DateResolution.Day),row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(9, 9,
+        assertTrue(messageSearches.isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(9, 9,
                 2001), DateResolution.Day),row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(10,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(10,
                 9, 2001), DateResolution.Day),row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(9, 9,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(9, 9,
                 2002), DateResolution.Day), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateOn("BOGUS", getDate(9, 9,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateOn("BOGUS", getDate(9, 9,
                 2001), DateResolution.Day), row, recent));
     }
 
@@ -244,17 +253,17 @@ public class SearchUtilsTest {
     public void testShouldMatchCapsHeaderDateOn() throws Exception {
         builder.header(DATE_FIELD.toUpperCase(Locale.US), RFC822_SUN_SEP_9TH_2001);
         MailboxMessage row = builder.build();
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(9, 9,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(9, 9,
                 2000), DateResolution.Day),row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(8, 9,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(8, 9,
                 2001), DateResolution.Day),row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(9, 9,
+        assertTrue(messageSearches.isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(9, 9,
                 2001), DateResolution.Day),row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(10,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(10,
                 9, 2001), DateResolution.Day),row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(9, 9,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(9, 9,
                 2002), DateResolution.Day),row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateOn("BOGUS", getDate(9, 9,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateOn("BOGUS", getDate(9, 9,
                 2001), DateResolution.Day),row, recent));
     }
 
@@ -262,17 +271,17 @@ public class SearchUtilsTest {
     public void testShouldMatchLowersHeaderDateOn() throws Exception {
         builder.header(DATE_FIELD.toLowerCase(Locale.US), RFC822_SUN_SEP_9TH_2001);
         MailboxMessage row = builder.build();
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(9, 9,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(9, 9,
                 2000), DateResolution.Day),row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(8, 9,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(8, 9,
                 2001), DateResolution.Day),row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(9, 9,
+        assertTrue(messageSearches.isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(9, 9,
                 2001), DateResolution.Day),row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(10,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(10,
                 9, 2001), DateResolution.Day),row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(9, 9,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(9, 9,
                 2002), DateResolution.Day),row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateOn("BOGUS", getDate(9, 9,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateOn("BOGUS", getDate(9, 9,
                 2001), DateResolution.Day),row, recent));
     }
 
@@ -280,17 +289,17 @@ public class SearchUtilsTest {
     public void testMatchHeaderDateBefore() throws Exception {
         builder.header(DATE_FIELD.toLowerCase(Locale.US), RFC822_SUN_SEP_9TH_2001);
         MailboxMessage row = builder.build();
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateBefore(DATE_FIELD,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateBefore(DATE_FIELD,
                 getDate(9, 9, 2000), DateResolution.Day),row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateBefore(DATE_FIELD,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateBefore(DATE_FIELD,
                 getDate(8, 9, 2001), DateResolution.Day),row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateBefore(DATE_FIELD,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateBefore(DATE_FIELD,
                 getDate(9, 9, 2001), DateResolution.Day),row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.headerDateBefore(DATE_FIELD,
+        assertTrue(messageSearches.isMatch(SearchQuery.headerDateBefore(DATE_FIELD,
                 getDate(10, 9, 2001), DateResolution.Day),row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.headerDateBefore(DATE_FIELD, getDate(9,
+        assertTrue(messageSearches.isMatch(SearchQuery.headerDateBefore(DATE_FIELD, getDate(9,
                 9, 2002), DateResolution.Day),row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateBefore("BOGUS", getDate(9,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateBefore("BOGUS", getDate(9,
                 9, 2001), DateResolution.Day),row, recent));
     }
 
@@ -298,17 +307,17 @@ public class SearchUtilsTest {
     public void testShouldMatchCapsHeaderDateBefore() throws Exception {
         builder.header(DATE_FIELD.toLowerCase(Locale.US), RFC822_SUN_SEP_9TH_2001);
         MailboxMessage row = builder.build();
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateBefore(DATE_FIELD,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateBefore(DATE_FIELD,
                 getDate(9, 9, 2000), DateResolution.Day),row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateBefore(DATE_FIELD,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateBefore(DATE_FIELD,
                 getDate(8, 9, 2001), DateResolution.Day),row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateBefore(DATE_FIELD,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateBefore(DATE_FIELD,
                 getDate(9, 9, 2001), DateResolution.Day),row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.headerDateBefore(DATE_FIELD,
+        assertTrue(messageSearches.isMatch(SearchQuery.headerDateBefore(DATE_FIELD,
                 getDate(10, 9, 2001), DateResolution.Day),row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.headerDateBefore(DATE_FIELD, getDate(9,
+        assertTrue(messageSearches.isMatch(SearchQuery.headerDateBefore(DATE_FIELD, getDate(9,
                 9, 2002), DateResolution.Day),row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateBefore("BOGUS", getDate(9,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateBefore("BOGUS", getDate(9,
                 9, 2001), DateResolution.Day),row, recent));
     }
 
@@ -316,17 +325,17 @@ public class SearchUtilsTest {
     public void testShouldMatchLowersHeaderDateBefore() throws Exception {
         builder.header(DATE_FIELD.toLowerCase(Locale.US), RFC822_SUN_SEP_9TH_2001);
         MailboxMessage row = builder.build();
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateBefore(DATE_FIELD,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateBefore(DATE_FIELD,
                 getDate(9, 9, 2000), DateResolution.Day),row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateBefore(DATE_FIELD,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateBefore(DATE_FIELD,
                 getDate(8, 9, 2001), DateResolution.Day),row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateBefore(DATE_FIELD,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateBefore(DATE_FIELD,
                 getDate(9, 9, 2001), DateResolution.Day),row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.headerDateBefore(DATE_FIELD,
+        assertTrue(messageSearches.isMatch(SearchQuery.headerDateBefore(DATE_FIELD,
                 getDate(10, 9, 2001), DateResolution.Day),row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.headerDateBefore(DATE_FIELD, getDate(9,
+        assertTrue(messageSearches.isMatch(SearchQuery.headerDateBefore(DATE_FIELD, getDate(9,
                 9, 2002), DateResolution.Day),row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateBefore("BOGUS", getDate(9,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateBefore("BOGUS", getDate(9,
                 9, 2001), DateResolution.Day),row, recent));
     }
 
@@ -334,15 +343,15 @@ public class SearchUtilsTest {
     public void testMatchHeaderContainsCaps() throws Exception {
         builder.header(SUBJECT_FIELD, TEXT.toUpperCase(Locale.US));
         MailboxMessage row = builder.build();
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerContains(DATE_FIELD,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerContains(DATE_FIELD,
                 CUSTARD), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerContains(DATE_FIELD,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerContains(DATE_FIELD,
                 TEXT), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.headerContains(SUBJECT_FIELD,
+        assertTrue(messageSearches.isMatch(SearchQuery.headerContains(SUBJECT_FIELD,
                 TEXT), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.headerContains(SUBJECT_FIELD,
+        assertTrue(messageSearches.isMatch(SearchQuery.headerContains(SUBJECT_FIELD,
                 RHUBARD), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerContains(SUBJECT_FIELD,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerContains(SUBJECT_FIELD,
                 CUSTARD), row, recent));
     }
 
@@ -350,15 +359,15 @@ public class SearchUtilsTest {
     public void testMatchHeaderContainsLowers() throws Exception {
         builder.header(SUBJECT_FIELD, TEXT.toUpperCase(Locale.US));
         MailboxMessage row = builder.build();
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerContains(DATE_FIELD,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerContains(DATE_FIELD,
                 CUSTARD), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerContains(DATE_FIELD,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerContains(DATE_FIELD,
                 TEXT), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.headerContains(SUBJECT_FIELD,
+        assertTrue(messageSearches.isMatch(SearchQuery.headerContains(SUBJECT_FIELD,
                 TEXT), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.headerContains(SUBJECT_FIELD,
+        assertTrue(messageSearches.isMatch(SearchQuery.headerContains(SUBJECT_FIELD,
                 RHUBARD), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerContains(SUBJECT_FIELD,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerContains(SUBJECT_FIELD,
                 CUSTARD), row, recent));
     }
 
@@ -366,15 +375,15 @@ public class SearchUtilsTest {
     public void testMatchHeaderContains() throws Exception {
         builder.header(SUBJECT_FIELD, TEXT.toUpperCase(Locale.US));
         MailboxMessage row = builder.build();
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerContains(DATE_FIELD,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerContains(DATE_FIELD,
                 CUSTARD), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerContains(DATE_FIELD,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerContains(DATE_FIELD,
                 TEXT), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.headerContains(SUBJECT_FIELD,
+        assertTrue(messageSearches.isMatch(SearchQuery.headerContains(SUBJECT_FIELD,
                 TEXT), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.headerContains(SUBJECT_FIELD,
+        assertTrue(messageSearches.isMatch(SearchQuery.headerContains(SUBJECT_FIELD,
                 RHUBARD), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerContains(SUBJECT_FIELD,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerContains(SUBJECT_FIELD,
                 CUSTARD), row, recent));
     }
 
@@ -382,15 +391,15 @@ public class SearchUtilsTest {
     public void testShouldMatchLowerHeaderContains() throws Exception {
         builder.header(SUBJECT_FIELD.toLowerCase(Locale.US), TEXT);
         MailboxMessage row = builder.build();
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerContains(DATE_FIELD,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerContains(DATE_FIELD,
                 CUSTARD), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerContains(DATE_FIELD,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerContains(DATE_FIELD,
                 TEXT), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.headerContains(SUBJECT_FIELD,
+        assertTrue(messageSearches.isMatch(SearchQuery.headerContains(SUBJECT_FIELD,
                 TEXT), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.headerContains(SUBJECT_FIELD,
+        assertTrue(messageSearches.isMatch(SearchQuery.headerContains(SUBJECT_FIELD,
                 RHUBARD), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerContains(SUBJECT_FIELD,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerContains(SUBJECT_FIELD,
                 CUSTARD), row, recent));
     }
 
@@ -398,15 +407,15 @@ public class SearchUtilsTest {
     public void testShouldMatchCapsHeaderContains() throws Exception {
         builder.header(SUBJECT_FIELD.toUpperCase(Locale.US), TEXT);
         MailboxMessage row = builder.build();
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerContains(DATE_FIELD,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerContains(DATE_FIELD,
                 CUSTARD), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerContains(DATE_FIELD,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerContains(DATE_FIELD,
                 TEXT), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.headerContains(SUBJECT_FIELD,
+        assertTrue(messageSearches.isMatch(SearchQuery.headerContains(SUBJECT_FIELD,
                 TEXT), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.headerContains(SUBJECT_FIELD,
+        assertTrue(messageSearches.isMatch(SearchQuery.headerContains(SUBJECT_FIELD,
                 RHUBARD), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerContains(SUBJECT_FIELD,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerContains(SUBJECT_FIELD,
                 CUSTARD), row, recent));
     }
 
@@ -414,9 +423,9 @@ public class SearchUtilsTest {
     public void testMatchHeaderExists() throws Exception {
         builder.header(SUBJECT_FIELD, TEXT);
         MailboxMessage row = builder.build();
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerExists(DATE_FIELD), row,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerExists(DATE_FIELD), row,
                 recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.headerExists(SUBJECT_FIELD),
+        assertTrue(messageSearches.isMatch(SearchQuery.headerExists(SUBJECT_FIELD),
                 row, recent));
     }
 
@@ -424,9 +433,9 @@ public class SearchUtilsTest {
     public void testShouldMatchLowersHeaderExists() throws Exception {
         builder.header(SUBJECT_FIELD.toLowerCase(Locale.US), TEXT);
         MailboxMessage row = builder.build();
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerExists(DATE_FIELD), row,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerExists(DATE_FIELD), row,
                 recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.headerExists(SUBJECT_FIELD),
+        assertTrue(messageSearches.isMatch(SearchQuery.headerExists(SUBJECT_FIELD),
                 row, recent));
     }
 
@@ -434,9 +443,9 @@ public class SearchUtilsTest {
     public void testShouldMatchUppersHeaderExists() throws Exception {
         builder.header(SUBJECT_FIELD.toLowerCase(Locale.US), TEXT);
         MailboxMessage row = builder.build();
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerExists(DATE_FIELD), row,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerExists(DATE_FIELD), row,
                 recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.headerExists(SUBJECT_FIELD),
+        assertTrue(messageSearches.isMatch(SearchQuery.headerExists(SUBJECT_FIELD),
                 row, recent));
     }
 
@@ -444,30 +453,30 @@ public class SearchUtilsTest {
     public void testShouldMatchUidRange() throws Exception {
         builder.setKey(1, MessageUid.of(1729));
         MailboxMessage row = builder.build();
-        assertFalse(new MessageSearches().isMatch(SearchQuery.uid(range(MessageUid.of(1), MessageUid.of(1))), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.uid(range(MessageUid.of(1728), MessageUid.of(1728))), row,
+        assertFalse(messageSearches.isMatch(SearchQuery.uid(range(MessageUid.of(1), MessageUid.of(1))), row, recent));
+        assertFalse(messageSearches.isMatch(SearchQuery.uid(range(MessageUid.of(1728), MessageUid.of(1728))), row,
                 recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.uid(range(MessageUid.of(1729), MessageUid.of(1729))), row,
+        assertTrue(messageSearches.isMatch(SearchQuery.uid(range(MessageUid.of(1729), MessageUid.of(1729))), row,
                 recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.uid(range(MessageUid.of(1730), MessageUid.of(1730))), row,
+        assertFalse(messageSearches.isMatch(SearchQuery.uid(range(MessageUid.of(1730), MessageUid.of(1730))), row,
                 recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.uid(range(MessageUid.of(1), MessageUid.of(1728))), row,
+        assertFalse(messageSearches.isMatch(SearchQuery.uid(range(MessageUid.of(1), MessageUid.of(1728))), row,
                 recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.uid(range(MessageUid.of(1), MessageUid.of(1729))), row,
+        assertTrue(messageSearches.isMatch(SearchQuery.uid(range(MessageUid.of(1), MessageUid.of(1729))), row,
                 recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.uid(range(MessageUid.of(1729), MessageUid.of(1800))), row,
+        assertTrue(messageSearches.isMatch(SearchQuery.uid(range(MessageUid.of(1729), MessageUid.of(1800))), row,
                 recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery
+        assertFalse(messageSearches.isMatch(SearchQuery
                 .uid(range(MessageUid.of(1730), MessageUid.MAX_VALUE)), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.uid(range(MessageUid.of(1730),
+        assertFalse(messageSearches.isMatch(SearchQuery.uid(range(MessageUid.of(1730),
                 MessageUid.MAX_VALUE, MessageUid.of(1), MessageUid.of(1728))), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.uid(range(MessageUid.of(1730), MessageUid.MAX_VALUE,
+        assertTrue(messageSearches.isMatch(SearchQuery.uid(range(MessageUid.of(1730), MessageUid.MAX_VALUE,
                 MessageUid.of(1), MessageUid.of(1729))), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery
+        assertFalse(messageSearches.isMatch(SearchQuery
                 .uid(range(MessageUid.of(1), MessageUid.of(1728), MessageUid.of(1800), MessageUid.of(1810))), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.uid(range(MessageUid.of(1), MessageUid.of(1), MessageUid.of(1729), MessageUid.of(1729))),
+        assertTrue(messageSearches.isMatch(SearchQuery.uid(range(MessageUid.of(1), MessageUid.of(1), MessageUid.of(1729), MessageUid.of(1729))),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.uid(range(MessageUid.of(1), MessageUid.of(1), MessageUid.of(1800), MessageUid.of(1800))),
+        assertFalse(messageSearches.isMatch(SearchQuery.uid(range(MessageUid.of(1), MessageUid.of(1), MessageUid.of(1800), MessageUid.of(1800))),
                 row, recent));
     }
 
@@ -475,17 +484,17 @@ public class SearchUtilsTest {
     public void testShouldMatchSeenFlagSet() throws Exception {
         builder.setFlags(true, false, false, false, false, false);
         MailboxMessage row = builder.build();
-        assertTrue(new MessageSearches().isMatch(SearchQuery.flagIsSet(Flags.Flag.SEEN),
+        assertTrue(messageSearches.isMatch(SearchQuery.flagIsSet(Flags.Flag.SEEN),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsSet(Flags.Flag.FLAGGED),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsSet(Flags.Flag.FLAGGED),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(
+        assertFalse(messageSearches.isMatch(
                 SearchQuery.flagIsSet(Flags.Flag.ANSWERED), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsSet(Flags.Flag.DRAFT),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsSet(Flags.Flag.DRAFT),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsSet(Flags.Flag.DELETED),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsSet(Flags.Flag.DELETED),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsSet(Flags.Flag.RECENT),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsSet(Flags.Flag.RECENT),
                 row, recent));
     }
 
@@ -493,17 +502,17 @@ public class SearchUtilsTest {
     public void testShouldMatchAnsweredFlagSet() throws Exception {
         builder.setFlags(false, false, true, false, false, false);
         MailboxMessage row = builder.build();
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsSet(Flags.Flag.SEEN),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsSet(Flags.Flag.SEEN),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsSet(Flags.Flag.FLAGGED),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsSet(Flags.Flag.FLAGGED),
                 row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.flagIsSet(Flags.Flag.ANSWERED),
+        assertTrue(messageSearches.isMatch(SearchQuery.flagIsSet(Flags.Flag.ANSWERED),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsSet(Flags.Flag.DRAFT),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsSet(Flags.Flag.DRAFT),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsSet(Flags.Flag.DELETED),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsSet(Flags.Flag.DELETED),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsSet(Flags.Flag.RECENT),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsSet(Flags.Flag.RECENT),
                 row, recent));
     }
 
@@ -511,17 +520,17 @@ public class SearchUtilsTest {
     public void testShouldMatchFlaggedFlagSet() throws Exception {
         builder.setFlags(false, true, false, false, false, false);
         MailboxMessage row = builder.build();
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsSet(Flags.Flag.SEEN),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsSet(Flags.Flag.SEEN),
                 row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.flagIsSet(Flags.Flag.FLAGGED),
+        assertTrue(messageSearches.isMatch(SearchQuery.flagIsSet(Flags.Flag.FLAGGED),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(
+        assertFalse(messageSearches.isMatch(
                 SearchQuery.flagIsSet(Flags.Flag.ANSWERED), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsSet(Flags.Flag.DRAFT),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsSet(Flags.Flag.DRAFT),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsSet(Flags.Flag.DELETED),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsSet(Flags.Flag.DELETED),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsSet(Flags.Flag.RECENT),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsSet(Flags.Flag.RECENT),
                 row, recent));
     }
 
@@ -529,17 +538,17 @@ public class SearchUtilsTest {
     public void testShouldMatchDraftFlagSet() throws Exception {
         builder.setFlags(false, false, false, true, false, false);
         MailboxMessage row = builder.build();
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsSet(Flags.Flag.SEEN),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsSet(Flags.Flag.SEEN),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsSet(Flags.Flag.FLAGGED),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsSet(Flags.Flag.FLAGGED),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(
+        assertFalse(messageSearches.isMatch(
                 SearchQuery.flagIsSet(Flags.Flag.ANSWERED), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.flagIsSet(Flags.Flag.DRAFT),
+        assertTrue(messageSearches.isMatch(SearchQuery.flagIsSet(Flags.Flag.DRAFT),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsSet(Flags.Flag.DELETED),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsSet(Flags.Flag.DELETED),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsSet(Flags.Flag.RECENT),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsSet(Flags.Flag.RECENT),
                 row, recent));
     }
 
@@ -548,17 +557,17 @@ public class SearchUtilsTest {
     public void testShouldMatchDeletedFlagSet() throws Exception {
         builder.setFlags(false, false, false, false, true, false);
         MailboxMessage row = builder.build();
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsSet(Flags.Flag.SEEN),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsSet(Flags.Flag.SEEN),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsSet(Flags.Flag.FLAGGED),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsSet(Flags.Flag.FLAGGED),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(
+        assertFalse(messageSearches.isMatch(
                 SearchQuery.flagIsSet(Flags.Flag.ANSWERED), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsSet(Flags.Flag.DRAFT),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsSet(Flags.Flag.DRAFT),
                 row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.flagIsSet(Flags.Flag.DELETED),
+        assertTrue(messageSearches.isMatch(SearchQuery.flagIsSet(Flags.Flag.DELETED),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsSet(Flags.Flag.RECENT),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsSet(Flags.Flag.RECENT),
                 row, recent));
     }
 
@@ -567,17 +576,17 @@ public class SearchUtilsTest {
         builder.setFlags(false, false, false, false, false, false);
         MailboxMessage row = builder.build();
         recent.add(row.getUid());
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsSet(Flags.Flag.SEEN),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsSet(Flags.Flag.SEEN),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsSet(Flags.Flag.FLAGGED),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsSet(Flags.Flag.FLAGGED),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(
+        assertFalse(messageSearches.isMatch(
                 SearchQuery.flagIsSet(Flags.Flag.ANSWERED), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsSet(Flags.Flag.DRAFT),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsSet(Flags.Flag.DRAFT),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsSet(Flags.Flag.DELETED),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsSet(Flags.Flag.DELETED),
                 row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.flagIsSet(Flags.Flag.RECENT),
+        assertTrue(messageSearches.isMatch(SearchQuery.flagIsSet(Flags.Flag.RECENT),
                 row, recent));
     }
 
@@ -586,17 +595,17 @@ public class SearchUtilsTest {
         builder.setFlags(false, true, true, true, true, true);
         MailboxMessage row = builder.build();
         recent.add(row.getUid());
-        assertTrue(new MessageSearches().isMatch(SearchQuery.flagIsUnSet(Flags.Flag.SEEN),
+        assertTrue(messageSearches.isMatch(SearchQuery.flagIsUnSet(Flags.Flag.SEEN),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery
+        assertFalse(messageSearches.isMatch(SearchQuery
                 .flagIsUnSet(Flags.Flag.FLAGGED), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery
+        assertFalse(messageSearches.isMatch(SearchQuery
                 .flagIsUnSet(Flags.Flag.ANSWERED), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsUnSet(Flags.Flag.DRAFT),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsUnSet(Flags.Flag.DRAFT),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery
+        assertFalse(messageSearches.isMatch(SearchQuery
                 .flagIsUnSet(Flags.Flag.DELETED), row, recent));
-        assertFalse(new MessageSearches().isMatch(
+        assertFalse(messageSearches.isMatch(
                 SearchQuery.flagIsUnSet(Flags.Flag.RECENT), row, recent));
     }
 
@@ -605,17 +614,17 @@ public class SearchUtilsTest {
         builder.setFlags(true, true, false, true, true, true);
         MailboxMessage row = builder.build();
         recent.add(row.getUid());
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsUnSet(Flags.Flag.SEEN),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsUnSet(Flags.Flag.SEEN),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery
+        assertFalse(messageSearches.isMatch(SearchQuery
                 .flagIsUnSet(Flags.Flag.FLAGGED), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery
+        assertTrue(messageSearches.isMatch(SearchQuery
                 .flagIsUnSet(Flags.Flag.ANSWERED), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsUnSet(Flags.Flag.DRAFT),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsUnSet(Flags.Flag.DRAFT),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery
+        assertFalse(messageSearches.isMatch(SearchQuery
                 .flagIsUnSet(Flags.Flag.DELETED), row, recent));
-        assertFalse(new MessageSearches().isMatch(
+        assertFalse(messageSearches.isMatch(
                 SearchQuery.flagIsUnSet(Flags.Flag.RECENT), row, recent));
     }
 
@@ -624,17 +633,17 @@ public class SearchUtilsTest {
         builder.setFlags(true, false, true, true, true, true);
         MailboxMessage row = builder.build();
         recent.add(row.getUid());
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsUnSet(Flags.Flag.SEEN),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsUnSet(Flags.Flag.SEEN),
                 row, recent));
-        assertTrue(new MessageSearches().isMatch(
+        assertTrue(messageSearches.isMatch(
                 SearchQuery.flagIsUnSet(Flags.Flag.FLAGGED), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery
+        assertFalse(messageSearches.isMatch(SearchQuery
                 .flagIsUnSet(Flags.Flag.ANSWERED), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsUnSet(Flags.Flag.DRAFT),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsUnSet(Flags.Flag.DRAFT),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery
+        assertFalse(messageSearches.isMatch(SearchQuery
                 .flagIsUnSet(Flags.Flag.DELETED), row, recent));
-        assertFalse(new MessageSearches().isMatch(
+        assertFalse(messageSearches.isMatch(
                 SearchQuery.flagIsUnSet(Flags.Flag.RECENT), row, recent));
     }
 
@@ -643,17 +652,17 @@ public class SearchUtilsTest {
         builder.setFlags(true, true, true, false, true, true);
         MailboxMessage row = builder.build();
         recent.add(row.getUid());
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsUnSet(Flags.Flag.SEEN),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsUnSet(Flags.Flag.SEEN),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery
+        assertFalse(messageSearches.isMatch(SearchQuery
                 .flagIsUnSet(Flags.Flag.FLAGGED), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery
+        assertFalse(messageSearches.isMatch(SearchQuery
                 .flagIsUnSet(Flags.Flag.ANSWERED), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.flagIsUnSet(Flags.Flag.DRAFT),
+        assertTrue(messageSearches.isMatch(SearchQuery.flagIsUnSet(Flags.Flag.DRAFT),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery
+        assertFalse(messageSearches.isMatch(SearchQuery
                 .flagIsUnSet(Flags.Flag.DELETED), row, recent));
-        assertFalse(new MessageSearches().isMatch(
+        assertFalse(messageSearches.isMatch(
                 SearchQuery.flagIsUnSet(Flags.Flag.RECENT), row, recent));
     }
 
@@ -662,17 +671,17 @@ public class SearchUtilsTest {
         builder.setFlags(true, true, true, true, false, true);
         MailboxMessage row = builder.build();
         recent.add(row.getUid());
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsUnSet(Flags.Flag.SEEN),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsUnSet(Flags.Flag.SEEN),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery
+        assertFalse(messageSearches.isMatch(SearchQuery
                 .flagIsUnSet(Flags.Flag.FLAGGED), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery
+        assertFalse(messageSearches.isMatch(SearchQuery
                 .flagIsUnSet(Flags.Flag.ANSWERED), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsUnSet(Flags.Flag.DRAFT),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsUnSet(Flags.Flag.DRAFT),
                 row, recent));
-        assertTrue(new MessageSearches().isMatch(
+        assertTrue(messageSearches.isMatch(
                 SearchQuery.flagIsUnSet(Flags.Flag.DELETED), row, recent));
-        assertFalse(new MessageSearches().isMatch(
+        assertFalse(messageSearches.isMatch(
                 SearchQuery.flagIsUnSet(Flags.Flag.RECENT), row, recent));
     }
 
@@ -681,60 +690,60 @@ public class SearchUtilsTest {
         builder.setFlags(true, true, true, true, true, true);
         MailboxMessage row = builder.build();
         recent.add(row.getUid().next());
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsUnSet(Flags.Flag.SEEN),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsUnSet(Flags.Flag.SEEN),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery
+        assertFalse(messageSearches.isMatch(SearchQuery
                 .flagIsUnSet(Flags.Flag.FLAGGED), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery
+        assertFalse(messageSearches.isMatch(SearchQuery
                 .flagIsUnSet(Flags.Flag.ANSWERED), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.flagIsUnSet(Flags.Flag.DRAFT),
+        assertFalse(messageSearches.isMatch(SearchQuery.flagIsUnSet(Flags.Flag.DRAFT),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery
+        assertFalse(messageSearches.isMatch(SearchQuery
                 .flagIsUnSet(Flags.Flag.DELETED), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.flagIsUnSet(Flags.Flag.RECENT),
+        assertTrue(messageSearches.isMatch(SearchQuery.flagIsUnSet(Flags.Flag.RECENT),
                 row, recent));
     }
 
     @Test
     public void testShouldMatchAll() throws Exception {
         MailboxMessage row = builder.build();
-        assertTrue(new MessageSearches().isMatch(SearchQuery.all(), row, recent));
+        assertTrue(messageSearches.isMatch(SearchQuery.all(), row, recent));
     }
 
     @Test
     public void testShouldMatchNot() throws Exception {
         MailboxMessage row = builder.build();
-        assertFalse(new MessageSearches().isMatch(SearchQuery.not(SearchQuery.all()), row,
+        assertFalse(messageSearches.isMatch(SearchQuery.not(SearchQuery.all()), row,
                 recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.not(SearchQuery
+        assertTrue(messageSearches.isMatch(SearchQuery.not(SearchQuery
                 .headerExists(DATE_FIELD)), row, recent));
     }
 
     @Test
     public void testShouldMatchOr() throws Exception {
         MailboxMessage row = builder.build();
-        assertTrue(new MessageSearches().isMatch(SearchQuery.or(SearchQuery.all(),
+        assertTrue(messageSearches.isMatch(SearchQuery.or(SearchQuery.all(),
                 SearchQuery.headerExists(DATE_FIELD)), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.or(SearchQuery
+        assertTrue(messageSearches.isMatch(SearchQuery.or(SearchQuery
                 .headerExists(DATE_FIELD), SearchQuery.all()), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery
+        assertFalse(messageSearches.isMatch(SearchQuery
                 .or(SearchQuery.headerExists(DATE_FIELD), SearchQuery
                         .headerExists(DATE_FIELD)), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.or(SearchQuery.all(),
+        assertTrue(messageSearches.isMatch(SearchQuery.or(SearchQuery.all(),
                 SearchQuery.all()), row, recent));
     }
 
     @Test
     public void testShouldMatchAnd() throws Exception {
         MailboxMessage row = builder.build();
-        assertFalse(new MessageSearches().isMatch(SearchQuery.and(SearchQuery.all(),
+        assertFalse(messageSearches.isMatch(SearchQuery.and(SearchQuery.all(),
                 SearchQuery.headerExists(DATE_FIELD)), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.and(SearchQuery
+        assertFalse(messageSearches.isMatch(SearchQuery.and(SearchQuery
                 .headerExists(DATE_FIELD), SearchQuery.all()), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery
+        assertFalse(messageSearches.isMatch(SearchQuery
                 .and(SearchQuery.headerExists(DATE_FIELD), SearchQuery
                         .headerExists(DATE_FIELD)), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.and(SearchQuery.all(),
+        assertTrue(messageSearches.isMatch(SearchQuery.and(SearchQuery.all(),
                 SearchQuery.all()), row, recent));
     }
     
@@ -754,12 +763,12 @@ public class SearchUtilsTest {
     public void testMatchHeaderDateOnWithOffset() throws Exception {
         builder.header(DATE_FIELD, "Mon, 26 Mar 2007 00:00:00 +0300");
         MailboxMessage row = builder.build();
-        assertTrue(new MessageSearches().isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(26, 3,
+        assertTrue(messageSearches.isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(26, 3,
                 2007), DateResolution.Day),row, recent));
         
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(25, 3,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(25, 3,
                 2007), DateResolution.Day),row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(27, 3,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateOn(DATE_FIELD, getDate(27, 3,
                 2007), DateResolution.Day),row, recent));
     }
     
@@ -768,12 +777,12 @@ public class SearchUtilsTest {
     public void testShouldMatchHeaderDateBeforeWithOffset() throws Exception {
         builder.header(DATE_FIELD, "Mon, 26 Mar 2007 00:00:00 +0300");
         MailboxMessage row = builder.build();
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateBefore(DATE_FIELD, getDate(26, 3,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateBefore(DATE_FIELD, getDate(26, 3,
                 2007), DateResolution.Day),row, recent));
         
-        assertTrue(new MessageSearches().isMatch(SearchQuery.headerDateBefore(DATE_FIELD, getDate(27, 3,
+        assertTrue(messageSearches.isMatch(SearchQuery.headerDateBefore(DATE_FIELD, getDate(27, 3,
                 2007), DateResolution.Day),row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateBefore(DATE_FIELD, getDate(25, 3,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateBefore(DATE_FIELD, getDate(25, 3,
                 2007), DateResolution.Day),row, recent));
     }
 
@@ -781,12 +790,12 @@ public class SearchUtilsTest {
     public void testShouldMatchHeaderDateAfterWithOffset() throws Exception {
         builder.header(DATE_FIELD, "Mon, 26 Mar 2007 00:00:00 +0300");
         MailboxMessage row = builder.build();
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateAfter(DATE_FIELD, getDate(26, 3,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateAfter(DATE_FIELD, getDate(26, 3,
                 2007), DateResolution.Day),row, recent));
         
-        assertFalse(new MessageSearches().isMatch(SearchQuery.headerDateAfter(DATE_FIELD, getDate(27, 3,
+        assertFalse(messageSearches.isMatch(SearchQuery.headerDateAfter(DATE_FIELD, getDate(27, 3,
                 2007), DateResolution.Day),row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.headerDateAfter(DATE_FIELD, getDate(25, 3,
+        assertTrue(messageSearches.isMatch(SearchQuery.headerDateAfter(DATE_FIELD, getDate(25, 3,
                 2007), DateResolution.Day),row, recent));
     }
     
@@ -794,8 +803,8 @@ public class SearchUtilsTest {
     public void testShouldMatchAddressHeaderWithComments() throws Exception {
         builder.header("To", "<user-from (comment)@ (comment) domain.org>");
         MailboxMessage row = builder.build();
-        assertTrue(new MessageSearches().isMatch(SearchQuery.address(AddressType.To, "user-from@domain.org"), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.address(AddressType.From, "user-from@domain.org"), row, recent));
+        assertTrue(messageSearches.isMatch(SearchQuery.address(AddressType.To, "user-from@domain.org"), row, recent));
+        assertFalse(messageSearches.isMatch(SearchQuery.address(AddressType.From, "user-from@domain.org"), row, recent));
     }
 
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/d76f8fc4/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/AbstractMessageSearchIndexTest.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/AbstractMessageSearchIndexTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/AbstractMessageSearchIndexTest.java
index fd9d173..a2686f3 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/AbstractMessageSearchIndexTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/AbstractMessageSearchIndexTest.java
@@ -22,12 +22,14 @@ package org.apache.james.mailbox.store.search;
 import static org.assertj.core.api.Assertions.assertThat;
 
 import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.List;
 
 import javax.mail.Flags;
 
+import org.apache.commons.io.IOUtils;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageIdManager;
@@ -47,10 +49,18 @@ import org.apache.james.mailbox.model.SearchQuery.Sort.SortClause;
 import org.apache.james.mailbox.store.StoreMailboxManager;
 import org.apache.james.mailbox.store.StoreMessageManager;
 import org.apache.james.mailbox.store.mail.model.Mailbox;
+import org.apache.james.mime4j.dom.Message;
+import org.apache.james.mime4j.dom.MessageWriter;
+import org.apache.james.mime4j.dom.Multipart;
+import org.apache.james.mime4j.message.BodyPart;
+import org.apache.james.mime4j.message.BodyPartBuilder;
+import org.apache.james.mime4j.message.DefaultMessageWriter;
+import org.apache.james.mime4j.message.MultipartBuilder;
 import org.junit.Assume;
 import org.junit.Before;
 import org.junit.Test;
 
+import com.google.common.base.Charsets;
 import com.google.common.collect.ImmutableList;
 
 public abstract class AbstractMessageSearchIndexTest {
@@ -208,6 +218,7 @@ public abstract class AbstractMessageSearchIndexTest {
             otherSession,
             RECENT,
             new Flags());
+
         await();
     }
 
@@ -574,7 +585,7 @@ public abstract class AbstractMessageSearchIndexTest {
     }
 
     @Test
-    public void flagIsUnSetShouldReturnUidOfMessageNotMarkedAsSeendWhenUsedWithFlagSeen() throws MailboxException {
+    public void flagIsUnSetShouldReturnUidOfMessageNotMarkedAsSeenWhenUsedWithFlagSeen() throws MailboxException {
         // Only message 6 is marked as read.
         SearchQuery searchQuery = new SearchQuery(SearchQuery.flagIsUnSet(Flags.Flag.SEEN));
 
@@ -1102,6 +1113,56 @@ public abstract class AbstractMessageSearchIndexTest {
     }
 
     @Test
+    public void searchWithTextAttachmentShouldReturnMailsWhenAttachmentContentMatches() throws Exception {
+        Assume.assumeTrue(storeMailboxManager.getSupportedSearchCapabilities().contains(MailboxManager.SearchCapabilities.Attachment));
+        ComposedMessageId messageWithBeautifulBananaAsTextAttachment = myFolderMessageManager.appendMessage(
+                ClassLoader.getSystemResourceAsStream("eml/emailWithTextAttachment.eml"),
+                new Date(1404252000000L),
+                session,
+                RECENT,
+                new Flags());
+        await();
+
+        SearchQuery searchQuery = new SearchQuery(SearchQuery.attachmentContains("beautiful banana"));
+
+        assertThat(messageSearchIndex.search(session, mailbox2, searchQuery))
+            .containsExactly(messageWithBeautifulBananaAsTextAttachment.getUid());
+    }
+
+    @Test
+    public void searchWithPDFAttachmentShouldReturnMailsWhenAttachmentContentMatches() throws Exception {
+        Assume.assumeTrue(storeMailboxManager.getSupportedSearchCapabilities().contains(MailboxManager.SearchCapabilities.Attachment));
+        byte[] attachmentContent = IOUtils.toByteArray(ClassLoader.getSystemResourceAsStream("eml/attachment.pdf"));
+        BodyPart attachment = BodyPartBuilder.create()
+                .setBody(attachmentContent, "application/pdf")
+                .setContentDisposition("attachment")
+                .build();
+        BodyPart textPart = BodyPartBuilder.create().setBody("The message has a PDF attachment.", "plain", Charsets.UTF_8).build();
+        Multipart multipart = MultipartBuilder.create("mixed")
+                .addBodyPart(attachment)
+                .addBodyPart(textPart)
+                .build();
+        Message message = Message.Builder.of()
+                .setBody(multipart)
+                .build();
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        MessageWriter writer = new DefaultMessageWriter();
+        writer.writeMessage(message, outputStream);
+        ComposedMessageId messageWithBeautifulBananaAsPDFAttachment = myFolderMessageManager.appendMessage(
+                new ByteArrayInputStream(outputStream.toByteArray()),
+                new Date(1404252000000L),
+                session,
+                RECENT,
+                new Flags());
+        await();
+
+        SearchQuery searchQuery = new SearchQuery(SearchQuery.attachmentContains("beautiful banana"));
+
+        assertThat(messageSearchIndex.search(session, mailbox2, searchQuery))
+            .containsExactly(messageWithBeautifulBananaAsPDFAttachment.getUid());
+    }
+
+    @Test
     public void sortShouldNotDiscardResultWhenSearchingFieldIsIdentical() throws Exception {
         SearchQuery searchQuery = new SearchQuery(SearchQuery.all());
         searchQuery.setSorts(ImmutableList.of(new Sort(SortClause.Arrival)));

http://git-wip-us.apache.org/repos/asf/james-project/blob/d76f8fc4/mailbox/store/src/test/resources/eml/attachment.pdf
----------------------------------------------------------------------
diff --git a/mailbox/store/src/test/resources/eml/attachment.pdf b/mailbox/store/src/test/resources/eml/attachment.pdf
new file mode 100644
index 0000000..6db56a2
Binary files /dev/null and b/mailbox/store/src/test/resources/eml/attachment.pdf differ

http://git-wip-us.apache.org/repos/asf/james-project/blob/d76f8fc4/mailbox/store/src/test/resources/eml/emailWithTextAttachment.eml
----------------------------------------------------------------------
diff --git a/mailbox/store/src/test/resources/eml/emailWithTextAttachment.eml b/mailbox/store/src/test/resources/eml/emailWithTextAttachment.eml
new file mode 100644
index 0000000..0a487ef
--- /dev/null
+++ b/mailbox/store/src/test/resources/eml/emailWithTextAttachment.eml
@@ -0,0 +1,26 @@
+To: James User <us...@james.org>
+From: James Sender <se...@james.org>
+Subject: Message with text attachment
+Message-ID: <ff...@linagora.com>
+Date: Tue, 5 Sep 2017 09:54:16 +0200
+MIME-Version: 1.0
+Content-Type: multipart/mixed;
+ boundary="------------D24E361990BDBA143D4D8794"
+Content-Language: en-US
+
+This is a multi-part message in MIME format.
+--------------D24E361990BDBA143D4D8794
+Content-Type: text/plain; charset=utf-8; format=flowed
+Content-Transfer-Encoding: 7bit
+
+The message has a text attachment.
+
+--------------D24E361990BDBA143D4D8794
+Content-Type: text/plain; charset=UTF-8;
+ name="attachment.txt"
+Content-Transfer-Encoding: base64
+Content-Disposition: attachment;
+ filename="attachment.txt"
+
+VGhpcyBpcyBhIGJlYXV0aWZ1bCBiYW5hbmEuCg==
+--------------D24E361990BDBA143D4D8794--


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[3/7] james-project git commit: JAMES-2137 Provide a method for searching in attachments and associated capability

Posted by ad...@apache.org.
JAMES-2137 Provide a method for searching in attachments and associated capability


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/d76f8fc4
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/d76f8fc4
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/d76f8fc4

Branch: refs/heads/master
Commit: d76f8fc402ec64d47b2520f33e01f08eb028f99e
Parents: adad8aa
Author: Antoine Duprat <ad...@linagora.com>
Authored: Tue Sep 5 14:37:48 2017 +0200
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Fri Sep 8 21:53:13 2017 +0200

----------------------------------------------------------------------
 .../apache/james/mailbox/MailboxManager.java    |   3 +-
 .../apache/james/mailbox/model/SearchQuery.java |  17 +-
 ...lasticSearchListeningMessageSearchIndex.java |   4 +-
 .../elasticsearch/query/CriterionConverter.java |   4 +
 .../ElasticSearchIntegrationTest.java           |  22 +-
 mailbox/scanning-search/pom.xml                 |   6 +
 .../mailbox/store/search/PDFTextExtractor.java  |  63 +++
 .../search/SimpleMessageSearchIndexTest.java    |   2 +-
 .../mailbox/store/StoreMailboxManager.java      |   4 +-
 .../mailbox/store/search/MessageSearches.java   |  37 +-
 .../store/search/SimpleMessageSearchIndex.java  |  10 +-
 .../store/SearchUtilsMultipartMixedTest.java    |  73 +--
 .../mailbox/store/SearchUtilsRFC822Test.java    |  37 +-
 .../james/mailbox/store/SearchUtilsTest.java    | 447 ++++++++++---------
 .../search/AbstractMessageSearchIndexTest.java  |  63 ++-
 .../store/src/test/resources/eml/attachment.pdf | Bin 0 -> 9404 bytes
 .../resources/eml/emailWithTextAttachment.eml   |  26 ++
 17 files changed, 531 insertions(+), 287 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/d76f8fc4/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 4e8d2a7..f0b3eb1 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
@@ -102,7 +102,8 @@ public interface MailboxManager extends RequestAware, MailboxListenerSupport {
          *  provide an index on the fields: 
          *  From, To, Cc, Bcc, Subjects, textBody & htmlBody
          */
-        Text
+        Text,
+        Attachment
     }
     
     EnumSet<SearchCapabilities> getSupportedSearchCapabilities();

http://git-wip-us.apache.org/repos/asf/james-project/blob/d76f8fc4/mailbox/api/src/main/java/org/apache/james/mailbox/model/SearchQuery.java
----------------------------------------------------------------------
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/SearchQuery.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/SearchQuery.java
index b6fa953..d3c25af 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/SearchQuery.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/SearchQuery.java
@@ -543,6 +543,17 @@ public class SearchQuery implements Serializable {
     }
 
     /**
+     * Creates a filter matching messages which has an attachment containing the given text.
+     * 
+     * @param value
+     *            search value
+     * @return <code>Criterion</code>, not null
+     */
+    public static Criterion attachmentContains(String value) {
+        return new TextCriterion(value, Scope.ATTACHMENTS);
+    }
+
+    /**
      * Creates a filter matching messages within any of the given ranges.
      * 
      * @param range
@@ -1092,8 +1103,10 @@ public class SearchQuery implements Serializable {
          */
         TEXT,
 
-        /** Full message content including headers */
-        FULL
+        /** Full message content including headers and attachments */
+        FULL,
+        /** Attachment content */
+        ATTACHMENTS
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/james-project/blob/d76f8fc4/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 ec9f1b4..34c0d2b 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
@@ -19,11 +19,13 @@
 package org.apache.james.mailbox.elasticsearch.events;
 
 import static org.elasticsearch.index.query.QueryBuilders.termQuery;
+
 import java.util.EnumSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Optional;
 import java.util.stream.Collectors;
+
 import javax.inject.Inject;
 
 import org.apache.james.backends.es.ElasticSearchIndexer;
@@ -76,7 +78,7 @@ public class ElasticSearchListeningMessageSearchIndex extends ListeningMessageSe
 
     @Override
     public EnumSet<SearchCapabilities> getSupportedCapabilities() {
-        return EnumSet.of(SearchCapabilities.MultimailboxSearch, SearchCapabilities.Text);
+        return EnumSet.of(SearchCapabilities.MultimailboxSearch, SearchCapabilities.Text, SearchCapabilities.Attachment);
     }
     
     @Override

http://git-wip-us.apache.org/repos/asf/james-project/blob/d76f8fc4/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/CriterionConverter.java
----------------------------------------------------------------------
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/CriterionConverter.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/CriterionConverter.java
index 9e06c87..59d2029 100644
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/CriterionConverter.java
+++ b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/CriterionConverter.java
@@ -146,6 +146,10 @@ public class CriterionConverter {
                     .should(matchQuery(JsonMessageConstants.HTML_BODY, textCriterion.getOperator().getValue()))
                     .should(matchQuery(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.TEXT_CONTENT,
                         textCriterion.getOperator().getValue()));
+        case ATTACHMENTS:
+            return boolQuery()
+                    .should(matchQuery(JsonMessageConstants.ATTACHMENTS + "." + JsonMessageConstants.Attachment.TEXT_CONTENT,
+                        textCriterion.getOperator().getValue()));
         }
         throw new RuntimeException("Unknown SCOPE for text criterion");
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/d76f8fc4/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 a9344b2..13e1352 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
@@ -56,10 +56,14 @@ import org.apache.james.mailbox.store.FakeAuthenticator;
 import org.apache.james.mailbox.store.FakeAuthorizator;
 import org.apache.james.mailbox.store.JVMMailboxPathLocker;
 import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
-import org.apache.james.mailbox.store.extractor.DefaultTextExtractor;
 import org.apache.james.mailbox.store.mail.model.impl.MessageParser;
 import org.apache.james.mailbox.store.search.AbstractMessageSearchIndexTest;
+import org.apache.james.mailbox.tika.TikaConfiguration;
+import org.apache.james.mailbox.tika.TikaContainer;
+import org.apache.james.mailbox.tika.TikaHttpClientImpl;
+import org.apache.james.mailbox.tika.TikaTextExtractor;
 import org.elasticsearch.client.Client;
+import org.junit.ClassRule;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.RuleChain;
@@ -80,6 +84,20 @@ public class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest
     @Rule
     public RuleChain ruleChain = RuleChain.outerRule(temporaryFolder).around(embeddedElasticSearch);
 
+    @ClassRule
+    public static TikaContainer tika = new TikaContainer();
+    private TikaTextExtractor textExtractor;
+
+    @Override
+    public void setUp() throws Exception {
+        textExtractor = new TikaTextExtractor(new TikaHttpClientImpl(TikaConfiguration.builder()
+                .host(tika.getIp())
+                .port(tika.getPort())
+                .timeoutInMillis(tika.getTimeoutInMillis())
+                .build()));
+        super.setUp();
+    }
+
     @Override
     protected void await() {
         embeddedElasticSearch.awaitForElasticSearch();
@@ -107,7 +125,7 @@ public class ElasticSearchIntegrationTest extends AbstractMessageSearchIndexTest
                 MailboxElasticsearchConstants.MAILBOX_INDEX,
                 MailboxElasticsearchConstants.MESSAGE_TYPE),
             new ElasticSearchSearcher(client, new QueryConverter(new CriterionConverter()), SEARCH_SIZE, new InMemoryId.Factory(), messageIdFactory),
-            new MessageToElasticSearchJson(new DefaultTextExtractor(), ZoneId.of("Europe/Paris"), IndexAttachments.YES));
+            new MessageToElasticSearchJson(textExtractor, ZoneId.of("Europe/Paris"), IndexAttachments.YES));
         storeMailboxManager = new InMemoryMailboxManager(
             mapperFactory,
             new FakeAuthenticator(),

http://git-wip-us.apache.org/repos/asf/james-project/blob/d76f8fc4/mailbox/scanning-search/pom.xml
----------------------------------------------------------------------
diff --git a/mailbox/scanning-search/pom.xml b/mailbox/scanning-search/pom.xml
index 5094710..1ee91bc 100644
--- a/mailbox/scanning-search/pom.xml
+++ b/mailbox/scanning-search/pom.xml
@@ -62,6 +62,12 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>org.apache.pdfbox</groupId>
+            <artifactId>pdfbox</artifactId>
+            <version>2.0.7</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.assertj</groupId>
             <artifactId>assertj-core</artifactId>
             <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/james-project/blob/d76f8fc4/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/PDFTextExtractor.java
----------------------------------------------------------------------
diff --git a/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/PDFTextExtractor.java b/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/PDFTextExtractor.java
new file mode 100644
index 0000000..1a5b5eb
--- /dev/null
+++ b/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/PDFTextExtractor.java
@@ -0,0 +1,63 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+package org.apache.james.mailbox.store.search;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.james.mailbox.extractor.ParsedContent;
+import org.apache.james.mailbox.extractor.TextExtractor;
+import org.apache.pdfbox.pdmodel.PDDocument;
+import org.apache.pdfbox.text.PDFTextStripper;
+
+import com.google.common.base.Charsets;
+import com.google.common.collect.ImmutableMap;
+
+public class PDFTextExtractor implements TextExtractor {
+
+    private static final String PDF_TYPE = "application/pdf";
+
+    @Override
+    public ParsedContent extractContent(InputStream inputStream, String contentType) throws Exception {
+        if (isPDF(contentType)) {
+            return extractTextFromPDF(inputStream);
+        }
+        try {
+            return new ParsedContent(IOUtils.toString(inputStream, Charsets.UTF_8), ImmutableMap.of());
+        } catch (IOException e) {
+            return new ParsedContent(null, ImmutableMap.of());
+        }
+    }
+
+    private boolean isPDF(String contentType) {
+        return contentType.equals(PDF_TYPE);
+    }
+
+    private ParsedContent extractTextFromPDF(InputStream inputStream) {
+        try {
+            return new ParsedContent(
+                    new PDFTextStripper().getText(
+                            PDDocument.load(inputStream)),
+                    ImmutableMap.of());
+        } catch (IOException e) {
+            return new ParsedContent(null, ImmutableMap.of());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/d76f8fc4/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndexTest.java
----------------------------------------------------------------------
diff --git a/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndexTest.java b/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndexTest.java
index 533ac00..9d5f2ba 100644
--- a/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndexTest.java
+++ b/mailbox/scanning-search/src/test/java/org/apache/james/mailbox/store/search/SimpleMessageSearchIndexTest.java
@@ -42,7 +42,7 @@ public class SimpleMessageSearchIndexTest extends AbstractMessageSearchIndexTest
     @Override
     protected void initializeMailboxManager() throws Exception {
         MailboxSessionMapperFactory mapperFactory = new InMemoryMailboxSessionMapperFactory();
-        messageSearchIndex = new SimpleMessageSearchIndex(mapperFactory, mapperFactory);
+        messageSearchIndex = new SimpleMessageSearchIndex(mapperFactory, mapperFactory, new PDFTextExtractor());
         storeMailboxManager = new InMemoryMailboxManager(
             mapperFactory,
             new FakeAuthenticator(),

http://git-wip-us.apache.org/repos/asf/james-project/blob/d76f8fc4/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 8bdebb2..818cc97 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
@@ -26,6 +26,7 @@ import java.util.List;
 import java.util.Optional;
 import java.util.Random;
 import java.util.Set;
+
 import javax.annotation.PostConstruct;
 import javax.inject.Inject;
 
@@ -68,6 +69,7 @@ import org.apache.james.mailbox.store.event.DefaultDelegatingMailboxListener;
 import org.apache.james.mailbox.store.event.DelegatingMailboxListener;
 import org.apache.james.mailbox.store.event.MailboxAnnotationListener;
 import org.apache.james.mailbox.store.event.MailboxEventDispatcher;
+import org.apache.james.mailbox.store.extractor.DefaultTextExtractor;
 import org.apache.james.mailbox.store.mail.AnnotationMapper;
 import org.apache.james.mailbox.store.mail.MailboxMapper;
 import org.apache.james.mailbox.store.mail.model.Mailbox;
@@ -242,7 +244,7 @@ public class StoreMailboxManager implements MailboxManager {
         }
 
         if (index == null) {
-            index = new SimpleMessageSearchIndex(mailboxSessionMapperFactory, mailboxSessionMapperFactory);
+            index = new SimpleMessageSearchIndex(mailboxSessionMapperFactory, mailboxSessionMapperFactory, new DefaultTextExtractor());
         }
         if (index instanceof ListeningMessageSearchIndex) {
             this.addGlobalListener((MailboxListener) index, null);

http://git-wip-us.apache.org/repos/asf/james-project/blob/d76f8fc4/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 87e6c24..d34c522 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
@@ -35,11 +35,16 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Optional;
 import java.util.TimeZone;
+
 import javax.mail.Flags;
 
 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.extractor.ParsedContent;
+import org.apache.james.mailbox.extractor.TextExtractor;
+import org.apache.james.mailbox.model.Attachment;
+import org.apache.james.mailbox.model.MessageAttachment;
 import org.apache.james.mailbox.model.MessageResult.Header;
 import org.apache.james.mailbox.model.SearchQuery;
 import org.apache.james.mailbox.model.SearchQuery.AddressType;
@@ -72,7 +77,9 @@ import org.apache.james.mime4j.utils.search.MessageMatcher;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.github.fge.lambdas.Throwing;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Lists;
 
 /**
@@ -90,18 +97,14 @@ public class MessageSearches implements Iterable<SimpleMessageSearchIndex.Search
         .setMaxLineLen(-1)
         .build();
 
-    private Iterator<MailboxMessage> messages;
-    private SearchQuery query;
+    private final Iterator<MailboxMessage> messages;
+    private final SearchQuery query;
+    private final TextExtractor textExtractor;
 
-    public MessageSearches(Iterator<MailboxMessage> messages, SearchQuery query) {
+    public MessageSearches(Iterator<MailboxMessage> messages, SearchQuery query, TextExtractor textExtractor) {
         this.messages = messages;
         this.query = query;
-    }
-
-    /**
-     * Empty constructor only for tests (which test isMatch())
-     */
-    public MessageSearches() {
+        this.textExtractor = textExtractor;
     }
 
     @Override
@@ -207,6 +210,8 @@ public class MessageSearches implements Iterable<SimpleMessageSearchIndex.Search
                 return textContains(value, message);
             case FULL:
                 return messageContains(value, message);
+            case ATTACHMENTS:
+                return attachmentsContain(value, message);
             }
             throw new UnsupportedSearchException();
         } catch (IOException | MimeException e) {
@@ -239,6 +244,20 @@ public class MessageSearches implements Iterable<SimpleMessageSearchIndex.Search
         return isInMessage(value, new SequenceInputStream(textHeaders(message), bodyContent), true);
     }
 
+    private boolean attachmentsContain(String value, MailboxMessage message) throws IOException, MimeException {
+        List<MessageAttachment> attachments = message.getAttachments();
+        return isInAttachments(value, attachments);
+    }
+
+    private boolean isInAttachments(String value, List<MessageAttachment> attachments) {
+        return attachments.stream()
+            .map(MessageAttachment::getAttachment)
+            .map(Throwing.function((Attachment attachment) -> textExtractor.extractContent(attachment.getStream(), attachment.getType()))
+                    .orReturn(new ParsedContent(null, ImmutableMap.of())))
+            .map(ParsedContent::getTextualContent)
+            .anyMatch(string -> string.contains(value));
+    }
+
     private InputStream textHeaders(MailboxMessage message) throws MimeIOException, IOException {
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         new DefaultMessageWriter()

http://git-wip-us.apache.org/repos/asf/james-project/blob/d76f8fc4/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 c2614de..9a301b4 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
@@ -24,12 +24,14 @@ import java.util.List;
 import java.util.SortedSet;
 import java.util.TreeSet;
 import java.util.stream.Stream;
+
 import javax.inject.Inject;
 
 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.extractor.TextExtractor;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.MessageId;
 import org.apache.james.mailbox.model.MessageRange;
@@ -64,16 +66,18 @@ public class SimpleMessageSearchIndex implements MessageSearchIndex {
 
     private final MessageMapperFactory messageMapperFactory;
     private final MailboxMapperFactory mailboxMapperFactory;
+    private final TextExtractor textExtractor;
     
     @Inject
-    public SimpleMessageSearchIndex(MessageMapperFactory messageMapperFactory, MailboxMapperFactory mailboxMapperFactory) {
+    public SimpleMessageSearchIndex(MessageMapperFactory messageMapperFactory, MailboxMapperFactory mailboxMapperFactory, TextExtractor textExtractor) {
         this.messageMapperFactory = messageMapperFactory;
         this.mailboxMapperFactory = mailboxMapperFactory;
+        this.textExtractor = textExtractor;
     }
     
     @Override
     public EnumSet<SearchCapabilities> getSupportedCapabilities() {
-        return EnumSet.of(SearchCapabilities.MultimailboxSearch, SearchCapabilities.Text);
+        return EnumSet.of(SearchCapabilities.MultimailboxSearch, SearchCapabilities.Text, SearchCapabilities.Attachment);
     }
     
     /**
@@ -132,7 +136,7 @@ public class SimpleMessageSearchIndex implements MessageSearchIndex {
             	hitSet.add(m);
             }
         }
-        return ImmutableList.copyOf(new MessageSearches(hitSet.iterator(), query).iterator());
+        return ImmutableList.copyOf(new MessageSearches(hitSet.iterator(), query, textExtractor).iterator());
     }
 
     private boolean isMatchingUser(MailboxSession session, Mailbox mailbox) {

http://git-wip-us.apache.org/repos/asf/james-project/blob/d76f8fc4/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsMultipartMixedTest.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsMultipartMixedTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsMultipartMixedTest.java
index d9f6117..6a5e8df 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsMultipartMixedTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsMultipartMixedTest.java
@@ -25,9 +25,11 @@ import static org.junit.Assert.assertTrue;
 import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Iterator;
 import java.util.Locale;
 
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.extractor.TextExtractor;
 import org.apache.james.mailbox.model.SearchQuery;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
 import org.apache.james.mailbox.store.search.MessageSearches;
@@ -109,9 +111,9 @@ public class SearchUtilsMultipartMixedTest {
             + "\r\n--2.50290787509--\r\n" + "\r\n--1729--\r\n";
 
     MailboxMessage row;
-
-
     Collection<MessageUid> recent;
+    private MessageSearches messageSearches;
+
     @Before
     public void setUp() throws Exception {
         final MessageBuilder builder = new MessageBuilder();
@@ -124,100 +126,105 @@ public class SearchUtilsMultipartMixedTest {
         builder.body = Charset.forName("us-ascii").encode(BODY).array();
         row = builder.build();
         recent = new ArrayList<>();
+        
+        Iterator<MailboxMessage> messages = null;
+        SearchQuery query = null; 
+        TextExtractor textExtractor = null;
+        messageSearches = new MessageSearches(messages, query, textExtractor);
     }
     
 
     @Test
     public void testShouldNotFindWhatIsNotThere() throws Exception {
-        assertFalse(new MessageSearches().isMatch(SearchQuery.bodyContains("BOGUS"), row,
+        assertFalse(messageSearches.isMatch(SearchQuery.bodyContains("BOGUS"), row,
                 recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.mailContains("BOGUS"), row,
+        assertFalse(messageSearches.isMatch(SearchQuery.mailContains("BOGUS"), row,
                 recent));
     }
 
     @Test
     public void testBodyShouldFindTextInBody() throws Exception {
-        assertTrue(new MessageSearches().isMatch(SearchQuery
+        assertTrue(messageSearches.isMatch(SearchQuery
                 .bodyContains(SAMPLE_INNER_MAIL_BODY_ONE), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.bodyContains(SAMPLE_PART_ONE),
+        assertTrue(messageSearches.isMatch(SearchQuery.bodyContains(SAMPLE_PART_ONE),
                 row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.bodyContains(SAMPLE_PART_TWO),
+        assertTrue(messageSearches.isMatch(SearchQuery.bodyContains(SAMPLE_PART_TWO),
                 row, recent));
     }
 
     @Test
     public void testBodyShouldFindTextInBodyCaseInsensitive() throws Exception {
-        assertTrue(new MessageSearches().isMatch(SearchQuery
+        assertTrue(messageSearches.isMatch(SearchQuery
                 .bodyContains(SAMPLE_INNER_MAIL_BODY_ONE), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.bodyContains(SAMPLE_PART_ONE),
+        assertTrue(messageSearches.isMatch(SearchQuery.bodyContains(SAMPLE_PART_ONE),
                 row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.bodyContains(SAMPLE_PART_TWO),
+        assertTrue(messageSearches.isMatch(SearchQuery.bodyContains(SAMPLE_PART_TWO),
                 row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery
+        assertTrue(messageSearches.isMatch(SearchQuery
                 .bodyContains(SAMPLE_INNER_MAIL_BODY_ONE.toLowerCase(Locale.US)), row,
                 recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.bodyContains(SAMPLE_PART_ONE
+        assertTrue(messageSearches.isMatch(SearchQuery.bodyContains(SAMPLE_PART_ONE
                 .toLowerCase(Locale.US)), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.bodyContains(SAMPLE_PART_TWO
+        assertTrue(messageSearches.isMatch(SearchQuery.bodyContains(SAMPLE_PART_TWO
                 .toLowerCase(Locale.US)), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery
+        assertTrue(messageSearches.isMatch(SearchQuery
                 .bodyContains(SAMPLE_INNER_MAIL_BODY_ONE.toUpperCase(Locale.US)), row,
                 recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.bodyContains(SAMPLE_PART_ONE
+        assertTrue(messageSearches.isMatch(SearchQuery.bodyContains(SAMPLE_PART_ONE
                 .toUpperCase(Locale.US)), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.bodyContains(SAMPLE_PART_TWO
+        assertTrue(messageSearches.isMatch(SearchQuery.bodyContains(SAMPLE_PART_TWO
                 .toUpperCase(Locale.US)), row, recent));
     }
 
     @Test
     public void testBodyShouldNotFindTextInHeaders() throws Exception {
-        assertFalse(new MessageSearches().isMatch(SearchQuery
+        assertFalse(messageSearches.isMatch(SearchQuery
                 .bodyContains(SAMPLE_INNER_MAIL_FIELD), row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery
+        assertFalse(messageSearches.isMatch(SearchQuery
                 .bodyContains(SAMPLE_PART_TWO_FIELD), row, recent));
     }
 
     @Test
     public void testTextShouldFindTextInBody() throws Exception {
-        assertTrue(new MessageSearches().isMatch(SearchQuery
+        assertTrue(messageSearches.isMatch(SearchQuery
                 .mailContains(SAMPLE_INNER_MAIL_BODY_ONE), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.mailContains(SAMPLE_PART_ONE),
+        assertTrue(messageSearches.isMatch(SearchQuery.mailContains(SAMPLE_PART_ONE),
                 row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.mailContains(SAMPLE_PART_TWO),
+        assertTrue(messageSearches.isMatch(SearchQuery.mailContains(SAMPLE_PART_TWO),
                 row, recent));
     }
 
     @Test
     public void testTextShouldFindTextInBodyCaseInsensitive() throws Exception {
-        assertTrue(new MessageSearches().isMatch(SearchQuery
+        assertTrue(messageSearches.isMatch(SearchQuery
                 .mailContains(SAMPLE_INNER_MAIL_BODY_ONE), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.mailContains(SAMPLE_PART_ONE),
+        assertTrue(messageSearches.isMatch(SearchQuery.mailContains(SAMPLE_PART_ONE),
                 row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.mailContains(SAMPLE_PART_TWO),
+        assertTrue(messageSearches.isMatch(SearchQuery.mailContains(SAMPLE_PART_TWO),
                 row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery
+        assertTrue(messageSearches.isMatch(SearchQuery
                 .mailContains(SAMPLE_INNER_MAIL_BODY_ONE.toLowerCase(Locale.US)), row,
                 recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.mailContains(SAMPLE_PART_ONE
+        assertTrue(messageSearches.isMatch(SearchQuery.mailContains(SAMPLE_PART_ONE
                 .toLowerCase(Locale.US)), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.mailContains(SAMPLE_PART_TWO
+        assertTrue(messageSearches.isMatch(SearchQuery.mailContains(SAMPLE_PART_TWO
                 .toLowerCase(Locale.US)), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery
+        assertTrue(messageSearches.isMatch(SearchQuery
                 .mailContains(SAMPLE_INNER_MAIL_BODY_ONE.toUpperCase(Locale.US)), row,
                 recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.mailContains(SAMPLE_PART_ONE
+        assertTrue(messageSearches.isMatch(SearchQuery.mailContains(SAMPLE_PART_ONE
                 .toUpperCase(Locale.US)), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.mailContains(SAMPLE_PART_TWO
+        assertTrue(messageSearches.isMatch(SearchQuery.mailContains(SAMPLE_PART_TWO
                 .toUpperCase(Locale.US)), row, recent));
     }
 
     @Test
     public void testTextShouldFindTextInHeaders() throws Exception {
-        assertTrue(new MessageSearches().isMatch(SearchQuery
+        assertTrue(messageSearches.isMatch(SearchQuery
                 .mailContains(SAMPLE_INNER_MAIL_FIELD), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery
+        assertTrue(messageSearches.isMatch(SearchQuery
                 .mailContains(SAMPLE_INNER_MAIL_BODY_ONE), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery
+        assertTrue(messageSearches.isMatch(SearchQuery
                 .mailContains(SAMPLE_PART_TWO_FIELD), row, recent));
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/d76f8fc4/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsRFC822Test.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsRFC822Test.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsRFC822Test.java
index 8f8d9d3..32ff7c8 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsRFC822Test.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/SearchUtilsRFC822Test.java
@@ -25,9 +25,11 @@ import static org.junit.Assert.assertTrue;
 import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Iterator;
 import java.util.Locale;
 
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.extractor.TextExtractor;
 import org.apache.james.mailbox.model.SearchQuery;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
 import org.apache.james.mailbox.store.search.MessageSearches;
@@ -52,6 +54,8 @@ public class SearchUtilsRFC822Test {
 
     Collection<MessageUid> recent;
 
+    private MessageSearches messageSearches;
+
     @Before
     public void setUp() throws Exception {
         recent = new ArrayList<>();
@@ -62,58 +66,63 @@ public class SearchUtilsRFC822Test {
         builder.header("Date", "Thu, 14 Feb 2008 12:00:00 +0000 (GMT)");
         builder.body = Charset.forName("us-ascii").encode(BODY).array();
         row = builder.build();
+        
+        Iterator<MailboxMessage> messages = null;
+        SearchQuery query = null; 
+        TextExtractor textExtractor = null;
+        messageSearches = new MessageSearches(messages, query, textExtractor);
     }
 
 
     @Test
     public void testBodyShouldMatchPhraseInBody() throws Exception {
-        assertTrue(new MessageSearches().isMatch(SearchQuery.bodyContains(CUSTARD), row,
+        assertTrue(messageSearches.isMatch(SearchQuery.bodyContains(CUSTARD), row,
                 recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery
+        assertFalse(messageSearches.isMatch(SearchQuery
                 .bodyContains(CUSTARD + CUSTARD), row, recent));
     }
 
     @Test
     public void testBodyMatchShouldBeCaseInsensitive() throws Exception {
-        assertTrue(new MessageSearches().isMatch(SearchQuery.bodyContains(RHUBARD), row,
+        assertTrue(messageSearches.isMatch(SearchQuery.bodyContains(RHUBARD), row,
                 recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.bodyContains(RHUBARD
+        assertTrue(messageSearches.isMatch(SearchQuery.bodyContains(RHUBARD
                 .toLowerCase(Locale.US)), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.bodyContains(RHUBARD
+        assertTrue(messageSearches.isMatch(SearchQuery.bodyContains(RHUBARD
                 .toLowerCase(Locale.US)), row, recent));
     }
 
     @Test
     public void testBodyShouldNotMatchPhraseOnlyInHeader() throws Exception {
-        assertFalse(new MessageSearches().isMatch(SearchQuery.bodyContains(FROM_ADDRESS),
+        assertFalse(messageSearches.isMatch(SearchQuery.bodyContains(FROM_ADDRESS),
                 row, recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery.bodyContains(SUBJECT_PART),
+        assertFalse(messageSearches.isMatch(SearchQuery.bodyContains(SUBJECT_PART),
                 row, recent));
     }
 
     @Test
     public void testTextShouldMatchPhraseInBody() throws Exception {
-        assertTrue(new MessageSearches().isMatch(SearchQuery.mailContains(CUSTARD), row,
+        assertTrue(messageSearches.isMatch(SearchQuery.mailContains(CUSTARD), row,
                 recent));
-        assertFalse(new MessageSearches().isMatch(SearchQuery
+        assertFalse(messageSearches.isMatch(SearchQuery
                 .mailContains(CUSTARD + CUSTARD), row, recent));
     }
 
     @Test
     public void testTextMatchShouldBeCaseInsensitive() throws Exception {
-        assertTrue(new MessageSearches().isMatch(SearchQuery.mailContains(RHUBARD), row,
+        assertTrue(messageSearches.isMatch(SearchQuery.mailContains(RHUBARD), row,
                 recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.mailContains(RHUBARD
+        assertTrue(messageSearches.isMatch(SearchQuery.mailContains(RHUBARD
                 .toLowerCase(Locale.US)), row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.mailContains(RHUBARD
+        assertTrue(messageSearches.isMatch(SearchQuery.mailContains(RHUBARD
                 .toLowerCase(Locale.US)), row, recent));
     }
 
     @Test
     public void testBodyShouldMatchPhraseOnlyInHeader() throws Exception {
-        assertTrue(new MessageSearches().isMatch(SearchQuery.mailContains(FROM_ADDRESS),
+        assertTrue(messageSearches.isMatch(SearchQuery.mailContains(FROM_ADDRESS),
                 row, recent));
-        assertTrue(new MessageSearches().isMatch(SearchQuery.mailContains(SUBJECT_PART),
+        assertTrue(messageSearches.isMatch(SearchQuery.mailContains(SUBJECT_PART),
                 row, recent));
     }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[6/7] james-project git commit: JAMES-2137 Correct advertised Search capabilities

Posted by ad...@apache.org.
JAMES-2137 Correct advertised Search capabilities

 - Scanning search Attachment capability depends on **Attachment Message Capability**
 - Scanning search DOES NOT support Full text search
 - Lucene DOES support multi-mailbox search (test passes)
 - JMAP should not enforce Full Text search to start


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/5bd16049
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/5bd16049
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/5bd16049

Branch: refs/heads/master
Commit: 5bd16049be80669b720d5c4c06b9984d849f2767
Parents: 11e336a
Author: benwa <bt...@linagora.com>
Authored: Fri Sep 8 10:57:50 2017 +0700
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Fri Sep 8 21:58:03 2017 +0200

----------------------------------------------------------------------
 .../ElasticSearchListeningMessageSearchIndex.java    |  3 ++-
 .../lucene/search/LuceneMessageSearchIndex.java      |  6 ++++--
 .../james/mailbox/store/StoreMailboxManager.java     |  2 +-
 .../mailbox/store/search/LazyMessageSearchIndex.java |  3 ++-
 .../mailbox/store/search/MessageSearchIndex.java     |  2 +-
 .../store/search/SimpleMessageSearchIndex.java       | 11 +++++++++--
 .../store/search/AbstractMessageSearchIndexTest.java |  2 +-
 .../apache/james/JamesCapabilitiesServerTest.java    | 15 ---------------
 .../main/java/org/apache/james/jmap/JMAPModule.java  |  2 --
 9 files changed, 20 insertions(+), 26 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/5bd16049/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 f36ffdb..3ecf84d 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
@@ -29,6 +29,7 @@ import java.util.stream.Collectors;
 import javax.inject.Inject;
 
 import org.apache.james.backends.es.ElasticSearchIndexer;
+import org.apache.james.mailbox.MailboxManager.MessageCapabilities;
 import org.apache.james.mailbox.MailboxManager.SearchCapabilities;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
@@ -77,7 +78,7 @@ public class ElasticSearchListeningMessageSearchIndex extends ListeningMessageSe
     }
 
     @Override
-    public EnumSet<SearchCapabilities> getSupportedCapabilities() {
+    public EnumSet<SearchCapabilities> getSupportedCapabilities(EnumSet<MessageCapabilities> messageCapabilities) {
         return EnumSet.of(SearchCapabilities.MultimailboxSearch, SearchCapabilities.Text, SearchCapabilities.FullText, SearchCapabilities.Attachment);
     }
     

http://git-wip-us.apache.org/repos/asf/james-project/blob/5bd16049/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 dcf9abc..1e7d632 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
@@ -36,6 +36,7 @@ import java.util.Locale;
 import java.util.Optional;
 import java.util.Set;
 import java.util.TimeZone;
+
 import javax.inject.Inject;
 import javax.mail.Flags;
 import javax.mail.Flags.Flag;
@@ -402,8 +403,9 @@ public class LuceneMessageSearchIndex extends ListeningMessageSearchIndex {
 
 
     @Override
-    public EnumSet<SearchCapabilities> getSupportedCapabilities() {
-        return EnumSet.noneOf(SearchCapabilities.class);
+    public EnumSet<SearchCapabilities> getSupportedCapabilities(EnumSet<MailboxManager.MessageCapabilities> messageCapabilities) {
+        return EnumSet.of(SearchCapabilities.MultimailboxSearch);
+
     }
     
     /**

http://git-wip-us.apache.org/repos/asf/james-project/blob/5bd16049/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 818cc97..710790b 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
@@ -286,7 +286,7 @@ public class StoreMailboxManager implements MailboxManager {
     
     @Override
     public EnumSet<SearchCapabilities> getSupportedSearchCapabilities() {
-        return index.getSupportedCapabilities();
+        return index.getSupportedCapabilities(getSupportedMessageCapabilities());
     }
     
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/5bd16049/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 f4c9947..90146d2 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
@@ -23,6 +23,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.concurrent.ConcurrentHashMap;
 
+import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxManager.SearchCapabilities;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
@@ -70,7 +71,7 @@ public class LazyMessageSearchIndex extends ListeningMessageSearchIndex {
     }
     
     @Override
-    public EnumSet<SearchCapabilities> getSupportedCapabilities() {
+    public EnumSet<SearchCapabilities> getSupportedCapabilities(EnumSet<MailboxManager.MessageCapabilities> messageCapabilities) {
         return EnumSet.noneOf(SearchCapabilities.class);
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/5bd16049/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 496f481..df7924f 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
@@ -52,7 +52,7 @@ public interface MessageSearchIndex {
      */
     List<MessageId> search(MailboxSession session, MultimailboxesSearchQuery searchQuery, long limit) throws MailboxException;
 
-    EnumSet<MailboxManager.SearchCapabilities> getSupportedCapabilities();
+    EnumSet<MailboxManager.SearchCapabilities> getSupportedCapabilities(EnumSet<MailboxManager.MessageCapabilities> messageCapabilities);
 
     class SearchResult {
         private final Optional<MessageId> messageId;

http://git-wip-us.apache.org/repos/asf/james-project/blob/5bd16049/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 6388fff..55297c0 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
@@ -27,6 +27,7 @@ import java.util.stream.Stream;
 
 import javax.inject.Inject;
 
+import org.apache.james.mailbox.MailboxManager.MessageCapabilities;
 import org.apache.james.mailbox.MailboxManager.SearchCapabilities;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageUid;
@@ -76,8 +77,14 @@ public class SimpleMessageSearchIndex implements MessageSearchIndex {
     }
     
     @Override
-    public EnumSet<SearchCapabilities> getSupportedCapabilities() {
-        return EnumSet.of(SearchCapabilities.MultimailboxSearch, SearchCapabilities.Text, SearchCapabilities.FullText, SearchCapabilities.Attachment);
+    public EnumSet<SearchCapabilities> getSupportedCapabilities(EnumSet<MessageCapabilities> messageCapabilities) {
+        if (messageCapabilities.contains(MessageCapabilities.Attachment)) {
+            return EnumSet.of(SearchCapabilities.MultimailboxSearch,
+                SearchCapabilities.Text,
+                SearchCapabilities.Attachment);
+        }
+        return EnumSet.of(SearchCapabilities.MultimailboxSearch,
+            SearchCapabilities.Text);
     }
     
     /**

http://git-wip-us.apache.org/repos/asf/james-project/blob/5bd16049/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/AbstractMessageSearchIndexTest.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/AbstractMessageSearchIndexTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/AbstractMessageSearchIndexTest.java
index 9fc2062..ba74c82 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/AbstractMessageSearchIndexTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/AbstractMessageSearchIndexTest.java
@@ -1113,7 +1113,7 @@ public abstract class AbstractMessageSearchIndexTest {
     }
 
     @Test
-    public void searchWithFulTextShouldReturnMailsWhenToAndBodyAndAttachmentMatches() throws Exception {
+    public void searchWithFullTextShouldReturnMailsWhenNotAPerfectMatch() throws Exception {
         Assume.assumeTrue(storeMailboxManager.getSupportedSearchCapabilities().contains(MailboxManager.SearchCapabilities.FullText));
         ComposedMessageId messageWithBeautifulBananaAsTextAttachment = myFolderMessageManager.appendMessage(
                 ClassLoader.getSystemResourceAsStream("eml/emailWithTextAttachment.eml"),

http://git-wip-us.apache.org/repos/asf/james-project/blob/5bd16049/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesCapabilitiesServerTest.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesCapabilitiesServerTest.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesCapabilitiesServerTest.java
index e0f447c..5b03a23 100644
--- a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesCapabilitiesServerTest.java
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/JamesCapabilitiesServerTest.java
@@ -101,21 +101,6 @@ public class JamesCapabilitiesServerTest {
     }
     
     @Test
-    public void startShouldFailWhenNoFullTextCapability() throws Exception {
-        MailboxManager mailboxManager = mock(MailboxManager.class);
-        when(mailboxManager.getSupportedMailboxCapabilities())
-            .thenReturn(EnumSet.allOf(MailboxManager.MailboxCapabilities.class));
-        when(mailboxManager.getSupportedMessageCapabilities())
-            .thenReturn(EnumSet.allOf(MailboxManager.MessageCapabilities.class));
-        when(mailboxManager.getSupportedSearchCapabilities())
-            .thenReturn(EnumSet.complementOf(EnumSet.of(MailboxManager.SearchCapabilities.FullText)));
-
-        server = createCassandraJamesServer(mailboxManager);
-
-        assertThatThrownBy(() -> server.start()).isInstanceOf(IllegalArgumentException.class);
-    }
-    
-    @Test
     public void startShouldFailWhenNoAttachmentSearchCapability() throws Exception {
         MailboxManager mailboxManager = mock(MailboxManager.class);
         when(mailboxManager.getSupportedMailboxCapabilities())

http://git-wip-us.apache.org/repos/asf/james-project/blob/5bd16049/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java
index 9150680..b0909a5 100644
--- a/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java
+++ b/server/container/guice/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPModule.java
@@ -151,8 +151,6 @@ public class JMAPModule extends AbstractModule {
             EnumSet<SearchCapabilities> searchCapabilities = mailboxManager.getSupportedSearchCapabilities();
             Preconditions.checkArgument(searchCapabilities.contains(MailboxManager.SearchCapabilities.MultimailboxSearch),
                     "Multimailbox search in MailboxManager is required by JMAP Module");
-            Preconditions.checkArgument(searchCapabilities.contains(MailboxManager.SearchCapabilities.FullText),
-                    "FullText support in MailboxManager is required by JMAP Module");
             Preconditions.checkArgument(searchCapabilities.contains(MailboxManager.SearchCapabilities.Attachment),
                     "Attachment Search support in MailboxManager is required by JMAP Module");
         }


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org