summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEvilSeph <evilseph@gmail.com>2012-01-25 04:11:37 -0500
committerEvilSeph <evilseph@gmail.com>2012-01-25 04:11:37 -0500
commitd7469ca79e0da1e75bbb6fdfa631b6f17df1b3ac (patch)
treed0c9ece32e69e085e17450b66a60fd7b7a6d8577 /src
parenta31f506e257890a5223bc76d464080922d93d27c (diff)
downloadbukkit-d7469ca79e0da1e75bbb6fdfa631b6f17df1b3ac.tar
bukkit-d7469ca79e0da1e75bbb6fdfa631b6f17df1b3ac.tar.gz
bukkit-d7469ca79e0da1e75bbb6fdfa631b6f17df1b3ac.tar.lz
bukkit-d7469ca79e0da1e75bbb6fdfa631b6f17df1b3ac.tar.xz
bukkit-d7469ca79e0da1e75bbb6fdfa631b6f17df1b3ac.zip
Fixed plugin loader. Thanks Wolvereness!
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/bukkit/plugin/PluginLoader.java12
-rw-r--r--src/main/java/org/bukkit/plugin/SimplePluginManager.java242
-rw-r--r--src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java96
3 files changed, 243 insertions, 107 deletions
diff --git a/src/main/java/org/bukkit/plugin/PluginLoader.java b/src/main/java/org/bukkit/plugin/PluginLoader.java
index 2a9dc10f..141311ab 100644
--- a/src/main/java/org/bukkit/plugin/PluginLoader.java
+++ b/src/main/java/org/bukkit/plugin/PluginLoader.java
@@ -29,6 +29,7 @@ public interface PluginLoader {
/**
* Loads the plugin contained in the specified file
*
+ * @deprecated SoftDependencies are always ignored
* @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
@@ -37,9 +38,20 @@ public interface PluginLoader {
* @throws InvalidDescriptionException If the plugin description file was invalid
* @throws UnknownDependencyException If a required dependency could not be found
*/
+ @Deprecated
public Plugin loadPlugin(File file, boolean ignoreSoftDependencies) throws InvalidPluginException, InvalidDescriptionException, UnknownDependencyException;
/**
+ * Loads a PluginDescriptionFile from the specified file
+ *
+ * @param file File to attempt to load from
+ * @return A new PluginDescriptionFile loaded from the plugin.yml in the specified file
+ * @throws InvalidPluginException If when the specified file does not contain a plugin description file
+ * @throws InvalidDescriptionException If the plugin description file could not be created
+ */
+ public PluginDescriptionFile getPluginDescription(File file) throws InvalidPluginException, InvalidDescriptionException;
+
+ /**
* Returns a list of all filename filters expected by this PluginLoader
*
* @return The filters
diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
index b6fbe2eb..cc99bf83 100644
--- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java
+++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
@@ -8,6 +8,7 @@ import java.util.*;
import java.util.logging.Level;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.apache.commons.lang.Validate;
import org.bukkit.Server;
import org.bukkit.command.Command;
import org.bukkit.command.PluginCommandYamlParser;
@@ -85,54 +86,170 @@ public final class SimplePluginManager implements PluginManager {
* @return A list of all plugins loaded
*/
public Plugin[] loadPlugins(File directory) {
- List<Plugin> result = new ArrayList<Plugin>();
- File[] files = directory.listFiles();
-
- boolean allFailed = false;
- boolean finalPass = false;
+ Validate.notNull(directory, "Directory cannot be null");
+ Validate.isTrue(directory.isDirectory(), "Directory must be a directory");
- LinkedList<File> filesList = new LinkedList<File>(Arrays.asList(files));
+ List<Plugin> result = new ArrayList<Plugin>();
+ Set<Pattern> filters = fileAssociations.keySet();
if (!(server.getUpdateFolder().equals(""))) {
updateDirectory = new File(directory, server.getUpdateFolder());
}
- while (!allFailed || finalPass) {
- allFailed = true;
- Iterator<File> itr = filesList.iterator();
+ Map<String, File> plugins = new HashMap<String, File>();
+ Set<String> loadedPlugins = new HashSet<String>();
+ Map<String, Collection<String>> dependencies = new HashMap<String, Collection<String>>();
+ Map<String, Collection<String>> softDependencies = new HashMap<String, Collection<String>>();
- while (itr.hasNext()) {
- File file = itr.next();
- Plugin plugin = null;
+ // This is where it figures out all possible plugins
+ for (File file : directory.listFiles()) {
+ PluginLoader loader = null;
+ for (Pattern filter : filters) {
+ Matcher match = filter.matcher(file.getName());
+ if (match.find()) {
+ loader = fileAssociations.get(filter);
+ }
+ }
- try {
- plugin = loadPlugin(file, finalPass);
- } catch (UnknownDependencyException ex) {
- if (finalPass) {
- server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + directory.getPath() + "': " + ex.getMessage(), ex);
- itr.remove();
- } else {
- plugin = null;
+ if (loader == null) continue;
+
+ PluginDescriptionFile description = null;
+ try {
+ description = loader.getPluginDescription(file);
+ } catch (InvalidPluginException ex) {
+ server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + directory.getPath() + "': " + ex.getMessage(), ex);
+ continue;
+ } catch (InvalidDescriptionException ex) {
+ server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + directory.getPath() + "': " + ex.getMessage(), ex);
+ continue;
+ }
+
+ plugins.put(description.getName(), file);
+
+ Collection<? extends String> softDependencySet = (Collection<? extends String>) description.getSoftDepend();
+ if (softDependencySet != null) {
+ softDependencies.put(description.getName(), new LinkedList<String>(softDependencySet));
+ }
+
+ Collection<? extends String> dependencySet = (Collection<? extends String>) description.getDepend();
+ if (dependencySet != null) {
+ dependencies.put(description.getName(), new LinkedList<String>(dependencySet));
+ }
+ }
+
+ while (!plugins.isEmpty()) {
+ boolean missingDependency = true;
+ Iterator<String> pluginIterator = plugins.keySet().iterator();
+
+ while (pluginIterator.hasNext()) {
+ String plugin = pluginIterator.next();
+
+ if (dependencies.containsKey(plugin)) {
+ Iterator<String> dependencyIterator = dependencies.get(plugin).iterator();
+
+ while (dependencyIterator.hasNext()) {
+ String dependency = dependencyIterator.next();
+
+ // Dependency loaded
+ if (loadedPlugins.contains(dependency)) {
+ dependencyIterator.remove();
+
+ // We have a dependency not found
+ } else if (!plugins.containsKey(dependency)) {
+ missingDependency = false;
+ File file = plugins.get(plugin);
+ pluginIterator.remove();
+ softDependencies.remove(plugin);
+ dependencies.remove(plugin);
+
+ server.getLogger().log(
+ Level.SEVERE,
+ "Could not load '" + file.getPath() + "' in folder '" + directory.getPath() + "': ",
+ new UnknownDependencyException(dependency));
+ break;
+ }
+ }
+
+ if (dependencies.containsKey(plugin) && dependencies.get(plugin).isEmpty()) {
+ dependencies.remove(plugin);
+ }
+ }
+ if (softDependencies.containsKey(plugin)) {
+ Iterator<String> softDependencyIterator = softDependencies.get(plugin).iterator();
+
+ while (softDependencyIterator.hasNext()) {
+ String softDependency = softDependencyIterator.next();
+
+ // Soft depend is no longer around
+ if (!plugins.containsKey(softDependency)) {
+ softDependencyIterator.remove();
+ }
+ }
+
+ if (softDependencies.get(plugin).isEmpty()) {
+ softDependencies.remove(plugin);
}
- } catch (InvalidPluginException ex) {
- server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + directory.getPath() + "': ", ex.getCause());
- itr.remove();
- } catch (InvalidDescriptionException ex) {
- server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + directory.getPath() + "': " + ex.getMessage(), ex);
- itr.remove();
}
+ if (!(dependencies.containsKey(plugin) || softDependencies.containsKey(plugin)) && plugins.containsKey(plugin)) {
+ // We're clear to load, no more soft or hard dependencies left
+ File file = plugins.get(plugin);
+ pluginIterator.remove();
+ missingDependency = false;
- if (plugin != null) {
- result.add(plugin);
- allFailed = false;
- finalPass = false;
- itr.remove();
+ try {
+ result.add(loadPlugin(file));
+ loadedPlugins.add(plugin);
+ continue;
+ } catch (InvalidPluginException ex) {
+ server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + directory.getPath() + "': ", ex.getCause());
+ } catch (InvalidDescriptionException ex) {
+ server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + directory.getPath() + "': " + ex.getMessage(), ex);
+ } catch (UnknownDependencyException ex) {
+ server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + directory.getPath() + "': " + ex.getMessage(), ex);
+ }
}
}
- if (finalPass) {
- break;
- } else if (allFailed) {
- finalPass = true;
+
+ if (missingDependency) {
+ // We now iterate over plugins until something loads
+ // This loop will ignore soft dependencies
+ pluginIterator = plugins.keySet().iterator();
+
+ while (pluginIterator.hasNext()) {
+ String plugin = pluginIterator.next();
+
+ if (!dependencies.containsKey(plugin)) {
+ softDependencies.remove(plugin);
+ dependencies.remove(plugin);
+ missingDependency = false;
+ File file = plugins.get(plugin);
+ pluginIterator.remove();
+
+ try {
+ result.add(loadPlugin(file));
+ loadedPlugins.add(plugin);
+ break;
+ } catch (InvalidPluginException ex) {
+ server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + directory.getPath() + "': ", ex.getCause());
+ } catch (InvalidDescriptionException ex) {
+ server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + directory.getPath() + "': " + ex.getMessage(), ex);
+ } catch (UnknownDependencyException ex) {
+ server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + directory.getPath() + "': " + ex.getMessage(), ex);
+ }
+ }
+ }
+ // We have no plugins left without a depend
+ if (missingDependency) {
+ softDependencies.clear();
+ dependencies.clear();
+ Iterator<File> failedPluginIterator = plugins.values().iterator();
+
+ while (failedPluginIterator.hasNext()) {
+ File file = failedPluginIterator.next();
+ failedPluginIterator.remove();
+ server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + directory.getPath() + "': circular dependency detected");
+ }
+ }
}
}
@@ -151,29 +268,9 @@ public final class SimplePluginManager implements PluginManager {
* @throws UnknownDependencyException If a required dependency could not be found
*/
public synchronized Plugin loadPlugin(File file) throws InvalidPluginException, InvalidDescriptionException, UnknownDependencyException {
- return loadPlugin(file, true);
- }
+ Validate.notNull(file, "File cannot be null");
- /**
- * Loads the plugin in the specified file
- * <p />
- * 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
- * @throws UnknownDependencyException If a required dependency could not be found
- */
- public synchronized Plugin loadPlugin(File file, boolean ignoreSoftDependencies) throws InvalidPluginException, InvalidDescriptionException, UnknownDependencyException {
- File updateFile = null;
-
- if (updateDirectory != null && updateDirectory.isDirectory() && (updateFile = new File(updateDirectory, file.getName())).isFile()) {
- if (FileUtil.copy(updateFile, file)) {
- updateFile.delete();
- }
- }
+ checkUpdate(file);
Set<Pattern> filters = fileAssociations.keySet();
Plugin result = null;
@@ -185,7 +282,7 @@ public final class SimplePluginManager implements PluginManager {
if (match.find()) {
PluginLoader loader = fileAssociations.get(filter);
- result = loader.loadPlugin(file, ignoreSoftDependencies);
+ result = loader.loadPlugin(file);
}
}
@@ -197,6 +294,35 @@ public final class SimplePluginManager implements PluginManager {
return result;
}
+ private void checkUpdate(File file) {
+ if (updateDirectory == null || !updateDirectory.isDirectory()) {
+ return;
+ }
+
+ File updateFile = new File(updateDirectory, file.getName());
+ if (updateFile.isFile() && FileUtil.copy(updateFile, file)) {
+ updateFile.delete();
+ }
+ }
+
+ /**
+ * Loads the plugin in the specified file
+ * <p />
+ * File must be valid according to the current enabled Plugin interfaces
+ *
+ * @deprecated soft-dependencies are now ignored
+ * @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
+ * @throws UnknownDependencyException If a required dependency could not be found
+ */
+ @Deprecated
+ public synchronized Plugin loadPlugin(File file, boolean ignoreSoftDependencies) throws InvalidPluginException, InvalidDescriptionException, UnknownDependencyException {
+ return loadPlugin(file);
+ }
+
/**
* Checks if the given plugin is loaded and returns it when applicable
* <p />
diff --git a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
index 2099fbda..4fb8e31a 100644
--- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
+++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
@@ -13,6 +13,8 @@ import java.util.jar.JarFile;
import java.util.logging.Level;
import java.util.regex.Pattern;
+import org.apache.commons.lang.Validate;
+
import org.bukkit.Bukkit;
import org.bukkit.Server;
@@ -45,36 +47,13 @@ public class JavaPluginLoader implements PluginLoader {
}
public Plugin loadPlugin(File file) throws InvalidPluginException, InvalidDescriptionException, UnknownDependencyException {
- return loadPlugin(file, false);
- }
-
- @SuppressWarnings("unchecked")
- public Plugin loadPlugin(File file, boolean ignoreSoftDependencies) throws InvalidPluginException, InvalidDescriptionException, UnknownDependencyException {
- JavaPlugin result = null;
- PluginDescriptionFile description = null;
+ Validate.notNull(file, "File cannot be null");
if (!file.exists()) {
throw new InvalidPluginException(new FileNotFoundException(String.format("%s does not exist", file.getPath())));
}
- try {
- JarFile jar = new JarFile(file);
- JarEntry entry = jar.getJarEntry("plugin.yml");
- if (entry == null) {
- throw new InvalidPluginException(new FileNotFoundException("Jar does not contain plugin.yml"));
- }
-
- InputStream stream = jar.getInputStream(entry);
-
- description = new PluginDescriptionFile(stream);
-
- stream.close();
- jar.close();
- } catch (IOException ex) {
- throw new InvalidPluginException(ex);
- } catch (YAMLException ex) {
- throw new InvalidPluginException(ex);
- }
+ PluginDescriptionFile description = getPluginDescription(file);
File dataFolder = new File(file.getParentFile(), description.getName());
File oldDataFolder = getDataFolder(file);
@@ -134,31 +113,8 @@ public class JavaPluginLoader implements PluginLoader {
}
}
- if (!ignoreSoftDependencies) {
- ArrayList<String> softDepend;
-
- try {
- softDepend = (ArrayList<String>) description.getSoftDepend();
- if (softDepend == null) {
- softDepend = new ArrayList<String>();
- }
- } 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;
+ JavaPlugin result = null;
try {
URL[] urls = new URL[1];
@@ -189,6 +145,10 @@ public class JavaPluginLoader implements PluginLoader {
return result;
}
+ public Plugin loadPlugin(File file, boolean ignoreSoftDependencies) throws InvalidPluginException, InvalidDescriptionException, UnknownDependencyException {
+ return loadPlugin(file);
+ }
+
protected File getDataFolder(File file) {
File dataFolder = null;
@@ -209,6 +169,44 @@ public class JavaPluginLoader implements PluginLoader {
return dataFolder;
}
+ public PluginDescriptionFile getPluginDescription(File file) throws InvalidDescriptionException, InvalidPluginException {
+ Validate.notNull(file, "File cannot be null");
+
+ JarFile jar = null;
+ InputStream stream = null;
+
+ try {
+ jar = new JarFile(file);
+ JarEntry entry = jar.getJarEntry("plugin.yml");
+
+ if (entry == null) {
+ throw new InvalidPluginException(new FileNotFoundException("Jar does not contain plugin.yml"));
+ }
+
+ stream = jar.getInputStream(entry);
+
+ return new PluginDescriptionFile(stream);
+
+ } catch (IOException ex) {
+ throw new InvalidPluginException(ex);
+ } catch (YAMLException ex) {
+ throw new InvalidDescriptionException(ex);
+ } finally {
+ if (jar != null) {
+ try {
+ jar.close();
+ } catch (IOException e) {
+ }
+ }
+ if (stream != null) {
+ try {
+ stream.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+ }
+
public Pattern[] getPluginFileFilters() {
return fileFilters;
}