Author: matthieu
Date: Fri Dec 11 12:35:39 2015
New Revision: 1719395

URL: http://svn.apache.org/viewvc?rev=1719395&view=rev
Log:
JAMES-1644 integrate GetMessage into Jmap Server

        Register the handler into Jmap Server and cover basic features with
        integration tests

Added:
    
james/project/trunk/server/protocols/jmap-integration-testing/src/test/java/org/apache/james/jmap/methods/GetMessagesMethodTest.java
    
james/project/trunk/server/protocols/jmap-integration-testing/src/test/java/org/apache/james/jmap/methods/cassandra/CassandraGetMessagesMethodTest.java
      - copied, changed from r1719394, 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/GetMessagesResponse.java
Modified:
    
james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
    james/project/trunk/server/container/cassandra-guice/pom.xml
    
james/project/trunk/server/container/cassandra-guice/src/main/java/org/apache/james/jmap/MethodsModule.java
    james/project/trunk/server/pom.xml
    james/project/trunk/server/protocols/jmap-integration-testing/pom.xml
    
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPServlet.java
    
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/GetMessagesMethod.java
    
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/JmapResponseWriterImpl.java
    
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/RequestHandler.java
    
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/GetMessagesRequest.java
    
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/GetMessagesResponse.java
    
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageId.java
    
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/GetMessagesMethodTest.java

Modified: 
james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java?rev=1719395&r1=1719394&r2=1719395&view=diff
==============================================================================
--- 
james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
 (original)
+++ 
james/project/trunk/mailbox/store/src/main/java/org/apache/james/mailbox/store/StoreMailboxManager.java
 Fri Dec 11 12:35:39 2015
@@ -59,8 +59,8 @@ import org.apache.james.mailbox.store.ev
 import org.apache.james.mailbox.store.event.DefaultDelegatingMailboxListener;
 import org.apache.james.mailbox.store.event.MailboxEventDispatcher;
 import org.apache.james.mailbox.store.mail.MailboxMapper;
-import org.apache.james.mailbox.store.mail.model.MailboxId;
 import org.apache.james.mailbox.store.mail.model.Mailbox;
+import org.apache.james.mailbox.store.mail.model.MailboxId;
 import org.apache.james.mailbox.store.mail.model.impl.SimpleMailbox;
 import org.apache.james.mailbox.store.quota.DefaultQuotaRootResolver;
 import org.apache.james.mailbox.store.quota.NoQuotaManager;

Modified: james/project/trunk/server/container/cassandra-guice/pom.xml
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/container/cassandra-guice/pom.xml?rev=1719395&r1=1719394&r2=1719395&view=diff
==============================================================================
--- james/project/trunk/server/container/cassandra-guice/pom.xml (original)
+++ james/project/trunk/server/container/cassandra-guice/pom.xml Fri Dec 11 
12:35:39 2015
@@ -370,6 +370,10 @@
                     <artifactId>jackson-datatype-jdk8</artifactId>
                 </dependency>
                 <dependency>
+                    <groupId>com.fasterxml.jackson.datatype</groupId>
+                    <artifactId>jackson-datatype-jsr310</artifactId>
+                </dependency>
+                <dependency>
                     <groupId>com.google.guava</groupId>
                     <artifactId>guava</artifactId>
                 </dependency>

Modified: 
james/project/trunk/server/container/cassandra-guice/src/main/java/org/apache/james/jmap/MethodsModule.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/container/cassandra-guice/src/main/java/org/apache/james/jmap/MethodsModule.java?rev=1719395&r1=1719394&r2=1719395&view=diff
==============================================================================
--- 
james/project/trunk/server/container/cassandra-guice/src/main/java/org/apache/james/jmap/MethodsModule.java
 (original)
+++ 
james/project/trunk/server/container/cassandra-guice/src/main/java/org/apache/james/jmap/MethodsModule.java
 Fri Dec 11 12:35:39 2015
@@ -19,8 +19,10 @@
 
 package org.apache.james.jmap;
 
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
 import org.apache.james.jmap.methods.GetMailboxesMethod;
 import org.apache.james.jmap.methods.GetMessageListMethod;
+import org.apache.james.jmap.methods.GetMessagesMethod;
 import org.apache.james.jmap.methods.JmapRequestParser;
 import org.apache.james.jmap.methods.JmapRequestParserImpl;
 import org.apache.james.jmap.methods.JmapResponseWriter;
@@ -42,6 +44,7 @@ public class MethodsModule extends Abstr
     protected void configure() {
         Multibinder<Module> jacksonModules = 
Multibinder.newSetBinder(binder(), Module.class);
         jacksonModules.addBinding().to(Jdk8Module.class);
+        jacksonModules.addBinding().to(JavaTimeModule.class);
         
bind(JmapRequestParser.class).to(JmapRequestParserImpl.class).in(Singleton.class);
         
bind(JmapResponseWriter.class).to(JmapResponseWriterImpl.class).in(Singleton.class);
 
@@ -50,6 +53,7 @@ public class MethodsModule extends Abstr
         Multibinder<Method> methods = Multibinder.newSetBinder(binder(), 
Method.class);
         methods.addBinding().to(new 
TypeLiteral<GetMailboxesMethod<CassandraId>>(){});
         methods.addBinding().to(new 
TypeLiteral<GetMessageListMethod<CassandraId>>(){});
+        methods.addBinding().to(new 
TypeLiteral<GetMessagesMethod<CassandraId>>(){});
     }
 
 }

Modified: james/project/trunk/server/pom.xml
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/pom.xml?rev=1719395&r1=1719394&r2=1719395&view=diff
==============================================================================
--- james/project/trunk/server/pom.xml (original)
+++ james/project/trunk/server/pom.xml Fri Dec 11 12:35:39 2015
@@ -944,7 +944,11 @@
                 <artifactId>jackson-datatype-jdk8</artifactId>
                 <version>${jackson-data.version}</version>
             </dependency>
-
+            <dependency>
+                <groupId>com.fasterxml.jackson.datatype</groupId>
+                <artifactId>jackson-datatype-jsr310</artifactId>
+                <version>2.6.1</version>
+            </dependency>
             <dependency>
                 <groupId>dnsjava</groupId>
                 <artifactId>dnsjava</artifactId>

Modified: james/project/trunk/server/protocols/jmap-integration-testing/pom.xml
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap-integration-testing/pom.xml?rev=1719395&r1=1719394&r2=1719395&view=diff
==============================================================================
--- james/project/trunk/server/protocols/jmap-integration-testing/pom.xml 
(original)
+++ james/project/trunk/server/protocols/jmap-integration-testing/pom.xml Fri 
Dec 11 12:35:39 2015
@@ -181,6 +181,12 @@
                     <artifactId>guice-multibindings</artifactId>
                 </dependency>
                 <dependency>
+                    <groupId>com.jayway.jsonpath</groupId>
+                    <artifactId>json-path</artifactId>
+                    <scope>test</scope>
+                    <version>2.1.0</version>
+                </dependency>
+                <dependency>
                     <groupId>com.jayway.restassured</groupId>
                     <artifactId>rest-assured</artifactId>
                     <scope>test</scope>

Added: 
james/project/trunk/server/protocols/jmap-integration-testing/src/test/java/org/apache/james/jmap/methods/GetMessagesMethodTest.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap-integration-testing/src/test/java/org/apache/james/jmap/methods/GetMessagesMethodTest.java?rev=1719395&view=auto
==============================================================================
--- 
james/project/trunk/server/protocols/jmap-integration-testing/src/test/java/org/apache/james/jmap/methods/GetMessagesMethodTest.java
 (added)
+++ 
james/project/trunk/server/protocols/jmap-integration-testing/src/test/java/org/apache/james/jmap/methods/GetMessagesMethodTest.java
 Fri Dec 11 12:35:39 2015
@@ -0,0 +1,215 @@
+/****************************************************************
+ * 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.methods;
+
+import static com.jayway.restassured.RestAssured.given;
+import static com.jayway.restassured.config.EncoderConfig.encoderConfig;
+import static com.jayway.restassured.config.RestAssuredConfig.newConfig;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.startsWith;
+
+import java.io.ByteArrayInputStream;
+import java.time.ZonedDateTime;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import javax.mail.Flags;
+
+import org.apache.james.jmap.JmapAuthentication;
+import org.apache.james.jmap.JmapServer;
+import org.apache.james.jmap.api.access.AccessToken;
+import org.apache.james.mailbox.elasticsearch.EmbeddedElasticSearch;
+import org.apache.james.mailbox.model.MailboxConstants;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.assertj.core.data.MapEntry;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.RuleChain;
+import org.junit.rules.TemporaryFolder;
+
+import com.google.common.base.Charsets;
+import com.jayway.jsonpath.Configuration;
+import com.jayway.jsonpath.JsonPath;
+import com.jayway.jsonpath.ParseContext;
+import com.jayway.jsonpath.spi.json.JacksonJsonProvider;
+import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider;
+import com.jayway.restassured.RestAssured;
+import com.jayway.restassured.http.ContentType;
+
+public abstract class GetMessagesMethodTest {
+
+    private TemporaryFolder temporaryFolder = new TemporaryFolder();
+    private EmbeddedElasticSearch embeddedElasticSearch = new 
EmbeddedElasticSearch(temporaryFolder);
+    private JmapServer jmapServer = jmapServer(temporaryFolder, 
embeddedElasticSearch);
+
+    protected abstract JmapServer jmapServer(TemporaryFolder temporaryFolder, 
EmbeddedElasticSearch embeddedElasticSearch);
+
+    @Rule
+    public RuleChain chain = RuleChain
+        .outerRule(temporaryFolder)
+        .around(embeddedElasticSearch)
+        .around(jmapServer);
+
+    private AccessToken accessToken;
+    private ParseContext jsonPath;
+
+    @Before
+    public void setup() throws Exception {
+        RestAssured.port = jmapServer.getPort();
+        RestAssured.config = 
newConfig().encoderConfig(encoderConfig().defaultContentCharset(Charsets.UTF_8));
+        jsonPath = JsonPath.using(Configuration.builder()
+                                    .jsonProvider(new JacksonJsonProvider())
+                                    .mappingProvider(new 
JacksonMappingProvider())
+                                    .build());
+
+        String domain = "domain.tld";
+        String username = "username@" + domain;
+        String password = "password";
+        jmapServer.serverProbe().addDomain(domain);
+        jmapServer.serverProbe().addUser(username, password);
+        jmapServer.serverProbe().createMailbox("#private", "username", 
"inbox");
+        accessToken = JmapAuthentication.authenticateJamesUser(username, 
password);
+    }
+
+    @After
+    public void tearDown() {
+        jmapServer.clean();
+    }
+
+    @Test
+    public void 
getMessagesShouldErrorNotSupportedWhenRequestContainsNonNullAccountId() throws 
Exception {
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"getMessages\", {\"accountId\": \"1\"}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .content(equalTo("[[\"error\",{\"type\":\"Not yet 
implemented\"},\"#0\"]]"));
+    }
+    
+    @Test
+    public void getMessagesShouldIgnoreUnknownArguments() throws Exception {
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"getMessages\", {\"WAT\": true}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            
.content(equalTo("[[\"messages\",{\"notFound\":[],\"list\":[]},\"#0\"]]"));
+    }
+
+    @Test
+    public void 
getMessagesShouldErrorInvalidArgumentsWhenRequestContainsInvalidArgument() 
throws Exception {
+        given()
+                .accept(ContentType.JSON)
+                .contentType(ContentType.JSON)
+                .header("Authorization", accessToken.serialize())
+                .body("[[\"getMessages\", {\"ids\": null}, \"#0\"]]")
+                .when()
+                .post("/jmap")
+                .then()
+                .statusCode(200)
+                
.content(equalTo("[[\"error\",{\"type\":\"invalidArguments\"},\"#0\"]]"));
+    }
+
+    @Test
+    public void getMessagesShouldReturnEmptyListWhenNoMessage() throws 
Exception {
+        String response = given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"getMessages\", {\"ids\": []}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .content(startsWith("[[\"getMessages\","))
+            .extract()
+            .asString();
+        
+        
assertThat(jsonPath.parse(response).<Integer>read("$.length()")).isEqualTo(1);
+        
assertThat(jsonPath.parse(response).<Integer>read("$.[0].[1].list.length()")).isEqualTo(0);
+    }
+
+    @Test
+    public void getMessagesShouldReturnNoFoundIndicesWhenMessageNotFound() 
throws Exception {
+        String response = given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"getMessages\", {\"ids\": [\"username-inbox-12\"]}, 
\"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .content(startsWith("[[\"getMessages\","))
+            .extract()
+            .asString();
+        
+        
assertThat(jsonPath.parse(response).<Integer>read("$.length()")).isEqualTo(1);
+        
assertThat(jsonPath.parse(response).<List<String>>read("$.[0].[1].notFound")).containsExactly("username-inbox-12");
+    }
+    
+    @Test
+    public void getMessagesShouldReturnMessagesWhenAvailable() throws 
Exception {
+        ZonedDateTime dateTime = ZonedDateTime.parse("2014-10-30T14:12:00Z");
+        jmapServer.serverProbe().appendMessage("username", new 
MailboxPath(MailboxConstants.USER_NAMESPACE, "username", "inbox"),
+                new ByteArrayInputStream("Subject: my test 
subject\r\n\r\ntestmail".getBytes()), Date.from(dateTime.toInstant()), false, 
new Flags());
+        
+        embeddedElasticSearch.awaitForElasticSearch();
+        
+        String response = given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"getMessages\", {\"ids\": [\"username-inbox-1\"]}, 
\"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .content(startsWith("[[\"getMessages\","))
+            .extract()
+            .asString();
+
+        String firstResponsePath = "$.[0].[1]";
+        String firstMessagePath = firstResponsePath + ".list[0]";
+
+        
assertThat(jsonPath.parse(response).<Integer>read("$.length()")).isEqualTo(1);
+        assertThat(jsonPath.parse(response).<Integer>read(firstResponsePath + 
".list.length()")).isEqualTo(1);
+        assertThat(jsonPath.parse(response).<String>read(firstMessagePath + 
".id")).isEqualTo("[email protected]");
+        assertThat(jsonPath.parse(response).<String>read(firstMessagePath + 
".subject")).isEqualTo("my test subject");
+        assertThat(jsonPath.parse(response).<String>read(firstMessagePath + 
".textBody")).isEqualTo("testmail");
+        assertThat(jsonPath.parse(response).<Boolean>read(firstMessagePath + 
".isUnread")).isTrue();
+        assertThat(jsonPath.parse(response).<String>read(firstMessagePath + 
".preview")).isEqualTo("testmail");
+        assertThat(jsonPath.parse(response).<Map<String, 
String>>read(firstMessagePath + 
".headers")).containsExactly(MapEntry.entry("subject", "my test subject"));
+        assertThat(jsonPath.parse(response).<String>read(firstMessagePath + 
".date")).isEqualTo("2014-10-30T14:12:00Z");
+    }
+
+}

Copied: 
james/project/trunk/server/protocols/jmap-integration-testing/src/test/java/org/apache/james/jmap/methods/cassandra/CassandraGetMessagesMethodTest.java
 (from r1719394, 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/GetMessagesResponse.java)
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap-integration-testing/src/test/java/org/apache/james/jmap/methods/cassandra/CassandraGetMessagesMethodTest.java?p2=james/project/trunk/server/protocols/jmap-integration-testing/src/test/java/org/apache/james/jmap/methods/cassandra/CassandraGetMessagesMethodTest.java&p1=james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/GetMessagesResponse.java&r1=1719394&r2=1719395&rev=1719395&view=diff
==============================================================================
--- 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/GetMessagesResponse.java
 (original)
+++ 
james/project/trunk/server/protocols/jmap-integration-testing/src/test/java/org/apache/james/jmap/methods/cassandra/CassandraGetMessagesMethodTest.java
 Fri Dec 11 12:35:39 2015
@@ -16,22 +16,19 @@
  * specific language governing permissions and limitations      *
  * under the License.                                           *
  ****************************************************************/
-package org.apache.james.jmap.model;
 
-import java.util.List;
+package org.apache.james.jmap.methods.cassandra;
 
-import org.apache.james.jmap.methods.Method;
-
-public class GetMessagesResponse implements Method.Response {
-
-    private final List<Message> messages;
-
-    public GetMessagesResponse(List<Message> messages) {
-        this.messages = messages;
+import org.apache.james.jmap.JmapServer;
+import org.apache.james.jmap.cassandra.CassandraJmapServer;
+import org.apache.james.jmap.methods.GetMessagesMethodTest;
+import org.apache.james.mailbox.elasticsearch.EmbeddedElasticSearch;
+import org.junit.rules.TemporaryFolder;
+
+public class CassandraGetMessagesMethodTest extends GetMessagesMethodTest {
+
+    @Override
+    protected JmapServer jmapServer(TemporaryFolder temporaryFolder, 
EmbeddedElasticSearch embeddedElasticSearch) {
+        return new CassandraJmapServer(temporaryFolder, embeddedElasticSearch);
     }
-    
-    public List<Message> list() {
-        return messages;
-    }
-
 }

Modified: 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPServlet.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPServlet.java?rev=1719395&r1=1719394&r2=1719395&view=diff
==============================================================================
--- 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPServlet.java
 (original)
+++ 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/JMAPServlet.java
 Fri Dec 11 12:35:39 2015
@@ -67,6 +67,7 @@ public class JMAPServlet extends HttpSer
                 .map(ProtocolResponse::asProtocolSpecification)
                 .collect(Collectors.toList());
 
+            resp.setContentType(JSON_CONTENT_TYPE);
             objectMapper.writeValue(resp.getOutputStream(), responses);
         } catch (IOException e) {
             resp.setStatus(SC_BAD_REQUEST);

Modified: 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/GetMessagesMethod.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/GetMessagesMethod.java?rev=1719395&r1=1719394&r2=1719395&view=diff
==============================================================================
--- 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/GetMessagesMethod.java
 (original)
+++ 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/GetMessagesMethod.java
 Fri Dec 11 12:35:39 2015
@@ -28,6 +28,7 @@ import java.util.stream.StreamSupport;
 
 import javax.inject.Inject;
 
+import org.apache.commons.lang.NotImplementedException;
 import org.apache.james.jmap.model.GetMessagesRequest;
 import org.apache.james.jmap.model.GetMessagesResponse;
 import org.apache.james.jmap.model.Message;
@@ -82,6 +83,7 @@ public class GetMessagesMethod<Id extend
         Preconditions.checkNotNull(mailboxSession);
         Preconditions.checkArgument(request instanceof GetMessagesRequest);
         GetMessagesRequest getMessagesRequest = (GetMessagesRequest) request;
+        
getMessagesRequest.getAccountId().ifPresent(GetMessagesMethod::notImplemented);
         
         Function<MessageId, 
Stream<Pair<org.apache.james.mailbox.store.mail.model.Message<Id>, 
MailboxPath>>> loadMessages = loadMessage(mailboxSession);
         Function<Pair<org.apache.james.mailbox.store.mail.model.Message<Id>, 
MailboxPath>, Message> convertToJmapMessage = toJmapMessage(mailboxSession);
@@ -93,9 +95,14 @@ public class GetMessagesMethod<Id extend
 //            .map(filterFields)
             .collect(Collectors.toList());
 
-        return new GetMessagesResponse(result);
+        return 
GetMessagesResponse.builder().messages(result).expectedMessageIds(getMessagesRequest.getIds()).build();
     }
 
+    private static void notImplemented(String input) {
+        throw new NotImplementedException();
+    }
+
+    
     private 
Function<Pair<org.apache.james.mailbox.store.mail.model.Message<Id>, 
MailboxPath>, Message> toJmapMessage(MailboxSession mailboxSession) {
         return (value) -> {
             org.apache.james.mailbox.store.mail.model.Message<Id> 
messageResult = value.getValue0();
@@ -108,6 +115,7 @@ public class GetMessagesMethod<Id extend
                                     
Pair<org.apache.james.mailbox.store.mail.model.Message<Id>, 
                                          MailboxPath>>> 
                 loadMessage(MailboxSession mailboxSession) {
+
         return Throwing
                 .function((MessageId messageId) -> {
                      MailboxPath mailboxPath = 
messageId.getMailboxPath(mailboxSession);

Modified: 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/JmapResponseWriterImpl.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/JmapResponseWriterImpl.java?rev=1719395&r1=1719394&r2=1719395&view=diff
==============================================================================
--- 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/JmapResponseWriterImpl.java
 (original)
+++ 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/JmapResponseWriterImpl.java
 Fri Dec 11 12:35:39 2015
@@ -23,6 +23,7 @@ import java.util.Set;
 
 import javax.inject.Inject;
 
+import com.fasterxml.jackson.databind.SerializationFeature;
 import org.apache.james.jmap.model.ProtocolResponse;
 
 import com.fasterxml.jackson.databind.Module;
@@ -34,7 +35,8 @@ public class JmapResponseWriterImpl impl
 
     @Inject
     public JmapResponseWriterImpl(Set<Module> jacksonModules) {
-        this.objectMapper = new ObjectMapper().registerModules(jacksonModules);
+        this.objectMapper = new ObjectMapper().registerModules(jacksonModules)
+            .configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
     }
 
     @Override

Modified: 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/RequestHandler.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/RequestHandler.java?rev=1719395&r1=1719394&r2=1719395&view=diff
==============================================================================
--- 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/RequestHandler.java
 (original)
+++ 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/RequestHandler.java
 Fri Dec 11 12:35:39 2015
@@ -69,6 +69,8 @@ public class RequestHandler {
                             return responseBuilder.error("Not yet 
implemented").build();
                         }
                         return 
responseBuilder.error("invalidArguments").build();
+                    } catch (NotImplementedException e) {
+                        return responseBuilder.error("Not yet 
implemented").build();
                     }
                 };
         

Modified: 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/GetMessagesRequest.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/GetMessagesRequest.java?rev=1719395&r1=1719394&r2=1719395&view=diff
==============================================================================
--- 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/GetMessagesRequest.java
 (original)
+++ 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/GetMessagesRequest.java
 Fri Dec 11 12:35:39 2015
@@ -23,14 +23,18 @@ import java.util.Optional;
 
 import org.apache.james.jmap.methods.JmapRequest;
 
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
 import com.google.common.collect.ImmutableList;
 
+@JsonDeserialize(builder = GetMessagesRequest.Builder.class)
 public class GetMessagesRequest implements JmapRequest {
 
     public static Builder builder() {
         return new Builder();
     }
     
+    @JsonPOJOBuilder(withPrefix = "")
     public static class Builder {
         
         private Optional<String> accountId;

Modified: 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/GetMessagesResponse.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/GetMessagesResponse.java?rev=1719395&r1=1719394&r2=1719395&view=diff
==============================================================================
--- 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/GetMessagesResponse.java
 (original)
+++ 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/GetMessagesResponse.java
 Fri Dec 11 12:35:39 2015
@@ -19,19 +19,75 @@
 package org.apache.james.jmap.model;
 
 import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 import org.apache.james.jmap.methods.Method;
 
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+
+@JsonDeserialize(builder = GetMessagesResponse.Builder.class)
 public class GetMessagesResponse implements Method.Response {
 
+    public static Builder builder() {
+        return new Builder();
+    }
+    
+    @JsonPOJOBuilder(withPrefix = "")
+    public static class Builder {
+        private ImmutableList<Message> messages;
+        private List<MessageId> expectedMessageIds;
+
+        private Builder() {
+            this.messages = ImmutableList.of();
+        }
+
+        public Builder messages(List<Message> messages) {
+            this.messages = ImmutableList.copyOf(messages);
+            return this;
+        }
+
+        public Builder expectedMessageIds(List<MessageId> expectedMessageIds) {
+            this.expectedMessageIds = ImmutableList.copyOf(expectedMessageIds);
+            return this;
+        }
+        
+        public GetMessagesResponse build() {
+            Preconditions.checkState(messages != null);
+            return new GetMessagesResponse(messages, messagesNotFound());
+        }
+        
+
+        private List<MessageId> messagesNotFound() {
+            Set<MessageId> foundMessageIds = 
messages.stream().map(Message::getId).collect(Collectors.toSet());
+            return ImmutableList.copyOf(expectedMessageIds.stream()
+                .filter(id -> !foundMessageIds.contains(id))
+                .collect(Collectors.toList()));
+        }
+    }
+    
+    
+    
     private final List<Message> messages;
+    private final List<MessageId> messagesNotFound;
 
-    public GetMessagesResponse(List<Message> messages) {
+    private GetMessagesResponse(List<Message> messages, List<MessageId> 
messagesNotFound) {
         this.messages = messages;
+        this.messagesNotFound = messagesNotFound;
     }
-    
+
+    @JsonSerialize
     public List<Message> list() {
         return messages;
     }
+    
+    @JsonSerialize
+    public List<MessageId> notFound() {
+        return messagesNotFound;
+    }
 
 }

Modified: 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageId.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageId.java?rev=1719395&r1=1719394&r2=1719395&view=diff
==============================================================================
--- 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageId.java
 (original)
+++ 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MessageId.java
 Fri Dec 11 12:35:39 2015
@@ -25,6 +25,7 @@ import org.apache.james.mailbox.MailboxS
 import org.apache.james.mailbox.model.MailboxPath;
 import org.javatuples.Triplet;
 
+import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonValue;
 import com.google.common.base.Joiner;
 import com.google.common.base.Splitter;
@@ -33,6 +34,7 @@ public class MessageId {
 
     private static final String SEPARATOR = "-";
 
+    @JsonCreator
     public static MessageId of(String id) {
         Triplet<String, String, String> parts = 
Triplet.fromIterable(Splitter.on(SEPARATOR).split(id));
         return new MessageId(parts.getValue0(), parts.getValue1(), 
Long.valueOf(parts.getValue2()));

Modified: 
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/GetMessagesMethodTest.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/GetMessagesMethodTest.java?rev=1719395&r1=1719394&r2=1719395&view=diff
==============================================================================
--- 
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/GetMessagesMethodTest.java
 (original)
+++ 
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/GetMessagesMethodTest.java
 Fri Dec 11 12:35:39 2015
@@ -27,6 +27,7 @@ import java.util.Date;
 import java.util.List;
 import java.util.Locale;
 
+import org.apache.commons.lang.NotImplementedException;
 import org.apache.james.jmap.model.GetMessagesRequest;
 import org.apache.james.jmap.model.GetMessagesResponse;
 import org.apache.james.jmap.model.Message;
@@ -120,6 +121,14 @@ public class GetMessagesMethodTest {
         assertThatThrownBy(() -> 
testee.process(mock(GetMessagesRequest.class), 
mailboxSession)).isInstanceOf(NullPointerException.class);
     }
     
+
+    @Test
+    public void processShouldThrowWhenRequestHasAccountId() {
+        GetMessagesMethod<InMemoryId> testee = new 
GetMessagesMethod<>(mailboxSessionMapperFactory, mailboxSessionMapperFactory);
+        assertThatThrownBy(() -> testee.process(
+                GetMessagesRequest.builder().accountId("abc").build(), 
mock(MailboxSession.class))).isInstanceOf(NotImplementedException.class);
+    }
+    
     @Test
     public void processShouldFetchMessages() throws MailboxException {
         MessageManager inbox = mailboxManager.getMailbox(inboxPath, session);



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to