Author: matthieu
Date: Fri Dec 11 12:33:20 2015
New Revision: 1719384
URL: http://svn.apache.org/viewvc?rev=1719384&view=rev
Log:
JAMES-1644 Convert JMAP sort to comparator
Added:
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/SortToComparatorConvertor.java
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/SortToComparatorConvertorTest.java
Added:
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/SortToComparatorConvertor.java
URL:
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/SortToComparatorConvertor.java?rev=1719384&view=auto
==============================================================================
---
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/SortToComparatorConvertor.java
(added)
+++
james/project/trunk/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/SortToComparatorConvertor.java
Fri Dec 11 12:33:20 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.utils;
+
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+
+import org.apache.james.mailbox.store.mail.model.MailboxId;
+import org.apache.james.mailbox.store.mail.model.Message;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableMap;
+
+public class SortToComparatorConvertor {
+
+ private static final String SEPARATOR = " ";
+ private static final String DESC_ORDERING = "desc";
+
+ private SortToComparatorConvertor() {
+ }
+
+ @SuppressWarnings("rawtypes")
+ private static final Map<String, Function<Message<?>, Comparable>>
fieldsMessageFunctionMap = ImmutableMap.of(
+ "date", Message::getInternalDate,
+ "id", Message::getUid);
+
+ public static <M extends Message<Id>, Id extends MailboxId> Comparator<M>
comparatorFor(List<String> sort) {
+ return sort.stream()
+ .map(SortToComparatorConvertor::<M, Id> comparatorForField)
+ .reduce(new EmptyComparator<M>(), (x, y) -> x.thenComparing(y));
+ }
+
+ @SuppressWarnings("unchecked")
+ private static <M extends Message<Id>, Id extends MailboxId> Comparator<M>
comparatorForField(String field) {
+ List<String> splitToList = Splitter.on(SEPARATOR).splitToList(field);
+ checkField(splitToList);
+ Comparator<M> fieldComparator =
Comparator.comparing(functionForField(splitToList.get(0)));
+ if (splitToList.size() == 1 ||
splitToList.get(1).equals(DESC_ORDERING)) {
+ return fieldComparator.reversed();
+ }
+ return fieldComparator;
+ }
+
+ @SuppressWarnings("rawtypes")
+ private static Function<Message<?>, Comparable> functionForField(String
field) {
+ if (!fieldsMessageFunctionMap.containsKey(field)) {
+ throw new IllegalArgumentException("Unknown sorting field");
+ }
+ return fieldsMessageFunctionMap.get(field);
+ }
+
+ private static void checkField(List<String> splitToList) {
+ Preconditions.checkArgument(splitToList.size() >= 1 &&
splitToList.size() <= 2, "Bad sort field definition");
+ }
+
+ private static class EmptyComparator<Type> implements Comparator<Type> {
+
+ @Override
+ public int compare(Type o1, Type o2) {
+ return 0;
+ }
+
+ }
+}
Added:
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/SortToComparatorConvertorTest.java
URL:
http://svn.apache.org/viewvc/james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/SortToComparatorConvertorTest.java?rev=1719384&view=auto
==============================================================================
---
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/SortToComparatorConvertorTest.java
(added)
+++
james/project/trunk/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/SortToComparatorConvertorTest.java
Fri Dec 11 12:33:20 2015
@@ -0,0 +1,116 @@
+/****************************************************************
+ * 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 java.time.LocalDate;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.List;
+
+import javax.mail.Flags;
+
+import org.apache.james.mailbox.store.TestId;
+import org.apache.james.mailbox.store.mail.model.Message;
+import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
+import org.apache.james.mailbox.store.mail.model.impl.SimpleMessage;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+
+public class SortToComparatorConvertorTest {
+
+ private List<SimpleMessage<TestId>> messages;
+ private SimpleMessage<TestId> firstMessage;
+ private SimpleMessage<TestId> secondMessage;
+
+ @Before
+ @SuppressWarnings("unchecked")
+ public void setup() {
+ LocalDate date = LocalDate.now();
+ firstMessage = new SimpleMessage<TestId>(new Date(date.toEpochDay()),
0, 0, null, new Flags(), new PropertyBuilder(), null);
+ firstMessage.setUid(1);
+ secondMessage = new SimpleMessage<TestId>(new
Date(date.plusDays(1).toEpochDay()), 0, 0, null, new Flags(), new
PropertyBuilder(), null);
+ secondMessage.setUid(2);
+ messages = Lists.newArrayList(firstMessage, secondMessage);
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void comparatorForShouldBeInitialOrderWhenEmptyList() {
+ Comparator<SimpleMessage<TestId>> comparator =
SortToComparatorConvertor.comparatorFor(ImmutableList.of());
+ messages.sort(comparator);
+ assertThat(messages).containsExactly(firstMessage, secondMessage);
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void comparatorForShouldBeDescByDateWhenOnlyDateInList() {
+ Comparator<Message<TestId>> comparator =
SortToComparatorConvertor.comparatorFor(ImmutableList.of("date"));
+ messages.sort(comparator);
+ assertThat(messages).containsExactly(secondMessage, firstMessage);
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void comparatorForShouldBeDescByDateWhenOnlyDateDescInList() {
+ Comparator<Message<TestId>> comparator =
SortToComparatorConvertor.comparatorFor(ImmutableList.of("date desc"));
+ messages.sort(comparator);
+ assertThat(messages).containsExactly(secondMessage, firstMessage);
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void comparatorForShouldBeAscByDateWhenOnlyDateAscInList() {
+ Comparator<Message<TestId>> comparator =
SortToComparatorConvertor.comparatorFor(ImmutableList.of("date asc"));
+ messages.sort(comparator);
+ assertThat(messages).containsExactly(firstMessage, secondMessage);
+ }
+
+ @Test
+ @SuppressWarnings("unchecked")
+ public void
comparatorForShouldChainComparatorsWhenOnlyMultipleElementInList() {
+ SimpleMessage<TestId> thirdMessage = new
SimpleMessage<TestId>(secondMessage.getInternalDate(), 0, 0, null, new Flags(),
new PropertyBuilder(), null);
+ thirdMessage.setUid(3);
+ messages.add(thirdMessage);
+
+ Comparator<Message<TestId>> comparator =
SortToComparatorConvertor.comparatorFor(ImmutableList.of("date asc", "id
desc"));
+ messages.sort(comparator);
+ assertThat(messages).containsExactly(firstMessage, thirdMessage,
secondMessage);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void comparatorForShouldThrowWhenBadFieldFormat() {
+ SortToComparatorConvertor.comparatorFor(ImmutableList.of("this is a
bad field"));
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void comparatorForShouldThrowWhenEmptyField() {
+ SortToComparatorConvertor.comparatorFor(ImmutableList.of(" "));
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void comparatorForShouldThrowWhenUnknownField() {
+ SortToComparatorConvertor.comparatorFor(ImmutableList.of("unknown"));
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]