]> source.dussan.org Git - pf4j.git/commitdiff
Add methods to start & stop a single plugin and it's dependencies
authorJames Moger <james.moger@gitblit.com>
Wed, 2 Apr 2014 22:16:46 +0000 (18:16 -0400)
committerJames Moger <james.moger@gitblit.com>
Wed, 2 Apr 2014 23:42:37 +0000 (19:42 -0400)
pf4j/pom.xml
pf4j/src/main/java/ro/fortsoft/pf4j/DefaultPluginManager.java
pf4j/src/main/java/ro/fortsoft/pf4j/PluginManager.java

index f06491e0f66edc89242db826cb6e4708aa0c1c9f..b5b42047fa51fbb55eb09fca16c4cc964fbaa217 100644 (file)
             <artifactId>slf4j-api</artifactId>
             <version>1.6.4</version>
         </dependency>
+          <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.8.1</version>
+      <scope>test</scope>
+    </dependency>
     </dependencies>
 
 </project>
index 013eadf82106155f034090089780d46584989c15..1680a5a98a8ab0fa2719ef35e038781791bf826f 100644 (file)
@@ -1,11 +1,11 @@
 /*\r
  * Copyright 2012 Decebal Suiu\r
- * \r
+ *\r
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with\r
  * the License. You may obtain a copy of the License in the LICENSE file, or at:\r
- * \r
+ *\r
  * http://www.apache.org/licenses/LICENSE-2.0\r
- * \r
+ *\r
  * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on\r
  * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the\r
  * specific language governing permissions and limitations under the License.\r
@@ -19,6 +19,7 @@ import java.util.ArrayList;
 import java.util.Arrays;\r
 import java.util.Collections;\r
 import java.util.HashMap;\r
+import java.util.Iterator;\r
 import java.util.List;\r
 import java.util.Map;\r
 \r
@@ -42,7 +43,7 @@ import ro.fortsoft.pf4j.util.ZipFileFilter;
 public class DefaultPluginManager implements PluginManager {\r
 \r
        private static final Logger log = LoggerFactory.getLogger(DefaultPluginManager.class);\r
-       \r
+\r
        public static final String DEFAULT_PLUGINS_DIRECTORY = "plugins";\r
        public static final String DEVELOPMENT_PLUGINS_DIRECTORY = "../plugins";\r
 \r
@@ -52,11 +53,11 @@ public class DefaultPluginManager implements PluginManager {
     private File pluginsDirectory;\r
 \r
     private ExtensionFinder extensionFinder;\r
-    \r
+\r
     private PluginDescriptorFinder pluginDescriptorFinder;\r
-    \r
+\r
     private PluginClasspath pluginClasspath;\r
-    \r
+\r
     /**\r
      * A map of plugins this manager is responsible for (the key is the 'pluginId').\r
      */\r
@@ -81,35 +82,35 @@ public class DefaultPluginManager implements PluginManager {
      * A list with resolved plugins (resolved dependency).\r
      */\r
     private List<PluginWrapper> resolvedPlugins;\r
-    \r
+\r
     /**\r
      * A list with started plugins.\r
      */\r
     private List<PluginWrapper> startedPlugins;\r
-    \r
+\r
     private List<String> enabledPlugins;\r
     private List<String> disabledPlugins;\r
-    \r
+\r
     /**\r
-     * A compound class loader of resolved plugins. \r
+     * A compound class loader of resolved plugins.\r
      */\r
     protected CompoundClassLoader compoundClassLoader;\r
-    \r
+\r
     /**\r
      * Cache value for the runtime mode. No need to re-read it because it wont change at\r
         * runtime.\r
      */\r
     private RuntimeMode runtimeMode;\r
-    \r
+\r
     /**\r
      * The plugins directory is supplied by System.getProperty("pf4j.pluginsDir", "plugins").\r
      */\r
     public DefaultPluginManager() {\r
        this.pluginsDirectory = createPluginsDirectory();\r
-       \r
+\r
        initialize();\r
     }\r
-    \r
+\r
     /**\r
      * Constructs DefaultPluginManager which the given plugins directory.\r
      *\r
@@ -118,7 +119,7 @@ public class DefaultPluginManager implements PluginManager {
      */\r
     public DefaultPluginManager(File pluginsDirectory) {\r
         this.pluginsDirectory = pluginsDirectory;\r
-        \r
+\r
         initialize();\r
     }\r
 \r
@@ -145,7 +146,7 @@ public class DefaultPluginManager implements PluginManager {
        public List<PluginWrapper> getStartedPlugins() {\r
                return startedPlugins;\r
        }\r
-       \r
+\r
     /**\r
      * Start all active plugins.\r
      */\r
@@ -163,6 +164,34 @@ public class DefaultPluginManager implements PluginManager {
         }\r
     }\r
 \r
+       /**\r
+     * Start the specified plugin and it's dependencies.\r
+     */\r
+    @Override\r
+    public PluginState startPlugin(String pluginId) {\r
+       if (!plugins.containsKey(pluginId)) {\r
+               throw new IllegalArgumentException(String.format("Unknown pluginId %s", pluginId));\r
+       }\r
+       PluginWrapper pluginWrapper = plugins.get(pluginId);\r
+       PluginDescriptor pluginDescriptor = pluginWrapper.getDescriptor();\r
+       if (pluginWrapper.getPluginState().equals(PluginState.STARTED)) {\r
+               log.debug("Already started plugin '{}:{}'", pluginDescriptor.getPluginId(), pluginDescriptor.getVersion());\r
+               return PluginState.STARTED;\r
+       }\r
+       for (PluginDependency dependency : pluginDescriptor.getDependencies()) {\r
+               startPlugin(dependency.getPluginId());\r
+       }\r
+       try {\r
+               log.info("Start plugin '{}:{}'", pluginDescriptor.getPluginId(), pluginDescriptor.getVersion());\r
+               pluginWrapper.getPlugin().start();\r
+               pluginWrapper.setPluginState(PluginState.STARTED);\r
+               startedPlugins.add(pluginWrapper);\r
+       } catch (PluginException e) {\r
+               log.error(e.getMessage(), e);\r
+       }\r
+       return pluginWrapper.getPluginState();\r
+    }\r
+\r
     /**\r
      * Stop all active plugins.\r
      */\r
@@ -170,17 +199,49 @@ public class DefaultPluginManager implements PluginManager {
     public void stopPlugins() {\r
        // stop started plugins in reverse order\r
        Collections.reverse(startedPlugins);\r
-        for (PluginWrapper pluginWrapper : startedPlugins) {\r
+       Iterator<PluginWrapper> itr = startedPlugins.iterator();\r
+        while (itr.hasNext()) {\r
+               PluginWrapper pluginWrapper = itr.next();\r
+               PluginDescriptor pluginDescriptor = pluginWrapper.getDescriptor();\r
             try {\r
-               log.info("Stop plugin '{}'", pluginWrapper.getDescriptor().getPluginId());\r
+               log.info("Stop plugin '{}:{}'", pluginDescriptor.getPluginId(), pluginDescriptor.getVersion());\r
                pluginWrapper.getPlugin().stop();\r
                pluginWrapper.setPluginState(PluginState.STOPPED);\r
+               itr.remove();\r
                        } catch (PluginException e) {\r
                                log.error(e.getMessage(), e);\r
                        }\r
         }\r
     }\r
 \r
+    /**\r
+     * Stop the specified plugin and it's dependencies.\r
+     */\r
+    @Override\r
+    public PluginState stopPlugin(String pluginId) {\r
+       if (!plugins.containsKey(pluginId)) {\r
+               throw new IllegalArgumentException(String.format("Unknown pluginId %s", pluginId));\r
+       }\r
+       PluginWrapper pluginWrapper = plugins.get(pluginId);\r
+       PluginDescriptor pluginDescriptor = pluginWrapper.getDescriptor();\r
+       if (pluginWrapper.getPluginState().equals(PluginState.STOPPED)) {\r
+               log.debug("Already stopped plugin '{}:{}'", pluginDescriptor.getPluginId(), pluginDescriptor.getVersion());\r
+               return PluginState.STOPPED;\r
+       }\r
+       for (PluginDependency dependency : pluginDescriptor.getDependencies()) {\r
+               stopPlugin(dependency.getPluginId());\r
+       }\r
+       try {\r
+               log.info("Stop plugin '{}:{}'", pluginDescriptor.getPluginId(), pluginDescriptor.getVersion());\r
+               pluginWrapper.getPlugin().stop();\r
+               pluginWrapper.setPluginState(PluginState.STOPPED);\r
+               startedPlugins.remove(pluginWrapper);\r
+       } catch (PluginException e) {\r
+               log.error(e.getMessage(), e);\r
+       }\r
+       return pluginWrapper.getPluginState();\r
+    }\r
+\r
     /**\r
      * Load plugins.\r
      */\r
@@ -248,24 +309,24 @@ public class DefaultPluginManager implements PluginManager {
                for (ExtensionWrapper<T> extensionWrapper : extensionsWrapper) {\r
                        extensions.add(extensionWrapper.getInstance());\r
                }\r
-               \r
+\r
                return extensions;\r
        }\r
-       \r
+\r
     @Override\r
        public RuntimeMode getRuntimeMode() {\r
        if (runtimeMode == null) {\r
-               // retrieves the runtime mode from system  \r
+               // retrieves the runtime mode from system\r
                String modeAsString = System.getProperty("pf4j.mode", RuntimeMode.DEPLOYMENT.toString());\r
                runtimeMode = RuntimeMode.byName(modeAsString);\r
 \r
                log.info("PF4J runtime mode is '{}'", runtimeMode);\r
 \r
        }\r
-       \r
+\r
                return runtimeMode;\r
        }\r
-       \r
+\r
     /**\r
      * Retrieves the {@link PluginWrapper} that loaded the given class 'clazz'.\r
      */\r
@@ -276,63 +337,63 @@ public class DefaultPluginManager implements PluginManager {
                return plugin;\r
             }\r
         }\r
-        \r
+\r
         return null;\r
     }\r
 \r
        /**\r
-        * Add the possibility to override the PluginDescriptorFinder. \r
-        * By default if getRuntimeMode() returns RuntimeMode.DEVELOPMENT than a \r
-        * PropertiesPluginDescriptorFinder is returned else this method returns \r
+        * Add the possibility to override the PluginDescriptorFinder.\r
+        * By default if getRuntimeMode() returns RuntimeMode.DEVELOPMENT than a\r
+        * PropertiesPluginDescriptorFinder is returned else this method returns\r
         * DefaultPluginDescriptorFinder.\r
         */\r
     protected PluginDescriptorFinder createPluginDescriptorFinder() {\r
        if (RuntimeMode.DEVELOPMENT.equals(getRuntimeMode())) {\r
                return new PropertiesPluginDescriptorFinder();\r
        }\r
-       \r
+\r
        return new DefaultPluginDescriptorFinder(pluginClasspath);\r
     }\r
 \r
     /**\r
-     * Add the possibility to override the ExtensionFinder. \r
+     * Add the possibility to override the ExtensionFinder.\r
      */\r
     protected ExtensionFinder createExtensionFinder() {\r
        return new DefaultExtensionFinder(compoundClassLoader);\r
     }\r
 \r
     /**\r
-     * Add the possibility to override the PluginClassPath. \r
-     * By default if getRuntimeMode() returns RuntimeMode.DEVELOPMENT than a \r
-        * DevelopmentPluginClasspath is returned else this method returns \r
+     * Add the possibility to override the PluginClassPath.\r
+     * By default if getRuntimeMode() returns RuntimeMode.DEVELOPMENT than a\r
+        * DevelopmentPluginClasspath is returned else this method returns\r
         * PluginClasspath.\r
      */\r
     protected PluginClasspath createPluginClasspath() {\r
        if (RuntimeMode.DEVELOPMENT.equals(getRuntimeMode())) {\r
                return new DevelopmentPluginClasspath();\r
        }\r
-       \r
+\r
        return new PluginClasspath();\r
     }\r
-    \r
+\r
     protected boolean isPluginDisabled(String pluginId) {\r
        if (enabledPlugins.isEmpty()) {\r
                return disabledPlugins.contains(pluginId);\r
        }\r
-       \r
+\r
        return !enabledPlugins.contains(pluginId);\r
     }\r
-    \r
+\r
     protected FileFilter createHiddenPluginFilter() {\r
        return new HiddenFilter();\r
     }\r
-    \r
+\r
     /**\r
      * Add the possibility to override the plugins directory.\r
      * If a "pf4j.pluginsDir" system property is defined than this method returns\r
      * that directory.\r
-     * If getRuntimeMode() returns RuntimeMode.DEVELOPMENT than a \r
-        * DEVELOPMENT_PLUGINS_DIRECTORY ("../plugins") is returned else this method returns \r
+     * If getRuntimeMode() returns RuntimeMode.DEVELOPMENT than a\r
+        * DEVELOPMENT_PLUGINS_DIRECTORY ("../plugins") is returned else this method returns\r
         * DEFAULT_PLUGINS_DIRECTORY ("plugins").\r
      * @return\r
      */\r
@@ -345,10 +406,10 @@ public class DefaultPluginManager implements PluginManager {
                        pluginsDir = DEFAULT_PLUGINS_DIRECTORY;\r
                }\r
        }\r
-       \r
+\r
        return new File(pluginsDir);\r
     }\r
-    \r
+\r
        private void initialize() {\r
                plugins = new HashMap<String, PluginWrapper>();\r
         pluginClassLoaders = new HashMap<String, PluginClassLoader>();\r
@@ -358,7 +419,7 @@ public class DefaultPluginManager implements PluginManager {
         startedPlugins = new ArrayList<PluginWrapper>();\r
         disabledPlugins = new ArrayList<String>();\r
         compoundClassLoader = new CompoundClassLoader();\r
-        \r
+\r
         pluginClasspath = createPluginClasspath();\r
         pluginDescriptorFinder = createPluginDescriptorFinder();\r
         extensionFinder = createExtensionFinder();\r
@@ -367,7 +428,7 @@ public class DefaultPluginManager implements PluginManager {
                // create a list with plugin identifiers that should be only accepted by this manager (whitelist from plugins/enabled.txt file)\r
                enabledPlugins = FileUtils.readLines(new File(pluginsDirectory, "enabled.txt"), true);\r
                log.info("Enabled plugins: {}", enabledPlugins);\r
-               \r
+\r
                // create a list with plugin identifiers that should not be accepted by this manager (blacklist from plugins/disabled.txt file)\r
                disabledPlugins = FileUtils.readLines(new File(pluginsDirectory, "disabled.txt"), true);\r
                log.info("Disabled plugins: {}", disabledPlugins);\r
@@ -406,7 +467,7 @@ public class DefaultPluginManager implements PluginManager {
         PluginLoader pluginLoader = new PluginLoader(this, pluginDescriptor, pluginDirectory, pluginClasspath);\r
         pluginLoader.load();\r
         log.debug("Loaded plugin '{}'", pluginPath);\r
-        \r
+\r
         // create the plugin wrapper\r
         log.debug("Creating wrapper for plugin '{}'", pluginPath);\r
         PluginWrapper pluginWrapper = new PluginWrapper(pluginDescriptor, pluginPath, pluginLoader.getPluginClassLoader());\r
@@ -456,5 +517,5 @@ public class DefaultPluginManager implements PluginManager {
                log.info("Plugin '{}' resolved", pluginWrapper.getDescriptor().getPluginId());\r
         }\r
        }\r
-       \r
+\r
 }\r
index 7c78b89c1112d7171b07d2472acd89544f67de42..e183a959e0812b061464b5c486043a29504adb6b 100644 (file)
@@ -1,11 +1,11 @@
 /*
  * Copyright 2012 Decebal Suiu
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this work except in compliance with
  * the License. You may obtain a copy of the License in the LICENSE file, or 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.
@@ -36,7 +36,7 @@ public interface PluginManager {
         * Retrieves all unresolved plugins (with unresolved dependency).
         */
        public List<PluginWrapper> getUnresolvedPlugins();
-       
+
     /**
      * Retrieves all started plugins.
      */
@@ -52,18 +52,32 @@ public interface PluginManager {
      */
     public void startPlugins();
 
+    /**
+     * Start the specified plugin and it's dependencies.
+     *
+     * @return the plugin state
+     */
+    public PluginState startPlugin(String pluginId);
+
     /**
      * Stop all active plugins.
      */
     public void stopPlugins();
 
+    /**
+     * Stop the specified plugin and it's dependencies.
+     *
+     * @return the plugin state
+     */
+    public PluginState stopPlugin(String pluginId);
+
        public PluginClassLoader getPluginClassLoader(String pluginId);
 
        public <T> List<T> getExtensions(Class<T> type);
-       
+
        /**
         * The runtime mode. Must currently be either DEVELOPMENT or DEPLOYMENT.
         */
        public RuntimeMode getRuntimeMode();
-       
+
 }