This is an automated email from the ASF dual-hosted git repository. ntimofeev pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/cayenne.git
commit 96c75bd5dbbced79122c8cbccbd20cd69b4d26ce Author: Nikita Timofeev <stari...@gmail.com> AuthorDate: Tue Nov 15 17:25:45 2022 +0300 CAY-2774 Overriding service ordering in DI List causes DIRuntimeException --- .../src/main/java/org/apache/cayenne/di/spi/DIGraph.java | 10 +++++++++- .../src/main/java/org/apache/cayenne/di/spi/ListProvider.java | 8 ++++---- .../src/test/java/org/apache/cayenne/di/spi/DIGraphTest.java | 10 +++++++++- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DIGraph.java b/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DIGraph.java index e2678e9d5..531ad03c6 100644 --- a/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DIGraph.java +++ b/cayenne-di/src/main/java/org/apache/cayenne/di/spi/DIGraph.java @@ -68,10 +68,18 @@ class DIGraph<V> { public void add(V from, V to) { this.add(from); this.add(to); - neighbors.get(to).remove(from); neighbors.get(from).add(to); } + /** + * Add an edge to the graph; if either vertex does not exist, it's added. + * This implementation allows the creation of multi-edges and self-loops. + */ + public void addWithOverride(V from, V to) { + add(from, to); + neighbors.get(to).remove(from); + } + /** * True iff graph contains vertex. */ diff --git a/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ListProvider.java b/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ListProvider.java index 053bf2c5b..62c8c69fc 100644 --- a/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ListProvider.java +++ b/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ListProvider.java @@ -73,12 +73,12 @@ class ListProvider<T> implements Provider<List<T>> { void addAfter(Key<? extends T> key, Provider<? extends T> provider, Key<? extends T> after) { providers.put(key, provider); - graph.add(key, after); + graph.addWithOverride(key, after); } void insertBefore(Key<? extends T> key, Provider<? extends T> provider, Key<? extends T> before) { providers.put(key, provider); - graph.add(before, key); + graph.addWithOverride(before, key); } void addAll(Map<Key<? extends T>, Provider<? extends T>> keyProviderMap) { @@ -89,14 +89,14 @@ class ListProvider<T> implements Provider<List<T>> { void addAllAfter(Map<Key<? extends T>, Provider<? extends T>> keyProviderMap, Key<? extends T> after) { providers.putAll(keyProviderMap); for (Key<? extends T> key : keyProviderMap.keySet()) { - graph.add(key, after); + graph.addWithOverride(key, after); } } void insertAllBefore(Map<Key<? extends T>, Provider<? extends T>> keyProviderMap, Key<? extends T> before) { providers.putAll(keyProviderMap); for (Key<? extends T> key : keyProviderMap.keySet()) { - graph.add(before, key); + graph.addWithOverride(before, key); } } } diff --git a/cayenne-di/src/test/java/org/apache/cayenne/di/spi/DIGraphTest.java b/cayenne-di/src/test/java/org/apache/cayenne/di/spi/DIGraphTest.java index 0d391e8b0..d2558b698 100644 --- a/cayenne-di/src/test/java/org/apache/cayenne/di/spi/DIGraphTest.java +++ b/cayenne-di/src/test/java/org/apache/cayenne/di/spi/DIGraphTest.java @@ -39,11 +39,19 @@ public class DIGraphTest { assertEquals(asList("y", "a", "z", "x"), sorted); } - @Test + @Test(expected = DIRuntimeException.class) public void testTopSortDirectCycle() { DIGraph<String> graph = new DIGraph<>(); graph.add("x", "y"); graph.add("y", "x"); + graph.topSort(); + } + + @Test + public void testTopSortDirectCycleOverride() { + DIGraph<String> graph = new DIGraph<>(); + graph.addWithOverride("x", "y"); + graph.addWithOverride("y", "x"); List<String> sorted = graph.topSort(); assertEquals(asList("x", "y"), sorted); }