JAMES-2183 Adding KeywordsCombiner
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/f0b27714 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/f0b27714 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/f0b27714 Branch: refs/heads/master Commit: f0b277144369e938fdd11eebc705e7f02c96ed9c Parents: d1238fc Author: benwa <btell...@linagora.com> Authored: Thu Oct 12 10:04:33 2017 +0700 Committer: benwa <btell...@linagora.com> Committed: Wed Oct 18 09:00:56 2017 +0700 ---------------------------------------------------------------------- .../org/apache/james/jmap/model/Keywords.java | 6 + .../james/jmap/utils/KeywordsCombiner.java | 65 +++++++++ .../james/jmap/utils/KeywordsCombinerTest.java | 132 +++++++++++++++++++ 3 files changed, 203 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/f0b27714/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/Keywords.java ---------------------------------------------------------------------- diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/Keywords.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/Keywords.java index ed07982..c410cf9 100644 --- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/Keywords.java +++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/Keywords.java @@ -19,6 +19,7 @@ package org.apache.james.jmap.model; +import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Optional; @@ -86,6 +87,11 @@ public class Keywords { .collect(Guavate.toImmutableSet())); } + public Keywords from(Keyword... keywords) { + return fromSet(Arrays.stream(keywords) + .collect(Guavate.toImmutableSet())); + } + public Keywords fromList(List<String> keywords) { return fromSet(keywords.stream() .map(Keyword::new) http://git-wip-us.apache.org/repos/asf/james-project/blob/f0b27714/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/KeywordsCombiner.java ---------------------------------------------------------------------- diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/KeywordsCombiner.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/KeywordsCombiner.java new file mode 100644 index 0000000..258f5df --- /dev/null +++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/KeywordsCombiner.java @@ -0,0 +1,65 @@ +/**************************************************************** + * 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.List; +import java.util.Set; +import java.util.function.BinaryOperator; + +import org.apache.james.jmap.model.Keyword; +import org.apache.james.jmap.model.Keywords; + +import com.github.steveash.guavate.Guavate; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Sets; + +public class KeywordsCombiner implements BinaryOperator<Keywords> { + private static final ImmutableList<Keyword> KEYWORD_TO_INTERSECT = ImmutableList.of(Keyword.DRAFT); + private static final ImmutableList<Keyword> KEYWORD_NOT_TO_UNION = KEYWORD_TO_INTERSECT; + + private Keywords.KeywordsFactory keywordsFactory; + + public KeywordsCombiner() { + this.keywordsFactory = Keywords.factory() + .filterImapNonExposedKeywords(); + } + + @Override + public Keywords apply(Keywords keywords, Keywords keywords2) { + return keywordsFactory + .fromSet(Sets.union( + union(keywords.getKeywords(), keywords2.getKeywords(), KEYWORD_NOT_TO_UNION), + intersect(keywords.getKeywords(), keywords2.getKeywords(), KEYWORD_TO_INTERSECT))); + } + + public Set<Keyword> union(Set<Keyword> set1, Set<Keyword> set2, List<Keyword> exceptKeywords) { + return Sets.union(set1, set2) + .stream() + .filter(keyword -> !exceptKeywords.contains(keyword)) + .collect(Guavate.toImmutableSet()); + } + + public Set<Keyword> intersect(Set<Keyword> set1, Set<Keyword> set2, List<Keyword> forKeywords) { + return Sets.intersection(set1, set2) + .stream() + .filter(forKeywords::contains) + .collect(Guavate.toImmutableSet()); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/f0b27714/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/KeywordsCombinerTest.java ---------------------------------------------------------------------- diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/KeywordsCombinerTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/KeywordsCombinerTest.java new file mode 100644 index 0000000..df36ab4 --- /dev/null +++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/KeywordsCombinerTest.java @@ -0,0 +1,132 @@ +/**************************************************************** + * 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 org.apache.james.jmap.model.Keyword; +import org.apache.james.jmap.model.Keywords; +import org.apache.james.util.CommutativityChecker; +import org.junit.Test; + +import com.google.common.collect.ImmutableSet; + +public class KeywordsCombinerTest { + + public static final Keywords.KeywordsFactory FACTORY = Keywords.factory(); + + @Test + public void applyShouldUnionSeenKeyword() { + KeywordsCombiner keywordsCombiner = new KeywordsCombiner(); + + assertThat(keywordsCombiner.apply( + Keywords.DEFAULT_VALUE, + Keywords.factory().from(Keyword.SEEN))) + .isEqualTo(Keywords.factory().from(Keyword.SEEN)); + } + + @Test + public void applyShouldUnionAnsweredKeyword() { + KeywordsCombiner keywordsCombiner = new KeywordsCombiner(); + + assertThat(keywordsCombiner.apply( + Keywords.DEFAULT_VALUE, + Keywords.factory().from(Keyword.ANSWERED))) + .isEqualTo(Keywords.factory().from(Keyword.ANSWERED)); + } + + @Test + public void applyShouldUnionFlaggedKeyword() { + KeywordsCombiner keywordsCombiner = new KeywordsCombiner(); + + assertThat(keywordsCombiner.apply( + Keywords.DEFAULT_VALUE, + Keywords.factory().from(Keyword.FLAGGED))) + .isEqualTo(Keywords.factory().from(Keyword.FLAGGED)); + } + + @Test + public void applyShouldIntersectDraftKeyword() { + KeywordsCombiner keywordsCombiner = new KeywordsCombiner(); + + assertThat(keywordsCombiner.apply( + Keywords.DEFAULT_VALUE, + Keywords.factory().from(Keyword.DRAFT))) + .isEqualTo(Keywords.DEFAULT_VALUE); + } + + @Test + public void applyShouldUnionCustomKeyword() { + KeywordsCombiner keywordsCombiner = new KeywordsCombiner(); + + Keyword customKeyword = new Keyword("$Any"); + assertThat(keywordsCombiner.apply( + Keywords.DEFAULT_VALUE, + Keywords.factory().from(customKeyword))) + .isEqualTo(Keywords.factory().from(customKeyword)); + } + + @Test + public void applyShouldAcceptEmptyAsAZeroValue() { + KeywordsCombiner keywordsCombiner = new KeywordsCombiner(); + + assertThat(keywordsCombiner.apply( + Keywords.DEFAULT_VALUE, + Keywords.DEFAULT_VALUE)) + .isEqualTo(Keywords.DEFAULT_VALUE); + } + + @Test + public void applyShouldUnionDifferentFlags() { + KeywordsCombiner keywordsCombiner = new KeywordsCombiner(); + + assertThat(keywordsCombiner.apply( + Keywords.factory().from(Keyword.FLAGGED), + Keywords.factory().from(Keyword.ANSWERED))) + .isEqualTo(Keywords.factory().from(Keyword.FLAGGED, Keyword.ANSWERED)); + } + + @Test + public void keywordsCombinerShouldBeCommutative() { + Keywords allKeyword = FACTORY.from(Keyword.ANSWERED, + Keyword.DELETED, + Keyword.DRAFT, + Keyword.FLAGGED, + Keyword.SEEN, + new Keyword("$Forwarded"), + new Keyword("$Any")); + + ImmutableSet<Keywords> values = ImmutableSet.of( + FACTORY.from(Keyword.ANSWERED), + FACTORY.from(Keyword.DELETED), + FACTORY.from(Keyword.DRAFT), + FACTORY.from(Keyword.FLAGGED), + FACTORY.from(Keyword.SEEN), + FACTORY.from(), + FACTORY.from(new Keyword("$Forwarded")), + FACTORY.from(new Keyword("$Any")), + allKeyword); + + assertThat( + new CommutativityChecker<>(values, new KeywordsCombiner()) + .findNonCommutativeInput()) + .isEmpty(); + } +} \ No newline at end of file --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org