JAMES-1712 Give MailboxHierarchySorter functions for index & parentId
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/beaecf70 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/beaecf70 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/beaecf70 Branch: refs/heads/master Commit: beaecf70b7094c62f9d54c24b1c80d37699c0b76 Parents: f9f6e84 Author: Antoine Duprat <[email protected]> Authored: Tue Mar 29 15:31:33 2016 +0200 Committer: Antoine Duprat <[email protected]> Committed: Mon Apr 4 16:27:11 2016 +0200 ---------------------------------------------------------------------- .../jmap/utils/CollectionHierarchySorter.java | 64 +++++++++ .../jmap/utils/MailboxHierarchySorter.java | 54 ------- .../utils/CollectionHierarchySorterTest.java | 140 +++++++++++++++++++ .../jmap/utils/MailboxHierarchySorterTest.java | 139 ------------------ 4 files changed, 204 insertions(+), 193 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/beaecf70/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/CollectionHierarchySorter.java ---------------------------------------------------------------------- diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/CollectionHierarchySorter.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/CollectionHierarchySorter.java new file mode 100644 index 0000000..66fbf50 --- /dev/null +++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/CollectionHierarchySorter.java @@ -0,0 +1,64 @@ +/**************************************************************** + * 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.Collection; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Collectors; + +import org.apache.james.jmap.utils.DependencyGraph.CycleDetectedException; + +import com.google.common.collect.Lists; + +public class CollectionHierarchySorter<T, Id> { + + private final Function<T, Id> index; + private final Function<T, Optional<Id>> parentId; + + public CollectionHierarchySorter(Function<T, Id> index, + Function<T, Optional<Id>> parentId) { + this.index = index; + this.parentId = parentId; + } + + public List<T> sortFromRootToLeaf(Collection<T> elements) throws CycleDetectedException { + + Map<Id, T> mapOfElementsById = indexElementsById(elements); + + DependencyGraph<T> graph = new DependencyGraph<>(m -> + parentId.apply(m).map(mapOfElementsById::get)); + + elements.stream().forEach(graph::registerItem); + + return graph.getBuildChain().collect(Collectors.toList()); + } + + private Map<Id, T> indexElementsById(Collection<T> elements) { + return elements.stream() + .collect(Collectors.toMap(index, Function.identity())); + } + + public List<T> sortFromLeafToRoot(Collection<T> elements) throws CycleDetectedException { + return Lists.reverse(sortFromRootToLeaf(elements)); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/beaecf70/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/MailboxHierarchySorter.java ---------------------------------------------------------------------- diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/MailboxHierarchySorter.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/MailboxHierarchySorter.java deleted file mode 100644 index ea12215..0000000 --- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/MailboxHierarchySorter.java +++ /dev/null @@ -1,54 +0,0 @@ -/**************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one * - * or more contributor license agreements. See the NOTICE file * - * distributed with this work for additional information * - * regarding copyright ownership. The ASF licenses this file * - * to you under the Apache License, Version 2.0 (the * - * "License"); you may not use this file except in compliance * - * with the License. You may obtain a copy of the License at * - * * - * http://www.apache.org/licenses/LICENSE-2.0 * - * * - * Unless required by applicable law or agreed to in writing, * - * software distributed under the License is distributed on an * - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * - * KIND, either express or implied. See the License for the * - * specific language governing permissions and limitations * - * under the License. * - ****************************************************************/ - -package org.apache.james.jmap.utils; - -import java.util.List; -import java.util.Map; -import java.util.function.Function; -import java.util.stream.Collectors; - -import org.apache.james.jmap.model.mailbox.Mailbox; -import org.apache.james.jmap.utils.DependencyGraph.CycleDetectedException; - -import com.google.common.collect.Lists; - -public class MailboxHierarchySorter { - - public List<Mailbox> sortFromRootToLeaf(List<Mailbox> mailboxes) throws CycleDetectedException { - - Map<String, Mailbox> mapOfMailboxesById = indexMailboxesById(mailboxes); - - DependencyGraph<Mailbox> graph = new DependencyGraph<>(m -> - m.getParentId().map(mapOfMailboxesById::get)); - - mailboxes.stream().forEach(graph::registerItem); - - return graph.getBuildChain().collect(Collectors.toList()); - } - - private Map<String, Mailbox> indexMailboxesById(List<Mailbox> mailboxes) { - return mailboxes.stream() - .collect(Collectors.toMap(Mailbox::getId, Function.identity())); - } - - public List<Mailbox> sortFromLeafToRoot(List<Mailbox> mailboxes) throws CycleDetectedException { - return Lists.reverse(sortFromRootToLeaf(mailboxes)); - } -} http://git-wip-us.apache.org/repos/asf/james-project/blob/beaecf70/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/CollectionHierarchySorterTest.java ---------------------------------------------------------------------- diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/CollectionHierarchySorterTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/CollectionHierarchySorterTest.java new file mode 100644 index 0000000..1870f9e --- /dev/null +++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/CollectionHierarchySorterTest.java @@ -0,0 +1,140 @@ +/**************************************************************** + * 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.util.List; +import java.util.stream.Collectors; + +import org.apache.james.jmap.model.mailbox.Mailbox; +import org.apache.james.jmap.utils.DependencyGraph.CycleDetectedException; +import org.junit.Before; +import org.junit.Test; + +import com.google.common.collect.ImmutableList; + +public class CollectionHierarchySorterTest { + + private CollectionHierarchySorter<Mailbox, String> sut; + + @Before + public void setup() { + sut = new CollectionHierarchySorter<>(Mailbox::getId, Mailbox::getParentId); + } + + @Test + public void sortFromRootToLeafShouldReturnOrderedMailbox() { + // Given + Mailbox inbox = Mailbox.builder().name("INBOX").id("INBOX").build(); + Mailbox a = Mailbox.builder().name("A").id("A").parentId("INBOX").build(); + Mailbox b = Mailbox.builder().name("B").id("B").parentId("INBOX").build(); + Mailbox c = Mailbox.builder().name("C").id("C").parentId("B").build(); + Mailbox d = Mailbox.builder().name("D").id("D").parentId("A").build(); + Mailbox e = Mailbox.builder().name("E").id("E").parentId("C").build(); + ImmutableList<Mailbox> input = ImmutableList.of(b, c, d, a, inbox, e); + + // When + List<Mailbox> result = sut.sortFromRootToLeaf(input); + + // Then + assertThat(result).extracting(Mailbox::getName).endsWith("C", "D", "E").startsWith("INBOX"); + } + + @Test + public void sortFromRootToLeafEmptyMailboxShouldReturnEmpty() { + ImmutableList<Mailbox> input = ImmutableList.of(); + List<Mailbox> result = sut.sortFromRootToLeaf(input); + assertThat(result).isEmpty(); + } + + @Test + public void sortFromRootToLeafOrphanMailboxesShouldReturnInput() { + Mailbox a = Mailbox.builder().name("A").id("A").build(); + Mailbox b = Mailbox.builder().name("B").id("B").build(); + Mailbox c = Mailbox.builder().name("C").id("C").build(); + + ImmutableList<Mailbox> input = ImmutableList.of(a, b, c); + List<String> result = sut.sortFromRootToLeaf(input).stream() + .map(Mailbox::getName) + .collect(Collectors.toList()); + + assertThat(result).containsExactly("A", "B", "C"); + } + + @Test(expected=CycleDetectedException.class) + public void sortFromRootToLeafWithLoopShouldThrow() { + Mailbox a = Mailbox.builder().name("A").id("A").parentId("B").build(); + Mailbox b = Mailbox.builder().name("B").id("B").parentId("A").build(); + + ImmutableList<Mailbox> input = ImmutableList.of(a, b); + + sut.sortFromRootToLeaf(input); + } + + @Test + public void sortFromLeafToRootShouldReturnOrderedMailbox() { + //Given + Mailbox inbox = Mailbox.builder().name("INBOX").id("INBOX").build(); + Mailbox a = Mailbox.builder().name("A").id("A").parentId("INBOX").build(); + Mailbox b = Mailbox.builder().name("B").id("B").parentId("INBOX").build(); + Mailbox c = Mailbox.builder().name("C").id("C").parentId("B").build(); + Mailbox d = Mailbox.builder().name("D").id("D").parentId("A").build(); + Mailbox e = Mailbox.builder().name("E").id("E").parentId("C").build(); + + ImmutableList<Mailbox> input = ImmutableList.of(b, c, d, a, inbox, e); + + //When + List<Mailbox> result = sut.sortFromLeafToRoot(input); + + assertThat(result).extracting(Mailbox::getName).endsWith("INBOX").startsWith("E"); + } + + @Test + public void sortFromLeafToRootEmptyMailboxShouldReturnEmpty() { + ImmutableList<Mailbox> input = ImmutableList.of(); + List<Mailbox> result = sut.sortFromLeafToRoot(input); + assertThat(result).isEmpty(); + } + + @Test + public void sortFromLeafToRootOrphanMailboxesShouldReturnInput() { + Mailbox a = Mailbox.builder().name("A").id("A").build(); + Mailbox b = Mailbox.builder().name("B").id("B").build(); + Mailbox c = Mailbox.builder().name("C").id("C").build(); + + ImmutableList<Mailbox> input = ImmutableList.of(a, b, c); + List<String> result = sut.sortFromLeafToRoot(input).stream() + .map(Mailbox::getName) + .collect(Collectors.toList()); + + assertThat(result).containsExactly("C", "B", "A"); + } + + @Test(expected=CycleDetectedException.class) + public void sortFromLeafToRootWithLoopShouldThrow() { + Mailbox a = Mailbox.builder().name("A").id("A").parentId("B").build(); + Mailbox b = Mailbox.builder().name("B").id("B").parentId("A").build(); + + ImmutableList<Mailbox> input = ImmutableList.of(a, b); + + sut.sortFromLeafToRoot(input); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/james-project/blob/beaecf70/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/MailboxHierarchySorterTest.java ---------------------------------------------------------------------- diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/MailboxHierarchySorterTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/MailboxHierarchySorterTest.java deleted file mode 100644 index 32f4829..0000000 --- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/utils/MailboxHierarchySorterTest.java +++ /dev/null @@ -1,139 +0,0 @@ -/**************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one * - * or more contributor license agreements. See the NOTICE file * - * distributed with this work for additional information * - * regarding copyright ownership. The ASF licenses this file * - * to you under the Apache License, Version 2.0 (the * - * "License"); you may not use this file except in compliance * - * with the License. You may obtain a copy of the License at * - * * - * http://www.apache.org/licenses/LICENSE-2.0 * - * * - * Unless required by applicable law or agreed to in writing, * - * software distributed under the License is distributed on an * - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * - * KIND, either express or implied. See the License for the * - * specific language governing permissions and limitations * - * under the License. * - ****************************************************************/ - -package org.apache.james.jmap.utils; - -import static org.assertj.core.api.Assertions.assertThat; - -import java.util.List; -import java.util.stream.Collectors; - -import org.apache.james.jmap.model.mailbox.Mailbox; -import org.apache.james.jmap.utils.DependencyGraph.CycleDetectedException; -import org.junit.Test; - -import com.google.common.collect.ImmutableList; - -public class MailboxHierarchySorterTest { - - @Test - public void sortFromRootToLeafShouldReturnOrderedMailbox() { - // Given - Mailbox inbox = Mailbox.builder().name("INBOX").id("INBOX").build(); - Mailbox a = Mailbox.builder().name("A").id("A").parentId("INBOX").build(); - Mailbox b = Mailbox.builder().name("B").id("B").parentId("INBOX").build(); - Mailbox c = Mailbox.builder().name("C").id("C").parentId("B").build(); - Mailbox d = Mailbox.builder().name("D").id("D").parentId("A").build(); - Mailbox e = Mailbox.builder().name("E").id("E").parentId("C").build(); - ImmutableList<Mailbox> input = ImmutableList.of(b, c, d, a, inbox, e); - - MailboxHierarchySorter sut = new MailboxHierarchySorter(); - // When - List<Mailbox> result = sut.sortFromRootToLeaf(input); - - // Then - assertThat(result).extracting(Mailbox::getName).endsWith("C", "D", "E").startsWith("INBOX"); - } - - @Test - public void sortFromRootToLeafEmptyMailboxShouldReturnEmpty() { - MailboxHierarchySorter sut = new MailboxHierarchySorter(); - ImmutableList<Mailbox> input = ImmutableList.of(); - List<Mailbox> result = sut.sortFromRootToLeaf(input); - assertThat(result).isEmpty(); - } - - @Test - public void sortFromRootToLeafOrphanMailboxesShouldReturnInput() { - Mailbox a = Mailbox.builder().name("A").id("A").build(); - Mailbox b = Mailbox.builder().name("B").id("B").build(); - Mailbox c = Mailbox.builder().name("C").id("C").build(); - - MailboxHierarchySorter sut = new MailboxHierarchySorter(); - ImmutableList<Mailbox> input = ImmutableList.of(a, b, c); - List<String> result = sut.sortFromRootToLeaf(input).stream() - .map(Mailbox::getName) - .collect(Collectors.toList()); - - assertThat(result).containsExactly("A", "B", "C"); - } - - @Test(expected=CycleDetectedException.class) - public void sortFromRootToLeafWithLoopShouldThrow() { - Mailbox a = Mailbox.builder().name("A").id("A").parentId("B").build(); - Mailbox b = Mailbox.builder().name("B").id("B").parentId("A").build(); - - MailboxHierarchySorter sut = new MailboxHierarchySorter(); - ImmutableList<Mailbox> input = ImmutableList.of(a, b); - - sut.sortFromRootToLeaf(input); - } - - @Test - public void sortFromLeafToRootShouldReturnOrderedMailbox() { - //Given - Mailbox inbox = Mailbox.builder().name("INBOX").id("INBOX").build(); - Mailbox a = Mailbox.builder().name("A").id("A").parentId("INBOX").build(); - Mailbox b = Mailbox.builder().name("B").id("B").parentId("INBOX").build(); - Mailbox c = Mailbox.builder().name("C").id("C").parentId("B").build(); - Mailbox d = Mailbox.builder().name("D").id("D").parentId("A").build(); - Mailbox e = Mailbox.builder().name("E").id("E").parentId("C").build(); - MailboxHierarchySorter sut = new MailboxHierarchySorter(); - ImmutableList<Mailbox> input = ImmutableList.of(b, c, d, a, inbox, e); - - //When - List<Mailbox> result = sut.sortFromLeafToRoot(input); - - assertThat(result).extracting(Mailbox::getName).endsWith("INBOX").startsWith("E"); - } - - @Test - public void sortFromLeafToRootEmptyMailboxShouldReturnEmpty() { - MailboxHierarchySorter sut = new MailboxHierarchySorter(); - ImmutableList<Mailbox> input = ImmutableList.of(); - List<Mailbox> result = sut.sortFromLeafToRoot(input); - assertThat(result).isEmpty(); - } - - @Test - public void sortFromLeafToRootOrphanMailboxesShouldReturnInput() { - Mailbox a = Mailbox.builder().name("A").id("A").build(); - Mailbox b = Mailbox.builder().name("B").id("B").build(); - Mailbox c = Mailbox.builder().name("C").id("C").build(); - - MailboxHierarchySorter sut = new MailboxHierarchySorter(); - ImmutableList<Mailbox> input = ImmutableList.of(a, b, c); - List<String> result = sut.sortFromLeafToRoot(input).stream() - .map(Mailbox::getName) - .collect(Collectors.toList()); - - assertThat(result).containsExactly("C", "B", "A"); - } - - @Test(expected=CycleDetectedException.class) - public void sortFromLeafToRootWithLoopShouldThrow() { - Mailbox a = Mailbox.builder().name("A").id("A").parentId("B").build(); - Mailbox b = Mailbox.builder().name("B").id("B").parentId("A").build(); - - MailboxHierarchySorter sut = new MailboxHierarchySorter(); - ImmutableList<Mailbox> input = ImmutableList.of(a, b); - - sut.sortFromLeafToRoot(input); - } -} \ No newline at end of file --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
