From 5ef26c647b6b4eb693153fe6c9c1a87244f05fc7 Mon Sep 17 00:00:00 2001 From: Bukkit/Spigot Date: Wed, 27 Apr 2011 20:35:08 +0100 Subject: [PATCH] Added support for soft dependencies. Soft dependencies allow plugins to request to be loaded after another plugin, but they will not throw an UnknownDependency exception if the other plugin is not present. By: Raphfrk --- .../bukkit/plugin/PluginDescriptionFile.java | 14 ++++++ .../java/org/bukkit/plugin/PluginLoader.java | 11 +++++ .../bukkit/plugin/SimplePluginManager.java | 20 ++++++++- .../UnknownSoftDependencyException.java | 45 +++++++++++++++++++ .../bukkit/plugin/java/JavaPluginLoader.java | 26 +++++++++++ 5 files changed, 114 insertions(+), 2 deletions(-) create mode 100644 paper-api/src/main/java/org/bukkit/plugin/UnknownSoftDependencyException.java diff --git a/paper-api/src/main/java/org/bukkit/plugin/PluginDescriptionFile.java b/paper-api/src/main/java/org/bukkit/plugin/PluginDescriptionFile.java index be4fb0aff6..f1574f951d 100644 --- a/paper-api/src/main/java/org/bukkit/plugin/PluginDescriptionFile.java +++ b/paper-api/src/main/java/org/bukkit/plugin/PluginDescriptionFile.java @@ -18,6 +18,7 @@ public final class PluginDescriptionFile { private String name = null; private String main = null; private ArrayList depend = null; + private ArrayList softDepend = null; private String version = null; private Object commands = null; private String description = null; @@ -104,6 +105,10 @@ public final class PluginDescriptionFile { return depend; } + public Object getSoftDepend() { + return softDepend; + } + /** * Gets the description of this plugin * @@ -177,6 +182,14 @@ public final class PluginDescriptionFile { } } + if (map.containsKey("softdepend")) { + try { + softDepend = (ArrayList)map.get("softdepend"); + } catch (ClassCastException ex) { + throw new InvalidDescriptionException(ex, "softdepend is of wrong type"); + } + } + if (map.containsKey("database")) { try { database = (Boolean)map.get("database"); @@ -229,6 +242,7 @@ public final class PluginDescriptionFile { if (commands != null) map.put("command", commands); if (depend != null) map.put("depend", depend); + if (softDepend != null) map.put("softdepend", softDepend); if (website != null) map.put("website", website); if (description != null) map.put("description", description); diff --git a/paper-api/src/main/java/org/bukkit/plugin/PluginLoader.java b/paper-api/src/main/java/org/bukkit/plugin/PluginLoader.java index 245c850f76..5deafa5c55 100644 --- a/paper-api/src/main/java/org/bukkit/plugin/PluginLoader.java +++ b/paper-api/src/main/java/org/bukkit/plugin/PluginLoader.java @@ -22,6 +22,17 @@ public interface PluginLoader { */ public Plugin loadPlugin(File file) throws InvalidPluginException, InvalidDescriptionException, UnknownDependencyException; + /** + * Loads the plugin contained in the specified file + * + * @param file File to attempt to load + * @param ignoreSoftDependencies Loader will ignore soft dependencies if this flag is set to true + * @return Plugin that was contained in the specified file, or null if + * unsuccessful + * @throws InvalidPluginException Thrown when the specified file is not a plugin + */ + public Plugin loadPlugin(File file, boolean ignoreSoftDependencies) throws InvalidPluginException, InvalidDescriptionException, UnknownDependencyException; + /** * Returns a list of all filename filters expected by this PluginLoader */ diff --git a/paper-api/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/paper-api/src/main/java/org/bukkit/plugin/SimplePluginManager.java index 5ab303ec73..ffdbb5fd75 100644 --- a/paper-api/src/main/java/org/bukkit/plugin/SimplePluginManager.java +++ b/paper-api/src/main/java/org/bukkit/plugin/SimplePluginManager.java @@ -105,7 +105,7 @@ public final class SimplePluginManager implements PluginManager { Plugin plugin = null; try { - plugin = loadPlugin(file); + plugin = loadPlugin(file, finalPass); itr.remove(); } catch (UnknownDependencyException ex) { if(finalPass) { @@ -125,6 +125,7 @@ public final class SimplePluginManager implements PluginManager { if (plugin != null) { result.add(plugin); allFailed = false; + finalPass = false; } } if(finalPass) { @@ -148,6 +149,21 @@ public final class SimplePluginManager implements PluginManager { * @throws InvalidDescriptionException Thrown when the specified file contains an invalid description */ public synchronized Plugin loadPlugin(File file) throws InvalidPluginException, InvalidDescriptionException, UnknownDependencyException { + return loadPlugin(file, true); + } + + /** + * Loads the plugin in the specified file + * + * File must be valid according to the current enabled Plugin interfaces + * + * @param file File containing the plugin to load + * @param ignoreSoftDependencies Loader will ignore soft dependencies if this flag is set to true + * @return The Plugin loaded, or null if it was invalid + * @throws InvalidPluginException Thrown when the specified file is not a valid plugin + * @throws InvalidDescriptionException Thrown when the specified file contains an invalid description + */ + public synchronized Plugin loadPlugin(File file, boolean ignoreSoftDependencies) throws InvalidPluginException, InvalidDescriptionException, UnknownDependencyException { Set filters = fileAssociations.keySet(); Plugin result = null; @@ -157,7 +173,7 @@ public final class SimplePluginManager implements PluginManager { if (match.find()) { PluginLoader loader = fileAssociations.get(filter); - result = loader.loadPlugin(file); + result = loader.loadPlugin(file, ignoreSoftDependencies); } } diff --git a/paper-api/src/main/java/org/bukkit/plugin/UnknownSoftDependencyException.java b/paper-api/src/main/java/org/bukkit/plugin/UnknownSoftDependencyException.java new file mode 100644 index 0000000000..99fdb4fa4e --- /dev/null +++ b/paper-api/src/main/java/org/bukkit/plugin/UnknownSoftDependencyException.java @@ -0,0 +1,45 @@ +package org.bukkit.plugin; + +/** + * Thrown when attempting to load an invalid Plugin file + */ +public class UnknownSoftDependencyException extends UnknownDependencyException { + + private static final long serialVersionUID = 5721389371901775899L; + + /** + * Constructs a new UnknownSoftDependencyException based on the given Exception + * + * @param throwable Exception that triggered this Exception + */ + public UnknownSoftDependencyException(Throwable throwable) { + this(throwable, "Unknown soft dependency"); + } + + /** + * Constructs a new UnknownSoftDependencyException with the given message + * + * @param message Brief message explaining the cause of the exception + */ + public UnknownSoftDependencyException(final String message) { + this(null, message); + } + + /** + * Constructs a new UnknownSoftDependencyException based on the given Exception + * + * @param message Brief message explaining the cause of the exception + * @param throwable Exception that triggered this Exception + */ + public UnknownSoftDependencyException(final Throwable throwable, final String message) { + super(throwable, message); + } + + /** + * Constructs a new UnknownSoftDependencyException + */ + public UnknownSoftDependencyException() { + this(null, "Unknown dependency"); + } + +} diff --git a/paper-api/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/paper-api/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java index 013bc1d20d..6d9ba9c13e 100644 --- a/paper-api/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java +++ b/paper-api/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java @@ -45,6 +45,10 @@ public final class JavaPluginLoader implements PluginLoader { } public Plugin loadPlugin(File file) throws InvalidPluginException, InvalidDescriptionException, UnknownDependencyException { + return loadPlugin(file, false); + } + + public Plugin loadPlugin(File file, boolean ignoreSoftDependencies) throws InvalidPluginException, InvalidDescriptionException, UnknownDependencyException { JavaPlugin result = null; PluginDescriptionFile description = null; @@ -126,6 +130,28 @@ public final class JavaPluginLoader implements PluginLoader { } } + if (!ignoreSoftDependencies) { + ArrayList softDepend; + try { + softDepend = (ArrayList)description.getSoftDepend(); + if (softDepend == null) { + softDepend = new ArrayList(); + } + } catch (ClassCastException ex) { + throw new InvalidPluginException(ex); + } + + for (String pluginName : softDepend) { + if (loaders == null) { + throw new UnknownSoftDependencyException(pluginName); + } + PluginClassLoader current = loaders.get(pluginName); + if (current == null) { + throw new UnknownSoftDependencyException(pluginName); + } + } + } + PluginClassLoader loader = null; try { URL[] urls = new URL[1];