Author: matthieu
Date: Fri Dec 11 12:33:02 2015
New Revision: 1719382

URL: http://svn.apache.org/viewvc?rev=1719382&view=rev
Log:
JAMES-1644 Simple GetMessageListMethod implementation

Added:
    
james/project/trunk/server/protocols/jmap-integration-testing/src/test/java/org/apache/james/jmap/methods/GetMessageListMethodTest.java
    
james/project/trunk/server/protocols/jmap-integration-testing/src/test/java/org/apache/james/jmap/methods/cassandra/CassandraGetMessageListMethodTest.java
    
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/GetMessageListMethod.java
    
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/GetMessageListRequest.java
    
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/GetMessageListResponse.java
    
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/GetMessageListRequestTest.java
    
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/GetMessageListResponseTest.java
Modified:
    
james/project/trunk/server/container/cassandra-guice/src/main/java/org/apache/james/jmap/MethodsModule.java

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=1719382&r1=1719381&r2=1719382&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:33:02 2015
@@ -20,6 +20,7 @@
 package org.apache.james.jmap;
 
 import org.apache.james.jmap.methods.GetMailboxesMethod;
+import org.apache.james.jmap.methods.GetMessageListMethod;
 import org.apache.james.jmap.methods.JmapRequestParser;
 import org.apache.james.jmap.methods.JmapRequestParserImpl;
 import org.apache.james.jmap.methods.JmapResponseWriter;
@@ -45,6 +46,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>>(){});
     }
 
 }

Added: 
james/project/trunk/server/protocols/jmap-integration-testing/src/test/java/org/apache/james/jmap/methods/GetMessageListMethodTest.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap-integration-testing/src/test/java/org/apache/james/jmap/methods/GetMessageListMethodTest.java?rev=1719382&view=auto
==============================================================================
--- 
james/project/trunk/server/protocols/jmap-integration-testing/src/test/java/org/apache/james/jmap/methods/GetMessageListMethodTest.java
 (added)
+++ 
james/project/trunk/server/protocols/jmap-integration-testing/src/test/java/org/apache/james/jmap/methods/GetMessageListMethodTest.java
 Fri Dec 11 12:33:02 2015
@@ -0,0 +1,152 @@
+/****************************************************************
+ * 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.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.startsWith;
+
+import java.io.ByteArrayInputStream;
+import java.util.Date;
+
+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.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+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.restassured.RestAssured;
+import com.jayway.restassured.http.ContentType;
+
+public abstract class GetMessageListMethodTest {
+
+    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;
+
+    @Before
+    public void setup() throws Exception {
+        RestAssured.port = jmapServer.getPort();
+        RestAssured.config = 
newConfig().encoderConfig(encoderConfig().defaultContentCharset(Charsets.UTF_8));
+
+        String domain = "domain.tld";
+        String username = "username@" + domain;
+        String password = "password";
+        jmapServer.serverProbe().addDomain(domain);
+        jmapServer.serverProbe().addUser(username, password);
+        accessToken = JmapAuthentication.authenticateJamesUser(username, 
password);
+    }
+
+    @After
+    public void tearDown() {
+        jmapServer.clean();
+    }
+
+    @Test
+    public void 
getMessageListShouldErrorInvalidArgumentsWhenRequestIsInvalid() throws 
Exception {
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"getMessageList\", {\"filter\": true}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            
.content(equalTo("[[\"error\",{\"type\":\"invalidArguments\"},\"#0\"]]"));
+    }
+
+    @Test
+    public void 
getMessageListShouldReturnAllMessagesWhenSingleMailboxNoParameters() throws 
Exception {
+        String user = "user";
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, user, 
"name");
+
+        jmapServer.serverProbe().appendMessage(user, new 
MailboxPath(MailboxConstants.USER_NAMESPACE, user, "name"), 
+                new ByteArrayInputStream("Subject: 
test\r\n\r\ntestmail".getBytes()), new Date(), false, new Flags());
+        jmapServer.serverProbe().appendMessage(user, new 
MailboxPath(MailboxConstants.USER_NAMESPACE, user, "name"), 
+                new ByteArrayInputStream("Subject: 
test2\r\n\r\ntestmail".getBytes()), new Date(), false, new Flags());
+        embeddedElasticSearch.awaitForElasticSearch();
+
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"getMessageList\", {}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .content(startsWith("[[\"getMessageList\","
+                    + 
"{\"accountId\":null,\"filter\":null,\"sort\":[],\"collapseThreads\":false,\"state\":null,"
+                    +   
"\"canCalculateUpdates\":false,\"position\":0,\"total\":0,\"threadIds\":[],\"messageIds\":[\"1\",\"2\"]},"
+                    + "\"#0\"]]"));
+    }
+
+    @Ignore("ISSUE-53")
+    @Test
+    public void 
getMessageListShouldReturnAllMessagesWhenMultipleMailboxesAndNoParameters() 
throws Exception {
+        String user = "user";
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, user, 
"mailbox");
+        jmapServer.serverProbe().appendMessage(user, new 
MailboxPath(MailboxConstants.USER_NAMESPACE, user, "mailbox"), 
+                new ByteArrayInputStream("Subject: 
test\r\n\r\ntestmail".getBytes()), new Date(), false, new Flags());
+
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, user, 
"mailbox2");
+        jmapServer.serverProbe().appendMessage(user, new 
MailboxPath(MailboxConstants.USER_NAMESPACE, user, "mailbox2"), 
+                new ByteArrayInputStream("Subject: 
test2\r\n\r\ntestmail".getBytes()), new Date(), false, new Flags());
+        embeddedElasticSearch.awaitForElasticSearch();
+
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"getMessageList\", {}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .content(startsWith("[[\"getMessageList\","
+                    + 
"{\"accountId\":null,\"filter\":null,\"sort\":[],\"collapseThreads\":false,\"state\":null,"
+                    +   
"\"canCalculateUpdates\":false,\"position\":0,\"total\":0,\"threadIds\":[],\"messageIds\":[\"1\",\"2\"]},"
+                    + "\"#0\"]]"));
+    }
+}

Added: 
james/project/trunk/server/protocols/jmap-integration-testing/src/test/java/org/apache/james/jmap/methods/cassandra/CassandraGetMessageListMethodTest.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap-integration-testing/src/test/java/org/apache/james/jmap/methods/cassandra/CassandraGetMessageListMethodTest.java?rev=1719382&view=auto
==============================================================================
--- 
james/project/trunk/server/protocols/jmap-integration-testing/src/test/java/org/apache/james/jmap/methods/cassandra/CassandraGetMessageListMethodTest.java
 (added)
+++ 
james/project/trunk/server/protocols/jmap-integration-testing/src/test/java/org/apache/james/jmap/methods/cassandra/CassandraGetMessageListMethodTest.java
 Fri Dec 11 12:33:02 2015
@@ -0,0 +1,34 @@
+/****************************************************************
+ * 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.cassandra;
+
+import org.apache.james.jmap.JmapServer;
+import org.apache.james.jmap.cassandra.CassandraJmapServer;
+import org.apache.james.jmap.methods.GetMessageListMethodTest;
+import org.apache.james.mailbox.elasticsearch.EmbeddedElasticSearch;
+import org.junit.rules.TemporaryFolder;
+
+public class CassandraGetMessageListMethodTest extends 
GetMessageListMethodTest {
+
+    @Override
+    protected JmapServer jmapServer(TemporaryFolder temporaryFolder, 
EmbeddedElasticSearch embeddedElasticSearch) {
+        return new CassandraJmapServer(temporaryFolder, embeddedElasticSearch);
+    }
+}

Added: 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/GetMessageListMethod.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/GetMessageListMethod.java?rev=1719382&view=auto
==============================================================================
--- 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/GetMessageListMethod.java
 (added)
+++ 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/GetMessageListMethod.java
 Fri Dec 11 12:33:02 2015
@@ -0,0 +1,109 @@
+/****************************************************************
+ * 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 java.util.List;
+import java.util.Optional;
+
+import javax.inject.Inject;
+
+import org.apache.james.jmap.model.GetMessageListRequest;
+import org.apache.james.jmap.model.GetMessageListResponse;
+import org.apache.james.mailbox.MailboxManager;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.MessageManager;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.model.SearchQuery;
+import org.apache.james.mailbox.store.mail.model.MailboxId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableList;
+
+public class GetMessageListMethod<Id extends MailboxId> implements Method {
+
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(GetMailboxesMethod.class);
+    private static final Method.Name METHOD_NAME = 
Method.name("getMessageList");
+
+    private final MailboxManager mailboxManager;
+
+    @Inject
+    @VisibleForTesting public GetMessageListMethod(MailboxManager 
mailboxManager) {
+        this.mailboxManager = mailboxManager;
+    }
+
+    @Override
+    public Name methodName() {
+        return METHOD_NAME;
+    }
+
+    @Override
+    public Class<? extends JmapRequest> requestType() {
+        return GetMessageListRequest.class;
+    }
+
+    @Override
+    public GetMessageListResponse process(JmapRequest request, MailboxSession 
mailboxSession) {
+        Preconditions.checkArgument(request instanceof GetMessageListRequest);
+        try {
+            return getMessageListResponse(mailboxSession);
+        } catch (MailboxException e) {
+            throw Throwables.propagate(e);
+        }
+    }
+
+    private GetMessageListResponse getMessageListResponse(MailboxSession 
mailboxSession) throws MailboxException {
+        GetMessageListResponse.Builder builder = 
GetMessageListResponse.builder();
+
+        mailboxManager.list(mailboxSession)
+            .stream()
+            .map(mailboxPath -> getMailbox(mailboxPath, mailboxSession))
+            .map(messageManager -> getMessageIds(messageManager.get(), 
mailboxSession))
+            .flatMap(List::stream)
+            .map(String::valueOf)
+            .forEach(builder::messageId);
+
+        return builder.build();
+    }
+
+    private Optional<MessageManager> getMailbox(MailboxPath mailboxPath, 
MailboxSession mailboxSession) {
+        try {
+            return Optional.of(mailboxManager.getMailbox(mailboxPath, 
mailboxSession));
+        } catch (MailboxException e) {
+            LOGGER.warn("Error retrieveing mailbox :" + mailboxPath, e);
+            return Optional.empty();
+        }
+    }
+
+    private List<Long> getMessageIds(MessageManager messageManager, 
MailboxSession mailboxSession) {
+        SearchQuery searchQuery = new SearchQuery();
+        searchQuery.andCriteria(SearchQuery.all());
+        try {
+            return ImmutableList.copyOf(messageManager.search(searchQuery, 
mailboxSession));
+        } catch (MailboxException e) {
+            LOGGER.warn("Error when searching messages for query :" + 
searchQuery, e);
+            return ImmutableList.of();
+        }
+    }
+}

Added: 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/GetMessageListRequest.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/GetMessageListRequest.java?rev=1719382&view=auto
==============================================================================
--- 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/GetMessageListRequest.java
 (added)
+++ 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/GetMessageListRequest.java
 Fri Dec 11 12:33:02 2015
@@ -0,0 +1,208 @@
+/****************************************************************
+ * 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 org.apache.commons.lang.NotImplementedException;
+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.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+
+@JsonDeserialize(builder = GetMessageListRequest.Builder.class)
+public class GetMessageListRequest implements JmapRequest {
+
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    @JsonPOJOBuilder(withPrefix = "")
+    public static class Builder {
+
+        private String accountId;
+        private Filter filter;
+        private ImmutableList.Builder<String> sort;
+        private Boolean collapseThreads;
+        private int position;
+        private String anchor;
+        private Integer anchorOffset;
+        private Integer limit;
+        private Boolean fetchThreads;
+        private Boolean fetchMessages;
+        private ImmutableList.Builder<String> fetchMessageProperties;
+        private Boolean fetchSearchSnippets;
+
+        private Builder() {
+            sort = ImmutableList.builder();
+            fetchMessageProperties = ImmutableList.builder();
+        }
+
+        public Builder accountId(String accountId) {
+            throw new NotImplementedException();
+        }
+
+        public Builder filter(Filter filter) {
+            this.filter = filter;
+            return this;
+        }
+
+        public Builder sort(List<String> sort) {
+            this.sort.addAll(sort);
+            return this;
+        }
+
+        public Builder collapseThreads(boolean collapseThreads) {
+            throw new NotImplementedException();
+        }
+
+        public Builder position(int position) {
+            this.position = position;
+            return this;
+        }
+
+        public Builder anchor(String anchor) {
+            throw new NotImplementedException();
+        }
+
+        public Builder anchorOffset(int anchorOffset) {
+            throw new NotImplementedException();
+        }
+
+        public Builder limit(int limit) {
+            this.limit = limit;
+            return this;
+        }
+
+        public Builder fetchThreads(boolean fetchThreads) {
+            throw new NotImplementedException();
+        }
+
+        public Builder fetchMessages(boolean fetchMessages) {
+            throw new NotImplementedException();
+        }
+
+        public Builder fetchMessageProperties(List<String> 
fetchMessageProperties) {
+            this.fetchMessageProperties.addAll(fetchMessageProperties);
+            return this;
+        }
+
+        public Builder fetchSearchSnippets(boolean fetchSearchSnippets) {
+            throw new NotImplementedException();
+        }
+
+        public GetMessageListRequest build() {
+            Preconditions.checkState(position >= 0, "'position' should be 
positive or null");
+            checkLimit();
+            return new GetMessageListRequest(Optional.ofNullable(accountId), 
Optional.ofNullable(filter), sort.build(), Optional.ofNullable(collapseThreads),
+                    position, Optional.ofNullable(anchor), 
Optional.ofNullable(anchorOffset), Optional.ofNullable(limit), 
Optional.ofNullable(fetchThreads),
+                    Optional.ofNullable(fetchMessages), 
fetchMessageProperties.build(), Optional.ofNullable(fetchSearchSnippets));
+        }
+
+        private void checkLimit() {
+            if (limit != null) {
+                Preconditions.checkState(limit >= 0, "'limit' should be 
positive or null");
+            }
+        }
+    }
+
+    private final Optional<String> accountId;
+    private final Optional<Filter> filter;
+    private final List<String> sort;
+    private final Optional<Boolean> collapseThreads;
+    private final int position;
+    private final Optional<String> anchor;
+    private final Optional<Integer> anchorOffset;
+    private final Optional<Integer> limit;
+    private final Optional<Boolean> fetchThreads;
+    private final Optional<Boolean> fetchMessages;
+    private final List<String> fetchMessageProperties;
+    private final Optional<Boolean> fetchSearchSnippets;
+
+    @VisibleForTesting GetMessageListRequest(Optional<String> accountId, 
Optional<Filter> filter, List<String> sort, Optional<Boolean> collapseThreads,
+            int position, Optional<String> anchor, Optional<Integer> 
anchorOffset, Optional<Integer> limit, Optional<Boolean> fetchThreads,
+            Optional<Boolean> fetchMessages, List<String> 
fetchMessageProperties, Optional<Boolean> fetchSearchSnippets) {
+
+        this.accountId = accountId;
+        this.filter = filter;
+        this.sort = sort;
+        this.collapseThreads = collapseThreads;
+        this.position = position;
+        this.anchor = anchor;
+        this.anchorOffset = anchorOffset;
+        this.limit = limit;
+        this.fetchThreads = fetchThreads;
+        this.fetchMessages = fetchMessages;
+        this.fetchMessageProperties = fetchMessageProperties;
+        this.fetchSearchSnippets = fetchSearchSnippets;
+    }
+
+    public Optional<String> getAccountId() {
+        return accountId;
+    }
+
+    public Optional<Filter> getFilter() {
+        return filter;
+    }
+
+    public List<String> getSort() {
+        return sort;
+    }
+
+    public Optional<Boolean> isCollapseThreads() {
+        return collapseThreads;
+    }
+
+    public int getPosition() {
+        return position;
+    }
+
+    public Optional<String> getAnchor() {
+        return anchor;
+    }
+
+    public Optional<Integer> getAnchorOffset() {
+        return anchorOffset;
+    }
+
+    public Optional<Integer> getLimit() {
+        return limit;
+    }
+
+    public Optional<Boolean> isFetchThreads() {
+        return fetchThreads;
+    }
+
+    public Optional<Boolean> isFetchMessages() {
+        return fetchMessages;
+    }
+
+    public List<String> getFetchMessageProperties() {
+        return fetchMessageProperties;
+    }
+
+    public Optional<Boolean> isFetchSearchSnippets() {
+        return fetchSearchSnippets;
+    }
+}

Added: 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/GetMessageListResponse.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/GetMessageListResponse.java?rev=1719382&view=auto
==============================================================================
--- 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/GetMessageListResponse.java
 (added)
+++ 
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/GetMessageListResponse.java
 Fri Dec 11 12:33:02 2015
@@ -0,0 +1,179 @@
+/****************************************************************
+ * 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 org.apache.commons.lang.NotImplementedException;
+import org.apache.james.jmap.methods.Method;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableList;
+
+public class GetMessageListResponse implements Method.Response {
+
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    public static class Builder {
+
+        private String accountId;
+        private Filter filter;
+        private ImmutableList.Builder<String> sort;
+        private boolean collapseThreads;
+        private String state;
+        private boolean canCalculateUpdates;
+        private int position;
+        private int total;
+        private ImmutableList.Builder<String> threadIds;
+        private ImmutableList.Builder<String> messageIds;
+
+        private Builder() {
+            sort = ImmutableList.builder();
+            threadIds = ImmutableList.builder();
+            messageIds = ImmutableList.builder();
+        }
+
+        public Builder accountId(String accountId) {
+            throw new NotImplementedException();
+        }
+
+        public Builder filter(Filter filter) {
+            this.filter = filter;
+            return this;
+        }
+
+        public Builder sort(List<String> sort) {
+            this.sort.addAll(sort);
+            return this;
+        }
+
+        public Builder collapseThreads(boolean collapseThreads) {
+            throw new NotImplementedException();
+        }
+
+        public Builder state(String state) {
+            throw new NotImplementedException();
+        }
+
+        public Builder canCalculateUpdates(boolean canCalculateUpdates) {
+            throw new NotImplementedException();
+        }
+
+        public Builder position(int position) {
+            throw new NotImplementedException();
+        }
+
+        public Builder total(int total) {
+            throw new NotImplementedException();
+        }
+
+        public Builder threadIds(List<String> threadIds) {
+            throw new NotImplementedException();
+        }
+
+        public Builder messageId(String messageId) {
+            this.messageIds.add(messageId);
+            return this;
+        }
+
+        public Builder messageId(long messageId) {
+            this.messageIds.add(String.valueOf(messageId));
+            return this;
+        }
+
+        public Builder messageIds(List<String> messageIds) {
+            this.messageIds.addAll(messageIds);
+            return this;
+        }
+
+        public GetMessageListResponse build() {
+            return new GetMessageListResponse(accountId, filter, sort.build(), 
collapseThreads, state,
+                    canCalculateUpdates, position, total, threadIds.build(), 
messageIds.build());
+        }
+    }
+
+    private final String accountId;
+    private final Filter filter;
+    private final List<String> sort;
+    private final boolean collapseThreads;
+    private final String state;
+    private final boolean canCalculateUpdates;
+    private final int position;
+    private final int total;
+    private final List<String> threadIds;
+    private final List<String> messageIds;
+
+    @VisibleForTesting GetMessageListResponse(String accountId, Filter filter, 
List<String> sort, boolean collapseThreads, String state,
+            boolean canCalculateUpdates, int position, int total, List<String> 
threadIds, List<String> messageIds) {
+
+        this.accountId = accountId;
+        this.filter = filter;
+        this.sort = sort;
+        this.collapseThreads = collapseThreads;
+        this.state = state;
+        this.canCalculateUpdates = canCalculateUpdates;
+        this.position = position;
+        this.total = total;
+        this.threadIds = threadIds;
+        this.messageIds = messageIds;
+    }
+
+    public String getAccountId() {
+        return accountId;
+    }
+
+    public Filter getFilter() {
+        return filter;
+    }
+
+    public List<String> getSort() {
+        return sort;
+    }
+
+    public boolean isCollapseThreads() {
+        return collapseThreads;
+    }
+
+    public String getState() {
+        return state;
+    }
+
+    public boolean isCanCalculateUpdates() {
+        return canCalculateUpdates;
+    }
+
+    public int getPosition() {
+        return position;
+    }
+
+    public int getTotal() {
+        return total;
+    }
+
+    public List<String> getThreadIds() {
+        return threadIds;
+    }
+
+    public List<String> getMessageIds() {
+        return messageIds;
+    }
+}

Added: 
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/GetMessageListRequestTest.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/GetMessageListRequestTest.java?rev=1719382&view=auto
==============================================================================
--- 
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/GetMessageListRequestTest.java
 (added)
+++ 
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/GetMessageListRequestTest.java
 Fri Dec 11 12:33:02 2015
@@ -0,0 +1,99 @@
+/****************************************************************
+ * 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 java.util.List;
+import java.util.Optional;
+
+import org.apache.commons.lang.NotImplementedException;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+
+public class GetMessageListRequestTest {
+
+    @Test(expected=IllegalStateException.class)
+    public void builderShouldThrowWhenPositionIsNegative() {
+        GetMessageListRequest.builder().position(-1).build();
+    }
+
+    @Test(expected=IllegalStateException.class)
+    public void builderShouldThrowWhenLimitIsNegative() {
+        GetMessageListRequest.builder().limit(-1).build();
+    }
+
+    @Test(expected=NotImplementedException.class)
+    public void builderShouldThrowWhenAccountId() {
+        GetMessageListRequest.builder().accountId(null);
+    }
+
+    @Test(expected=NotImplementedException.class)
+    public void builderShouldThrowWhenCollapseThreads() {
+        GetMessageListRequest.builder().collapseThreads(false);
+    }
+
+    @Test(expected=NotImplementedException.class)
+    public void builderShouldThrowWhenAnchor() {
+        GetMessageListRequest.builder().anchor(null);
+    }
+
+    @Test(expected=NotImplementedException.class)
+    public void builderShouldThrowWhenAnchorOffset() {
+        GetMessageListRequest.builder().anchorOffset(0);
+    }
+
+    @Test(expected=NotImplementedException.class)
+    public void builderShouldThrowWhenFetchThreads() {
+        GetMessageListRequest.builder().fetchThreads(false);
+    }
+
+    @Test(expected=NotImplementedException.class)
+    public void builderShouldThrowWhenFetchMessages() {
+        GetMessageListRequest.builder().fetchMessages(false);
+    }
+
+    @Test(expected=NotImplementedException.class)
+    public void builderShouldThrowWhenFetchSearchSnippets() {
+        GetMessageListRequest.builder().fetchSearchSnippets(false);
+    }
+
+    @Test
+    public void builderShouldWork() {
+        FilterCondition filterCondition = FilterCondition.builder()
+                .inMailboxes(ImmutableList.of("1", "2"))
+                .build();
+        List<String> sort = ImmutableList.of("date desc");
+        List<String> fetchMessageProperties = ImmutableList.of("id", "blobId");
+        GetMessageListRequest expectedGetMessageListRequest = new 
GetMessageListRequest(Optional.empty(), Optional.of(filterCondition), sort, 
Optional.empty(), 1, Optional.empty(), Optional.empty(), Optional.of(2),
+                Optional.empty(), Optional.empty(), fetchMessageProperties, 
Optional.empty());
+
+        GetMessageListRequest getMessageListRequest = 
GetMessageListRequest.builder()
+            .filter(filterCondition)
+            .sort(sort)
+            .position(1)
+            .limit(2)
+            .fetchMessageProperties(fetchMessageProperties)
+            .build();
+
+        
assertThat(getMessageListRequest).isEqualToComparingFieldByField(expectedGetMessageListRequest);
+    }
+}

Added: 
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/GetMessageListResponseTest.java
URL: 
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/GetMessageListResponseTest.java?rev=1719382&view=auto
==============================================================================
--- 
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/GetMessageListResponseTest.java
 (added)
+++ 
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/GetMessageListResponseTest.java
 Fri Dec 11 12:33:02 2015
@@ -0,0 +1,84 @@
+/****************************************************************
+ * 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 java.util.List;
+
+import org.apache.commons.lang.NotImplementedException;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+
+public class GetMessageListResponseTest {
+
+    @Test(expected=NotImplementedException.class)
+    public void builderShouldThrowWhenAccountId() {
+        GetMessageListResponse.builder().accountId(null);
+    }
+
+    @Test(expected=NotImplementedException.class)
+    public void builderShouldThrowWhenCollapseThreads() {
+        GetMessageListResponse.builder().collapseThreads(false);
+    }
+
+    @Test(expected=NotImplementedException.class)
+    public void builderShouldThrowWhenState() {
+        GetMessageListResponse.builder().state(null);
+    }
+
+    @Test(expected=NotImplementedException.class)
+    public void builderShouldThrowWhenCanCalculateUpdates() {
+        GetMessageListResponse.builder().canCalculateUpdates(false);
+    }
+
+    @Test(expected=NotImplementedException.class)
+    public void builderShouldThrowWhenPosition() {
+        GetMessageListResponse.builder().position(0);
+    }
+
+    @Test(expected=NotImplementedException.class)
+    public void builderShouldThrowWhenTotal() {
+        GetMessageListResponse.builder().total(0);
+    }
+
+    @Test(expected=NotImplementedException.class)
+    public void builderShouldThrowWhenThreadIds() {
+        GetMessageListResponse.builder().threadIds(null);
+    }
+    
+    @Test
+    public void builderShouldWork() {
+        FilterCondition filterCondition = FilterCondition.builder()
+                .inMailboxes(ImmutableList.of("1", "2"))
+                .build();
+        List<String> sort = ImmutableList.of("date desc");
+        List<String> messageIds = ImmutableList.of("3", "4");
+        GetMessageListResponse expectedGetMessageListResponse = new 
GetMessageListResponse(null, filterCondition, sort, false, null, false, 0, 0, 
ImmutableList.of(), messageIds);
+
+        GetMessageListResponse getMessageListResponse = 
GetMessageListResponse.builder()
+            .filter(filterCondition)
+            .sort(sort)
+            .messageIds(messageIds)
+            .build();
+        
assertThat(getMessageListResponse).isEqualToComparingFieldByField(expectedGetMessageListResponse);
+    }
+}




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

Reply via email to