Repository: james-project
Updated Branches:
  refs/heads/master 0d416804a -> 4bf777b1e


MAILBOX-314 search: precise spec about search on email and fix ES impl


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

Branch: refs/heads/master
Commit: 4bf777b1e8640a0a0ee721fca2a814e42f60837a
Parents: 0d41680
Author: Luc DUZAN <ldu...@linagora.com>
Authored: Thu Oct 26 17:06:26 2017 +0700
Committer: Matthieu Baechler <matth...@apache.org>
Committed: Mon Mar 26 15:27:46 2018 +0200

----------------------------------------------------------------------
 .../james/backends/es/IndexCreationFactory.java |  28 +++
 .../james/backends/es/NodeMappingFactory.java   |   2 +
 .../apache/james/mailbox/MailboxManager.java    |   1 +
 .../elasticsearch/MailboxMappingFactory.java    |  81 ++++++++-
 ...lasticSearchListeningMessageSearchIndex.java |   7 +-
 .../elasticsearch/query/CriterionConverter.java |  18 +-
 .../elasticsearch/query/SortConverter.java      |   2 +-
 .../store/search/SimpleMessageSearchIndex.java  |   3 +-
 .../search/AbstractMessageSearchIndexTest.java  | 172 ++++++++++++++++++-
 mailbox/store/src/test/resources/eml/mail4.eml  |   4 +-
 mailbox/store/src/test/resources/eml/mail5.eml  |  13 ++
 11 files changed, 310 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/4bf777b1/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/IndexCreationFactory.java
----------------------------------------------------------------------
diff --git 
a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/IndexCreationFactory.java
 
b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/IndexCreationFactory.java
index 22c4943..7da3d8a 100644
--- 
a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/IndexCreationFactory.java
+++ 
b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/IndexCreationFactory.java
@@ -41,6 +41,9 @@ public class IndexCreationFactory {
     private static final int DEFAULT_NB_SHARDS = 1;
     private static final int DEFAULT_NB_REPLICA = 0;
     public static final String CASE_INSENSITIVE = "case_insensitive";
+    public static final String KEEP_MAIL_AND_URL = "keep_mail_and_url";
+    public static final String SNOWBALL_KEEP_MAIL_AND_URL = 
"snowball_keep_mail_and_token";
+    public static final String ENGLISH_SNOWBALL = "english_snowball";
 
     private IndexName indexName;
     private ArrayList<AliasName> aliases;
@@ -137,6 +140,31 @@ public class IndexCreationFactory {
                             .endArray()
                         .endObject()
                     .endObject()
+                    .startObject("analyzer")
+                        .startObject(KEEP_MAIL_AND_URL)
+                            .field("tokenizer", "uax_url_email")
+                            .startArray("filter")
+                                .value("lowercase")
+                                .value("stop")
+                            .endArray()
+                        .endObject()
+                    .endObject()
+                    .startObject("filter")
+                        .startObject(ENGLISH_SNOWBALL)
+                            .field("type", "snowball")
+                            .field("language", "English")
+                        .endObject()
+                    .endObject()
+                    .startObject("analyzer")
+                        .startObject(SNOWBALL_KEEP_MAIL_AND_URL)
+                        .field("tokenizer", "uax_url_email")
+                            .startArray("filter")
+                                .value("lowercase")
+                                .value("stop")
+                                .value(ENGLISH_SNOWBALL)
+                            .endArray()
+                        .endObject()
+                    .endObject()
                 .endObject()
             .endObject();
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/4bf777b1/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/NodeMappingFactory.java
----------------------------------------------------------------------
diff --git 
a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/NodeMappingFactory.java
 
b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/NodeMappingFactory.java
index 3d16dc4..9c48526 100644
--- 
a/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/NodeMappingFactory.java
+++ 
b/backends-common/elasticsearch/src/main/java/org/apache/james/backends/es/NodeMappingFactory.java
@@ -36,7 +36,9 @@ public class NodeMappingFactory {
     public static final String NESTED = "nested";
     public static final String FIELDS = "fields";
     public static final String RAW = "raw";
+    public static final String SPLIT_EMAIL = "splitEmail";
     public static final String ANALYZER = "analyzer";
+    public static final String SEARCH_ANALYZER = "search_analyzer";
     public static final String SNOWBALL = "snowball";
     public static final String IGNORE_ABOVE = "ignore_above";
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/4bf777b1/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 67b122d..3374e4e 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
@@ -91,6 +91,7 @@ public interface MailboxManager extends RequestAware, 
MailboxListenerSupport, Ri
 
     enum SearchCapabilities {
         MultimailboxSearch,
+        PartialEmailMatch,
         /**
          *  The implementation supporting this capability should
          *  provide an index on the fields: 

http://git-wip-us.apache.org/repos/asf/james-project/blob/4bf777b1/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/MailboxMappingFactory.java
----------------------------------------------------------------------
diff --git 
a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/MailboxMappingFactory.java
 
b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/MailboxMappingFactory.java
index 25a1639..506b73c 100644
--- 
a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/MailboxMappingFactory.java
+++ 
b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/MailboxMappingFactory.java
@@ -20,6 +20,8 @@
 package org.apache.james.mailbox.elasticsearch;
 
 import static 
org.apache.james.backends.es.IndexCreationFactory.CASE_INSENSITIVE;
+import static 
org.apache.james.backends.es.IndexCreationFactory.KEEP_MAIL_AND_URL;
+import static 
org.apache.james.backends.es.IndexCreationFactory.SNOWBALL_KEEP_MAIL_AND_URL;
 import static org.apache.james.backends.es.NodeMappingFactory.ANALYZER;
 import static org.apache.james.backends.es.NodeMappingFactory.BOOLEAN;
 import static org.apache.james.backends.es.NodeMappingFactory.FIELDS;
@@ -31,7 +33,9 @@ import static 
org.apache.james.backends.es.NodeMappingFactory.NESTED;
 import static org.apache.james.backends.es.NodeMappingFactory.NOT_ANALYZED;
 import static org.apache.james.backends.es.NodeMappingFactory.PROPERTIES;
 import static org.apache.james.backends.es.NodeMappingFactory.RAW;
+import static org.apache.james.backends.es.NodeMappingFactory.SEARCH_ANALYZER;
 import static org.apache.james.backends.es.NodeMappingFactory.SNOWBALL;
+import static org.apache.james.backends.es.NodeMappingFactory.SPLIT_EMAIL;
 import static org.apache.james.backends.es.NodeMappingFactory.STRING;
 import static org.apache.james.backends.es.NodeMappingFactory.TYPE;
 import static 
org.apache.james.mailbox.elasticsearch.json.JsonMessageConstants.BCC;
@@ -74,6 +78,7 @@ import com.google.common.base.Throwables;
 public class MailboxMappingFactory {
 
     private static final int MAXIMUM_TERM_LENGTH = 4096;
+    private static final String STANDARD = "standard";
 
     public static XContentBuilder getMappingContent() {
         try {
@@ -154,6 +159,7 @@ public class MailboxMappingFactory {
                                 .startObject(PROPERTIES)
                                     .startObject(EMailer.NAME)
                                         .field(TYPE, STRING)
+                                        .field(ANALYZER, KEEP_MAIL_AND_URL)
                                         .startObject(FIELDS)
                                             .startObject(RAW)
                                                 .field(TYPE, STRING)
@@ -163,13 +169,21 @@ public class MailboxMappingFactory {
                                     .endObject()
                                     .startObject(EMailer.ADDRESS)
                                         .field(TYPE, STRING)
-                                        .field(INDEX, NOT_ANALYZED)
+                                        .field(ANALYZER, STANDARD)
+                                        .field(SEARCH_ANALYZER, 
KEEP_MAIL_AND_URL)
+                                        .startObject(FIELDS)
+                                            .startObject(RAW)
+                                                .field(TYPE, STRING)
+                                                .field(ANALYZER, 
CASE_INSENSITIVE)
+                                            .endObject()
+                                        .endObject()
                                     .endObject()
                                 .endObject()
                             .endObject()
 
                             .startObject(SUBJECT)
                                 .field(TYPE, STRING)
+                                .field(ANALYZER, KEEP_MAIL_AND_URL)
                                 .startObject(FIELDS)
                                     .startObject(RAW)
                                         .field(TYPE, STRING)
@@ -183,6 +197,7 @@ public class MailboxMappingFactory {
                                 .startObject(PROPERTIES)
                                     .startObject(EMailer.NAME)
                                         .field(TYPE, STRING)
+                                        .field(ANALYZER, KEEP_MAIL_AND_URL)
                                         .startObject(FIELDS)
                                             .startObject(RAW)
                                                 .field(TYPE, STRING)
@@ -192,7 +207,14 @@ public class MailboxMappingFactory {
                                     .endObject()
                                     .startObject(EMailer.ADDRESS)
                                         .field(TYPE, STRING)
-                                        .field(INDEX, NOT_ANALYZED)
+                                        .field(ANALYZER, STANDARD)
+                                        .field(SEARCH_ANALYZER, 
KEEP_MAIL_AND_URL)
+                                        .startObject(FIELDS)
+                                            .startObject(RAW)
+                                                .field(TYPE, STRING)
+                                                .field(ANALYZER, 
CASE_INSENSITIVE)
+                                            .endObject()
+                                        .endObject()
                                     .endObject()
                                 .endObject()
                             .endObject()
@@ -202,10 +224,24 @@ public class MailboxMappingFactory {
                                 .startObject(PROPERTIES)
                                     .startObject(EMailer.NAME)
                                         .field(TYPE, STRING)
+                                        .field(ANALYZER, KEEP_MAIL_AND_URL)
+                                        .startObject(FIELDS)
+                                            .startObject(RAW)
+                                                .field(TYPE, STRING)
+                                                .field(ANALYZER, 
CASE_INSENSITIVE)
+                                            .endObject()
+                                        .endObject()
                                     .endObject()
                                     .startObject(EMailer.ADDRESS)
                                         .field(TYPE, STRING)
-                                        .field(INDEX, NOT_ANALYZED)
+                                        .field(ANALYZER, STANDARD)
+                                        .field(SEARCH_ANALYZER, 
KEEP_MAIL_AND_URL)
+                                        .startObject(FIELDS)
+                                            .startObject(RAW)
+                                            .field(TYPE, STRING)
+                                            .field(ANALYZER, CASE_INSENSITIVE)
+                                            .endObject()
+                                        .endObject()
                                     .endObject()
                                 .endObject()
                             .endObject()
@@ -215,10 +251,24 @@ public class MailboxMappingFactory {
                                 .startObject(PROPERTIES)
                                     .startObject(EMailer.NAME)
                                         .field(TYPE, STRING)
+                                        .field(ANALYZER, KEEP_MAIL_AND_URL)
+                                        .startObject(FIELDS)
+                                            .startObject(RAW)
+                                                .field(TYPE, STRING)
+                                                .field(ANALYZER, 
CASE_INSENSITIVE)
+                                            .endObject()
+                                        .endObject()
                                     .endObject()
                                     .startObject(EMailer.ADDRESS)
                                         .field(TYPE, STRING)
-                                        .field(INDEX, NOT_ANALYZED)
+                                        .field(ANALYZER, STANDARD)
+                                        .field(SEARCH_ANALYZER, 
KEEP_MAIL_AND_URL)
+                                        .startObject(FIELDS)
+                                            .startObject(RAW)
+                                                .field(TYPE, STRING)
+                                                .field(ANALYZER, 
CASE_INSENSITIVE)
+                                            .endObject()
+                                        .endObject()
                                     .endObject()
                                 .endObject()
                             .endObject()
@@ -246,13 +296,20 @@ public class MailboxMappingFactory {
                                     .endObject()
                                     .startObject(Property.VALUE)
                                         .field(TYPE, STRING)
+                                        .field(INDEX, NOT_ANALYZED)
                                     .endObject()
                                 .endObject()
                             .endObject()
 
                             .startObject(TEXT_BODY)
                                 .field(TYPE, STRING)
+                                .field(ANALYZER, KEEP_MAIL_AND_URL)
                                 .startObject(FIELDS)
+                                    .startObject(SPLIT_EMAIL)
+                                        .field(TYPE, STRING)
+                                        .field(ANALYZER, STANDARD)
+                                        .field(SEARCH_ANALYZER, 
KEEP_MAIL_AND_URL)
+                                    .endObject()
                                     .startObject(RAW)
                                         .field(TYPE, STRING)
                                         .field(ANALYZER, CASE_INSENSITIVE)
@@ -263,7 +320,13 @@ public class MailboxMappingFactory {
 
                             .startObject(HTML_BODY)
                                 .field(TYPE, STRING)
+                                .field(ANALYZER, KEEP_MAIL_AND_URL)
                                 .startObject(FIELDS)
+                                    .startObject(SPLIT_EMAIL)
+                                        .field(TYPE, STRING)
+                                        .field(ANALYZER, STANDARD)
+                                        .field(SEARCH_ANALYZER, 
KEEP_MAIL_AND_URL)
+                                    .endObject()
                                     .startObject(RAW)
                                         .field(TYPE, STRING)
                                         .field(ANALYZER, CASE_INSENSITIVE)
@@ -278,8 +341,15 @@ public class MailboxMappingFactory {
 
                             .startObject(TEXT)
                                 .field(TYPE, STRING)
-                                .field(ANALYZER, SNOWBALL)
+                                .field(ANALYZER, SNOWBALL_KEEP_MAIL_AND_URL)
                                 .field(IGNORE_ABOVE, MAXIMUM_TERM_LENGTH)
+                                .startObject(FIELDS)
+                                    .startObject(SPLIT_EMAIL)
+                                        .field(TYPE, STRING)
+                                        .field(ANALYZER, SNOWBALL)
+                                        .field(SEARCH_ANALYZER, 
SNOWBALL_KEEP_MAIL_AND_URL)
+                                    .endObject()
+                                .endObject()
                             .endObject()
                         .endObject()
                     .endObject()
@@ -288,5 +358,4 @@ public class MailboxMappingFactory {
             throw Throwables.propagate(e);
         }
     }
-
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/4bf777b1/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 fb378ee..ed47b44 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
@@ -79,7 +79,12 @@ public class ElasticSearchListeningMessageSearchIndex 
extends ListeningMessageSe
 
     @Override
     public EnumSet<SearchCapabilities> 
getSupportedCapabilities(EnumSet<MessageCapabilities> messageCapabilities) {
-        return EnumSet.of(SearchCapabilities.MultimailboxSearch, 
SearchCapabilities.Text, SearchCapabilities.FullText, 
SearchCapabilities.Attachment);
+        return EnumSet.of(
+            SearchCapabilities.MultimailboxSearch,
+            SearchCapabilities.Text,
+            SearchCapabilities.FullText,
+            SearchCapabilities.Attachment,
+            SearchCapabilities.PartialEmailMatch);
     }
     
     @Override

http://git-wip-us.apache.org/repos/asf/james-project/blob/4bf777b1/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 dd61fb9..ab1cf0d 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
@@ -19,6 +19,8 @@
 
 package org.apache.james.mailbox.elasticsearch.query;
 
+import static org.apache.james.backends.es.NodeMappingFactory.RAW;
+import static org.apache.james.backends.es.NodeMappingFactory.SPLIT_EMAIL;
 import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
 import static org.elasticsearch.index.query.QueryBuilders.existsQuery;
 import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
@@ -136,13 +138,24 @@ public class CriterionConverter {
         case BODY:
             return boolQuery()
                     .should(matchQuery(JsonMessageConstants.TEXT_BODY, 
textCriterion.getOperator().getValue()))
+                    .should(matchQuery(JsonMessageConstants.TEXT_BODY + "." + 
SPLIT_EMAIL,
+                        textCriterion.getOperator().getValue()))
+                    .should(matchQuery(JsonMessageConstants.HTML_BODY + "." + 
SPLIT_EMAIL,
+                        textCriterion.getOperator().getValue()))
                     .should(matchQuery(JsonMessageConstants.HTML_BODY, 
textCriterion.getOperator().getValue()));
         case TEXT:
             return boolQuery()
-                    .should(matchQuery(JsonMessageConstants.TEXT, 
textCriterion.getOperator().getValue()));
+                    .should(matchQuery(JsonMessageConstants.TEXT, 
textCriterion.getOperator().getValue()))
+                    .should(matchQuery(JsonMessageConstants.TEXT + "." + 
SPLIT_EMAIL,
+                        textCriterion.getOperator().getValue()));
         case FULL:
             return boolQuery()
                     .should(matchQuery(JsonMessageConstants.TEXT_BODY, 
textCriterion.getOperator().getValue()))
+                    .should(matchQuery(JsonMessageConstants.TEXT_BODY + "." + 
SPLIT_EMAIL,
+                        textCriterion.getOperator().getValue()))
+                    .should(matchQuery(JsonMessageConstants.HTML_BODY + "." + 
SPLIT_EMAIL,
+                        textCriterion.getOperator().getValue()))
+                    .should(matchQuery(JsonMessageConstants.HTML_BODY, 
textCriterion.getOperator().getValue()))
                     .should(matchQuery(JsonMessageConstants.HTML_BODY, 
textCriterion.getOperator().getValue()))
                     .should(matchQuery(JsonMessageConstants.ATTACHMENTS + "." 
+ JsonMessageConstants.Attachment.TEXT_CONTENT,
                         textCriterion.getOperator().getValue()));
@@ -255,7 +268,8 @@ public class CriterionConverter {
     private QueryBuilder manageAddressFields(String headerName, String value) {
         return nestedQuery(getFieldNameFromHeaderName(headerName), boolQuery()
             .should(matchQuery(getFieldNameFromHeaderName(headerName) + "." + 
JsonMessageConstants.EMailer.NAME, value))
-            .should(matchQuery(getFieldNameFromHeaderName(headerName) + "." + 
JsonMessageConstants.EMailer.ADDRESS, value)));
+            .should(matchQuery(getFieldNameFromHeaderName(headerName) + "." + 
JsonMessageConstants.EMailer.ADDRESS, value))
+            .should(matchQuery(getFieldNameFromHeaderName(headerName) + "." + 
JsonMessageConstants.EMailer.ADDRESS + "." + RAW, value)));
     }
 
     private String getFieldNameFromHeaderName(String headerName) {

http://git-wip-us.apache.org/repos/asf/james-project/blob/4bf777b1/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/SortConverter.java
----------------------------------------------------------------------
diff --git 
a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/SortConverter.java
 
b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/SortConverter.java
index ebcc557..a6bad82 100644
--- 
a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/SortConverter.java
+++ 
b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/SortConverter.java
@@ -51,7 +51,7 @@ public class SortConverter {
                 return SortBuilders.fieldSort(JsonMessageConstants.TO + 
PATH_SEPARATOR + JsonMessageConstants.EMailer.ADDRESS)
                     .setNestedPath(JsonMessageConstants.TO);
             case BaseSubject :
-                return SortBuilders.fieldSort(JsonMessageConstants.SUBJECT);
+                return SortBuilders.fieldSort(JsonMessageConstants.SUBJECT + 
PATH_SEPARATOR + NodeMappingFactory.RAW);
             case Size :
                 return SortBuilders.fieldSort(JsonMessageConstants.SIZE);
             case SentDate :

http://git-wip-us.apache.org/repos/asf/james-project/blob/4bf777b1/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 2b15b6f..d9b4c1d 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
@@ -81,7 +81,8 @@ public class SimpleMessageSearchIndex implements 
MessageSearchIndex {
         if (messageCapabilities.contains(MessageCapabilities.Attachment)) {
             return EnumSet.of(SearchCapabilities.MultimailboxSearch,
                 SearchCapabilities.Text,
-                SearchCapabilities.Attachment);
+                SearchCapabilities.Attachment,
+                SearchCapabilities.PartialEmailMatch);
         }
         return EnumSet.of(SearchCapabilities.MultimailboxSearch,
             SearchCapabilities.Text);

http://git-wip-us.apache.org/repos/asf/james-project/blob/4bf777b1/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 eda993e..f4e891e 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
@@ -95,6 +95,7 @@ public abstract class AbstractMessageSearchIndexTest {
     private StoreMessageManager myFolderMessageManager;
     private MailboxPath inboxPath;
     private MailboxPath otherInboxPath;
+    private StoreMessageManager inboxMessageManager;
 
 
     @Before
@@ -110,7 +111,7 @@ public abstract class AbstractMessageSearchIndexTest {
         storeMailboxManager.createMailbox(inboxPath, session);
         storeMailboxManager.createMailbox(otherInboxPath, otherSession);
 
-        StoreMessageManager inboxMessageManager = (StoreMessageManager) 
storeMailboxManager.getMailbox(inboxPath, session);
+        inboxMessageManager = (StoreMessageManager) 
storeMailboxManager.getMailbox(inboxPath, session);
         StoreMessageManager otherInboxMessageManager = (StoreMessageManager) 
storeMailboxManager.getMailbox(otherInboxPath, otherSession);
 
         MailboxPath myFolderPath = MailboxPath.forUser(USERNAME, "MyFolder");
@@ -421,6 +422,34 @@ public abstract class AbstractMessageSearchIndexTest {
     }
 
     @Test
+    public void searchShouldBeExactOnEmailAddresses() throws MailboxException {
+        
Assume.assumeTrue(storeMailboxManager.getSupportedSearchCapabilities().contains(MailboxManager.SearchCapabilities.Text));
+
+        ComposedMessageId m11 = inboxMessageManager.appendMessage(
+            ClassLoader.getSystemResourceAsStream("eml/mail5.eml"),
+            new Date(1396389600000L),
+            session,
+            RECENT,
+            new Flags(Flags.Flag.FLAGGED));
+
+        String emailToSearch = "luc.du...@james.apache.org";
+
+        await();
+
+        SearchQuery searchQuery = new 
SearchQuery(SearchQuery.or(ImmutableList.of(
+            SearchQuery.address(AddressType.From, emailToSearch),
+            SearchQuery.address(AddressType.To, emailToSearch),
+            SearchQuery.address(AddressType.Cc, emailToSearch),
+            SearchQuery.address(AddressType.Bcc, emailToSearch),
+            SearchQuery.headerContains("Subject", emailToSearch),
+            SearchQuery.attachmentContains(emailToSearch),
+            SearchQuery.bodyContains(emailToSearch))));
+
+        assertThat(messageSearchIndex.search(session, mailbox, searchQuery))
+            .containsOnly(m11.getUid());
+    }
+
+    @Test
     public void 
hasNoAttachmenShouldOnlyReturnMessageThatHasNoAttachmentWhichAreNotInline() 
throws MailboxException {
         SearchQuery searchQuery = new 
SearchQuery(SearchQuery.hasNoAttachment());
 
@@ -767,6 +796,30 @@ public abstract class AbstractMessageSearchIndexTest {
     }
 
     @Test
+    public void 
addressShouldReturnUidHavingRightExpeditorWhenFromIsSpecifiedWithOnlyUserPartOfEmail()
 throws Exception {
+        Assume.assumeTrue(storeMailboxManager
+            .getSupportedSearchCapabilities()
+            .contains(MailboxManager.SearchCapabilities.PartialEmailMatch));
+
+        SearchQuery searchQuery = new 
SearchQuery(SearchQuery.address(AddressType.From, "murari"));
+
+        assertThat(messageSearchIndex.search(session, mailbox, searchQuery))
+            .containsOnly(m8.getUid());
+    }
+
+    @Test
+    public void 
addressShouldReturnUidHavingRightExpeditorWhenFromIsSpecifiedWithDomainPartOfEmail()
 throws Exception {
+        Assume.assumeTrue(storeMailboxManager
+            .getSupportedSearchCapabilities()
+            .contains(MailboxManager.SearchCapabilities.PartialEmailMatch));
+
+        SearchQuery searchQuery = new 
SearchQuery(SearchQuery.address(AddressType.From, "gmail.com"));
+
+        assertThat(messageSearchIndex.search(session, mailbox, searchQuery))
+            .containsOnly(m8.getUid());
+    }
+
+    @Test
     public void addressShouldReturnUidHavingRightRecipientWhenToIsSpecified() 
throws Exception {
         SearchQuery searchQuery = new 
SearchQuery(SearchQuery.address(AddressType.To, "r...@listes.minet.net"));
 
@@ -775,14 +828,91 @@ public abstract class AbstractMessageSearchIndexTest {
     }
 
     @Test
+    public void 
addressShouldReturnUidHavingRightRecipientWhenToIsSpecifiedWithOnlyEmailUserPart()
 throws Exception {
+        Assume.assumeTrue(storeMailboxManager
+            .getSupportedSearchCapabilities()
+            .contains(MailboxManager.SearchCapabilities.PartialEmailMatch));
+
+        SearchQuery searchQuery = new 
SearchQuery(SearchQuery.address(AddressType.To, "root"));
+
+        assertThat(messageSearchIndex.search(session, mailbox, searchQuery))
+            .containsOnly(m1.getUid());
+    }
+
+    @Test
+    public void 
addressShouldReturnUidHavingRightRecipientWhenToIsSpecifiedWithOnlyDomainPartSpecified()
 throws Exception {
+        Assume.assumeTrue(storeMailboxManager
+            .getSupportedSearchCapabilities()
+            .contains(MailboxManager.SearchCapabilities.PartialEmailMatch));
+
+        SearchQuery searchQuery = new 
SearchQuery(SearchQuery.address(AddressType.To, "listes.minet.net"));
+
+        assertThat(messageSearchIndex.search(session, mailbox, searchQuery))
+            .containsOnly(m1.getUid());
+    }
+
+    @Test
     public void addressShouldReturnUidHavingRightRecipientWhenCcIsSpecified() 
throws Exception {
-        SearchQuery searchQuery = new 
SearchQuery(SearchQuery.address(AddressType.Cc, "a...@any.com"));
+        Assume.assumeTrue(storeMailboxManager
+            .getSupportedSearchCapabilities()
+            .contains(MailboxManager.SearchCapabilities.PartialEmailMatch));
+
+        SearchQuery searchQuery = new 
SearchQuery(SearchQuery.address(AddressType.Cc, "mon...@any.com"));
+        assertThat(messageSearchIndex.search(session, mailbox, searchQuery))
+            .containsOnly(m5.getUid());
+    }
+
+    @Test
+    public void 
addressShouldReturnUidHavingRightRecipientWhenCcIsSpecifiedWithOnlyUserPartOfTheEmail()
 throws Exception {
+        Assume.assumeTrue(storeMailboxManager
+            .getSupportedSearchCapabilities()
+            .contains(MailboxManager.SearchCapabilities.PartialEmailMatch));
+
+        SearchQuery searchQuery = new 
SearchQuery(SearchQuery.address(AddressType.Cc, "monkey"));
+        assertThat(messageSearchIndex.search(session, mailbox, searchQuery))
+            .containsOnly(m5.getUid());
+    }
+
+    @Test
+    public void 
addressShouldReturnUidHavingRightRecipientWhenCcIsSpecifiedWithOnlyDomainPartOfTheEmail()
 throws Exception {
+        Assume.assumeTrue(storeMailboxManager
+            .getSupportedSearchCapabilities()
+            .contains(MailboxManager.SearchCapabilities.PartialEmailMatch));
+
+        SearchQuery searchQuery = new 
SearchQuery(SearchQuery.address(AddressType.Cc, "any.com"));
+        assertThat(messageSearchIndex.search(session, mailbox, searchQuery))
+            .containsOnly(m5.getUid());
+    }
+
+    @Test
+    public void 
addressShouldReturnUidHavingRightRecipientWhenBccIsSpecifiedWithOnlyUserPartOfTheEmail()
 throws Exception {
+        Assume.assumeTrue(storeMailboxManager
+            .getSupportedSearchCapabilities()
+            .contains(MailboxManager.SearchCapabilities.PartialEmailMatch));
+
+        SearchQuery searchQuery = new 
SearchQuery(SearchQuery.address(AddressType.Bcc, "monkey"));
+
+        assertThat(messageSearchIndex.search(session, mailbox, searchQuery))
+            .containsOnly(m5.getUid());
+    }
+
+    @Test
+    public void 
addressShouldReturnUidHavingRightRecipientWhenBccIsSpecifiedWithOnlyDomainPartOfTheEmail()
 throws Exception {
+        Assume.assumeTrue(storeMailboxManager
+            .getSupportedSearchCapabilities()
+            .contains(MailboxManager.SearchCapabilities.PartialEmailMatch));
+
+        SearchQuery searchQuery = new 
SearchQuery(SearchQuery.address(AddressType.Bcc, "any.com"));
         assertThat(messageSearchIndex.search(session, mailbox, searchQuery))
             .containsOnly(m5.getUid());
     }
 
     @Test
     public void addressShouldReturnUidHavingRightRecipientWhenBccIsSpecified() 
throws Exception {
+        Assume.assumeTrue(storeMailboxManager
+            .getSupportedSearchCapabilities()
+            .contains(MailboxManager.SearchCapabilities.PartialEmailMatch));
+
         SearchQuery searchQuery = new 
SearchQuery(SearchQuery.address(AddressType.Bcc, "n...@no.com"));
 
         assertThat(messageSearchIndex.search(session, mailbox, searchQuery))
@@ -917,7 +1047,7 @@ public abstract class AbstractMessageSearchIndexTest {
         // 2 : No cc
         // 3 : Cc : a...@abc.org
         // 4 : z...@bcd.org
-        // 5 : a...@any.com
+        // 5 : mon...@any.com
     }
 
     @Test
@@ -927,7 +1057,7 @@ public abstract class AbstractMessageSearchIndexTest {
         searchQuery.setSorts(ImmutableList.of(new 
Sort(SortClause.MailboxFrom)));
 
         assertThat(messageSearchIndex.search(session, mailbox, searchQuery))
-            .containsExactly(m3.getUid(), m2.getUid(), m4.getUid(), 
m5.getUid());
+            .containsExactly(m2.getUid(), m3.getUid(), m4.getUid(), 
m5.getUid());
         // 2 : ji...@apache.org
         // 3 : ji...@apache.org
         // 4 : j...@apache.org
@@ -1047,9 +1177,17 @@ public abstract class AbstractMessageSearchIndexTest {
     }
 
     @Test
-    public void searchWithTextShouldReturnMailsWhenToMatches() throws 
Exception {
+    public void searchWithTextShouldReturnMailsWhenMatches() throws Exception {
+        
Assume.assumeTrue(storeMailboxManager.getSupportedSearchCapabilities().contains(MailboxManager.SearchCapabilities.Text));
+        SearchQuery searchQuery = new 
SearchQuery(SearchQuery.textContains("r...@listes.minet.net"));
+
+        assertThat(messageSearchIndex.search(session, mailbox, searchQuery))
+            .containsExactly(m1.getUid());
+    }
+    @Test
+    public void searchWithTextShouldReturnMailsWhenToIsNotAnExactMatches() 
throws Exception {
         
Assume.assumeTrue(storeMailboxManager.getSupportedSearchCapabilities().contains(MailboxManager.SearchCapabilities.Text));
-        SearchQuery searchQuery = new 
SearchQuery(SearchQuery.textContains("listes.minet.net"));
+        SearchQuery searchQuery = new 
SearchQuery(SearchQuery.textContains("root"));
 
         assertThat(messageSearchIndex.search(session, mailbox, searchQuery))
             .containsExactly(m1.getUid());
@@ -1058,16 +1196,34 @@ public abstract class AbstractMessageSearchIndexTest {
     @Test
     public void searchWithTextShouldReturnMailsWhenCcMatches() throws 
Exception {
         
Assume.assumeTrue(storeMailboxManager.getSupportedSearchCapabilities().contains(MailboxManager.SearchCapabilities.Text));
-        SearchQuery searchQuery = new 
SearchQuery(SearchQuery.textContains("abc.org"));
+        SearchQuery searchQuery = new 
SearchQuery(SearchQuery.textContains("a...@abc.org"));
 
         assertThat(messageSearchIndex.search(session, mailbox, searchQuery))
             .containsExactly(m3.getUid());
     }
 
     @Test
+    public void searchWithTextShouldReturnMailsWhenCcIsNotAExactMatch() throws 
Exception {
+        
Assume.assumeTrue(storeMailboxManager.getSupportedSearchCapabilities().contains(MailboxManager.SearchCapabilities.Text));
+        SearchQuery searchQuery = new 
SearchQuery(SearchQuery.textContains("monkey"));
+
+        assertThat(messageSearchIndex.search(session, mailbox, searchQuery))
+            .containsExactly(m5.getUid());
+    }
+
+    @Test
     public void searchWithTextShouldReturnMailsWhenBccMatches() throws 
Exception {
         
Assume.assumeTrue(storeMailboxManager.getSupportedSearchCapabilities().contains(MailboxManager.SearchCapabilities.Text));
-        SearchQuery searchQuery = new 
SearchQuery(SearchQuery.textContains("any.com"));
+        SearchQuery searchQuery = new 
SearchQuery(SearchQuery.textContains("mon...@any.com"));
+
+        assertThat(messageSearchIndex.search(session, mailbox, searchQuery))
+            .containsExactly(m5.getUid());
+    }
+
+    @Test
+    public void searchWithTextShouldReturnMailsWhenBccIsNotAExactMatch() 
throws Exception {
+        
Assume.assumeTrue(storeMailboxManager.getSupportedSearchCapabilities().contains(MailboxManager.SearchCapabilities.Text));
+        SearchQuery searchQuery = new 
SearchQuery(SearchQuery.textContains("monkey"));
 
         assertThat(messageSearchIndex.search(session, mailbox, searchQuery))
             .containsExactly(m5.getUid());

http://git-wip-us.apache.org/repos/asf/james-project/blob/4bf777b1/mailbox/store/src/test/resources/eml/mail4.eml
----------------------------------------------------------------------
diff --git a/mailbox/store/src/test/resources/eml/mail4.eml 
b/mailbox/store/src/test/resources/eml/mail4.eml
index 3bf6dde..ad2a5f6 100644
--- a/mailbox/store/src/test/resources/eml/mail4.eml
+++ b/mailbox/store/src/test/resources/eml/mail4.eml
@@ -37,8 +37,8 @@ Received: from arcas.apache.org (HELO arcas.apache.org) 
(140.211.11.28)
 Date: Fri, 15 May 2015 06:35:59 +0000 (UTC)
 From: "Eric Charles (JIRA)" <mailet-...@james.apache.org>
 To: "zzz" <mailet-...@james.apache.org>
-Cc: a...@any.com
-Bcc: a...@any.com
+Cc: mon...@any.com
+Bcc: mon...@any.com
 Message-ID: <jira.12825882.1430301328000.124152.1431671759...@atlassian.jira>
 In-Reply-To: <jira.12825882.1430301328...@atlassian.jira>
 References: <jira.12825882.1430301328...@atlassian.jira> 
<JIRA.12825882.1430301328925@arcas>

http://git-wip-us.apache.org/repos/asf/james-project/blob/4bf777b1/mailbox/store/src/test/resources/eml/mail5.eml
----------------------------------------------------------------------
diff --git a/mailbox/store/src/test/resources/eml/mail5.eml 
b/mailbox/store/src/test/resources/eml/mail5.eml
new file mode 100644
index 0000000..0f785c5
--- /dev/null
+++ b/mailbox/store/src/test/resources/eml/mail5.eml
@@ -0,0 +1,13 @@
+Date: Fri, 15 May 2015 06:35:59 +0000 (UTC)
+From: "Luc DUZAN (JIRA)" <luc.du...@james.apache.org>
+To: "zzz" <mailet-...@james.apache.org>
+Cc: a...@any.com
+Bcc: a...@any.com
+Message-ID: <jira.1234567...@atlassian.jira>
+Subject: This is a mail about mail!
+MIME-Version: 1.0
+Content-Type: text/plain; charset=utf-8
+Content-Transfer-Encoding: 7bit
+
+This is the body of the mail
+


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

Reply via email to