From e4cf827a4caec0972f790f38b754ed08f3c842df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1rio=20Franco?= Date: Mon, 20 Jul 2015 12:00:03 +0100 Subject: [PATCH] Fix #42 and it's a help for #32 --- .../fortsoft/pf4j/DefaultPluginManager.java | 18 ++++++++++--- .../ro/fortsoft/pf4j/DependencyResolver.java | 26 ++++++++++++++----- .../ro/fortsoft/pf4j/util/DirectedGraph.java | 7 +++++ 3 files changed, 40 insertions(+), 11 deletions(-) diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/DefaultPluginManager.java b/pf4j/src/main/java/ro/fortsoft/pf4j/DefaultPluginManager.java index 49c87f1..d73a5ea 100644 --- a/pf4j/src/main/java/ro/fortsoft/pf4j/DefaultPluginManager.java +++ b/pf4j/src/main/java/ro/fortsoft/pf4j/DefaultPluginManager.java @@ -93,6 +93,7 @@ public class DefaultPluginManager implements PluginManager { private PluginFactory pluginFactory; private ExtensionFactory extensionFactory; private PluginStatusProvider pluginStatusProvider; + private DependencyResolver dependencyResolver; /** * The plugins repository. @@ -297,6 +298,10 @@ public class DefaultPluginManager implements PluginManager { */ @Override public PluginState stopPlugin(String pluginId) { + return stopPlugin(pluginId, true); + } + + private PluginState stopPlugin(String pluginId, boolean stopDependents) { if (!plugins.containsKey(pluginId)) { throw new IllegalArgumentException(String.format("Unknown pluginId %s", pluginId)); } @@ -315,9 +320,14 @@ public class DefaultPluginManager implements PluginManager { return pluginState; } - for (PluginDependency dependency : pluginDescriptor.getDependencies()) { - stopPlugin(dependency.getPluginId()); - } + if (stopDependents) { + List dependents = dependencyResolver.getDependents(pluginId); + while (!dependents.isEmpty()) { + String dependent = dependents.remove(0); + stopPlugin(dependent, false); + dependents.addAll(dependencyResolver.getDependents(dependent)); + } + } try { log.info("Stop plugin '{}:{}'", pluginDescriptor.getPluginId(), pluginDescriptor.getVersion()); @@ -813,7 +823,7 @@ public class DefaultPluginManager implements PluginManager { } private void resolveDependencies() throws PluginException { - DependencyResolver dependencyResolver = new DependencyResolver(unresolvedPlugins); + dependencyResolver = new DependencyResolver(unresolvedPlugins); resolvedPlugins = dependencyResolver.getSortedPlugins(); for (PluginWrapper pluginWrapper : resolvedPlugins) { unresolvedPlugins.remove(pluginWrapper); diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/DependencyResolver.java b/pf4j/src/main/java/ro/fortsoft/pf4j/DependencyResolver.java index 022d46e..fb6cee4 100644 --- a/pf4j/src/main/java/ro/fortsoft/pf4j/DependencyResolver.java +++ b/pf4j/src/main/java/ro/fortsoft/pf4j/DependencyResolver.java @@ -28,7 +28,8 @@ class DependencyResolver { private static final Logger log = LoggerFactory.getLogger(DependencyResolver.class); private List plugins; - private DirectedGraph graph; + private DirectedGraph dependenciesGraph; + private DirectedGraph dependentsGraph; public DependencyResolver(List plugins) { this.plugins = plugins; @@ -36,15 +37,23 @@ class DependencyResolver { initGraph(); } + public List getDependecies(String pluginsId) { + return dependenciesGraph.getNeighbors(pluginsId); + } + + public List getDependents(String pluginsId) { + return dependentsGraph.getNeighbors(pluginsId); + } + /** * Get the list of plugins in dependency sorted order. */ public List getSortedPlugins() throws PluginException { - log.debug("Graph: {}", graph); - List pluginsId = graph.reverseTopologicalSort(); + log.debug("Graph: {}", dependenciesGraph); + List pluginsId = dependenciesGraph.reverseTopologicalSort(); if (pluginsId == null) { - throw new CyclicDependencyException("Cyclic dependencies !!!" + graph.toString()); + throw new CyclicDependencyException("Cyclic dependencies !!!" + dependenciesGraph.toString()); } log.debug("Plugins order: {}", pluginsId); @@ -58,7 +67,8 @@ class DependencyResolver { private void initGraph() { // create graph - graph = new DirectedGraph<>(); + dependenciesGraph = new DirectedGraph<>(); + dependentsGraph = new DirectedGraph<>(); // populate graph for (PluginWrapper pluginWrapper : plugins) { @@ -67,10 +77,12 @@ class DependencyResolver { List dependencies = descriptor.getDependencies(); if (!dependencies.isEmpty()) { for (PluginDependency dependency : dependencies) { - graph.addEdge(pluginId, dependency.getPluginId()); + dependenciesGraph.addEdge(pluginId, dependency.getPluginId()); + dependentsGraph.addEdge(dependency.getPluginId(), pluginId); } } else { - graph.addVertex(pluginId); + dependenciesGraph.addVertex(pluginId); + dependentsGraph.addVertex(pluginId); } } } diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/util/DirectedGraph.java b/pf4j/src/main/java/ro/fortsoft/pf4j/util/DirectedGraph.java index 58b8d6c..08a90bf 100644 --- a/pf4j/src/main/java/ro/fortsoft/pf4j/util/DirectedGraph.java +++ b/pf4j/src/main/java/ro/fortsoft/pf4j/util/DirectedGraph.java @@ -69,6 +69,13 @@ public class DirectedGraph { neighbors.get(from).remove(to); } + public List getNeighbors(V vertex) { + if (neighbors.containsKey(vertex)) { + return new ArrayList(); + } + return neighbors.get(vertex); + } + /** * Report (as a Map) the out-degree of each vertex. */