diff --git a/demo/disabled.txt b/demo/disabled.txt new file mode 100644 index 0000000..b8fedab --- /dev/null +++ b/demo/disabled.txt @@ -0,0 +1,6 @@ +######################################## +# - load all plugins except these +# - add one plugin id on each line +# - put this file in plugins folder +######################################## +welcome-plugin diff --git a/demo/enabled.txt b/demo/enabled.txt new file mode 100644 index 0000000..96a92b3 --- /dev/null +++ b/demo/enabled.txt @@ -0,0 +1,6 @@ +######################################## +# - load only these plugins +# - add one plugin id on each line +# - put this file in plugins folder +######################################## +welcome-plugin diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/DefaultPluginManager.java b/pf4j/src/main/java/ro/fortsoft/pf4j/DefaultPluginManager.java index 5befbc2..20aba2d 100644 --- a/pf4j/src/main/java/ro/fortsoft/pf4j/DefaultPluginManager.java +++ b/pf4j/src/main/java/ro/fortsoft/pf4j/DefaultPluginManager.java @@ -26,6 +26,7 @@ import org.slf4j.LoggerFactory; import ro.fortsoft.pf4j.util.CompoundClassLoader; import ro.fortsoft.pf4j.util.DirectoryFilter; +import ro.fortsoft.pf4j.util.FileUtils; import ro.fortsoft.pf4j.util.Unzip; import ro.fortsoft.pf4j.util.ZipFilter; @@ -71,17 +72,15 @@ public class DefaultPluginManager implements PluginManager { * A list with resolved plugins (resolved dependency). */ private List resolvedPlugins; - - /** - * A list with disabled plugins. - */ - private List disabledPlugins; /** * A list with started plugins. */ private List startedPlugins; + private List enabledPlugins; + private List disabledPlugins; + /** * A compound class loader of resolved plugins. */ @@ -108,22 +107,26 @@ public class DefaultPluginManager implements PluginManager { pathToIdMap = new HashMap(); unresolvedPlugins = new ArrayList(); resolvedPlugins = new ArrayList(); - disabledPlugins = new ArrayList(); startedPlugins = new ArrayList(); + disabledPlugins = new ArrayList(); compoundClassLoader = new CompoundClassLoader(); pluginDescriptorFinder = createPluginDescriptorFinder(); extensionFinder = createExtensionFinder(); - - System.setProperty("pf4j.pluginsDir", pluginsDirectory.getAbsolutePath()); - } - protected PluginDescriptorFinder createPluginDescriptorFinder() { - return new DefaultPluginDescriptorFinder(); - } + try { + // 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); + } catch (IOException e) { + log.error(e.getMessage(), e); + } - protected ExtensionFinder createExtensionFinder() { - return new DefaultExtensionFinder(compoundClassLoader); + System.setProperty("pf4j.pluginsDir", pluginsDirectory.getAbsolutePath()); } @Override @@ -145,10 +148,6 @@ public class DefaultPluginManager implements PluginManager { return unresolvedPlugins; } - public List getDisabledPlugins() { - return disabledPlugins; - } - @Override public List getStartedPlugins() { return startedPlugins; @@ -211,9 +210,15 @@ public class DefaultPluginManager implements PluginManager { } } - // load any plugin from plugins directory + // check for no plugins FilenameFilter directoryFilter = new DirectoryFilter(); String[] directories = pluginsDirectory.list(directoryFilter); + if (directories.length == 0) { + log.info("No plugins"); + return; + } + + // load any plugin from plugins directory for (String directory : directories) { try { loadPlugin(directory); @@ -222,12 +227,6 @@ public class DefaultPluginManager implements PluginManager { } } - // check for no plugins - if (directories.length == 0) { - log.info("No plugins"); - return; - } - // resolve 'unresolvedPlugins' try { resolvePlugins(); @@ -279,11 +278,6 @@ public class DefaultPluginManager implements PluginManager { // try to load the plugin String pluginPath = "/".concat(fileName); - // test for disabled plugin - if (disabledPlugins.contains(pluginPath)) { - return; - } - // test for plugin duplication if (plugins.get(pathToIdMap.get(pluginPath)) != null) { return; @@ -296,6 +290,12 @@ public class DefaultPluginManager implements PluginManager { String pluginClassName = pluginDescriptor.getPluginClass(); log.debug("Class '" + pluginClassName + "'" + " for plugin '" + pluginPath + "'"); + // test for disabled plugin + if (isPluginDisabled(pluginDescriptor.getPluginId())) { + log.info("Plugin '" + pluginPath + "' is disabled"); + return; + } + // load plugin log.debug("Loading plugin '" + pluginPath + "'"); PluginLoader pluginLoader = new PluginLoader(this, pluginDescriptor, pluginDirectory); @@ -318,6 +318,28 @@ public class DefaultPluginManager implements PluginManager { pluginClassLoaders.put(pluginId, pluginClassLoader); } + /** + * Add the possibility to override the PluginDescriptorFinder. + */ + protected PluginDescriptorFinder createPluginDescriptorFinder() { + return new DefaultPluginDescriptorFinder(); + } + + /** + * Add the possibility to override the ExtensionFinder. + */ + protected ExtensionFinder createExtensionFinder() { + return new DefaultExtensionFinder(compoundClassLoader); + } + + protected boolean isPluginDisabled(String pluginId) { + if (enabledPlugins.isEmpty()) { + return disabledPlugins.contains(pluginId); + } + + return !enabledPlugins.contains(pluginId); + } + private void expandPluginArchive(String fileName) throws IOException { File pluginArchiveFile = new File(pluginsDirectory, fileName); long pluginArchiveDate = pluginArchiveFile.lastModified(); diff --git a/pf4j/src/main/java/ro/fortsoft/pf4j/util/FileUtils.java b/pf4j/src/main/java/ro/fortsoft/pf4j/util/FileUtils.java new file mode 100644 index 0000000..0b8c38a --- /dev/null +++ b/pf4j/src/main/java/ro/fortsoft/pf4j/util/FileUtils.java @@ -0,0 +1,53 @@ +/* + * 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.util; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * @author Decebal Suiu + */ +public class FileUtils { + + public static List readLines(File file, boolean ignoreComments) throws IOException { + if (!file.exists() || !file.isFile()) { + return Collections.emptyList(); + } + + List lines = new ArrayList(); + + BufferedReader reader = null; + try { + reader = new BufferedReader(new FileReader(file)); + String line; + while ((line = reader.readLine()) != null) { + if (ignoreComments && !line.startsWith("#") && !lines.contains(line)) { + lines.add(line); + } + } + } finally { + if (reader != null) { + reader.close(); + } + } + + return lines; + } + +}