13
0
geforkt von Mirrors/Paper

Adds basic plugin dependencies, courtesy of Raphfrk

By: Dinnerbone <dinnerbone@dinnerbone.com>
Dieser Commit ist enthalten in:
Bukkit/Spigot 2011-03-07 13:56:34 +00:00
Ursprung f370268047
Commit 6dc6946312
9 geänderte Dateien mit 183 neuen und 24 gelöschten Zeilen

Datei anzeigen

@ -8,6 +8,7 @@ import org.bukkit.*;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.plugin.InvalidDescriptionException; import org.bukkit.plugin.InvalidDescriptionException;
import org.bukkit.plugin.InvalidPluginException; import org.bukkit.plugin.InvalidPluginException;
import org.bukkit.plugin.UnknownDependencyException;
public class Getter { public class Getter {
private Server server; private Server server;
@ -40,6 +41,8 @@ public class Getter {
File plugin = new File(DIRECTORY, name + ".jar"); File plugin = new File(DIRECTORY, name + ".jar");
try { try {
server.getPluginManager().loadPlugin(plugin); server.getPluginManager().loadPlugin(plugin);
} catch (UnknownDependencyException ex) {
server.getLogger().log(Level.SEVERE, null, ex);
} catch (InvalidPluginException ex) { } catch (InvalidPluginException ex) {
server.getLogger().log(Level.SEVERE, null, ex); server.getLogger().log(Level.SEVERE, null, ex);
} catch (InvalidDescriptionException ex) { } catch (InvalidDescriptionException ex) {

Datei anzeigen

@ -98,6 +98,8 @@ public class Updater {
File plugin = new File(DIRECTORY, name + ".jar"); File plugin = new File(DIRECTORY, name + ".jar");
try { try {
server.getPluginManager().loadPlugin(plugin); server.getPluginManager().loadPlugin(plugin);
} catch (UnknownDependencyException ex) {
server.getLogger().log(Level.SEVERE, null, ex);
} catch (InvalidPluginException ex) { } catch (InvalidPluginException ex) {
server.getLogger().log(Level.SEVERE, null, ex); server.getLogger().log(Level.SEVERE, null, ex);
} catch (InvalidDescriptionException ex) { } catch (InvalidDescriptionException ex) {

Datei anzeigen

@ -7,6 +7,7 @@ import java.io.Writer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.SafeConstructor; import org.yaml.snakeyaml.constructor.SafeConstructor;
@ -18,6 +19,7 @@ public final class PluginDescriptionFile {
private static final Yaml yaml = new Yaml(new SafeConstructor()); private static final Yaml yaml = new Yaml(new SafeConstructor());
private String name = null; private String name = null;
private String main = null; private String main = null;
private ArrayList<String> depend = null;
private String version = null; private String version = null;
private Object commands = null; private Object commands = null;
private String description = null; private String description = null;
@ -99,6 +101,10 @@ public final class PluginDescriptionFile {
return commands; return commands;
} }
public Object getDepend() {
return depend;
}
/** /**
* Gets the description of this plugin * 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")) { if (map.containsKey("website")) {
try { try {
website = (String)map.get("website"); website = (String)map.get("website");
@ -191,6 +205,7 @@ public final class PluginDescriptionFile {
map.put("version", version); map.put("version", version);
if (commands != null) map.put("command", commands); if (commands != null) map.put("command", commands);
if (depend != null) map.put("depend", depend);
if (website != null) map.put("website", website); if (website != null) map.put("website", website);
if (description != null) map.put("description", description); if (description != null) map.put("description", description);

Datei anzeigen

@ -20,7 +20,7 @@ public interface PluginLoader {
* unsuccessful * unsuccessful
* @throws InvalidPluginException Thrown when the specified file is not a plugin * @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 * Returns a list of all filename filters expected by this PluginLoader

Datei anzeigen

@ -65,7 +65,7 @@ public interface PluginManager {
* @throws InvalidPluginException Thrown when the specified file is not a valid plugin * @throws InvalidPluginException Thrown when the specified file is not a valid plugin
* @throws InvalidDescriptionException Thrown when the specified file contains an invalid description * @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 * Loads the plugins contained within the specified directory

Datei anzeigen

@ -12,6 +12,9 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.TreeSet; 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.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.regex.Matcher; import java.util.regex.Matcher;
@ -88,19 +91,45 @@ public final class SimplePluginManager implements PluginManager {
List<Plugin> result = new ArrayList<Plugin>(); List<Plugin> result = new ArrayList<Plugin>();
File[] files = directory.listFiles(); File[] files = directory.listFiles();
for (File file : files) { boolean allFailed = false;
boolean finalPass = false;
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; Plugin plugin = null;
try { try {
plugin = loadPlugin(file); 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) { } catch (InvalidPluginException ex) {
server.getLogger().log(Level.SEVERE, "Could not load " + file.getPath() + " in " + directory.getPath() + ": " + ex.getMessage(), ex); server.getLogger().log(Level.SEVERE, "Could not load " + file.getPath() + " in " + directory.getPath() + ": " + ex.getMessage(), ex);
itr.remove();
} catch (InvalidDescriptionException ex) { } catch (InvalidDescriptionException ex) {
server.getLogger().log(Level.SEVERE, "Could not load " + file.getPath() + " in " + directory.getPath() + ": " + ex.getMessage(), ex); server.getLogger().log(Level.SEVERE, "Could not load " + file.getPath() + " in " + directory.getPath() + ": " + ex.getMessage(), ex);
itr.remove();
} }
if (plugin != null) { if (plugin != null) {
result.add(plugin); 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 InvalidPluginException Thrown when the specified file is not a valid plugin
* @throws InvalidDescriptionException Thrown when the specified file contains an invalid description * @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(); Set<Pattern> filters = fileAssociations.keySet();
Plugin result = null; Plugin result = null;

Datei anzeigen

@ -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;
}
}

Datei anzeigen

@ -9,6 +9,9 @@ import java.net.URL;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; 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.JarEntry;
import java.util.jar.JarFile; import java.util.jar.JarFile;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -36,12 +39,13 @@ public final class JavaPluginLoader implements PluginLoader {
Pattern.compile("\\.jar$"), Pattern.compile("\\.jar$"),
}; };
private final Map<String, Class<?>> classes = new HashMap<String, Class<?>>(); private final Map<String, Class<?>> classes = new HashMap<String, Class<?>>();
private final Map<String, File> files = new HashMap<String, File>();
public JavaPluginLoader(Server instance) { public JavaPluginLoader(Server instance) {
server = instance; server = instance;
} }
public Plugin loadPlugin(File file) throws InvalidPluginException, InvalidDescriptionException { public Plugin loadPlugin(File file) throws InvalidPluginException, InvalidDescriptionException, UnknownDependencyException {
JavaPlugin result = null; JavaPlugin result = null;
PluginDescriptionFile description = null; PluginDescriptionFile description = null;
@ -67,8 +71,37 @@ public final class JavaPluginLoader implements PluginLoader {
File dataFolder = getDataFolder(file); File dataFolder = getDataFolder(file);
ArrayList<String> depend;
try { try {
ClassLoader loader = new PluginClassLoader(this, new URL[]{file.toURI().toURL()}, getClass().getClassLoader()); 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 {
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<?> jarClass = Class.forName(description.getMain(), true, loader);
Class<? extends JavaPlugin> plugin = jarClass.asSubclass(JavaPlugin.class); Class<? extends JavaPlugin> plugin = jarClass.asSubclass(JavaPlugin.class);
@ -80,6 +113,8 @@ public final class JavaPluginLoader implements PluginLoader {
throw new InvalidPluginException(ex); throw new InvalidPluginException(ex);
} }
files.put(description.getName(), file);
return (Plugin)result; return (Plugin)result;
} }
@ -112,8 +147,10 @@ public final class JavaPluginLoader implements PluginLoader {
} }
public void setClass(final String name, final Class<?> clazz) { public void setClass(final String name, final Class<?> clazz) {
if(!classes.containsKey(name)) {
classes.put(name, clazz); classes.put(name, clazz);
} }
}
public EventExecutor createExecutor( Event.Type type, Listener listener ) { public EventExecutor createExecutor( Event.Type type, Listener listener ) {
// TODO: remove multiple Listener type and hence casts // TODO: remove multiple Listener type and hence casts
@ -429,6 +466,8 @@ public final class JavaPluginLoader implements PluginLoader {
server.getPluginManager().callEvent(new PluginEvent(Event.Type.PLUGIN_DISABLE, plugin)); server.getPluginManager().callEvent(new PluginEvent(Event.Type.PLUGIN_DISABLE, plugin));
files.remove(jPlugin.getDescription().getName());
if (cloader instanceof PluginClassLoader) { if (cloader instanceof PluginClassLoader) {
PluginClassLoader loader = (PluginClassLoader)cloader; PluginClassLoader loader = (PluginClassLoader)cloader;
Set<String> names = loader.getClasses(); Set<String> names = loader.getClasses();

Datei anzeigen

@ -24,17 +24,25 @@ public class PluginClassLoader extends URLClassLoader {
Class<?> result = classes.get(name); Class<?> result = classes.get(name);
if (result == null) { if (result == null) {
result = loader.getClassByName(name); ClassNotFoundException ex = null;
if (result == null) { try {
result = super.findClass(name); result = super.findClass(name);
} catch (ClassNotFoundException e) {
ex = e;
}
if (result != null) { if (result != null) {
loader.setClass(name, result); loader.setClass(name, result);
} } else {
result = loader.getClassByName(name);
} }
if (result != null ) {
classes.put(name, result); classes.put(name, result);
} else {
throw ex;
}
} }
return result; return result;