summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDinnerbone <dinnerbone@dinnerbone.com>2011-03-07 13:56:34 +0000
committerDinnerbone <dinnerbone@dinnerbone.com>2011-03-07 14:04:00 +0000
commit4879aee1b576addd69852bda06193ab7702f6006 (patch)
treec3f644f75387b61d2ee318c5751ec145feb46213 /src
parent34f8893a4b7a7ae8c319d1023a4649a06f5f7de6 (diff)
downloadbukkit-4879aee1b576addd69852bda06193ab7702f6006.tar
bukkit-4879aee1b576addd69852bda06193ab7702f6006.tar.gz
bukkit-4879aee1b576addd69852bda06193ab7702f6006.tar.lz
bukkit-4879aee1b576addd69852bda06193ab7702f6006.tar.xz
bukkit-4879aee1b576addd69852bda06193ab7702f6006.zip
Adds basic plugin dependencies, courtesy of Raphfrk
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/bukkit/fillr/Getter.java3
-rw-r--r--src/main/java/org/bukkit/fillr/Updater.java2
-rw-r--r--src/main/java/org/bukkit/plugin/PluginDescriptionFile.java15
-rw-r--r--src/main/java/org/bukkit/plugin/PluginLoader.java2
-rw-r--r--src/main/java/org/bukkit/plugin/PluginManager.java2
-rw-r--r--src/main/java/org/bukkit/plugin/SimplePluginManager.java53
-rw-r--r--src/main/java/org/bukkit/plugin/UnknownDependencyException.java63
-rw-r--r--src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java45
-rw-r--r--src/main/java/org/bukkit/plugin/java/PluginClassLoader.java20
9 files changed, 182 insertions, 23 deletions
diff --git a/src/main/java/org/bukkit/fillr/Getter.java b/src/main/java/org/bukkit/fillr/Getter.java
index 8a054189..55d65ded 100644
--- a/src/main/java/org/bukkit/fillr/Getter.java
+++ b/src/main/java/org/bukkit/fillr/Getter.java
@@ -8,6 +8,7 @@ import org.bukkit.*;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.InvalidDescriptionException;
import org.bukkit.plugin.InvalidPluginException;
+import org.bukkit.plugin.UnknownDependencyException;
public class Getter {
private Server server;
@@ -40,6 +41,8 @@ public class Getter {
File plugin = new File(DIRECTORY, name + ".jar");
try {
server.getPluginManager().loadPlugin(plugin);
+ } catch (UnknownDependencyException ex) {
+ server.getLogger().log(Level.SEVERE, null, ex);
} catch (InvalidPluginException ex) {
server.getLogger().log(Level.SEVERE, null, ex);
} catch (InvalidDescriptionException ex) {
diff --git a/src/main/java/org/bukkit/fillr/Updater.java b/src/main/java/org/bukkit/fillr/Updater.java
index 5479fbd5..e4ce9189 100644
--- a/src/main/java/org/bukkit/fillr/Updater.java
+++ b/src/main/java/org/bukkit/fillr/Updater.java
@@ -98,6 +98,8 @@ public class Updater {
File plugin = new File(DIRECTORY, name + ".jar");
try {
server.getPluginManager().loadPlugin(plugin);
+ } catch (UnknownDependencyException ex) {
+ server.getLogger().log(Level.SEVERE, null, ex);
} catch (InvalidPluginException ex) {
server.getLogger().log(Level.SEVERE, null, ex);
} catch (InvalidDescriptionException ex) {
diff --git a/src/main/java/org/bukkit/plugin/PluginDescriptionFile.java b/src/main/java/org/bukkit/plugin/PluginDescriptionFile.java
index 46aee5a3..c0ed5952 100644
--- a/src/main/java/org/bukkit/plugin/PluginDescriptionFile.java
+++ b/src/main/java/org/bukkit/plugin/PluginDescriptionFile.java
@@ -7,6 +7,7 @@ import java.io.Writer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Map;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.SafeConstructor;
@@ -18,6 +19,7 @@ public final class PluginDescriptionFile {
private static final Yaml yaml = new Yaml(new SafeConstructor());
private String name = null;
private String main = null;
+ private ArrayList<String> depend = null;
private String version = null;
private Object commands = null;
private String description = null;
@@ -99,6 +101,10 @@ public final class PluginDescriptionFile {
return commands;
}
+ public Object getDepend() {
+ return depend;
+ }
+
/**
* Gets the description of this plugin
*
@@ -149,6 +155,14 @@ public final class PluginDescriptionFile {
}
}
+ if (map.containsKey("depend")) {
+ try {
+ depend = (ArrayList<String>)map.get("depend");
+ } catch (ClassCastException ex) {
+ throw new InvalidDescriptionException(ex, "depend is of wrong type");
+ }
+ }
+
if (map.containsKey("website")) {
try {
website = (String)map.get("website");
@@ -191,6 +205,7 @@ public final class PluginDescriptionFile {
map.put("version", version);
if (commands != null) map.put("command", commands);
+ if (depend != null) map.put("depend", depend);
if (website != null) map.put("website", website);
if (description != null) map.put("description", description);
diff --git a/src/main/java/org/bukkit/plugin/PluginLoader.java b/src/main/java/org/bukkit/plugin/PluginLoader.java
index eaf6c066..245c850f 100644
--- a/src/main/java/org/bukkit/plugin/PluginLoader.java
+++ b/src/main/java/org/bukkit/plugin/PluginLoader.java
@@ -20,7 +20,7 @@ public interface PluginLoader {
* unsuccessful
* @throws InvalidPluginException Thrown when the specified file is not a plugin
*/
- public Plugin loadPlugin(File file) throws InvalidPluginException, InvalidDescriptionException;
+ public Plugin loadPlugin(File file) throws InvalidPluginException, InvalidDescriptionException, UnknownDependencyException;
/**
* Returns a list of all filename filters expected by this PluginLoader
diff --git a/src/main/java/org/bukkit/plugin/PluginManager.java b/src/main/java/org/bukkit/plugin/PluginManager.java
index e89351a0..18e8916e 100644
--- a/src/main/java/org/bukkit/plugin/PluginManager.java
+++ b/src/main/java/org/bukkit/plugin/PluginManager.java
@@ -65,7 +65,7 @@ public interface PluginManager {
* @throws InvalidPluginException Thrown when the specified file is not a valid plugin
* @throws InvalidDescriptionException Thrown when the specified file contains an invalid description
*/
- public Plugin loadPlugin(File file) throws InvalidPluginException, InvalidDescriptionException;
+ public Plugin loadPlugin(File file) throws InvalidPluginException, InvalidDescriptionException, UnknownDependencyException;
/**
* Loads the plugins contained within the specified directory
diff --git a/src/main/java/org/bukkit/plugin/SimplePluginManager.java b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
index 693e2eb1..4bb73957 100644
--- a/src/main/java/org/bukkit/plugin/SimplePluginManager.java
+++ b/src/main/java/org/bukkit/plugin/SimplePluginManager.java
@@ -12,6 +12,9 @@ import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
@@ -88,19 +91,45 @@ public final class SimplePluginManager implements PluginManager {
List<Plugin> result = new ArrayList<Plugin>();
File[] files = directory.listFiles();
- for (File file : files) {
- Plugin plugin = null;
+ boolean allFailed = false;
+ boolean finalPass = false;
- try {
- plugin = loadPlugin(file);
- } catch (InvalidPluginException ex) {
- server.getLogger().log(Level.SEVERE, "Could not load " + file.getPath() + " in " + directory.getPath() + ": " + ex.getMessage(), ex);
- } catch (InvalidDescriptionException ex) {
- server.getLogger().log(Level.SEVERE, "Could not load " + file.getPath() + " in " + directory.getPath() + ": " + ex.getMessage(), ex);
- }
+ LinkedList<File> filesList = new LinkedList(Arrays.asList(files));
+
+ while(!allFailed || finalPass) {
+ allFailed = true;
+ Iterator<File> itr = filesList.iterator();
+ while(itr.hasNext()) {
+ File file = itr.next();
+ Plugin plugin = null;
+
+ try {
+ plugin = loadPlugin(file);
+ itr.remove();
+ } catch (UnknownDependencyException ex) {
+ if(finalPass) {
+ server.getLogger().log(Level.SEVERE, "Could not load " + file.getPath() + " in " + directory.getPath() + ": " + ex.getMessage(), ex);
+ itr.remove();
+ } else {
+ plugin = null;
+ }
+ } catch (InvalidPluginException ex) {
+ server.getLogger().log(Level.SEVERE, "Could not load " + file.getPath() + " in " + directory.getPath() + ": " + ex.getMessage(), ex);
+ itr.remove();
+ } catch (InvalidDescriptionException ex) {
+ server.getLogger().log(Level.SEVERE, "Could not load " + file.getPath() + " in " + directory.getPath() + ": " + ex.getMessage(), ex);
+ itr.remove();
+ }
- if (plugin != null) {
- result.add(plugin);
+ if (plugin != null) {
+ result.add(plugin);
+ allFailed = false;
+ }
+ }
+ if(finalPass) {
+ break;
+ } else if(allFailed) {
+ finalPass = true;
}
}
@@ -117,7 +146,7 @@ public final class SimplePluginManager implements PluginManager {
* @throws InvalidPluginException Thrown when the specified file is not a valid plugin
* @throws InvalidDescriptionException Thrown when the specified file contains an invalid description
*/
- public Plugin loadPlugin(File file) throws InvalidPluginException, InvalidDescriptionException {
+ public Plugin loadPlugin(File file) throws InvalidPluginException, InvalidDescriptionException, UnknownDependencyException {
Set<Pattern> filters = fileAssociations.keySet();
Plugin result = null;
diff --git a/src/main/java/org/bukkit/plugin/UnknownDependencyException.java b/src/main/java/org/bukkit/plugin/UnknownDependencyException.java
new file mode 100644
index 00000000..dc5da651
--- /dev/null
+++ b/src/main/java/org/bukkit/plugin/UnknownDependencyException.java
@@ -0,0 +1,63 @@
+
+package org.bukkit.plugin;
+
+/**
+ * Thrown when attempting to load an invalid Plugin file
+ */
+public class UnknownDependencyException extends Exception {
+
+ private static final long serialVersionUID = 5721389371901775894L;
+ private final Throwable cause;
+ private final String message;
+
+ /**
+ * Constructs a new UnknownDependencyException based on the given Exception
+ *
+ * @param throwable Exception that triggered this Exception
+ */
+ public UnknownDependencyException(Throwable throwable) {
+ this(throwable, "Unknown dependency");
+ }
+
+ /**
+ * Constructs a new UnknownDependencyException with the given message
+ *
+ * @param message Brief message explaining the cause of the exception
+ */
+ public UnknownDependencyException(final String message) {
+ this(null, message);
+ }
+
+ /**
+ * Constructs a new UnknownDependencyException based on the given Exception
+ *
+ * @param message Brief message explaining the cause of the exception
+ * @param throwable Exception that triggered this Exception
+ */
+ public UnknownDependencyException(final Throwable throwable, final String message) {
+ this.cause = null;
+ this.message = message;
+ }
+
+ /**
+ * Constructs a new UnknownDependencyException
+ */
+ public UnknownDependencyException() {
+ this(null, "Unknown dependency");
+ }
+
+ /**
+ * If applicable, returns the Exception that triggered this Exception
+ *
+ * @return Inner exception, or null if one does not exist
+ */
+ @Override
+ public Throwable getCause() {
+ return cause;
+ }
+
+ @Override
+ public String getMessage() {
+ return message;
+ }
+}
diff --git a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
index 18fdfa90..2ab3e09f 100644
--- a/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
+++ b/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
@@ -9,6 +9,9 @@ import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.ArrayList;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.regex.Pattern;
@@ -36,12 +39,13 @@ public final class JavaPluginLoader implements PluginLoader {
Pattern.compile("\\.jar$"),
};
private final Map<String, Class<?>> classes = new HashMap<String, Class<?>>();
+ private final Map<String, File> files = new HashMap<String, File>();
public JavaPluginLoader(Server instance) {
server = instance;
}
- public Plugin loadPlugin(File file) throws InvalidPluginException, InvalidDescriptionException {
+ public Plugin loadPlugin(File file) throws InvalidPluginException, InvalidDescriptionException, UnknownDependencyException {
JavaPlugin result = null;
PluginDescriptionFile description = null;
@@ -67,8 +71,37 @@ public final class JavaPluginLoader implements PluginLoader {
File dataFolder = getDataFolder(file);
+ ArrayList<String> depend;
+ try {
+ depend = (ArrayList)description.getDepend();
+ if(depend == null) {
+ depend = new ArrayList<String>();
+ }
+ } catch (ClassCastException ex) {
+ throw new InvalidPluginException(ex);
+ }
+
+ ArrayList<File> dependFiles = new ArrayList<File>();
+
+ for(String pluginName : depend) {
+ if(files == null) {
+ throw new UnknownDependencyException(pluginName);
+ }
+ File current = files.get(pluginName);
+ if(current == null) {
+ throw new UnknownDependencyException(pluginName);
+ }
+ dependFiles.add(current);
+ }
+
try {
- ClassLoader loader = new PluginClassLoader(this, new URL[]{file.toURI().toURL()}, getClass().getClassLoader());
+ URL[] urls = new URL[dependFiles.size() + 1];
+ urls[0] = file.toURI().toURL();
+ int cnt = 1;
+ for(File f : dependFiles) {
+ urls[cnt++] = f.toURI().toURL();
+ }
+ ClassLoader loader = new PluginClassLoader(this, urls, getClass().getClassLoader());
Class<?> jarClass = Class.forName(description.getMain(), true, loader);
Class<? extends JavaPlugin> plugin = jarClass.asSubclass(JavaPlugin.class);
@@ -80,6 +113,8 @@ public final class JavaPluginLoader implements PluginLoader {
throw new InvalidPluginException(ex);
}
+ files.put(description.getName(), file);
+
return (Plugin)result;
}
@@ -112,7 +147,9 @@ public final class JavaPluginLoader implements PluginLoader {
}
public void setClass(final String name, final Class<?> clazz) {
- classes.put(name, clazz);
+ if(!classes.containsKey(name)) {
+ classes.put(name, clazz);
+ }
}
public EventExecutor createExecutor( Event.Type type, Listener listener ) {
@@ -429,6 +466,8 @@ public final class JavaPluginLoader implements PluginLoader {
server.getPluginManager().callEvent(new PluginEvent(Event.Type.PLUGIN_DISABLE, plugin));
+ files.remove(jPlugin.getDescription().getName());
+
if (cloader instanceof PluginClassLoader) {
PluginClassLoader loader = (PluginClassLoader)cloader;
Set<String> names = loader.getClasses();
diff --git a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java
index d17e0f4f..bc6cb0a2 100644
--- a/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java
+++ b/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java
@@ -24,17 +24,25 @@ public class PluginClassLoader extends URLClassLoader {
Class<?> result = classes.get(name);
if (result == null) {
- result = loader.getClassByName(name);
+ ClassNotFoundException ex = null;
- if (result == null) {
+ try {
result = super.findClass(name);
+ } catch (ClassNotFoundException e) {
+ ex = e;
+ }
- if (result != null) {
- loader.setClass(name, result);
- }
+ if (result != null) {
+ loader.setClass(name, result);
+ } else {
+ result = loader.getClassByName(name);
}
- classes.put(name, result);
+ if (result != null ) {
+ classes.put(name, result);
+ } else {
+ throw ex;
+ }
}
return result;