Browse Source

Add methods to start & stop a single plugin and it's dependencies

pull/3/head
James Moger 11 years ago
parent
commit
02455e68f6
  1. 6
      pf4j/pom.xml
  2. 153
      pf4j/src/main/java/ro/fortsoft/pf4j/DefaultPluginManager.java
  3. 26
      pf4j/src/main/java/ro/fortsoft/pf4j/PluginManager.java

6
pf4j/pom.xml

@ -32,6 +32,12 @@
<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>

153
pf4j/src/main/java/ro/fortsoft/pf4j/DefaultPluginManager.java

@ -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.
@ -19,6 +19,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@ -42,7 +43,7 @@ import ro.fortsoft.pf4j.util.ZipFileFilter;
public class DefaultPluginManager implements PluginManager {
private static final Logger log = LoggerFactory.getLogger(DefaultPluginManager.class);
public static final String DEFAULT_PLUGINS_DIRECTORY = "plugins";
public static final String DEVELOPMENT_PLUGINS_DIRECTORY = "../plugins";
@ -52,11 +53,11 @@ public class DefaultPluginManager implements PluginManager {
private File pluginsDirectory;
private ExtensionFinder extensionFinder;
private PluginDescriptorFinder pluginDescriptorFinder;
private PluginClasspath pluginClasspath;
/**
* A map of plugins this manager is responsible for (the key is the 'pluginId').
*/
@ -81,35 +82,35 @@ public class DefaultPluginManager implements PluginManager {
* A list with resolved plugins (resolved dependency).
*/
private List<PluginWrapper> resolvedPlugins;
/**
* A list with started plugins.
*/
private List<PluginWrapper> startedPlugins;
private List<String> enabledPlugins;
private List<String> disabledPlugins;
/**
* A compound class loader of resolved plugins.
* A compound class loader of resolved plugins.
*/
protected CompoundClassLoader compoundClassLoader;
/**
* Cache value for the runtime mode. No need to re-read it because it wont change at
* runtime.
*/
private RuntimeMode runtimeMode;
/**
* The plugins directory is supplied by System.getProperty("pf4j.pluginsDir", "plugins").
*/
public DefaultPluginManager() {
this.pluginsDirectory = createPluginsDirectory();
initialize();
}
/**
* Constructs DefaultPluginManager which the given plugins directory.
*
@ -118,7 +119,7 @@ public class DefaultPluginManager implements PluginManager {
*/
public DefaultPluginManager(File pluginsDirectory) {
this.pluginsDirectory = pluginsDirectory;
initialize();
}
@ -145,7 +146,7 @@ public class DefaultPluginManager implements PluginManager {
public List<PluginWrapper> getStartedPlugins() {
return startedPlugins;
}
/**
* Start all active plugins.
*/
@ -163,6 +164,34 @@ public class DefaultPluginManager implements PluginManager {
}
}
/**
* Start the specified plugin and it's dependencies.
*/
@Override
public PluginState startPlugin(String pluginId) {
if (!plugins.containsKey(pluginId)) {
throw new IllegalArgumentException(String.format("Unknown pluginId %s", pluginId));
}
PluginWrapper pluginWrapper = plugins.get(pluginId);
PluginDescriptor pluginDescriptor = pluginWrapper.getDescriptor();
if (pluginWrapper.getPluginState().equals(PluginState.STARTED)) {
log.debug("Already started plugin '{}:{}'", pluginDescriptor.getPluginId(), pluginDescriptor.getVersion());
return PluginState.STARTED;
}
for (PluginDependency dependency : pluginDescriptor.getDependencies()) {
startPlugin(dependency.getPluginId());
}
try {
log.info("Start plugin '{}:{}'", pluginDescriptor.getPluginId(), pluginDescriptor.getVersion());
pluginWrapper.getPlugin().start();
pluginWrapper.setPluginState(PluginState.STARTED);
startedPlugins.add(pluginWrapper);
} catch (PluginException e) {
log.error(e.getMessage(), e);
}
return pluginWrapper.getPluginState();
}
/**
* Stop all active plugins.
*/
@ -170,17 +199,49 @@ public class DefaultPluginManager implements PluginManager {
public void stopPlugins() {
// stop started plugins in reverse order
Collections.reverse(startedPlugins);
for (PluginWrapper pluginWrapper : startedPlugins) {
Iterator<PluginWrapper> itr = startedPlugins.iterator();
while (itr.hasNext()) {
PluginWrapper pluginWrapper = itr.next();
PluginDescriptor pluginDescriptor = pluginWrapper.getDescriptor();
try {
log.info("Stop plugin '{}'", pluginWrapper.getDescriptor().getPluginId());
log.info("Stop plugin '{}:{}'", pluginDescriptor.getPluginId(), pluginDescriptor.getVersion());
pluginWrapper.getPlugin().stop();
pluginWrapper.setPluginState(PluginState.STOPPED);
itr.remove();
} catch (PluginException e) {
log.error(e.getMessage(), e);
}
}
}
/**
* Stop the specified plugin and it's dependencies.
*/
@Override
public PluginState stopPlugin(String pluginId) {
if (!plugins.containsKey(pluginId)) {
throw new IllegalArgumentException(String.format("Unknown pluginId %s", pluginId));
}
PluginWrapper pluginWrapper = plugins.get(pluginId);
PluginDescriptor pluginDescriptor = pluginWrapper.getDescriptor();
if (pluginWrapper.getPluginState().equals(PluginState.STOPPED)) {
log.debug("Already stopped plugin '{}:{}'", pluginDescriptor.getPluginId(), pluginDescriptor.getVersion());
return PluginState.STOPPED;
}
for (PluginDependency dependency : pluginDescriptor.getDependencies()) {
stopPlugin(dependency.getPluginId());
}
try {
log.info("Stop plugin '{}:{}'", pluginDescriptor.getPluginId(), pluginDescriptor.getVersion());
pluginWrapper.getPlugin().stop();
pluginWrapper.setPluginState(PluginState.STOPPED);
startedPlugins.remove(pluginWrapper);
} catch (PluginException e) {
log.error(e.getMessage(), e);
}
return pluginWrapper.getPluginState();
}
/**
* Load plugins.
*/
@ -248,24 +309,24 @@ public class DefaultPluginManager implements PluginManager {
for (ExtensionWrapper<T> extensionWrapper : extensionsWrapper) {
extensions.add(extensionWrapper.getInstance());
}
return extensions;
}
@Override
public RuntimeMode getRuntimeMode() {
if (runtimeMode == null) {
// retrieves the runtime mode from system
// retrieves the runtime mode from system
String modeAsString = System.getProperty("pf4j.mode", RuntimeMode.DEPLOYMENT.toString());
runtimeMode = RuntimeMode.byName(modeAsString);
log.info("PF4J runtime mode is '{}'", runtimeMode);
}
return runtimeMode;
}
/**
* Retrieves the {@link PluginWrapper} that loaded the given class 'clazz'.
*/
@ -276,63 +337,63 @@ public class DefaultPluginManager implements PluginManager {
return plugin;
}
}
return null;
}
/**
* Add the possibility to override the PluginDescriptorFinder.
* By default if getRuntimeMode() returns RuntimeMode.DEVELOPMENT than a
* PropertiesPluginDescriptorFinder is returned else this method returns
* Add the possibility to override the PluginDescriptorFinder.
* By default if getRuntimeMode() returns RuntimeMode.DEVELOPMENT than a
* PropertiesPluginDescriptorFinder is returned else this method returns
* DefaultPluginDescriptorFinder.
*/
protected PluginDescriptorFinder createPluginDescriptorFinder() {
if (RuntimeMode.DEVELOPMENT.equals(getRuntimeMode())) {
return new PropertiesPluginDescriptorFinder();
}
return new DefaultPluginDescriptorFinder(pluginClasspath);
}
/**
* Add the possibility to override the ExtensionFinder.
* Add the possibility to override the ExtensionFinder.
*/
protected ExtensionFinder createExtensionFinder() {
return new DefaultExtensionFinder(compoundClassLoader);
}
/**
* Add the possibility to override the PluginClassPath.
* By default if getRuntimeMode() returns RuntimeMode.DEVELOPMENT than a
* DevelopmentPluginClasspath is returned else this method returns
* Add the possibility to override the PluginClassPath.
* By default if getRuntimeMode() returns RuntimeMode.DEVELOPMENT than a
* DevelopmentPluginClasspath is returned else this method returns
* PluginClasspath.
*/
protected PluginClasspath createPluginClasspath() {
if (RuntimeMode.DEVELOPMENT.equals(getRuntimeMode())) {
return new DevelopmentPluginClasspath();
}
return new PluginClasspath();
}
protected boolean isPluginDisabled(String pluginId) {
if (enabledPlugins.isEmpty()) {
return disabledPlugins.contains(pluginId);
}
return !enabledPlugins.contains(pluginId);
}
protected FileFilter createHiddenPluginFilter() {
return new HiddenFilter();
}
/**
* Add the possibility to override the plugins directory.
* If a "pf4j.pluginsDir" system property is defined than this method returns
* that directory.
* If getRuntimeMode() returns RuntimeMode.DEVELOPMENT than a
* DEVELOPMENT_PLUGINS_DIRECTORY ("../plugins") is returned else this method returns
* If getRuntimeMode() returns RuntimeMode.DEVELOPMENT than a
* DEVELOPMENT_PLUGINS_DIRECTORY ("../plugins") is returned else this method returns
* DEFAULT_PLUGINS_DIRECTORY ("plugins").
* @return
*/
@ -345,10 +406,10 @@ public class DefaultPluginManager implements PluginManager {
pluginsDir = DEFAULT_PLUGINS_DIRECTORY;
}
}
return new File(pluginsDir);
}
private void initialize() {
plugins = new HashMap<String, PluginWrapper>();
pluginClassLoaders = new HashMap<String, PluginClassLoader>();
@ -358,7 +419,7 @@ public class DefaultPluginManager implements PluginManager {
startedPlugins = new ArrayList<PluginWrapper>();
disabledPlugins = new ArrayList<String>();
compoundClassLoader = new CompoundClassLoader();
pluginClasspath = createPluginClasspath();
pluginDescriptorFinder = createPluginDescriptorFinder();
extensionFinder = createExtensionFinder();
@ -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)
enabledPlugins = FileUtils.readLines(new File(pluginsDirectory, "enabled.txt"), true);
log.info("Enabled plugins: {}", enabledPlugins);
// create a list with plugin identifiers that should not be accepted by this manager (blacklist from plugins/disabled.txt file)
disabledPlugins = FileUtils.readLines(new File(pluginsDirectory, "disabled.txt"), true);
log.info("Disabled plugins: {}", disabledPlugins);
@ -406,7 +467,7 @@ public class DefaultPluginManager implements PluginManager {
PluginLoader pluginLoader = new PluginLoader(this, pluginDescriptor, pluginDirectory, pluginClasspath);
pluginLoader.load();
log.debug("Loaded plugin '{}'", pluginPath);
// create the plugin wrapper
log.debug("Creating wrapper for plugin '{}'", pluginPath);
PluginWrapper pluginWrapper = new PluginWrapper(pluginDescriptor, pluginPath, pluginLoader.getPluginClassLoader());
@ -456,5 +517,5 @@ public class DefaultPluginManager implements PluginManager {
log.info("Plugin '{}' resolved", pluginWrapper.getDescriptor().getPluginId());
}
}
}

26
pf4j/src/main/java/ro/fortsoft/pf4j/PluginManager.java

@ -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();
}

Loading…
Cancel
Save