diff options
author | Decebal Suiu <decebal.suiu@gmail.com> | 2012-11-19 13:38:03 +0200 |
---|---|---|
committer | Decebal Suiu <decebal.suiu@gmail.com> | 2012-11-19 13:38:03 +0200 |
commit | 82319fe10185c0a38361d8c9c30b01daddcc2748 (patch) | |
tree | bc24fd49c8207a184594c5fcf5a1ea21cae49f62 /pf4j | |
parent | 04ea48d8b08207203f88cf5e5bb7ee79e29c80d4 (diff) | |
download | pf4j-82319fe10185c0a38361d8c9c30b01daddcc2748.tar.gz pf4j-82319fe10185c0a38361d8c9c30b01daddcc2748.zip |
added PluginState
Diffstat (limited to 'pf4j')
-rw-r--r-- | pf4j/src/main/java/ro/fortsoft/pf4j/DefaultPluginManager.java | 47 | ||||
-rw-r--r-- | pf4j/src/main/java/ro/fortsoft/pf4j/PluginDescriptor.java | 16 | ||||
-rw-r--r-- | pf4j/src/main/java/ro/fortsoft/pf4j/PluginState.java | 38 | ||||
-rw-r--r-- | pf4j/src/main/java/ro/fortsoft/pf4j/PluginWrapper.java | 48 | ||||
-rw-r--r-- | pf4j/src/main/java/ro/fortsoft/pf4j/util/CompoundClassLoader.java (renamed from pf4j/src/main/java/ro/fortsoft/pf4j/util/UberClassLoader.java) | 2 |
5 files changed, 106 insertions, 45 deletions
diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/DefaultPluginManager.java b/pf4j/src/main/java/ro/fortsoft/pf4j/DefaultPluginManager.java index 1081526..750e334 100644 --- a/pf4j/src/main/java/ro/fortsoft/pf4j/DefaultPluginManager.java +++ b/pf4j/src/main/java/ro/fortsoft/pf4j/DefaultPluginManager.java @@ -24,8 +24,8 @@ import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import ro.fortsoft.pf4j.util.CompoundClassLoader; import ro.fortsoft.pf4j.util.DirectoryFilter; -import ro.fortsoft.pf4j.util.UberClassLoader; import ro.fortsoft.pf4j.util.Unzip; import ro.fortsoft.pf4j.util.ZipFilter; @@ -82,8 +82,11 @@ public class DefaultPluginManager implements PluginManager { */ private List<PluginWrapper> startedPlugins; - private UberClassLoader uberClassLoader; - + /** + * A compound class loader of resolved plugins. + */ + private CompoundClassLoader compoundClassLoader; + /** * Th plugins directory is supplied by System.getProperty("pf4j.pluginsDir", "plugins"). */ @@ -108,16 +111,18 @@ public class DefaultPluginManager implements PluginManager { disabledPlugins = new ArrayList<PluginWrapper>(); startedPlugins = new ArrayList<PluginWrapper>(); pluginDescriptorFinder = new DefaultPluginDescriptorFinder(); - uberClassLoader = new UberClassLoader(); - extensionFinder = new DefaultExtensionFinder(uberClassLoader); + compoundClassLoader = new CompoundClassLoader(); + extensionFinder = new DefaultExtensionFinder(compoundClassLoader); System.setProperty("pf4j.pluginsDir", pluginsDirectory.getAbsolutePath()); } + @Override public List<PluginWrapper> getPlugins() { return new ArrayList<PluginWrapper>(plugins.values()); } + @Override public List<PluginWrapper> getResolvedPlugins() { return resolvedPlugins; } @@ -126,6 +131,7 @@ public class DefaultPluginManager implements PluginManager { return plugins.get(pluginId); } + @Override public List<PluginWrapper> getUnresolvedPlugins() { return unresolvedPlugins; } @@ -134,6 +140,7 @@ public class DefaultPluginManager implements PluginManager { return disabledPlugins; } + @Override public List<PluginWrapper> getStartedPlugins() { return startedPlugins; } @@ -141,11 +148,13 @@ public class DefaultPluginManager implements PluginManager { /** * Start all active plugins. */ + @Override public void startPlugins() { for (PluginWrapper pluginWrapper : resolvedPlugins) { try { LOG.info("Start plugin '" + pluginWrapper.getDescriptor().getPluginId() + "'"); pluginWrapper.getPlugin().start(); + pluginWrapper.setPluginState(PluginState.STARTED); startedPlugins.add(pluginWrapper); } catch (PluginException e) { LOG.error(e.getMessage(), e); @@ -156,6 +165,7 @@ public class DefaultPluginManager implements PluginManager { /** * Stop all active plugins. */ + @Override public void stopPlugins() { // stop started plugins in reverse order Collections.reverse(startedPlugins); @@ -163,6 +173,7 @@ public class DefaultPluginManager implements PluginManager { try { LOG.info("Stop plugin '" + pluginWrapper.getDescriptor().getPluginId() + "'"); pluginWrapper.getPlugin().stop(); + pluginWrapper.setPluginState(PluginState.STOPPED); } catch (PluginException e) { LOG.error(e.getMessage(), e); } @@ -172,6 +183,7 @@ public class DefaultPluginManager implements PluginManager { /** * Load plugins. */ + @Override public void loadPlugins() { // check for plugins directory if (!pluginsDirectory.exists() || !pluginsDirectory.isDirectory()) { @@ -218,10 +230,12 @@ public class DefaultPluginManager implements PluginManager { /** * Get plugin class loader for this path. */ + @Override public PluginClassLoader getPluginClassLoader(String pluginId) { return pluginClassLoaders.get(pluginId); } + @Override public <T> List<T> getExtensions(Class<T> type) { List<ExtensionWrapper<T>> extensionsWrapper = extensionFinder.find(type); List<T> extensions = new ArrayList<T>(extensionsWrapper.size()); @@ -232,13 +246,27 @@ public class DefaultPluginManager implements PluginManager { return extensions; } + /** + * Retrieves the {@link PluginWrapper} that loaded the given class 'clazz'. + */ + public PluginWrapper whichPlugin(Class<?> clazz) { + ClassLoader classLoader = clazz.getClassLoader(); + for (PluginWrapper plugin : resolvedPlugins) { + if (plugin.getPluginClassLoader() == classLoader) { + return plugin; + } + } + + return null; + } + private void loadPlugin(String fileName) throws PluginException { // test for plugin directory File pluginDirectory = new File(pluginsDirectory, fileName); if (!pluginDirectory.isDirectory()) { return; } - + // try to load the plugin String pluginPath = "/".concat(fileName); @@ -247,7 +275,7 @@ public class DefaultPluginManager implements PluginManager { return; } - // it's a new plugin + // test for plugin duplication if (plugins.get(pathToIdMap.get(pluginPath)) != null) { return; } @@ -278,7 +306,6 @@ public class DefaultPluginManager implements PluginManager { // add plugin class loader to the list with class loaders PluginClassLoader pluginClassLoader = pluginLoader.getPluginClassLoader(); - pluginDescriptor.setPluginClassLoader(pluginClassLoader); pluginClassLoaders.put(pluginId, pluginClassLoader); } @@ -288,7 +315,7 @@ public class DefaultPluginManager implements PluginManager { String pluginName = fileName.substring(0, fileName.length() - 4); File pluginDirectory = new File(pluginsDirectory, pluginName); // check if exists directory or the '.zip' file is "newer" than directory - if (!pluginDirectory.exists() || pluginArchiveDate > pluginDirectory.lastModified()) { + if (!pluginDirectory.exists() || (pluginArchiveDate > pluginDirectory.lastModified())) { LOG.debug("Expand plugin archive '" + pluginArchiveFile + "' in '" + pluginDirectory + "'"); // create directorie for plugin pluginDirectory.mkdirs(); @@ -310,7 +337,7 @@ public class DefaultPluginManager implements PluginManager { resolvedPlugins = dependencyResolver.getSortedPlugins(); for (PluginWrapper pluginWrapper : resolvedPlugins) { unresolvedPlugins.remove(pluginWrapper); - uberClassLoader.addLoader(pluginWrapper.getPluginClassLoader()); + compoundClassLoader.addLoader(pluginWrapper.getPluginClassLoader()); LOG.info("Plugin '" + pluginWrapper.getDescriptor().getPluginId() + "' resolved"); } } diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/PluginDescriptor.java b/pf4j/src/main/java/ro/fortsoft/pf4j/PluginDescriptor.java index e6006d2..546f003 100644 --- a/pf4j/src/main/java/ro/fortsoft/pf4j/PluginDescriptor.java +++ b/pf4j/src/main/java/ro/fortsoft/pf4j/PluginDescriptor.java @@ -29,7 +29,6 @@ public class PluginDescriptor { private PluginVersion version; private String provider; private List<PluginDependency> dependencies; - private PluginClassLoader pluginClassLoader; public PluginDescriptor() { dependencies = new ArrayList<PluginDependency>(); @@ -71,21 +70,12 @@ public class PluginDescriptor { return dependencies; } - /** - * Returns the plugin class loader used to load classes and resources - * for this plug-in. The class loader can be used to directly access - * plug-in resources and classes. - */ - public PluginClassLoader getPluginClassLoader() { - return pluginClassLoader; - } - @Override public String toString() { return "PluginDescriptor [pluginId=" + pluginId + ", pluginClass=" + pluginClass + ", version=" + version + ", provider=" + provider + ", dependencies=" + dependencies - + ", pluginClassLoader=" + pluginClassLoader + "]"; + + "]"; } void setPluginId(String pluginId) { @@ -127,8 +117,4 @@ public class PluginDescriptor { } } - void setPluginClassLoader(PluginClassLoader pluginClassLoader) { - this.pluginClassLoader = pluginClassLoader; - } - } diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/PluginState.java b/pf4j/src/main/java/ro/fortsoft/pf4j/PluginState.java new file mode 100644 index 0000000..3727087 --- /dev/null +++ b/pf4j/src/main/java/ro/fortsoft/pf4j/PluginState.java @@ -0,0 +1,38 @@ +/* + * 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. + */ +package ro.fortsoft.pf4j; + +/** + * @author Decebal Suiu + */ +public class PluginState { + + public static final PluginState CREATED = new PluginState("CREATED"); + public static final PluginState INITIALIZED = new PluginState("INITIALIZED"); + public static final PluginState STARTED = new PluginState("STARTED"); + public static final PluginState STOPPED = new PluginState("STOPPED"); + public static final PluginState DESTROYED = new PluginState("DESTROYED"); + public static final PluginState FAILED = new PluginState("FAILED"); + + private String status; + + private PluginState(String status) { + this.status = status; + } + + @Override + public String toString() { + return status; + } + +} diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/PluginWrapper.java b/pf4j/src/main/java/ro/fortsoft/pf4j/PluginWrapper.java index c960ec1..4dd18d1 100644 --- a/pf4j/src/main/java/ro/fortsoft/pf4j/PluginWrapper.java +++ b/pf4j/src/main/java/ro/fortsoft/pf4j/PluginWrapper.java @@ -26,6 +26,7 @@ public class PluginWrapper { String pluginPath; PluginClassLoader pluginClassLoader; Plugin plugin; + PluginState pluginState; public PluginWrapper(PluginDescriptor descriptor, String pluginPath, PluginClassLoader pluginClassLoader) { this.descriptor = descriptor; @@ -38,6 +39,8 @@ public class PluginWrapper { } catch (Exception e) { e.printStackTrace(); } + + pluginState = PluginState.CREATED; } /** @@ -67,25 +70,9 @@ public class PluginWrapper { return plugin; } - private Plugin createPluginInstance() throws Exception { - String pluginClassName = descriptor.getPluginClass(); - Class<?> pluginClass = pluginClassLoader.loadClass(pluginClassName); - - // once we have the class, we can do some checks on it to ensure - // that it is a valid implementation of a plugin. - int modifiers = pluginClass.getModifiers(); - if (Modifier.isAbstract(modifiers) || Modifier.isInterface(modifiers) - || (!Plugin.class.isAssignableFrom(pluginClass))) { - throw new PluginException("The plugin class '" + pluginClassName + "' is not compatible."); - } - - // create the plugin instance - Constructor<?> constructor = pluginClass.getConstructor(new Class[] { PluginWrapper.class }); - Plugin plugin = (Plugin) constructor.newInstance(new Object[] { this }); - - return plugin; - } - + public PluginState getPluginState() { + return pluginState; + } @Override public int hashCode() { @@ -124,4 +111,27 @@ public class PluginWrapper { + pluginPath + "]"; } + void setPluginState(PluginState pluginState) { + this.pluginState = pluginState; + } + + private Plugin createPluginInstance() throws Exception { + String pluginClassName = descriptor.getPluginClass(); + Class<?> pluginClass = pluginClassLoader.loadClass(pluginClassName); + + // once we have the class, we can do some checks on it to ensure + // that it is a valid implementation of a plugin. + int modifiers = pluginClass.getModifiers(); + if (Modifier.isAbstract(modifiers) || Modifier.isInterface(modifiers) + || (!Plugin.class.isAssignableFrom(pluginClass))) { + throw new PluginException("The plugin class '" + pluginClassName + "' is not compatible."); + } + + // create the plugin instance + Constructor<?> constructor = pluginClass.getConstructor(new Class[] { PluginWrapper.class }); + Plugin plugin = (Plugin) constructor.newInstance(new Object[] { this }); + + return plugin; + } + } diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/util/UberClassLoader.java b/pf4j/src/main/java/ro/fortsoft/pf4j/util/CompoundClassLoader.java index 013c2a1..f5c5df4 100644 --- a/pf4j/src/main/java/ro/fortsoft/pf4j/util/UberClassLoader.java +++ b/pf4j/src/main/java/ro/fortsoft/pf4j/util/CompoundClassLoader.java @@ -26,7 +26,7 @@ import java.util.Set; * * @author Decebal Suiu */ -public class UberClassLoader extends ClassLoader { +public class CompoundClassLoader extends ClassLoader { private Set<ClassLoader> loaders = new HashSet<ClassLoader>(); |