You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by ro...@apache.org on 2016/07/20 10:37:53 UTC

[1/2] james-project git commit: JAMES-1801 Replace ImmutableCollectors by Guavate

Repository: james-project
Updated Branches:
  refs/heads/master a17b49a64 -> 0ea95c34b


JAMES-1801 Replace ImmutableCollectors by Guavate


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

Branch: refs/heads/master
Commit: 0ea95c34b663888f207c1bd5e37bd352024884c0
Parents: ce1fcea
Author: Antoine Duprat <ad...@linagora.com>
Authored: Tue Jul 19 11:28:12 2016 +0200
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Wed Jul 20 11:44:48 2016 +0200

----------------------------------------------------------------------
 .../init/CassandraModuleComposite.java          |  8 +--
 .../cassandra/init/CassandraTypesProvider.java  |  4 +-
 .../mail/CassandraAttachmentMapper.java         |  4 +-
 .../cassandra/mail/CassandraMessageMapper.java  |  6 +--
 server/container/util-java8/pom.xml             |  4 ++
 .../james/util/streams/ImmutableCollectors.java | 56 --------------------
 .../util/streams/ImmutableCollectorsTest.java   | 21 ++++----
 server/pom.xml                                  |  6 +++
 server/protocols/jmap/pom.xml                   |  1 -
 .../jmap/methods/GetMessageListMethod.java      | 10 ++--
 .../james/jmap/methods/GetMessagesMethod.java   |  4 +-
 .../jmap/methods/JmapResponseWriterImpl.java    |  4 +-
 .../methods/SetMessagesCreationProcessor.java   |  6 +--
 .../james/jmap/model/GetMailboxesRequest.java   |  4 +-
 .../apache/james/jmap/model/MessageFactory.java |  8 +--
 .../james/jmap/model/MessageProperties.java     | 11 ++--
 .../james/jmap/model/SetMessagesRequest.java    |  4 +-
 .../webadmin/service/UserMailboxesService.java  |  4 +-
 .../james/webadmin/service/UserService.java     |  4 +-
 19 files changed, 61 insertions(+), 108 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/0ea95c34/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraModuleComposite.java
----------------------------------------------------------------------
diff --git a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraModuleComposite.java b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraModuleComposite.java
index bd1a52e..e46d7b7 100644
--- a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraModuleComposite.java
+++ b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraModuleComposite.java
@@ -26,8 +26,8 @@ import org.apache.james.backends.cassandra.components.CassandraIndex;
 import org.apache.james.backends.cassandra.components.CassandraModule;
 import org.apache.james.backends.cassandra.components.CassandraTable;
 import org.apache.james.backends.cassandra.components.CassandraType;
-import org.apache.james.util.streams.ImmutableCollectors;
 
+import com.github.steveash.guavate.Guavate;
 import com.google.common.collect.ImmutableList;
 
 public class CassandraModuleComposite implements CassandraModule {
@@ -39,13 +39,13 @@ public class CassandraModuleComposite implements CassandraModule {
     public CassandraModuleComposite(CassandraModule... modules) {
         tables = Arrays.stream(modules)
             .flatMap(module -> module.moduleTables().stream())
-            .collect(ImmutableCollectors.toImmutableList());
+            .collect(Guavate.toImmutableList());
         index = Arrays.stream(modules)
             .flatMap(module -> module.moduleIndex().stream())
-            .collect(ImmutableCollectors.toImmutableList());
+            .collect(Guavate.toImmutableList());
         types = Arrays.stream(modules)
             .flatMap(module -> module.moduleTypes().stream())
-            .collect(ImmutableCollectors.toImmutableList());
+            .collect(Guavate.toImmutableList());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/james-project/blob/0ea95c34/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTypesProvider.java
----------------------------------------------------------------------
diff --git a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTypesProvider.java b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTypesProvider.java
index 2618207..356c7ac 100644
--- a/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTypesProvider.java
+++ b/backends-common/cassandra/src/main/java/org/apache/james/backends/cassandra/init/CassandraTypesProvider.java
@@ -25,10 +25,10 @@ import javax.inject.Inject;
 
 import org.apache.james.backends.cassandra.components.CassandraModule;
 import org.apache.james.backends.cassandra.components.CassandraType;
-import org.apache.james.util.streams.ImmutableCollectors;
 
 import com.datastax.driver.core.Session;
 import com.datastax.driver.core.UserType;
+import com.github.steveash.guavate.Guavate;
 import com.google.common.collect.ImmutableMap;
 
 public class CassandraTypesProvider {
@@ -38,7 +38,7 @@ public class CassandraTypesProvider {
     public CassandraTypesProvider(CassandraModule module, Session session) {
         userTypes = module.moduleTypes()
             .stream()
-            .collect(ImmutableCollectors.toImmutableMap(
+            .collect(Guavate.toImmutableMap(
                     CassandraType::getName,
                     type -> getSessionType(session, type)));
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/0ea95c34/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
index bd764c3..e47ad93 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraAttachmentMapper.java
@@ -43,13 +43,13 @@ import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.store.mail.AttachmentMapper;
 import org.apache.james.mailbox.store.mail.model.Attachment;
 import org.apache.james.mailbox.store.mail.model.AttachmentId;
-import org.apache.james.util.streams.ImmutableCollectors;
 
 import com.datastax.driver.core.ResultSet;
 import com.datastax.driver.core.Row;
 import com.datastax.driver.core.Session;
 import com.github.fge.lambdas.Throwing;
 import com.github.fge.lambdas.ThrownByLambdaException;
+import com.github.steveash.guavate.Guavate;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableList.Builder;
@@ -96,7 +96,7 @@ public class CassandraAttachmentMapper implements AttachmentMapper {
         Preconditions.checkArgument(attachmentIds != null);
         List<String> ids = attachmentIds.stream()
                 .map(AttachmentId::getId)
-                .collect(ImmutableCollectors.toImmutableList());
+                .collect(Guavate.toImmutableList());
         return cassandraAsyncExecutor.execute(
             select(FIELDS)
                 .from(TABLE_NAME)

http://git-wip-us.apache.org/repos/asf/james-project/blob/0ea95c34/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java
----------------------------------------------------------------------
diff --git a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java
index 6bd1e5a..4e7bd9f 100644
--- a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java
+++ b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/mail/CassandraMessageMapper.java
@@ -102,7 +102,6 @@ import org.apache.james.mailbox.store.mail.model.impl.Cid;
 import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
 import org.apache.james.mailbox.store.mail.model.impl.SimpleMailboxMessage;
 import org.apache.james.mailbox.store.mail.model.impl.SimpleProperty;
-import org.apache.james.util.streams.ImmutableCollectors;
 
 import com.datastax.driver.core.ResultSet;
 import com.datastax.driver.core.Row;
@@ -114,6 +113,7 @@ import com.datastax.driver.core.querybuilder.QueryBuilder;
 import com.datastax.driver.core.querybuilder.Select;
 import com.datastax.driver.core.querybuilder.Select.Where;
 import com.github.fge.lambdas.Throwing;
+import com.github.steveash.guavate.Guavate;
 import com.google.common.base.Throwables;
 import com.google.common.collect.ImmutableList;
 import com.google.common.io.ByteStreams;
@@ -358,7 +358,7 @@ public class CassandraMessageMapper implements MessageMapper {
                             .cid(com.google.common.base.Optional.fromNullable(x.getString(Attachments.CID)).transform(Cid::from))
                             .isInline(x.getBool(Attachments.IS_INLINE))
                             .build()))
-                    .collect(ImmutableCollectors.toImmutableList());
+                    .collect(Guavate.toImmutableList());
         default:
             return ImmutableList.of();
         }
@@ -374,7 +374,7 @@ public class CassandraMessageMapper implements MessageMapper {
     private List<AttachmentId> attachmentIds(List<UDTValue> udtValues) {
         return udtValues.stream()
             .map(this::attachmentIdFrom)
-            .collect(ImmutableCollectors.toImmutableList());
+            .collect(Guavate.toImmutableList());
     }
 
     private AttachmentId attachmentIdFrom(UDTValue udtValue) {

http://git-wip-us.apache.org/repos/asf/james-project/blob/0ea95c34/server/container/util-java8/pom.xml
----------------------------------------------------------------------
diff --git a/server/container/util-java8/pom.xml b/server/container/util-java8/pom.xml
index 5558bd2..ed75944 100644
--- a/server/container/util-java8/pom.xml
+++ b/server/container/util-java8/pom.xml
@@ -128,6 +128,10 @@
             </activation>
             <dependencies>
                 <dependency>
+                    <groupId>com.github.steveash.guavate</groupId>
+                    <artifactId>guavate</artifactId>
+                </dependency>
+                <dependency>
                     <groupId>com.google.guava</groupId>
                     <artifactId>guava</artifactId>
                 </dependency>

http://git-wip-us.apache.org/repos/asf/james-project/blob/0ea95c34/server/container/util-java8/src/main/java/org/apache/james/util/streams/ImmutableCollectors.java
----------------------------------------------------------------------
diff --git a/server/container/util-java8/src/main/java/org/apache/james/util/streams/ImmutableCollectors.java b/server/container/util-java8/src/main/java/org/apache/james/util/streams/ImmutableCollectors.java
deleted file mode 100644
index 90d7703..0000000
--- a/server/container/util-java8/src/main/java/org/apache/james/util/streams/ImmutableCollectors.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/****************************************************************
- * 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.util.streams;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.function.Function;
-import java.util.stream.Collector;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-
-public class ImmutableCollectors {
-
-    public static <T> Collector<T, List<T>, ImmutableList<T>> toImmutableList() {
-        return Collector.of(ArrayList::new, List::add, (left, right) -> {
-            left.addAll(right);
-            return left;
-        }, ImmutableList::copyOf);
-    }
-
-    public static <T> Collector<T, ImmutableSet.Builder<T>, ImmutableSet<T>> toImmutableSet() {
-        return Collector.of(ImmutableSet::builder, ImmutableSet.Builder::add, (left, right) -> {
-            left.addAll(right.build());
-            return left;
-        }, ImmutableSet.Builder::build);
-    }
-
-    public static <T, K, V> Collector<T, ImmutableMap.Builder<K, V>, ImmutableMap<K, V>> toImmutableMap(
-            Function<? super T, ? extends K> keyMapper,
-            Function<? super T, ? extends V> valueMapper) {
-        return Collector.of(ImmutableMap::<K,V>builder,
-                (acc, v) -> acc.put(keyMapper.apply(v), valueMapper.apply(v)),
-                (map1, map2) -> map1.putAll(map2.build()),
-                ImmutableMap.Builder::build);
-    }
-}
-

http://git-wip-us.apache.org/repos/asf/james-project/blob/0ea95c34/server/container/util-java8/src/test/java/org/apache/james/util/streams/ImmutableCollectorsTest.java
----------------------------------------------------------------------
diff --git a/server/container/util-java8/src/test/java/org/apache/james/util/streams/ImmutableCollectorsTest.java b/server/container/util-java8/src/test/java/org/apache/james/util/streams/ImmutableCollectorsTest.java
index 31410d9..d22f984 100644
--- a/server/container/util-java8/src/test/java/org/apache/james/util/streams/ImmutableCollectorsTest.java
+++ b/server/container/util-java8/src/test/java/org/apache/james/util/streams/ImmutableCollectorsTest.java
@@ -27,11 +27,12 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import com.google.common.collect.ImmutableSet;
 import org.junit.Test;
 
+import com.github.steveash.guavate.Guavate;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
 
 public class ImmutableCollectorsTest {
 
@@ -39,7 +40,7 @@ public class ImmutableCollectorsTest {
     public void immutableListCollectorShouldReturnEmptyImmutableListWhenEmptyStream() {
         String[] data = {};
         List<String> actual = Arrays.stream(data)
-            .collect(ImmutableCollectors.toImmutableList());
+            .collect(Guavate.toImmutableList());
         assertThat(actual).isInstanceOf(ImmutableList.class);
         assertThat(actual).isEmpty();
     }
@@ -48,7 +49,7 @@ public class ImmutableCollectorsTest {
     public void immutableListCollectorShouldReturnImmutableListWhenOneElementStream() {
         String[] data = {"a"};
         List<String> actual = Arrays.stream(data)
-            .collect(ImmutableCollectors.toImmutableList());
+            .collect(Guavate.toImmutableList());
         assertThat(actual).isInstanceOf(ImmutableList.class);
         assertThat(actual).containsExactly("a");
     }
@@ -57,7 +58,7 @@ public class ImmutableCollectorsTest {
     public void immutableListCollectorShouldReturnImmutableListWhen3ElementsStream() {
         String[] data = {"a", "b", "c"};
         List<String> actual = Arrays.stream(data)
-            .collect(ImmutableCollectors.toImmutableList());
+            .collect(Guavate.toImmutableList());
         assertThat(actual).isInstanceOf(ImmutableList.class);
         assertThat(actual).containsExactly("a", "b", "c");
     }
@@ -66,7 +67,7 @@ public class ImmutableCollectorsTest {
     public void immutableSetCollectorShouldReturnEmptyImmutableSetWhenEmptyStream() {
         String[] data = {};
         Set<String> actual = Arrays.stream(data)
-            .collect(ImmutableCollectors.toImmutableSet());
+            .collect(Guavate.toImmutableSet());
         assertThat(actual).isInstanceOf(ImmutableSet.class);
         assertThat(actual).isEmpty();
     }
@@ -75,7 +76,7 @@ public class ImmutableCollectorsTest {
     public void immutableSetCollectorShouldReturnImmutableSetWhenOneElementStream() {
         String[] data = {"a"};
         Set<String> actual = Arrays.stream(data)
-            .collect(ImmutableCollectors.toImmutableSet());
+            .collect(Guavate.toImmutableSet());
         assertThat(actual).isInstanceOf(ImmutableSet.class);
         assertThat(actual).containsExactly("a");
     }
@@ -84,7 +85,7 @@ public class ImmutableCollectorsTest {
     public void immutableSetCollectorShouldReturnImmutableSetWhen3ElementsStream() {
         String[] data = {"a", "b", "c"};
         Set<String> actual = Arrays.stream(data)
-            .collect(ImmutableCollectors.toImmutableSet());
+            .collect(Guavate.toImmutableSet());
         assertThat(actual).isInstanceOf(ImmutableSet.class);
         assertThat(actual).containsExactly("a", "b", "c");
     }
@@ -94,7 +95,7 @@ public class ImmutableCollectorsTest {
     public void immutableMapCollectorShouldReturnEmptyImmutableMapWhenEmptyStream() {
         String[] data = {};
         Map<String, Integer> actual = Arrays.stream(data)
-                .collect(ImmutableCollectors.toImmutableMap(x -> x.toUpperCase(), x -> x.length()));
+                .collect(Guavate.toImmutableMap(x -> x.toUpperCase(), x -> x.length()));
         assertThat(actual).isInstanceOf(ImmutableMap.class);
         assertThat(actual).isEmpty();
     }
@@ -103,7 +104,7 @@ public class ImmutableCollectorsTest {
     public void immutableMapCollectorShouldReturnAppliedImmutableMapWhenOneElementStream() {
         String[] data = {"a"};
         Map<String, Integer> actual = Arrays.stream(data)
-                .collect(ImmutableCollectors.toImmutableMap(x -> x.toUpperCase(), x -> x.length()));
+                .collect(Guavate.toImmutableMap(x -> x.toUpperCase(), x -> x.length()));
         assertThat(actual).isInstanceOf(ImmutableMap.class);
         assertThat(actual).containsExactly(entry("A", 1));
     }
@@ -112,7 +113,7 @@ public class ImmutableCollectorsTest {
     public void immutableMapCollectorShouldReturnAppliedImmutableMapWhen3ElementsStream() {
         String[] data = {"a", "bb", "ccc"};
         Map<String, Integer> actual = Arrays.stream(data)
-                .collect(ImmutableCollectors.toImmutableMap(x -> x.toUpperCase(), x -> x.length()));
+                .collect(Guavate.toImmutableMap(x -> x.toUpperCase(), x -> x.length()));
         assertThat(actual).isInstanceOf(ImmutableMap.class);
         assertThat(actual).containsExactly(entry("A", 1), entry("BB", 2), entry("CCC", 3));
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/0ea95c34/server/pom.xml
----------------------------------------------------------------------
diff --git a/server/pom.xml b/server/pom.xml
index c9e9bf3..f07d7bf 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -190,6 +190,7 @@
         <assertj-1.version>1.7.1</assertj-1.version>
         <assertj-3.version>3.3.0</assertj-3.version>
         <testcontainers-version>1.0.2</testcontainers-version>
+        <guavate.version>1.0.0</guavate.version>
     </properties>
 
     <dependencyManagement>
@@ -1292,6 +1293,11 @@
             </dependency>
 
             <dependency>
+                <groupId>com.github.steveash.guavate</groupId>
+                <artifactId>guavate</artifactId>
+                <version>${guavate.version}</version>
+            </dependency>
+            <dependency>
                 <groupId>com.google.guava</groupId>
                 <artifactId>guava</artifactId>
                 <version>${guava.version}</version>

http://git-wip-us.apache.org/repos/asf/james-project/blob/0ea95c34/server/protocols/jmap/pom.xml
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/pom.xml b/server/protocols/jmap/pom.xml
index 3e73bac..3b67c3a 100644
--- a/server/protocols/jmap/pom.xml
+++ b/server/protocols/jmap/pom.xml
@@ -256,7 +256,6 @@
                 <dependency>
                     <groupId>com.github.steveash.guavate</groupId>
                     <artifactId>guavate</artifactId>
-                    <version>1.0.0</version>
                 </dependency>
                 <dependency>
                     <groupId>com.googlecode.thread-weaver</groupId>

http://git-wip-us.apache.org/repos/asf/james-project/blob/0ea95c34/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/GetMessageListMethod.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/GetMessageListMethod.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/GetMessageListMethod.java
index 73edc6c..2a26fa9 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/GetMessageListMethod.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/GetMessageListMethod.java
@@ -50,11 +50,11 @@ import org.apache.james.mailbox.store.mail.MessageMapper;
 import org.apache.james.mailbox.store.mail.MessageMapper.FetchType;
 import org.apache.james.mailbox.store.mail.model.Mailbox;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
-import org.apache.james.util.streams.ImmutableCollectors;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.github.fge.lambdas.Throwing;
+import com.github.steveash.guavate.Guavate;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Throwables;
@@ -136,7 +136,7 @@ public class GetMessageListMethod implements Method {
         return mailboxManager.search(userMailboxesQuery, mailboxSession)
                 .stream()
                 .map(MailboxMetaData::getPath)
-                .collect(ImmutableCollectors.toImmutableList());
+                .collect(Guavate.toImmutableList());
     }
 
     private Stream<JmapResponse> processGetMessages(GetMessageListRequest messageListRequest, GetMessageListResponse messageListResponse, ClientId clientId, MailboxSession mailboxSession) {
@@ -189,7 +189,7 @@ public class GetMessageListMethod implements Method {
         return mailboxPaths.stream()
                 .filter(inMailboxesPredicate)
                 .filter(notInMailboxesPredicate)
-                .collect(ImmutableCollectors.toImmutableList());
+                .collect(Guavate.toImmutableList());
     }
 
     private List<MailboxPath> mailboxIdsToMailboxPaths(List<String> mailboxIds, MailboxSession session) {
@@ -197,7 +197,7 @@ public class GetMessageListMethod implements Method {
             .map(id -> mailboxUtils.mailboxPathFromMailboxId(id, session))
             .filter(Optional::isPresent)
             .map(Optional::get)
-            .collect(ImmutableCollectors.toImmutableList());
+            .collect(Guavate.toImmutableList());
     }
     
     private Optional<MessageManager> getMessageManager(MailboxPath mailboxPath, MailboxSession mailboxSession) {
@@ -218,7 +218,7 @@ public class GetMessageListMethod implements Method {
             return ImmutableList.copyOf(messageManager.get().search(searchQuery, mailboxSession))
                     .stream()
                     .map(Throwing.function(messageId -> getMessage(mailboxPath, mailboxSession, messageMapper, messageId)))
-                    .collect(ImmutableCollectors.toImmutableList());
+                    .collect(Guavate.toImmutableList());
         } catch (MailboxException e) {
             LOGGER.warn("Error when searching messages for query :" + searchQuery, e);
             return ImmutableList.of();

http://git-wip-us.apache.org/repos/asf/james-project/blob/0ea95c34/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/GetMessagesMethod.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/GetMessagesMethod.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/GetMessagesMethod.java
index 5d6cb7e..08ca4ac 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/GetMessagesMethod.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/GetMessagesMethod.java
@@ -48,12 +48,12 @@ import org.apache.james.mailbox.store.mail.MessageMapperFactory;
 import org.apache.james.mailbox.store.mail.model.Mailbox;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
 import org.apache.james.mailbox.store.mail.model.MessageAttachment;
-import org.apache.james.util.streams.ImmutableCollectors;
 import org.javatuples.Pair;
 
 import com.fasterxml.jackson.databind.ser.PropertyFilter;
 import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
 import com.github.fge.lambdas.Throwing;
+import com.github.steveash.guavate.Guavate;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableSet;
@@ -122,7 +122,7 @@ public class GetMessagesMethod implements Method {
         List<Message> result = getMessagesRequest.getIds().stream()
             .flatMap(loadMessages)
             .map(convertToJmapMessage)
-            .collect(ImmutableCollectors.toImmutableList());
+            .collect(Guavate.toImmutableList());
 
         return GetMessagesResponse.builder().messages(result).expectedMessageIds(getMessagesRequest.getIds()).build();
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/0ea95c34/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/JmapResponseWriterImpl.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/JmapResponseWriterImpl.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/JmapResponseWriterImpl.java
index 9e06977..c2c3d47 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/JmapResponseWriterImpl.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/JmapResponseWriterImpl.java
@@ -28,13 +28,13 @@ import javax.inject.Inject;
 import org.apache.james.jmap.json.ObjectMapperFactory;
 import org.apache.james.jmap.model.Property;
 import org.apache.james.jmap.model.ProtocolResponse;
-import org.apache.james.util.streams.ImmutableCollectors;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.ser.FilterProvider;
 import com.fasterxml.jackson.databind.ser.PropertyFilter;
 import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
 import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
+import com.github.steveash.guavate.Guavate;
 
 public class JmapResponseWriterImpl implements JmapResponseWriter {
 
@@ -82,6 +82,6 @@ public class JmapResponseWriterImpl implements JmapResponseWriter {
     private Set<String> toFieldNames(Set<? extends Property> properties) {
         return properties.stream()
             .map(Property::asFieldName)
-            .collect(ImmutableCollectors.toImmutableSet());
+            .collect(Guavate.toImmutableSet());
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/0ea95c34/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMessagesCreationProcessor.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMessagesCreationProcessor.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMessagesCreationProcessor.java
index b541926..3e3eaff 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMessagesCreationProcessor.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetMessagesCreationProcessor.java
@@ -74,11 +74,11 @@ import org.apache.james.mailbox.store.mail.model.MessageAttachment;
 import org.apache.james.mailbox.store.mail.model.impl.Cid;
 import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
 import org.apache.james.mailbox.store.mail.model.impl.SimpleMailboxMessage;
-import org.apache.james.util.streams.ImmutableCollectors;
 import org.apache.mailet.Mail;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.github.steveash.guavate.Guavate;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Joiner;
 import com.google.common.base.Splitter;
@@ -214,7 +214,7 @@ public class SetMessagesCreationProcessor implements SetMessagesProcessor {
                 } catch (AttachmentNotFoundException e) {
                     return Stream.of(attachment.getBlobId());
                 }
-            }).collect(ImmutableCollectors.toImmutableList());
+            }).collect(Guavate.toImmutableList());
     }
 
     private AttachmentId getAttachmentId(Attachment attachment) {
@@ -321,7 +321,7 @@ public class SetMessagesCreationProcessor implements SetMessagesProcessor {
         AttachmentMapper attachmentMapper = attachmentMapperFactory.getAttachmentMapper(session);
         return attachments.stream()
             .map(att -> messageAttachment(attachmentMapper, att))
-            .collect(ImmutableCollectors.toImmutableList());
+            .collect(Guavate.toImmutableList());
     }
 
     private MessageAttachment messageAttachment(AttachmentMapper attachmentMapper, Attachment attachment) {

http://git-wip-us.apache.org/repos/asf/james-project/blob/0ea95c34/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/GetMailboxesRequest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/GetMailboxesRequest.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/GetMailboxesRequest.java
index d735d3b..a8f59d8 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/GetMailboxesRequest.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/GetMailboxesRequest.java
@@ -23,10 +23,10 @@ import java.util.Optional;
 
 import org.apache.commons.lang.NotImplementedException;
 import org.apache.james.jmap.methods.JmapRequest;
-import org.apache.james.util.streams.ImmutableCollectors;
 
 import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
 import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
+import com.github.steveash.guavate.Guavate;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 
@@ -69,7 +69,7 @@ public class GetMailboxesRequest implements JmapRequest {
                     .map(MailboxProperty::findProperty)
                     .filter(Optional::isPresent)
                     .map(Optional::get)
-                    .collect(ImmutableCollectors.toImmutableSet()));
+                    .collect(Guavate.toImmutableSet()));
             return this;
         }
         

http://git-wip-us.apache.org/repos/asf/james-project/blob/0ea95c34/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageFactory.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageFactory.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageFactory.java
index 1c592bf..fb3571d 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageFactory.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageFactory.java
@@ -35,8 +35,8 @@ import org.apache.james.mailbox.store.extractor.DefaultTextExtractor;
 import org.apache.james.mailbox.store.mail.model.MailboxMessage;
 import org.apache.james.mailbox.store.mail.model.MessageAttachment;
 import org.apache.james.mailbox.store.mail.model.impl.Cid;
-import org.apache.james.util.streams.ImmutableCollectors;
 
+import com.github.steveash.guavate.Guavate;
 import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
@@ -114,7 +114,7 @@ public class MessageFactory {
     private ImmutableList<Emailer> fromElasticSearchEmailers(Set<EMailer> emailers) {
         return emailers.stream()
                     .map(this::fromElasticSearchEmailer)
-                    .collect(ImmutableCollectors.toImmutableList());
+                    .collect(Guavate.toImmutableList());
     }
     
     private Emailer fromElasticSearchEmailer(EMailer emailer) {
@@ -129,7 +129,7 @@ public class MessageFactory {
                 .asMap()
                 .entrySet()
                 .stream()
-                .collect(ImmutableCollectors.toImmutableMap(Map.Entry::getKey, x -> joinOnComma(x.getValue())));
+                .collect(Guavate.toImmutableMap(Map.Entry::getKey, x -> joinOnComma(x.getValue())));
     }
     
     private String getHeaderAsSingleValue(IndexableMessage im, String header) {
@@ -155,7 +155,7 @@ public class MessageFactory {
     private List<Attachment> getAttachments(List<MessageAttachment> attachments) {
         return attachments.stream()
                 .map(this::fromMailboxAttachment)
-                .collect(ImmutableCollectors.toImmutableList());
+                .collect(Guavate.toImmutableList());
     }
 
     private Attachment fromMailboxAttachment(MessageAttachment attachment) {

http://git-wip-us.apache.org/repos/asf/james-project/blob/0ea95c34/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageProperties.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageProperties.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageProperties.java
index f9485ee..d3f095b 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageProperties.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageProperties.java
@@ -24,11 +24,10 @@ import java.util.Objects;
 import java.util.Optional;
 import java.util.stream.Stream;
 
-import com.google.common.collect.Sets;
-import org.apache.james.util.streams.ImmutableCollectors;
-
+import com.github.steveash.guavate.Guavate;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
 
 public class MessageProperties {
 
@@ -49,11 +48,11 @@ public class MessageProperties {
     }
 
     private ImmutableSet<MessageProperty> toMessageProperties(ImmutableSet<String> properties) {
-        return properties.stream().flatMap(MessageProperty::find).collect(ImmutableCollectors.toImmutableSet());
+        return properties.stream().flatMap(MessageProperty::find).collect(Guavate.toImmutableSet());
     }
     
     private ImmutableSet<HeaderProperty> toHeadersProperties(ImmutableSet<String> properties) {
-        return properties.stream().flatMap(HeaderProperty::find).collect(ImmutableCollectors.toImmutableSet());
+        return properties.stream().flatMap(HeaderProperty::find).collect(Guavate.toImmutableSet());
     }
 
     public Optional<ImmutableSet<HeaderProperty>> getOptionalHeadersProperties() {
@@ -168,7 +167,7 @@ public class MessageProperties {
         }
 
         public static ImmutableSet<MessageProperty> allOutputProperties() {
-            return Arrays.stream(values()).filter(MessageProperty::outputProperty).collect(ImmutableCollectors.toImmutableSet());
+            return Arrays.stream(values()).filter(MessageProperty::outputProperty).collect(Guavate.toImmutableSet());
         }
 
         private static boolean outputProperty(MessageProperty p) {

http://git-wip-us.apache.org/repos/asf/james-project/blob/0ea95c34/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/SetMessagesRequest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/SetMessagesRequest.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/SetMessagesRequest.java
index a064102..3de592a 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/SetMessagesRequest.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/SetMessagesRequest.java
@@ -29,11 +29,11 @@ import org.apache.commons.lang.NotImplementedException;
 import org.apache.james.jmap.methods.JmapRequest;
 import org.apache.james.jmap.methods.UpdateMessagePatchConverter;
 import org.apache.james.jmap.methods.ValueWithId.CreationMessageEntry;
-import org.apache.james.util.streams.ImmutableCollectors;
 
 import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
 import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
 import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.github.steveash.guavate.Guavate;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
@@ -104,7 +104,7 @@ public class SetMessagesRequest implements JmapRequest {
         private ImmutableList<CreationMessageEntry> messageCreations() {
             return create.entrySet().stream()
                     .map(entry -> new CreationMessageEntry(entry.getKey(), entry.getValue()))
-                    .collect(ImmutableCollectors.toImmutableList());
+                    .collect(Guavate.toImmutableList());
         }
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/0ea95c34/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/service/UserMailboxesService.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/service/UserMailboxesService.java b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/service/UserMailboxesService.java
index 076675a..469bdfb 100644
--- a/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/service/UserMailboxesService.java
+++ b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/service/UserMailboxesService.java
@@ -34,7 +34,6 @@ import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.MailboxQuery;
 import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.api.UsersRepositoryException;
-import org.apache.james.util.streams.ImmutableCollectors;
 import org.apache.james.webadmin.dto.MailboxResponse;
 import org.apache.james.webadmin.utils.MailboxHaveChildrenException;
 import org.apache.james.webadmin.validation.MailboxName;
@@ -42,6 +41,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.github.fge.lambdas.Throwing;
+import com.github.steveash.guavate.Guavate;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Strings;
 
@@ -85,7 +85,7 @@ public class UserMailboxesService {
         MailboxSession mailboxSession = mailboxManager.createSystemSession(USER_NAME, LOGGER);
         return listUserMailboxes(username, mailboxSession)
             .map(mailboxMetaData -> new MailboxResponse(mailboxMetaData.getPath().getName()))
-            .collect(ImmutableCollectors.toImmutableList());
+            .collect(Guavate.toImmutableList());
     }
 
     public boolean testMailboxExists(String username, MailboxName mailboxName) throws MailboxException, UsersRepositoryException {

http://git-wip-us.apache.org/repos/asf/james-project/blob/0ea95c34/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/service/UserService.java
----------------------------------------------------------------------
diff --git a/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/service/UserService.java b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/service/UserService.java
index 1eb8ae1..ee0952d 100644
--- a/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/service/UserService.java
+++ b/server/protocols/webadmin/src/main/java/org/apache/james/webadmin/service/UserService.java
@@ -28,12 +28,12 @@ import javax.inject.Inject;
 import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.api.UsersRepositoryException;
 import org.apache.james.user.api.model.User;
-import org.apache.james.util.streams.ImmutableCollectors;
 import org.apache.james.util.streams.Iterators;
 import org.apache.james.webadmin.dto.UserResponse;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.github.steveash.guavate.Guavate;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Strings;
 
@@ -57,7 +57,7 @@ public class UserService {
             .map(Iterators::toStream)
             .orElse(Stream.of())
             .map(UserResponse::new)
-            .collect(ImmutableCollectors.toImmutableList());
+            .collect(Guavate.toImmutableList());
     }
 
     public void removeUser(String username) throws UsersRepositoryException {


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


[2/2] james-project git commit: JAMES-1801 Convert JMAP filter to SearchQuery (all but inMailboxes, notInMailboxes & hasAttachment)

Posted by ro...@apache.org.
JAMES-1801 Convert JMAP filter to SearchQuery (all but inMailboxes, notInMailboxes & hasAttachment)


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

Branch: refs/heads/master
Commit: ce1fcea4f0604e869d4eba313faa78d181edbeb3
Parents: a17b49a
Author: Antoine Duprat <ad...@linagora.com>
Authored: Mon Jul 18 14:37:53 2016 +0200
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Wed Jul 20 11:44:48 2016 +0200

----------------------------------------------------------------------
 .../apache/james/mailbox/model/SearchQuery.java |  24 +-
 .../integration/GetMessageListMethodTest.java   |  37 +-
 server/protocols/jmap/pom.xml                   |   5 +
 .../james/jmap/model/FilterCondition.java       |  88 ++--
 .../org/apache/james/jmap/model/Header.java     |  76 ++++
 .../james/jmap/utils/FilterToSearchQuery.java   | 105 +++++
 .../james/jmap/model/FilterConditionTest.java   | 127 ++----
 .../org/apache/james/jmap/model/HeaderTest.java |  71 ++++
 .../jmap/utils/FilterToSearchQueryTest.java     | 415 +++++++++++++++++++
 9 files changed, 815 insertions(+), 133 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/ce1fcea4/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 b0efb1a..d815d9d 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
@@ -471,6 +471,17 @@ public class SearchQuery implements Serializable {
     }
 
     /**
+     * Creates a filter composing the listed criteria.
+     * 
+     * @param criteria
+     *            <code>List</code> of {@link Criterion}
+     * @return <code>Criterion</code>, not null
+     */
+    public static final Criterion or(List<Criterion> criteria) {
+        return new ConjunctionCriterion(Conjunction.OR, criteria);
+    }
+
+    /**
      * Creates a filter composing the two different criteria.
      * 
      * @param one
@@ -511,6 +522,17 @@ public class SearchQuery implements Serializable {
     }
 
     /**
+     * Creates a filter composing the listed criteria.
+     * 
+     * @param criteria
+     *            <code>List</code> of {@link Criterion}
+     * @return <code>Criterion</code>, not null
+     */
+    public static final Criterion not(List<Criterion> criteria) {
+        return new ConjunctionCriterion(Conjunction.NOR, criteria);
+    }
+
+    /**
      * Creates a filter on the given flag.
      * 
      * @param flag
@@ -611,7 +633,7 @@ public class SearchQuery implements Serializable {
 
     private final List<Criterion> criterias = new ArrayList<Criterion>();
 
-    private List<Sort> sorts = new ArrayList<SearchQuery.Sort>(Arrays.asList(new Sort(Sort.SortClause.Uid, false)));
+    private List<Sort> sorts = new ArrayList<Sort>(Arrays.asList(new Sort(Sort.SortClause.Uid, false)));
 
     public void andCriteria(Criterion crit) {
         criterias.add(crit);

http://git-wip-us.apache.org/repos/asf/james-project/blob/ce1fcea4/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMessageListMethodTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMessageListMethodTest.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMessageListMethodTest.java
index 161010f..60408ab 100644
--- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMessageListMethodTest.java
+++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMessageListMethodTest.java
@@ -69,11 +69,11 @@ public abstract class GetMessageListMethodTest {
         jmapServer = createJmapServer();
         jmapServer.start();
         RestAssured.requestSpecification = new RequestSpecBuilder()
-        		.setContentType(ContentType.JSON)
-        		.setAccept(ContentType.JSON)
-        		.setConfig(newConfig().encoderConfig(encoderConfig().defaultContentCharset(Charsets.UTF_8)))
-        		.setPort(jmapServer.getJmapPort())
-        		.build();
+                .setContentType(ContentType.JSON)
+                .setAccept(ContentType.JSON)
+                .setConfig(newConfig().encoderConfig(encoderConfig().defaultContentCharset(Charsets.UTF_8)))
+                .setPort(jmapServer.getJmapPort())
+                .build();
 
         this.domain = "domain.tld";
         this.username = "username@" + domain;
@@ -89,7 +89,7 @@ public abstract class GetMessageListMethodTest {
     }
     
     @Test
-    public void getMessageListShouldErrorInvalidArgumentsWhenRequestIsInvalid() throws Exception {
+    public void getMessageListShouldReturnErrorInvalidArgumentsWhenRequestIsInvalid() throws Exception {
         given()
             .header("Authorization", accessToken.serialize())
             .body("[[\"getMessageList\", {\"filter\": true}, \"#0\"]]")
@@ -102,6 +102,31 @@ public abstract class GetMessageListMethodTest {
     }
 
     @Test
+    public void getMessageListShouldReturnErrorInvalidArgumentsWhenHeaderIsInvalid() throws Exception {
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"getMessageList\", {\"filter\":{\"header\":[\"132\", \"456\", \"789\"]}}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(NAME, equalTo("error"))
+            .body(ARGUMENTS + ".type", equalTo("invalidArguments"));
+    }
+
+    @Test
+    public void getMessageListShouldNotFailWhenHeaderIsValid() throws Exception {
+        given()
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"getMessageList\", {\"filter\":{\"header\":[\"132\", \"456\"]}}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(NAME, equalTo("messageList"));
+    }
+
+    @Test
     public void getMessageListShouldReturnAllMessagesWhenSingleMailboxNoParameters() throws Exception {
         jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, username, "mailbox");
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/ce1fcea4/server/protocols/jmap/pom.xml
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/pom.xml b/server/protocols/jmap/pom.xml
index 39a0e85..3e73bac 100644
--- a/server/protocols/jmap/pom.xml
+++ b/server/protocols/jmap/pom.xml
@@ -254,6 +254,11 @@
                     <artifactId>throwing-lambdas</artifactId>
                 </dependency>
                 <dependency>
+                    <groupId>com.github.steveash.guavate</groupId>
+                    <artifactId>guavate</artifactId>
+                    <version>1.0.0</version>
+                </dependency>
+                <dependency>
                     <groupId>com.googlecode.thread-weaver</groupId>
                     <artifactId>threadweaver</artifactId>
                     <version>0.2</version>

http://git-wip-us.apache.org/repos/asf/james-project/blob/ce1fcea4/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/FilterCondition.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/FilterCondition.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/FilterCondition.java
index de5ea81..63663c5 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/FilterCondition.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/FilterCondition.java
@@ -19,13 +19,11 @@
 
 package org.apache.james.jmap.model;
 
-import java.util.Date;
+import java.time.ZonedDateTime;
 import java.util.List;
 import java.util.Objects;
 import java.util.Optional;
 
-import org.apache.commons.lang.NotImplementedException;
-
 import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
 import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
 import com.google.common.annotations.VisibleForTesting;
@@ -45,8 +43,8 @@ public class FilterCondition implements Filter {
 
         private Optional<List<String>> inMailboxes;
         private Optional<List<String>> notInMailboxes;
-        private Date before;
-        private Date after;
+        private ZonedDateTime before;
+        private ZonedDateTime after;
         private Integer minSize;
         private Integer maxSize;
         private Boolean isFlagged;
@@ -61,12 +59,11 @@ public class FilterCondition implements Filter {
         private String bcc;
         private String subject;
         private String body;
-        private Optional<List<String>> header;
+        private Header header;
 
         private Builder() {
             inMailboxes = Optional.empty();
             notInMailboxes = Optional.empty();
-            header = Optional.empty();
         }
 
         public Builder inMailboxes(String... inMailboxes) {
@@ -91,85 +88,102 @@ public class FilterCondition implements Filter {
             return this;
         }
 
-        public Builder before(Date before) {
-            throw new NotImplementedException();
+        public Builder before(ZonedDateTime before) {
+            this.before = before;
+            return this;
         }
 
-        public Builder after(Date after) {
-            throw new NotImplementedException();
+        public Builder after(ZonedDateTime after) {
+            this.after = after;
+            return this;
         }
 
         public Builder minSize(int minSize) {
-            throw new NotImplementedException();
+            this.minSize = minSize;
+            return this;
         }
 
         public Builder maxSize(int maxSize) {
-            throw new NotImplementedException();
+            this.maxSize = maxSize;
+            return this;
         }
 
-        public Builder isFlagged(boolean isFlagger) {
-            throw new NotImplementedException();
+        public Builder isFlagged(boolean isFlagged) {
+            this.isFlagged = isFlagged;
+            return this;
         }
 
         public Builder isUnread(boolean isUnread) {
-            throw new NotImplementedException();
+            this.isUnread = isUnread;
+            return this;
         }
 
         public Builder isAnswered(boolean isAnswered) {
-            throw new NotImplementedException();
+            this.isAnswered = isAnswered;
+            return this;
         }
 
         public Builder isDraft(boolean isDraft) {
-            throw new NotImplementedException();
+            this.isDraft = isDraft;
+            return this;
         }
 
         public Builder hasAttachment(boolean hasAttachment) {
-            throw new NotImplementedException();
+            this.hasAttachment = hasAttachment;
+            return this;
         }
 
         public Builder text(String text) {
-            throw new NotImplementedException();
+            this.text = text;
+            return this;
         }
 
         public Builder from(String from) {
-            throw new NotImplementedException();
+            this.from = from;
+            return this;
         }
 
         public Builder to(String to) {
-            throw new NotImplementedException();
+            this.to = to;
+            return this;
         }
 
         public Builder cc(String cc) {
-            throw new NotImplementedException();
+            this.cc = cc;
+            return this;
         }
 
         public Builder bcc(String bcc) {
-            throw new NotImplementedException();
+            this.bcc = bcc;
+            return this;
         }
 
         public Builder subject(String subject) {
-            throw new NotImplementedException();
+            this.subject = subject;
+            return this;
         }
 
         public Builder body(String body) {
-            throw new NotImplementedException();
+            this.body = body;
+            return this;
         }
 
-        public Builder header(List<String> body) {
-            throw new NotImplementedException();
+        public Builder header(Header header) {
+            this.header = header;
+            return this;
         }
 
         public FilterCondition build() {
             return new FilterCondition(inMailboxes, notInMailboxes, Optional.ofNullable(before), Optional.ofNullable(after), Optional.ofNullable(minSize), Optional.ofNullable(maxSize),
                     Optional.ofNullable(isFlagged), Optional.ofNullable(isUnread), Optional.ofNullable(isAnswered), Optional.ofNullable(isDraft), Optional.ofNullable(hasAttachment),
-                    Optional.ofNullable(text), Optional.ofNullable(from), Optional.ofNullable(to), Optional.ofNullable(cc), Optional.ofNullable(bcc), Optional.ofNullable(subject), Optional.ofNullable(body), header);
+                    Optional.ofNullable(text), Optional.ofNullable(from), Optional.ofNullable(to), Optional.ofNullable(cc), Optional.ofNullable(bcc), Optional.ofNullable(subject), Optional.ofNullable(body), Optional.ofNullable(header));
         }
     }
 
     private final Optional<List<String>> inMailboxes;
     private final Optional<List<String>> notInMailboxes;
-    private final Optional<Date> before;
-    private final Optional<Date> after;
+    private final Optional<ZonedDateTime> before;
+    private final Optional<ZonedDateTime> after;
     private final Optional<Integer> minSize;
     private final Optional<Integer> maxSize;
     private final Optional<Boolean> isFlagged;
@@ -184,11 +198,11 @@ public class FilterCondition implements Filter {
     private final Optional<String> bcc;
     private final Optional<String> subject;
     private final Optional<String> body;
-    private final Optional<List<String>> header;
+    private final Optional<Header> header;
 
-    @VisibleForTesting FilterCondition(Optional<List<String>> inMailboxes, Optional<List<String>> notInMailboxes, Optional<Date> before, Optional<Date> after, Optional<Integer> minSize, Optional<Integer> maxSize,
+    @VisibleForTesting FilterCondition(Optional<List<String>> inMailboxes, Optional<List<String>> notInMailboxes, Optional<ZonedDateTime> before, Optional<ZonedDateTime> after, Optional<Integer> minSize, Optional<Integer> maxSize,
             Optional<Boolean> isFlagged, Optional<Boolean> isUnread, Optional<Boolean> isAnswered, Optional<Boolean> isDraft, Optional<Boolean> hasAttachment,
-            Optional<String> text, Optional<String> from, Optional<String> to, Optional<String> cc, Optional<String> bcc, Optional<String> subject, Optional<String> body, Optional<List<String>> header) {
+            Optional<String> text, Optional<String> from, Optional<String> to, Optional<String> cc, Optional<String> bcc, Optional<String> subject, Optional<String> body, Optional<Header> header) {
 
         this.inMailboxes = inMailboxes;
         this.notInMailboxes = notInMailboxes;
@@ -219,11 +233,11 @@ public class FilterCondition implements Filter {
         return notInMailboxes;
     }
 
-    public Optional<Date> getBefore() {
+    public Optional<ZonedDateTime> getBefore() {
         return before;
     }
 
-    public Optional<Date> getAfter() {
+    public Optional<ZonedDateTime> getAfter() {
         return after;
     }
 
@@ -283,7 +297,7 @@ public class FilterCondition implements Filter {
         return body;
     }
 
-    public Optional<List<String>> getHeader() {
+    public Optional<Header> getHeader() {
         return header;
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/ce1fcea4/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/Header.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/Header.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/Header.java
new file mode 100644
index 0000000..2d2608c
--- /dev/null
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/Header.java
@@ -0,0 +1,76 @@
+/****************************************************************
+ * 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.jmap.model;
+
+import java.util.List;
+import java.util.Optional;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import com.google.common.collect.Iterables;
+
+public class Header {
+
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    @JsonCreator
+    public static Header from(List<String> header) {
+        return builder().header(header).build();
+    }
+
+    public static class Builder {
+        
+        private String name;
+        private Optional<String> value;
+
+        public Builder header(List<String> header) {
+            Preconditions.checkNotNull(header);
+            Preconditions.checkArgument(header.size() > 0, "'header' should contains at least one element");
+            Preconditions.checkArgument(header.size() < 3, "'header' should contains lesser than three elements");
+            this.name = header.get(0);
+            this.value = Optional.ofNullable(Iterables.get(header, 1, null));
+            return this;
+        }
+
+        public Header build() {
+            Preconditions.checkState(!Strings.isNullOrEmpty(name), "'name' is mandatory");
+            return new Header(name, value);
+        }
+    }
+
+    private final String name;
+    private final Optional<String> value;
+
+    private Header(String name, Optional<String> value) {
+        this.name = name;
+        this.value = value;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public Optional<String> getValue() {
+        return value;
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/ce1fcea4/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/FilterToSearchQuery.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/FilterToSearchQuery.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/FilterToSearchQuery.java
new file mode 100644
index 0000000..db7b485
--- /dev/null
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/FilterToSearchQuery.java
@@ -0,0 +1,105 @@
+/****************************************************************
+ * 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.jmap.utils;
+
+import java.util.Date;
+
+import javax.mail.Flags.Flag;
+
+import org.apache.commons.lang.NotImplementedException;
+import org.apache.james.jmap.model.Filter;
+import org.apache.james.jmap.model.FilterCondition;
+import org.apache.james.jmap.model.FilterOperator;
+import org.apache.james.mailbox.model.SearchQuery;
+import org.apache.james.mailbox.model.SearchQuery.AddressType;
+import org.apache.james.mailbox.model.SearchQuery.Criterion;
+import org.apache.james.mailbox.model.SearchQuery.DateResolution;
+
+import com.github.fge.lambdas.Throwing;
+import com.github.steveash.guavate.Guavate;
+import com.google.common.collect.ImmutableList;
+
+public class FilterToSearchQuery {
+
+    public SearchQuery convert(Filter filter) {
+        if (filter instanceof FilterCondition) {
+            return convertCondition((FilterCondition) filter);
+        }
+        if (filter instanceof FilterOperator) {
+            SearchQuery searchQuery = new SearchQuery();
+            searchQuery.andCriteria(convertOperator((FilterOperator) filter));
+            return searchQuery;
+        }
+        throw new RuntimeException("Unknown filter: " + filter.getClass());
+    }
+
+    private SearchQuery convertCondition(FilterCondition filter) {
+        SearchQuery searchQuery = new SearchQuery();
+        filter.getText().ifPresent(text -> {
+            searchQuery.andCriteria(
+                    SearchQuery.or(ImmutableList.of(
+                            SearchQuery.address(AddressType.From, text),
+                            SearchQuery.address(AddressType.To, text),
+                            SearchQuery.address(AddressType.Cc, text),
+                            SearchQuery.address(AddressType.Bcc, text),
+                            SearchQuery.headerContains("Subject", text),
+                            SearchQuery.bodyContains(text)))
+                    );
+        });
+        filter.getFrom().ifPresent(from -> searchQuery.andCriteria(SearchQuery.address(AddressType.From, from)));
+        filter.getTo().ifPresent(to -> searchQuery.andCriteria(SearchQuery.address(AddressType.To, to)));
+        filter.getCc().ifPresent(cc -> searchQuery.andCriteria(SearchQuery.address(AddressType.Cc, cc)));
+        filter.getBcc().ifPresent(bcc -> searchQuery.andCriteria(SearchQuery.address(AddressType.Bcc, bcc)));
+        filter.getSubject().ifPresent(subject -> searchQuery.andCriteria(SearchQuery.headerContains("Subject", subject)));
+        filter.getBody().ifPresent(body ->  searchQuery.andCriteria(SearchQuery.bodyContains(body)));
+        filter.getAfter().ifPresent(after -> searchQuery.andCriteria(SearchQuery.internalDateAfter(Date.from(after.toInstant()), DateResolution.Second)));
+        filter.getBefore().ifPresent(before -> searchQuery.andCriteria(SearchQuery.internalDateBefore(Date.from(before.toInstant()), DateResolution.Second)));
+        filter.getHasAttachment().ifPresent(Throwing.consumer(hasAttachment -> { throw new NotImplementedException(); } ));
+        filter.getHeader().ifPresent(header -> searchQuery.andCriteria(SearchQuery.headerContains(header.getName(), header.getValue().orElse(null))));
+        filter.getIsAnswered().ifPresent(isAnswered -> searchQuery.andCriteria(SearchQuery.flagIsSet(Flag.ANSWERED)));
+        filter.getIsDraft().ifPresent(isDraft -> searchQuery.andCriteria(SearchQuery.flagIsSet(Flag.DRAFT)));
+        filter.getIsFlagged().ifPresent(isFlagged -> searchQuery.andCriteria(SearchQuery.flagIsSet(Flag.FLAGGED)));
+        filter.getIsUnread().ifPresent(isUnread -> searchQuery.andCriteria(SearchQuery.flagIsUnSet(Flag.SEEN)));
+        filter.getMaxSize().ifPresent(maxSize -> searchQuery.andCriteria(SearchQuery.sizeLessThan(maxSize)));
+        filter.getMinSize().ifPresent(minSize -> searchQuery.andCriteria(SearchQuery.sizeGreaterThan(minSize)));
+        return searchQuery;
+    }
+
+    private Criterion convertOperator(FilterOperator filter) {
+        switch (filter.getOperator()) {
+        case AND:
+            return SearchQuery.and(convertCriterias(filter));
+   
+        case OR:
+            return SearchQuery.or(convertCriterias(filter));
+   
+        case NOT:
+            return SearchQuery.not(convertCriterias(filter));
+        }
+        throw new RuntimeException("Unknown operator");
+    }
+
+    private ImmutableList<Criterion> convertCriterias(FilterOperator filter) {
+        return filter.getConditions().stream()
+            .map(this::convert)
+            .flatMap(sq -> sq.getCriterias().stream())
+            .collect(Guavate.toImmutableList());
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/ce1fcea4/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/FilterConditionTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/FilterConditionTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/FilterConditionTest.java
index a4707e5..5a518f0 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/FilterConditionTest.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/FilterConditionTest.java
@@ -21,9 +21,9 @@ package org.apache.james.jmap.model;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
+import java.time.ZonedDateTime;
 import java.util.Optional;
 
-import org.apache.commons.lang.NotImplementedException;
 import org.junit.Test;
 
 import com.google.common.collect.ImmutableList;
@@ -69,101 +69,50 @@ public class FilterConditionTest {
                 .build();
         assertThat(filterCondition.getNotInMailboxes()).contains(ImmutableList.of("1", "2"));
     }
-    
-    @Test(expected=NotImplementedException.class)
-    public void builderShouldThrowWhenBefore() {
-        FilterCondition.builder().before(null);
-    }
-
-    @Test(expected=NotImplementedException.class)
-    public void builderShouldThrowWhenAfter() {
-        FilterCondition.builder().after(null);
-    }
-
-    @Test(expected=NotImplementedException.class)
-    public void builderShouldThrowWhenMinSize() {
-        FilterCondition.builder().minSize(0);
-    }
-
-    @Test(expected=NotImplementedException.class)
-    public void builderShouldThrowWhenMaxSize() {
-        FilterCondition.builder().maxSize(0);
-    }
-
-    @Test(expected=NotImplementedException.class)
-    public void builderShouldThrowWhenIsFlagged() {
-        FilterCondition.builder().isFlagged(false);
-    }
-
-    @Test(expected=NotImplementedException.class)
-    public void builderShouldThrowWhenIsUnread() {
-        FilterCondition.builder().isUnread(false);
-    }
-
-    @Test(expected=NotImplementedException.class)
-    public void builderShouldThrowWhenIsAnswered() {
-        FilterCondition.builder().isAnswered(false);
-    }
-
-    @Test(expected=NotImplementedException.class)
-    public void builderShouldThrowWhenIsDraft() {
-        FilterCondition.builder().isDraft(false);
-    }
-
-    @Test(expected=NotImplementedException.class)
-    public void builderShouldThrowWhenHasAttachment() {
-        FilterCondition.builder().hasAttachment(false);
-    }
-
-    @Test(expected=NotImplementedException.class)
-    public void builderShouldThrowWhenText() {
-        FilterCondition.builder().text(null);
-    }
-
-    @Test(expected=NotImplementedException.class)
-    public void builderShouldThrowWhenFrom() {
-        FilterCondition.builder().from(null);
-    }
-
-    @Test(expected=NotImplementedException.class)
-    public void builderShouldThrowWhenTo() {
-        FilterCondition.builder().to(null);
-    }
-
-    @Test(expected=NotImplementedException.class)
-    public void builderShouldThrowWhenCc() {
-        FilterCondition.builder().cc(null);
-    }
-
-    @Test(expected=NotImplementedException.class)
-    public void builderShouldThrowWhenBcc() {
-        FilterCondition.builder().bcc(null);
-    }
-
-    @Test(expected=NotImplementedException.class)
-    public void builderShouldThrowWhenSubject() {
-        FilterCondition.builder().subject(null);
-    }
-
-    @Test(expected=NotImplementedException.class)
-    public void builderShouldThrowWhenBody() {
-        FilterCondition.builder().body(null);
-    }
-
-    @Test(expected=NotImplementedException.class)
-    public void builderShouldThrowWhenHeader() {
-        FilterCondition.builder().header(ImmutableList.of());
-    }
 
     @Test
     public void buildShouldWork() {
-        FilterCondition expectedFilterCondition = new FilterCondition(Optional.of(ImmutableList.of("1")), Optional.of(ImmutableList.of("2")), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), 
-                Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), 
-                Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty());
+        ZonedDateTime before = ZonedDateTime.parse("2016-07-19T14:30:00Z");
+        ZonedDateTime after = ZonedDateTime.parse("2016-07-19T14:31:00Z");
+        int minSize = 4;
+        int maxSize = 123;
+        boolean isFlagged = true;
+        boolean isUnread = true;
+        boolean isAnswered = true;
+        boolean isDraft = true;
+        boolean hasAttachment = true;
+        String text = "text";
+        String from = "sender@james.org";
+        String to = "recipient@james.org";
+        String cc = "copy@james.org";
+        String bcc = "blindcopy@james.org";
+        String subject = "subject";
+        String body = "body";
+        Header header = Header.from(ImmutableList.of("name", "value"));
+        FilterCondition expectedFilterCondition = new FilterCondition(Optional.of(ImmutableList.of("1")), Optional.of(ImmutableList.of("2")), Optional.of(before), Optional.of(after), Optional.of(minSize), Optional.of(maxSize), 
+                Optional.of(isFlagged), Optional.of(isUnread), Optional.of(isAnswered), Optional.of(isDraft), Optional.of(hasAttachment), Optional.of(text), Optional.of(from), 
+                Optional.of(to), Optional.of(cc), Optional.of(bcc), Optional.of(subject), Optional.of(body), Optional.of(header));
 
         FilterCondition filterCondition = FilterCondition.builder()
                 .inMailboxes(Optional.of(ImmutableList.of("1")))
                 .notInMailboxes("2")
+                .before(before)
+                .after(after)
+                .minSize(minSize)
+                .maxSize(maxSize)
+                .isFlagged(isFlagged)
+                .isUnread(isUnread)
+                .isAnswered(isAnswered)
+                .isDraft(isDraft)
+                .hasAttachment(hasAttachment)
+                .text(text)
+                .from(from)
+                .to(to)
+                .cc(cc)
+                .bcc(bcc)
+                .subject(subject)
+                .body(body)
+                .header(header)
                 .build();
 
         assertThat(filterCondition).isEqualToComparingFieldByField(expectedFilterCondition);

http://git-wip-us.apache.org/repos/asf/james-project/blob/ce1fcea4/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/HeaderTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/HeaderTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/HeaderTest.java
new file mode 100644
index 0000000..9d5d09b
--- /dev/null
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/HeaderTest.java
@@ -0,0 +1,71 @@
+/****************************************************************
+ * 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.jmap.model;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import java.util.Optional;
+
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+
+public class HeaderTest {
+
+    @Test
+    public void builderShouldThrowWhenHeaderIsNull() {
+        assertThatThrownBy(() -> Header.builder().header(null)).isInstanceOf(NullPointerException.class);
+    }
+
+    @Test
+    public void builderShouldThrowWhenHeaderIsEmpty() {
+        assertThatThrownBy(() -> Header.builder().header(ImmutableList.of())).isInstanceOf(IllegalArgumentException.class);
+    }
+
+    @Test
+    public void builderShouldThrowWhenHeaderHasMoreThanTwoElements() {
+        assertThatThrownBy(() -> Header.builder().header(ImmutableList.of("1", "2", "3"))).isInstanceOf(IllegalArgumentException.class);
+    }
+
+    @Test
+    public void buildShouldThrowWhenNameIsNotGiven() {
+        assertThatThrownBy(() -> Header.builder().build()).isInstanceOf(IllegalStateException.class);
+    }
+
+    @Test
+    public void buildShouldSetNameWhenGiven() {
+        String expectedName = "name";
+        Header header = Header.builder().header(ImmutableList.of(expectedName)).build();
+
+        assertThat(header.getName()).isEqualTo(expectedName);
+        assertThat(header.getValue()).isEmpty();
+    }
+
+    @Test
+    public void buildShouldSetValueWhenGiven() {
+        String expectedName = "name";
+        String expectedValue = "value";
+        Header header = Header.builder().header(ImmutableList.of(expectedName, expectedValue)).build();
+
+        assertThat(header.getName()).isEqualTo(expectedName);
+        assertThat(header.getValue()).isEqualTo(Optional.of(expectedValue));
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/ce1fcea4/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/FilterToSearchQueryTest.java
----------------------------------------------------------------------
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/FilterToSearchQueryTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/FilterToSearchQueryTest.java
new file mode 100644
index 0000000..41cfb39
--- /dev/null
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/FilterToSearchQueryTest.java
@@ -0,0 +1,415 @@
+/****************************************************************
+ * 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.jmap.utils;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import java.time.ZonedDateTime;
+import java.util.Date;
+
+import javax.mail.Flags.Flag;
+
+import org.apache.commons.lang.NotImplementedException;
+import org.apache.james.jmap.model.Filter;
+import org.apache.james.jmap.model.FilterCondition;
+import org.apache.james.jmap.model.FilterOperator;
+import org.apache.james.jmap.model.Header;
+import org.apache.james.mailbox.model.SearchQuery;
+import org.apache.james.mailbox.model.SearchQuery.AddressType;
+import org.apache.james.mailbox.model.SearchQuery.DateResolution;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+
+public class FilterToSearchQueryTest {
+
+    @Test
+    public void filterConditionShouldThrowWhenUnknownFilter() {
+        Filter myFilter = (indentation -> null);
+        assertThatThrownBy(() -> new FilterToSearchQuery().convert(myFilter))
+            .isInstanceOf(RuntimeException.class)
+            .hasMessage("Unknown filter: " + myFilter.getClass());
+    }
+
+    @Test
+    public void filterConditionShouldMapEmptyWhenEmptyFilter() {
+        SearchQuery searchQuery = new FilterToSearchQuery().convert(FilterCondition.builder()
+                .build());
+
+        assertThat(searchQuery).isEqualTo(new SearchQuery());
+    }
+
+    @Test
+    public void filterConditionShouldMapWhenFrom() {
+        String from = "sender@james.org";
+        SearchQuery expectedSearchQuery = new SearchQuery();
+        expectedSearchQuery.andCriteria(SearchQuery.address(AddressType.From, from));
+
+        SearchQuery searchQuery = new FilterToSearchQuery().convert(FilterCondition.builder()
+                .from(from)
+                .build());
+
+        assertThat(searchQuery).isEqualTo(expectedSearchQuery);
+    }
+
+    @Test
+    public void filterConditionShouldMapWhenTo() {
+        String to = "recipient@james.org";
+        SearchQuery expectedSearchQuery = new SearchQuery();
+        expectedSearchQuery.andCriteria(SearchQuery.address(AddressType.To, to));
+
+        SearchQuery searchQuery = new FilterToSearchQuery().convert(FilterCondition.builder()
+                .to(to)
+                .build());
+
+        assertThat(searchQuery).isEqualTo(expectedSearchQuery);
+    }
+
+    @Test
+    public void filterConditionShouldMapWhenCc() {
+        String cc = "copy@james.org";
+        SearchQuery expectedSearchQuery = new SearchQuery();
+        expectedSearchQuery.andCriteria(SearchQuery.address(AddressType.Cc, cc));
+
+        SearchQuery searchQuery = new FilterToSearchQuery().convert(FilterCondition.builder()
+                .cc(cc)
+                .build());
+
+        assertThat(searchQuery).isEqualTo(expectedSearchQuery);
+    }
+
+    @Test
+    public void filterConditionShouldMapWhenBcc() {
+        String bcc = "blindcopy@james.org";
+        SearchQuery expectedSearchQuery = new SearchQuery();
+        expectedSearchQuery.andCriteria(SearchQuery.address(AddressType.Bcc, bcc));
+
+        SearchQuery searchQuery = new FilterToSearchQuery().convert(FilterCondition.builder()
+                .bcc(bcc)
+                .build());
+
+        assertThat(searchQuery).isEqualTo(expectedSearchQuery);
+    }
+
+    @Test
+    public void filterConditionShouldMapWhenSubject() {
+        String subject = "subject";
+        SearchQuery expectedSearchQuery = new SearchQuery();
+        expectedSearchQuery.andCriteria(SearchQuery.headerContains("Subject", subject));
+
+        SearchQuery searchQuery = new FilterToSearchQuery().convert(FilterCondition.builder()
+                .subject(subject)
+                .build());
+
+        assertThat(searchQuery).isEqualTo(expectedSearchQuery);
+    }
+
+    @Test
+    public void filterConditionShouldMapWhenBody() {
+        String body = "body";
+        SearchQuery expectedSearchQuery = new SearchQuery();
+        expectedSearchQuery.andCriteria(SearchQuery.bodyContains(body));
+
+        SearchQuery searchQuery = new FilterToSearchQuery().convert(FilterCondition.builder()
+                .body(body)
+                .build());
+
+        assertThat(searchQuery).isEqualTo(expectedSearchQuery);
+    }
+
+    @Test
+    public void filterConditionShouldMapWhenText() {
+        String text = "text";
+        SearchQuery expectedSearchQuery = new SearchQuery();
+        expectedSearchQuery.andCriteria(SearchQuery.or(ImmutableList.of(
+                SearchQuery.address(AddressType.From, text),
+                SearchQuery.address(AddressType.To, text),
+                SearchQuery.address(AddressType.Cc, text),
+                SearchQuery.address(AddressType.Bcc, text),
+                SearchQuery.headerContains("Subject", text),
+                SearchQuery.bodyContains(text))));
+
+        SearchQuery searchQuery = new FilterToSearchQuery().convert(FilterCondition.builder()
+                .text(text)
+                .build());
+
+        assertThat(searchQuery).isEqualTo(expectedSearchQuery);
+    }
+
+    @Test
+    public void filterConditionShouldMapWhenAfter() {
+        ZonedDateTime after = ZonedDateTime.now();
+        SearchQuery expectedSearchQuery = new SearchQuery();
+        expectedSearchQuery.andCriteria(SearchQuery.internalDateAfter(Date.from(after.toInstant()), DateResolution.Second));
+
+        SearchQuery searchQuery = new FilterToSearchQuery().convert(FilterCondition.builder()
+                .after(after)
+                .build());
+
+        assertThat(searchQuery).isEqualTo(expectedSearchQuery);
+    }
+
+    @Test
+    public void filterConditionShouldMapWhenBefore() {
+        ZonedDateTime before = ZonedDateTime.now();
+        SearchQuery expectedSearchQuery = new SearchQuery();
+        expectedSearchQuery.andCriteria(SearchQuery.internalDateBefore(Date.from(before.toInstant()), DateResolution.Second));
+
+        SearchQuery searchQuery = new FilterToSearchQuery().convert(FilterCondition.builder()
+                .before(before)
+                .build());
+
+        assertThat(searchQuery).isEqualTo(expectedSearchQuery);
+    }
+
+    @Test
+    public void filterConditionShouldThrowWhenHasAttachment() {
+        assertThatThrownBy(() -> new FilterToSearchQuery().convert(FilterCondition.builder()
+                .hasAttachment(true)
+                .build()))
+            .isInstanceOf(NotImplementedException.class);
+    }
+
+    @Test
+    public void filterConditionShouldMapWhenIsAnswered() {
+        SearchQuery expectedSearchQuery = new SearchQuery();
+        expectedSearchQuery.andCriteria(SearchQuery.flagIsSet(Flag.ANSWERED));
+
+        SearchQuery searchQuery = new FilterToSearchQuery().convert(FilterCondition.builder()
+                .isAnswered(true)
+                .build());
+
+        assertThat(searchQuery).isEqualTo(expectedSearchQuery);
+    }
+
+    @Test
+    public void filterConditionShouldMapWhenIsDraft() {
+        SearchQuery expectedSearchQuery = new SearchQuery();
+        expectedSearchQuery.andCriteria(SearchQuery.flagIsSet(Flag.DRAFT));
+
+        SearchQuery searchQuery = new FilterToSearchQuery().convert(FilterCondition.builder()
+                .isDraft(true)
+                .build());
+
+        assertThat(searchQuery).isEqualTo(expectedSearchQuery);
+    }
+
+    @Test
+    public void filterConditionShouldMapWhenIsFlagged() {
+        SearchQuery expectedSearchQuery = new SearchQuery();
+        expectedSearchQuery.andCriteria(SearchQuery.flagIsSet(Flag.FLAGGED));
+
+        SearchQuery searchQuery = new FilterToSearchQuery().convert(FilterCondition.builder()
+                .isFlagged(true)
+                .build());
+
+        assertThat(searchQuery).isEqualTo(expectedSearchQuery);
+    }
+
+    @Test
+    public void filterConditionShouldMapWhenIsUnread() {
+        SearchQuery expectedSearchQuery = new SearchQuery();
+        expectedSearchQuery.andCriteria(SearchQuery.flagIsUnSet(Flag.SEEN));
+
+        SearchQuery searchQuery = new FilterToSearchQuery().convert(FilterCondition.builder()
+                .isUnread(true)
+                .build());
+
+        assertThat(searchQuery).isEqualTo(expectedSearchQuery);
+    }
+
+    @Test
+    public void filterConditionShouldMapWhenMaxSize() {
+        int maxSize = 123;
+        SearchQuery expectedSearchQuery = new SearchQuery();
+        expectedSearchQuery.andCriteria(SearchQuery.sizeLessThan(maxSize));
+
+        SearchQuery searchQuery = new FilterToSearchQuery().convert(FilterCondition.builder()
+                .maxSize(maxSize)
+                .build());
+
+        assertThat(searchQuery).isEqualTo(expectedSearchQuery);
+    }
+
+    @Test
+    public void filterConditionShouldMapWhenMinSize() {
+        int minSize = 4;
+        SearchQuery expectedSearchQuery = new SearchQuery();
+        expectedSearchQuery.andCriteria(SearchQuery.sizeGreaterThan(minSize));
+
+        SearchQuery searchQuery = new FilterToSearchQuery().convert(FilterCondition.builder()
+                .minSize(minSize)
+                .build());
+
+        assertThat(searchQuery).isEqualTo(expectedSearchQuery);
+    }
+
+    @Test
+    public void filterConditionShouldMapWhenHeaderWithOneElement() {
+        String headerName = "name";
+        SearchQuery expectedSearchQuery = new SearchQuery();
+        expectedSearchQuery.andCriteria(SearchQuery.headerExists(headerName));
+
+        SearchQuery searchQuery = new FilterToSearchQuery().convert(FilterCondition.builder()
+                .header(Header.from(ImmutableList.of(headerName)))
+                .build());
+
+        assertThat(searchQuery).isEqualTo(expectedSearchQuery);
+    }
+
+    @Test
+    public void filterConditionShouldMapWhenHeaderWithTwoElements() {
+        String headerName = "name";
+        String headerValue = "value";
+        SearchQuery expectedSearchQuery = new SearchQuery();
+        expectedSearchQuery.andCriteria(SearchQuery.headerContains(headerName, headerValue));
+
+        SearchQuery searchQuery = new FilterToSearchQuery().convert(FilterCondition.builder()
+                .header(Header.from(ImmutableList.of(headerName, headerValue)))
+                .build());
+
+        assertThat(searchQuery).isEqualTo(expectedSearchQuery);
+    }
+
+    @Test
+    public void filterConditionShouldMapTwoConditions() {
+        String from = "sender@james.org";
+        String to = "recipient@james.org";
+        SearchQuery expectedSearchQuery = new SearchQuery();
+        expectedSearchQuery.andCriteria(SearchQuery.and(ImmutableList.of(
+                SearchQuery.address(AddressType.From, from),
+                SearchQuery.address(AddressType.To, to))));
+
+        Filter filter = FilterOperator.and(
+                FilterCondition.builder()
+                    .from(from)
+                    .build(),
+                FilterCondition.builder()
+                    .to(to)
+                    .build());
+
+        SearchQuery searchQuery = new FilterToSearchQuery().convert(filter);
+
+        assertThat(searchQuery).isEqualTo(expectedSearchQuery);
+    }
+
+    @Test
+    public void filterConditionShouldMapWhenAndOperator() {
+        String from = "sender@james.org";
+        String to = "recipient@james.org";
+        String subject = "subject";
+        SearchQuery expectedSearchQuery = new SearchQuery();
+        expectedSearchQuery.andCriteria(SearchQuery.and(ImmutableList.of(
+                SearchQuery.address(AddressType.From, from),
+                SearchQuery.address(AddressType.To, to),
+                SearchQuery.headerContains("Subject", subject))));
+
+        Filter complexFilter = FilterOperator.and(
+                FilterCondition.builder()
+                    .from(from)
+                    .to(to)
+                    .subject(subject)
+                    .build());
+
+        SearchQuery searchQuery = new FilterToSearchQuery().convert(complexFilter);
+
+        assertThat(searchQuery).isEqualTo(expectedSearchQuery);
+    }
+
+    @Test
+    public void filterConditionShouldMapWhenOrOperator() {
+        String from = "sender@james.org";
+        String to = "recipient@james.org";
+        String subject = "subject";
+        SearchQuery expectedSearchQuery = new SearchQuery();
+        expectedSearchQuery.andCriteria(SearchQuery.or(ImmutableList.of(
+                SearchQuery.address(AddressType.From, from),
+                SearchQuery.address(AddressType.To, to),
+                SearchQuery.headerContains("Subject", subject))));
+
+        Filter complexFilter = FilterOperator.or(
+                FilterCondition.builder()
+                    .from(from)
+                    .to(to)
+                    .subject(subject)
+                    .build());
+
+        SearchQuery searchQuery = new FilterToSearchQuery().convert(complexFilter);
+
+        assertThat(searchQuery).isEqualTo(expectedSearchQuery);
+    }
+
+    @Test
+    public void filterConditionShouldMapWhenNotOperator() {
+        String from = "sender@james.org";
+        String to = "recipient@james.org";
+        String subject = "subject";
+        SearchQuery expectedSearchQuery = new SearchQuery();
+        expectedSearchQuery.andCriteria(SearchQuery.not(ImmutableList.of(
+                SearchQuery.address(AddressType.From, from),
+                SearchQuery.address(AddressType.To, to),
+                SearchQuery.headerContains("Subject", subject))));
+
+        Filter complexFilter = FilterOperator.not(
+                FilterCondition.builder()
+                    .from(from)
+                    .to(to)
+                    .subject(subject)
+                    .build());
+
+        SearchQuery searchQuery = new FilterToSearchQuery().convert(complexFilter);
+
+        assertThat(searchQuery).isEqualTo(expectedSearchQuery);
+    }
+
+    @Test
+    public void filterConditionShouldMapWhenComplexFilterTree() {
+        String from = "sender@james.org";
+        String to = "recipient@james.org";
+        String cc = "copy@james.org";
+        SearchQuery expectedSearchQuery = new SearchQuery();
+        expectedSearchQuery.andCriteria(SearchQuery.and(ImmutableList.of(
+                SearchQuery.address(AddressType.From, from),
+                SearchQuery.or(ImmutableList.of(
+                        SearchQuery.not(SearchQuery.address(AddressType.To, to)),
+                        SearchQuery.address(AddressType.Cc, cc))
+                        )
+                )));
+
+        Filter complexFilter = FilterOperator.and(
+                FilterCondition.builder()
+                    .from(from)
+                    .build(),
+                FilterOperator.or(
+                    FilterOperator.not(
+                        FilterCondition.builder()
+                            .to(to)
+                            .build()),
+                    FilterCondition.builder()
+                        .cc(cc)
+                        .build()
+                ));
+
+        SearchQuery searchQuery = new FilterToSearchQuery().convert(complexFilter);
+
+        assertThat(searchQuery).isEqualTo(expectedSearchQuery);
+    }
+}


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