From bbc318217153c5baf850edc913483a4340008bbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phan=20Kochen?= Date: Fri, 11 Feb 2011 10:05:16 +0100 Subject: [PATCH] Reverse roles of manager and loader in discovery. The PluginLoader is now itself responsible for iterating a plugin directory, because we're keeping different loaders' plugins in subdirectories. (The data directory of the loader's plugin.) The JavaPluginLoader is the only exception, which still reads from the main plugin directory. This also neatly tucks away system plugin functionality, which is Java-specific, in the JavaPluginLoader. --- .../java/org/bukkit/plugin/PluginLoader.java | 28 ++++----- .../java/org/bukkit/plugin/PluginManager.java | 26 +++----- .../bukkit/plugin/SimplePluginManager.java | 59 ++++--------------- .../bukkit/plugin/java/JavaPluginLoader.java | 54 +++++++++++++---- 4 files changed, 74 insertions(+), 93 deletions(-) diff --git a/src/main/java/org/bukkit/plugin/PluginLoader.java b/src/main/java/org/bukkit/plugin/PluginLoader.java index 66ab73bd36..3736a1ca33 100644 --- a/src/main/java/org/bukkit/plugin/PluginLoader.java +++ b/src/main/java/org/bukkit/plugin/PluginLoader.java @@ -1,8 +1,5 @@ package org.bukkit.plugin; -import java.io.File; -import java.util.regex.Pattern; - import org.bukkit.event.Event; import org.bukkit.event.Listener; @@ -18,11 +15,6 @@ * @see JavaPluginLoader */ public interface PluginLoader { - /** - * Returns a list of all filename filters expected by this PluginLoader - */ - public Pattern[] getPluginFileFilters(); - /** * Creates and returns an event executor * @@ -32,18 +24,22 @@ public interface PluginLoader { public EventExecutor createExecutor(Event.Type type, Listener listener); /** - * Reads the description for the plugin in the specified file + * Find plugins, and read their descriptions. + * + * Called by the PluginManager to find out about, or get an update on + * plugins handled by this loader. + * + * The loader should look for plugins in the data folder of it's own + * containing plugin, which can be retrieved using + * {@link PluginDescription#getDataFolder()}. * - * The implementation gathers the necessary information, usually - * with help from metadata included with the plugin, and returns - * a PluginDescription subclass. + * For each plugin it finds, the implementation constructs an instance of + * PluginDescription, and registers it using + * {@link PluginManager#register(PluginDescription)}. * - * @param pluginFile The file containing the plugin - * @return A filled PluginDescription object - * @throws InvalidDescriptionException Thrown when the metadata was not understood * @see PluginDescription */ - public PluginDescription readDescription(File pluginFile) throws InvalidDescriptionException; + public void discoverPlugins(); /** * Called by PluginManager to enable a plugin diff --git a/src/main/java/org/bukkit/plugin/PluginManager.java b/src/main/java/org/bukkit/plugin/PluginManager.java index 8b2cf2b3f7..d52fd961f5 100644 --- a/src/main/java/org/bukkit/plugin/PluginManager.java +++ b/src/main/java/org/bukkit/plugin/PluginManager.java @@ -19,29 +19,21 @@ public interface PluginManager { public void registerInterface(PluginLoader loader); /** - * Rediscover and reindex all plugins + * Registers a plugin description * - * Walks the plugin directory, reads descriptions and rebuilds the index - * of all plugins it can find for the registered loaders. + * Typically called from {@link PluginLoader#discoverPlugins()}. + * + * @param description The description to register */ - public void rebuildIndex(); + public void register(PluginDescription description); /** - * Discover and add to the index plugins handled by the given loader. - * - * This method is similar to {@link #rebuildIndex()}, but iterates only - * the plugins that match the given loader's filename filters, and adds - * those to the index, (rather than clearing the index and rebuilding - * from scratch.) - * - * This method is useful for plugins defining new interfaces. Those - * should call this method to index newly available plugins, and then - * call {@link #enablePlugin(PluginDescription)} for each returned. + * Rediscover and reindex all plugins * - * @param loader The loader of the type of plugin to index. - * @return A list of plugin descriptions that was indexed. + * Walks the plugin directory, reads descriptions and rebuilds the index + * of all plugins it can find for the registered loaders. */ - public PluginDescription[] updateIndexForInterface(PluginLoader loader); + public void rebuildIndex(); /** * Checks if the given plugin is loaded and returns it when applicable diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java index 1ae2b4e633..fc2d23ca68 100644 --- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java +++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java @@ -13,9 +13,7 @@ import java.util.TreeSet; import java.util.logging.Level; import java.util.logging.Logger; -import java.util.regex.Matcher; import org.bukkit.Server; -import java.util.regex.Pattern; import org.bukkit.command.CommandMap; import org.bukkit.command.SimpleCommandMap; @@ -33,7 +31,6 @@ public final class SimplePluginManager implements PluginManager { private final Server server; private final File pluginFolder; - private final List systemPlugins; private final CommandMap commandMap; private final List pluginLoaders = new ArrayList(); private final JavaPluginLoader javaPluginLoader; @@ -64,10 +61,13 @@ public int compare(RegisteredListener i, RegisteredListener j) { public SimplePluginManager(Server server, File pluginFolder, List systemPlugins) { this.server = server; this.pluginFolder = pluginFolder; - this.systemPlugins = systemPlugins; this.commandMap = new SimpleCommandMap(server); - javaPluginLoader = new JavaPluginLoader(server); + if (!pluginFolder.exists()) { + pluginFolder.mkdir(); + } + + javaPluginLoader = new JavaPluginLoader(server, pluginFolder, systemPlugins); registerInterface(javaPluginLoader); } @@ -81,56 +81,19 @@ public void registerInterface(PluginLoader loader) { /** * {@inheritDoc} */ - public void rebuildIndex() { - pluginDescriptions.clear(); - - for (PluginLoader loader : pluginLoaders) { - updateIndexForInterface(loader); - } - - for (File file : systemPlugins) { - try { - PluginDescription description = javaPluginLoader.readSystemPluginDescription(file); - if (pluginDescriptions.contains(description)) { - throw new InvalidDescriptionException("A plugin with this name already exists: " + description.getName()); - } - pluginDescriptions.insert(description); - } catch (InvalidDescriptionException ex) { - server.getLogger().log(Level.SEVERE, "Could not load " + file.getPath() + " in " + pluginFolder.getPath() + ": " + ex.getMessage(), ex); - } - } + public void register(PluginDescription description) { + pluginDescriptions.insert(description); } /** * {@inheritDoc} */ - public PluginDescription[] updateIndexForInterface(PluginLoader loader) { - if (!pluginFolder.exists()) { - pluginFolder.mkdir(); - } + public void rebuildIndex() { + pluginDescriptions.clear(); - File[] files = pluginFolder.listFiles(); - Pattern[] filters = loader.getPluginFileFilters(); - ArrayList result = new ArrayList(); - for (Pattern filter : filters) { - for (File file : files) { - Matcher match = filter.matcher(file.getName()); - if (match.find()) { - try { - PluginDescription description = loader.readDescription(file); - if (pluginDescriptions.contains(description)) { - throw new InvalidDescriptionException("A plugin with this name already exists: " + description.getName()); - } - pluginDescriptions.insert(description); - result.add(description); - } catch (InvalidDescriptionException ex) { - server.getLogger().log(Level.SEVERE, "Could not load " + file.getPath() + " in " + pluginFolder.getPath() + ": " + ex.getMessage(), ex); - } - } - } + for (PluginLoader loader : pluginLoaders) { + loader.discoverPlugins(); } - - return result.toArray(new PluginDescription[0]); } /** diff --git a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java index aad37ebfca..4c6f48d6fe 100644 --- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java +++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java @@ -12,7 +12,9 @@ import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; -import java.util.regex.Pattern; +import java.util.logging.Level; +import java.util.logging.Logger; + import org.bukkit.Server; import org.bukkit.command.Command; import org.bukkit.command.CommandMap; @@ -34,19 +36,16 @@ * Represents a Java plugin loader, allowing plugins in the form of .jar */ public final class JavaPluginLoader implements PluginLoader { + private static final Logger log = Logger.getLogger(JavaPluginLoader.class.getName()); private final Server server; - private final Pattern[] fileFilters = new Pattern[] { Pattern.compile("\\.jar$"), }; + private final File pluginFolder; + private final List systemPlugins; private final Map> classes = new HashMap>(); - public JavaPluginLoader(Server instance) { - server = instance; - } - - /** - * {@inheritDoc} - */ - public Pattern[] getPluginFileFilters() { - return fileFilters; + public JavaPluginLoader(Server server, File pluginFolder, List systemPlugins) { + this.server = server; + this.pluginFolder = pluginFolder; + this.systemPlugins = systemPlugins; } /** @@ -372,7 +371,38 @@ public void execute( Listener listener, Event event ) { /** * {@inheritDoc} */ - public PluginDescription readDescription(File file) throws InvalidDescriptionException { + public void discoverPlugins() { + PluginManager manager = server.getPluginManager(); + for (File file : pluginFolder.listFiles()) { + if (!file.getName().endsWith(".jar")) { + continue; + } + try { + PluginDescription description = readDescription(file); + manager.register(description); + } catch (InvalidDescriptionException ex) { + log.log(Level.SEVERE, "Could not load " + file.getPath() + " in " + pluginFolder.getPath() + ": " + ex.getMessage(), ex); + } + } + + for (File file : systemPlugins) { + try { + PluginDescription description = readSystemPluginDescription(file); + manager.register(description); + } catch (InvalidDescriptionException ex) { + log.log(Level.SEVERE, "Could not load " + file.getPath() + " in " + pluginFolder.getPath() + ": " + ex.getMessage(), ex); + } + } + } + + /** + * Reads the description for the plugin in the specified JAR-file + * + * @param file The JAR-file containing the plugin + * @return A PluginDescription instance + * @throws InvalidDescriptionException Thrown when the metadata was not understood + */ + private PluginDescription readDescription(File file) throws InvalidDescriptionException { JavaPluginDescription result = null; if (!file.exists()) {