From 76051f6454bf09150841895616e6f1bc44b398c2 Mon Sep 17 00:00:00 2001 From: James Fitzpatrick Date: Sun, 1 Sep 2013 10:01:22 +0100 Subject: [PATCH 01/10] index on master: 563ad62 Shade JNBT into jar at runtime From d226ee4e68a2124cb0f22e3a512c0b8a72ebd2ba Mon Sep 17 00:00:00 2001 From: James Fitzpatrick Date: Sun, 1 Sep 2013 10:04:17 +0100 Subject: [PATCH 02/10] Update .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index c444a6d..3f40015 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,5 @@ target/ *.class *.jar /bFundamentals/dependency-reduced-pom.xml +/bItems +/bEntityEdit From c400c5a58c219ad9049f8a06e0c81d82fe7104db Mon Sep 17 00:00:00 2001 From: James Fitzpatrick Date: Mon, 2 Sep 2013 17:00:32 +0100 Subject: [PATCH 03/10] Add support for setting module information via a annotation. --- bFundamentals/pom.xml | 1 + .../module/ModuleDescription.java | 13 +- .../module/annotation/ModuleInfo.java | 22 +++ .../module/loader/ClassFinder.java | 25 +++ .../module/loader/ModuleClassFinder.java | 18 -- .../module/loader/ModuleLoader.java | 162 +++++++++--------- 6 files changed, 145 insertions(+), 96 deletions(-) create mode 100644 bFundamentals/src/uk/codingbadgers/bFundamentals/module/annotation/ModuleInfo.java create mode 100644 bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ClassFinder.java delete mode 100644 bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleClassFinder.java diff --git a/bFundamentals/pom.xml b/bFundamentals/pom.xml index 5afb55a..565050f 100644 --- a/bFundamentals/pom.xml +++ b/bFundamentals/pom.xml @@ -56,6 +56,7 @@ commons-*:* org.jnbt:jnbt + org.javassist:javassist org.reflections:reflections org.apache.httpcomponents:* diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/ModuleDescription.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/ModuleDescription.java index 511329d..da21fca 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/ModuleDescription.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/ModuleDescription.java @@ -1,6 +1,8 @@ package uk.codingbadgers.bFundamentals.module; import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -40,7 +42,16 @@ public ModuleDescription(InputStream istream) { dependencies = Collections.unmodifiableCollection(ldf.getStringList("dependencies")); } - /** + public ModuleDescription(String value, String version, String mainClass, String description, String[] authors) { + this.name = value; + this.version = version; + this.mainClass = mainClass; + this.description = description; + this.authors = CollectionUtils.toImmutableList(Arrays.asList(authors)); + this.dependencies = Collections.unmodifiableCollection(new ArrayList()); + } + + /** * Gets the name of this loadable. * * @return the name of this loadable diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/annotation/ModuleInfo.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/annotation/ModuleInfo.java new file mode 100644 index 0000000..40ba502 --- /dev/null +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/annotation/ModuleInfo.java @@ -0,0 +1,22 @@ +package uk.codingbadgers.bFundamentals.module.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface ModuleInfo { + + String value(); + + String version() default "1.0"; + + String[] authors() default {"Unkown"}; + + String description() default ""; + +} diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ClassFinder.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ClassFinder.java new file mode 100644 index 0000000..5127dc9 --- /dev/null +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ClassFinder.java @@ -0,0 +1,25 @@ +package uk.codingbadgers.bFundamentals.module.loader; + +import java.net.URL; +import java.util.Set; + +import org.bukkit.event.Listener; +import org.reflections.Reflections; +import org.reflections.util.ConfigurationBuilder; + +import uk.codingbadgers.bFundamentals.module.Module; +import uk.codingbadgers.bFundamentals.module.ModuleClassLoader; + +public class ClassFinder { + + public static Set> findModules(ModuleClassLoader loader, URL[] url) { + Reflections reflect = new Reflections(new ConfigurationBuilder().addUrls(url).addClassLoader(loader).addClassLoader(ClassFinder.class.getClassLoader())); + return reflect.getSubTypesOf(Module.class); + } + + public static Set> findListeners(ModuleClassLoader loader, URL[] url) { + Reflections reflect = new Reflections(new ConfigurationBuilder().addUrls(url).addClassLoader(loader).addClassLoader(ClassFinder.class.getClassLoader())); + return reflect.getSubTypesOf(Listener.class); + } + +} \ No newline at end of file diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleClassFinder.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleClassFinder.java deleted file mode 100644 index 2406bfc..0000000 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleClassFinder.java +++ /dev/null @@ -1,18 +0,0 @@ -package uk.codingbadgers.bFundamentals.module.loader; - -import java.net.URL; -import java.util.Set; - -import org.reflections.Reflections; -import org.reflections.util.ConfigurationBuilder; - -import uk.codingbadgers.bFundamentals.module.Module; - -public class ModuleClassFinder { - - public static Set> findModules(URL[] url) { - Reflections reflect = new Reflections(new ConfigurationBuilder().addUrls(url)); - return reflect.getSubTypesOf(Module.class); - } - -} diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleLoader.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleLoader.java index 446a424..3901dbf 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleLoader.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleLoader.java @@ -1,7 +1,7 @@ package uk.codingbadgers.bFundamentals.module.loader; import java.io.File; -import java.lang.reflect.Constructor; +import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; @@ -29,6 +29,7 @@ import uk.codingbadgers.bFundamentals.module.ModuleClassLoader; import uk.codingbadgers.bFundamentals.module.ModuleDescription; import uk.codingbadgers.bFundamentals.module.ModuleHelpTopic; +import uk.codingbadgers.bFundamentals.module.annotation.ModuleInfo; /** * The ModuleLoader. @@ -48,16 +49,16 @@ public ModuleLoader() { bFundamentals.log(Level.INFO, "Creating Module Directory..."); } } - + /** * Gets the directory of the modules. - * + * * @return the module dir */ public File getModuleDir() { return new File(bFundamentals.getInstance().getDataFolder(), "modules"); } - + /** * Loads all the modules in the base modules directory. */ @@ -65,11 +66,11 @@ public void load() { List files = Arrays.asList(getModuleDir().listFiles(new FileExtensionFilter(".jar"))); for (File file : files) { - load0(file); + loadModule(file); } - + sort(); - + for (Module module : m_modules) { try { module.onLoad(); @@ -78,11 +79,11 @@ public void load() { ExceptionHandler.handleException(ex); } } - + bFundamentals.log(Level.INFO, "Loaded " + m_modules.size() + " modules."); } - - public Module load0(File file) { + + public Module loadModule(File file) { Module result = null; try { @@ -93,56 +94,59 @@ public Module load0(File file) { JarFile jarFile = new JarFile(file); ModuleDescription ldf = null; Set> modules = new HashSet>(); + + modules.addAll(ClassFinder.findModules(loader, urls)); // Old system, left for backwards compatibility if (jarFile.getEntry("path.yml") != null) { JarEntry element = jarFile.getJarEntry("path.yml"); ldf = new ModuleDescription(jarFile.getInputStream(element)); - modules.add(Class.forName(ldf.getMainClass(), true, loader).asSubclass(Module.class)); - } else { - modules.addAll(ModuleClassFinder.findModules(urls)); - // TODO sort out ModuleInformation } - + if (modules.size() == 0) { jarFile.close(); - throw new ClassNotFoundException("Could not find main class in the path.yml."); + throw new ClassNotFoundException("Could not find a main class in jar " + file.getName() + "."); } - - if (bFundamentals.getConfigurationManager().isDebugEnabled()) getLogger().log(Level.INFO, "Loading " + modules.size() + " modules for jar " + file.getName()); - + + if (bFundamentals.getConfigurationManager().isDebugEnabled()) + getLogger().log(Level.INFO, "Loading " + modules.size() + " modules for jar " + file.getName()); + for (Class clazz : modules) { - if (bFundamentals.getConfigurationManager().isDebugEnabled()) getLogger().log(Level.INFO, "Loading module " + clazz.getName()); + if (bFundamentals.getConfigurationManager().isDebugEnabled()) + getLogger().log(Level.INFO, "Loading module " + clazz.getName()); + + ModuleDescription description = ldf; - if (clazz != null) { - Class loadableClass = clazz.asSubclass(Module.class); - Constructor constructor = loadableClass.getConstructor(); - result = constructor.newInstance(); - - if (m_modules.contains(result)) { - getLogger().log(Level.WARNING, "The loadable " + file.getName() + " is already loaded, make sure to disable the module first"); - getLogger().log(Level.WARNING, "The JAR file " + file.getName() + " failed to load"); - jarFile.close(); - return null; - } - - result.setFile(file); - result.setDesciption(ldf); - result.setJarFile(jarFile); - result.setDatafolder(new File(file.getParentFile(), result.getName())); - result.init(); - - ModuleLoadEvent event = new ModuleLoadEvent(bFundamentals.getInstance(), result, jarFile); - Bukkit.getServer().getPluginManager().callEvent(event); - - m_modules.add(result); - loaders.put(result.getName(), loader); - - } else { + if (clazz.isAnnotationPresent(ModuleInfo.class)) { + ModuleInfo info = clazz.getAnnotation(ModuleInfo.class); + description = new ModuleDescription(info.value(), info.version(), clazz.getName(), info.description(), info.authors()); + } + + if (description == null) { + throw new IOException("Description not found for module " + file.getName() + "."); + } + + result = clazz.newInstance(); + + if (m_modules.contains(result)) { + getLogger().log(Level.WARNING, "The loadable " + file.getName() + " is already loaded, make sure to disable the module first"); + getLogger().log(Level.WARNING, "The JAR file " + file.getName() + " failed to load"); jarFile.close(); - throw new ClassNotFoundException("Class " + clazz.getName() + " could not be found."); + return null; } + + result.setFile(file); + result.setDesciption(description); + result.setJarFile(jarFile); + result.setDatafolder(new File(getModuleDir(), result.getName())); + result.init(); + + ModuleLoadEvent event = new ModuleLoadEvent(bFundamentals.getInstance(), result, jarFile); + Bukkit.getServer().getPluginManager().callEvent(event); + + m_modules.add(result); + loaders.put(result.getName(), loader); } } catch (ClassCastException e) { @@ -161,7 +165,7 @@ public Module load0(File file) { return result; } - + private Logger getLogger() { return bFundamentals.getInstance().getLogger(); } @@ -169,35 +173,37 @@ private Logger getLogger() { /** * Loads a module with a given name * - * @param fileName the files name + * @param fileName + * the files name */ public void load(String fileName) { File module = new File(getModuleDir() + File.separator + fileName + ".jar"); load(module); } - + /** * Loads a module with a jar file - * - * @param file the jar file for this module + * + * @param file + * the jar file for this module */ public void load(File file) { if (getModule(file) != null) { throw new IllegalArgumentException("Module " + file.getName() + " is already loaded"); } - - Module result = load0(file); - + + Module result = loadModule(file); + if (result == null) { return; - } - + } + m_modules.add(result); - + result.onLoad(); result.log(Level.INFO, result.getName() + " v:" + result.getVersion() + " has been loaded successfuly"); } - + /** * Unloads the modules. */ @@ -205,11 +211,12 @@ public void unload() { disable(); m_modules.clear(); } - + /** * Unload a specific module. - * - * @param module the module + * + * @param module + * the module */ public void unload(Module module) { try { @@ -222,7 +229,7 @@ public void unload(Module module) { ExceptionHandler.handleException(ex); } } - + /** * Run on enable in all modules. */ @@ -236,7 +243,7 @@ public void enable() { } } } - + /** * run on disable in all modules. */ @@ -253,14 +260,13 @@ public void disable() { /** * Gets the modules. - * + * * @return the modules */ public List getModules() { return m_modules; } - - + /** * Update all the loaded modules if an updater is set */ @@ -268,7 +274,7 @@ public void update() { if (!bFundamentals.getConfigurationManager().isAutoUpdateEnabled()) { return; } - + for (Module module : m_modules) { module.update(); } @@ -276,30 +282,32 @@ public void update() { /** * Gets the module from its name. - * - * @param string the string + * + * @param string + * the string * @return the module */ public Module getModule(String string) { Iterator itr = m_modules.iterator(); - while(itr.hasNext()) { + while (itr.hasNext()) { Module module = itr.next(); if (module.getName().equalsIgnoreCase(string)) { return module; } } - return null; + return null; } - + /** * Gets the module from its file. - * - * @param file the file + * + * @param file + * the file * @return the module */ public Module getModule(File file) { Iterator itr = m_modules.iterator(); - while(itr.hasNext()) { + while (itr.hasNext()) { Module module = itr.next(); if (module.getFile().getPath().equalsIgnoreCase(file.getPath())) { return module; @@ -307,7 +315,7 @@ public Module getModule(File file) { } return null; } - + public Class getClassByName(String name) { Class cachedClass = classes.get(name); @@ -339,7 +347,7 @@ public void setClass(String name, Class clazz) { } } } - + public void sort() { List sortedLoadables = new ArrayList(); List names = new ArrayList(); From 6c3c3b8b89da9f5760fd6e4ad789bbdc8334c318 Mon Sep 17 00:00:00 2001 From: James Fitzpatrick Date: Sun, 8 Sep 2013 12:50:05 +0100 Subject: [PATCH 04/10] Add better events for module loading/unloading Fix module loading error Cleanup in Module/ModuleDescription --- .../bFundamentals/module/Module.java | 215 ++++++++++-------- .../module/ModuleDescription.java | 51 +++-- .../module/events/ModuleDisableEvent.java | 13 ++ .../module/events/ModuleEnableEvent.java | 13 ++ .../ModuleEvent.java} | 51 ++--- .../module/events/ModuleLoadEvent.java | 34 +++ .../module/loader/ModuleLoader.java | 20 +- 7 files changed, 232 insertions(+), 165 deletions(-) create mode 100644 bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleDisableEvent.java create mode 100644 bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleEnableEvent.java rename bFundamentals/src/uk/codingbadgers/bFundamentals/module/{loader/ModuleLoadEvent.java => events/ModuleEvent.java} (50%) create mode 100644 bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleLoadEvent.java diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/Module.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/Module.java index ec83140..74f91d4 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/Module.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/Module.java @@ -22,6 +22,7 @@ import org.apache.commons.io.IOUtils; import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import org.bukkit.configuration.file.FileConfiguration; @@ -35,6 +36,9 @@ import uk.codingbadgers.bFundamentals.config.ConfigFactory; import uk.codingbadgers.bFundamentals.config.ConfigFile; import uk.codingbadgers.bFundamentals.config.annotation.Element; +import uk.codingbadgers.bFundamentals.module.annotation.ModuleInfo; +import uk.codingbadgers.bFundamentals.module.events.ModuleDisableEvent; +import uk.codingbadgers.bFundamentals.module.events.ModuleEnableEvent; import uk.codingbadgers.bFundamentals.module.loader.ModuleLoader; import uk.codingbadgers.bFundamentals.update.UpdateThread; import uk.codingbadgers.bFundamentals.update.Updater; @@ -42,7 +46,8 @@ /** * The base Module class any module should extend this, it also provides helper - * methods for the module. + * methods for the module, modules should be annotated with {@link ModuleInfo} + * to save the information of the module. */ public abstract class Module implements Listener { @@ -68,22 +73,21 @@ public abstract class Module implements Listener { * Instantiates a new module with default settings. */ public Module() { - super(); m_plugin = bFundamentals.getInstance(); m_database = bFundamentals.getBukkitDatabase(); m_debug = bFundamentals.getConfigurationManager().isDebugEnabled(); } - public void init() { + public final void init() { m_log = new ModuleLogger(this); } - protected void setUpdater(Updater updater) { + protected final void setUpdater(Updater updater) { m_updater = new UpdateThread(updater); log(Level.INFO, "Set new updater to " + m_updater.getUpdater().getUpdater()); } - public void update() { + public final void update() { if (m_updater == null) { log(Level.INFO, "Updater is null, cannot check for updates"); return; @@ -192,6 +196,31 @@ protected void loadLanguageFile() { } + /** + * Gets the language value for the current loaded language, case + * insensitive, all keys are forced to be in lower case. + * + * @param key + * the language key + * @return the language value, if available, the key with hyphens removed + * and in lower case otherwise + */ + public String getLanguageValue(String key) { + Validate.notNull(key, "Language key cannot be null"); + + if (!loadedLanguageFile) { + log(Level.SEVERE, "Cannot get language value before loading language file"); + } + + String value = m_languageMap.get(key.toLowerCase()); + + if (value == null) { + value = key.toLowerCase().replace("-", " "); + } + + return value; + } + /** * Log a message console via this modules logger. * @@ -220,6 +249,10 @@ public Logger getLogger() { * the bukkit event listener */ public final void register(Listener listener) { + if (m_listeners.contains(listener)) { + return; + } + m_plugin.getServer().getPluginManager().registerEvents(listener, m_plugin); m_listeners.add(listener); } @@ -229,7 +262,7 @@ public final void register(Listener listener) { * * @return the vault permissions instance */ - public Permission getPermissions() { + public final Permission getPermissions() { return bFundamentals.getPermissions(); } @@ -238,14 +271,14 @@ public Permission getPermissions() { * {@link #setEnabled(boolean)} this is used to register commands, events * and any other things that should be registered on enabling the module. */ - public abstract void onEnable(); + public void onEnable() {} /** * The disable method for this module, called on disabling the module via * {@link #setEnabled(boolean)} this is used to clean up after the module when * it is disabled. */ - public abstract void onDisable(); + public void onDisable() {} /** * The load method for this module, called on loading the module via the @@ -262,19 +295,25 @@ public void onLoad() {} * * @param enabled if you want to enable or disable the module */ - public void setEnabled(boolean enabled) { + public final void setEnabled(boolean enabled) { if (enabled) { if (m_enabled) { return; } - + + ModuleEnableEvent event = new ModuleEnableEvent(bFundamentals.getInstance(), this); + Bukkit.getServer().getPluginManager().callEvent(event); + onEnable(); m_enabled = true; } else { if (!m_enabled) { return; } - + + ModuleDisableEvent event = new ModuleDisableEvent(bFundamentals.getInstance(), this); + Bukkit.getServer().getPluginManager().callEvent(event); + onDisable(); ModuleCommandHandler.deregisterCommand(this); m_enabled = false; @@ -286,7 +325,7 @@ public void setEnabled(boolean enabled) { * * @return if the module is enabled */ - public boolean isEnabled() { + public final boolean isEnabled() { return m_enabled; } @@ -313,56 +352,10 @@ public boolean onCommand(CommandSender sender, String label, String[] args) { * * @return the module version */ - public String getVersion() { + public final String getVersion() { return getDesciption().getVersion(); } - /** - * Checks if a player has a specific permission. - * - * @param player - * the player to check - * @param node - * the permission node - * @return true, if the player has the permission - */ - public static boolean hasPermission(final Player player, final String node) { - if (bFundamentals.getPermissions().has(player, node)) { - return true; - } - return false; - } - - /** - * Checks if a player has a specific permission. - * - * @param player - * the player to check - * @param node - * the permission node - * @return true, if the player has the permission - */ - public static boolean hasPermission(final CommandSender player, final String node) { - if (bFundamentals.getPermissions().has(player, node)) { - return true; - } - return false; - } - - /** - * Send message to a player formated in the default style. - * - * @param name - * the name of the module - * @param player - * the player to send to - * @param message - * the message - */ - public static void sendMessage(String name, CommandSender player, String message) { - player.sendMessage(ChatColor.DARK_PURPLE + "[" + name + "] " + ChatColor.RESET + message); - } - /** * Register a command to this module. * @@ -383,38 +376,13 @@ public List getCommands() { return ModuleCommandHandler.getCommands(this); } - /** - * Gets the language value for the current loaded language, case - * insensitive, all keys are forced to be in lower case. - * - * @param key - * the language key - * @return the language value, if available, the key with hyphens removed - * and in lower case otherwise - */ - public String getLanguageValue(String key) { - Validate.notNull(key, "Language key cannot be null"); - - if (!loadedLanguageFile) { - log(Level.SEVERE, "Cannot get language value before loading language file"); - } - - String value = m_languageMap.get(key.toLowerCase()); - - if (value == null) { - value = key.toLowerCase().replace("-", " "); - } - - return value; - } - /** * Get all the listeners registered to this module, for cleaning up on * disable * * @return a list of all listeners */ - public List getListeners() { + public final List getListeners() { return m_listeners; } @@ -423,7 +391,7 @@ public List getListeners() { * * @return if debug is enabled */ - public boolean isDebug() { + public final boolean isDebug() { return m_debug; } @@ -433,7 +401,7 @@ public boolean isDebug() { * @param debug * whether debug is on or not */ - public void setDebug(boolean debug) { + public final void setDebug(boolean debug) { m_debug = debug; } @@ -443,7 +411,7 @@ public void setDebug(boolean debug) { * @param message * the message to output */ - public void debugConsole(String message) { + public final void debugConsole(String message) { if (!m_debug) return; @@ -459,7 +427,7 @@ public void debugConsole(String message) { * @param clazz * the config class */ - public void registerConfig(Class clazz) { + public final void registerConfig(Class clazz) { if (m_configFiles == null) { m_configFiles = new ArrayList>(); } @@ -480,7 +448,7 @@ public void registerConfig(Class clazz) { * @param dataFolder the data folder * @return the file */ - public void setDatafolder(File dataFolder) { + public final void setDatafolder(File dataFolder) { dataFolder.mkdirs(); this.m_dataFolder = dataFolder; } @@ -491,7 +459,7 @@ public void setDatafolder(File dataFolder) { * @param file the file * @return the file */ - public void setFile(File file) { + public final void setFile(File file) { this.m_file = file; } @@ -501,7 +469,7 @@ public void setFile(File file) { * @param jar the jar * @return the jar file */ - public void setJarFile(JarFile jar) { + public final void setJarFile(JarFile jar) { this.m_jar = jar; } @@ -511,7 +479,7 @@ public void setJarFile(JarFile jar) { * @param ldf the loadable description file * @return the loadable description file */ - public void setDesciption(ModuleDescription ldf) { + public final void setDesciption(ModuleDescription ldf) { this.m_description = ldf; } @@ -520,7 +488,7 @@ public void setDesciption(ModuleDescription ldf) { * * @return The config */ - public FileConfiguration getConfig() { + public final FileConfiguration getConfig() { if (m_config == null) { reloadConfig(); } @@ -533,7 +501,7 @@ public FileConfiguration getConfig() { * * @return The directory of this */ - public File getDataFolder() { + public final File getDataFolder() { return m_dataFolder; } @@ -542,7 +510,7 @@ public File getDataFolder() { * * @return the jar file as a {@link File} */ - public File getFile() { + public final File getFile() { return m_file; } @@ -561,7 +529,7 @@ public final String getName() { * @param name File name of the resource * @return InputStream of the file if found, otherwise null */ - public InputStream getResource(String name) { + public final InputStream getResource(String name) { ZipEntry entry = m_jar.getEntry(name); if (entry == null) @@ -577,7 +545,7 @@ public InputStream getResource(String name) { /** * Reloads the config. */ - public void reloadConfig() { + public final void reloadConfig() { if (m_configFile == null) { m_configFile = new File(getDataFolder(), "config.yml"); } @@ -595,7 +563,7 @@ public void reloadConfig() { /** * Saves the config. */ - public void saveConfig() { + public final void saveConfig() { if (m_config == null || m_configFile == null) { return; } @@ -611,7 +579,54 @@ public void saveConfig() { * * @return the desciption */ - public ModuleDescription getDesciption() { + public final ModuleDescription getDesciption() { return this.m_description; } + + /** + * Checks if a player has a specific permission. + * + * @param player + * the player to check + * @param node + * the permission node + * @return true, if the player has the permission + */ + public static boolean hasPermission(final Player player, final String node) { + if (bFundamentals.getPermissions().has(player, node)) { + return true; + } + return false; + } + + /** + * Checks if a player has a specific permission. + * + * @param player + * the player to check + * @param node + * the permission node + * @return true, if the player has the permission + */ + public static boolean hasPermission(final CommandSender player, final String node) { + if (bFundamentals.getPermissions().has(player, node)) { + return true; + } + return false; + } + + /** + * Send message to a player formated in the default style. + * + * @param name + * the name of the module + * @param player + * the player to send to + * @param message + * the message + */ + public static void sendMessage(String name, CommandSender player, String message) { + player.sendMessage(ChatColor.DARK_PURPLE + "[" + name + "] " + ChatColor.RESET + message); + } + } \ No newline at end of file diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/ModuleDescription.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/ModuleDescription.java index da21fca..0cc1ad0 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/ModuleDescription.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/ModuleDescription.java @@ -9,12 +9,14 @@ import org.bukkit.configuration.file.YamlConfiguration; +import uk.codingbadgers.bFundamentals.module.annotation.ModuleInfo; import uk.codingbadgers.bFundamentals.utils.CollectionUtils; /** * The Class LoadableDescriptionFile, represents the data stored in the - * path.yml file of a {@link Loadable}. - * + * about a module, either by a path.yml file of a {@link Loadable} or a + * {@link ModuleInfo} annotation. + * * @author James Fitzpatrick */ public class ModuleDescription { @@ -27,7 +29,8 @@ public class ModuleDescription { private final Collection dependencies; /** - * Instantiates a new loadable description file. + * Instantiates a new module description from the data in a path.yml + * file. * * @param istream the input stream that this file is loaded from */ @@ -41,47 +44,53 @@ public ModuleDescription(InputStream istream) { authors = CollectionUtils.toImmutableList(ldf.getStringList("authors")); dependencies = Collections.unmodifiableCollection(ldf.getStringList("dependencies")); } - - public ModuleDescription(String value, String version, String mainClass, String description, String[] authors) { - this.name = value; - this.version = version; - this.mainClass = mainClass; - this.description = description; - this.authors = CollectionUtils.toImmutableList(Arrays.asList(authors)); + + /** + * Instantiates a new module description from the data in a + * {@link ModuleInfo} annotation. + * + * @param istream the input stream that this file is loaded from + */ + public ModuleDescription(ModuleInfo info, String mainclass) { + this.name = info.value(); + this.version = info.version(); + this.mainClass = mainclass; + this.description = info.description(); + this.authors = CollectionUtils.toImmutableList(Arrays.asList(info.authors())); this.dependencies = Collections.unmodifiableCollection(new ArrayList()); } /** - * Gets the name of this loadable. + * Gets the name of this module. * - * @return the name of this loadable + * @return the name of this module */ public String getName() { return name; } /** - * Gets the version of this loadable. + * Gets the version of this module. * - * @return the version of this loadable + * @return the version of this module */ public String getVersion() { return version; } /** - * Gets the description for this loadable. + * Gets the description for this module. * - * @return the description of this loadable + * @return the description of this module */ public String getDescription() { return description; } /** - * Gets the main class of this loadable. + * Gets the main class of this module. * - * @return the fully qualified name of the main class of this loadable + * @return the fully qualified name of the main class of this module * @deprecated Main classes should not have to be defined anymore */ public String getMainClass() { @@ -89,9 +98,9 @@ public String getMainClass() { } /** - * Gets the authors of this loadable. + * Gets the authors of this module. * - * @return a immutable list of the authors of this loadable + * @return a immutable list of the authors of this module */ public List getAuthors() { return authors; @@ -99,7 +108,7 @@ public List getAuthors() { /** * Gets the module dependencies of this loadable, this module will load after - * all of the dependencies have loaded. + * all of the dependencies have module. * * @return a unmodifiable collection of the dependencies */ diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleDisableEvent.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleDisableEvent.java new file mode 100644 index 0000000..e49bc79 --- /dev/null +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleDisableEvent.java @@ -0,0 +1,13 @@ +package uk.codingbadgers.bFundamentals.module.events; + +import org.bukkit.plugin.Plugin; + +import uk.codingbadgers.bFundamentals.module.Module; + +public class ModuleDisableEvent extends ModuleEvent { + + public ModuleDisableEvent(Plugin plugin, Module loadable) { + super(plugin, loadable); + } + +} diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleEnableEvent.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleEnableEvent.java new file mode 100644 index 0000000..a863d99 --- /dev/null +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleEnableEvent.java @@ -0,0 +1,13 @@ +package uk.codingbadgers.bFundamentals.module.events; + +import org.bukkit.plugin.Plugin; + +import uk.codingbadgers.bFundamentals.module.Module; + +public class ModuleEnableEvent extends ModuleEvent { + + public ModuleEnableEvent(Plugin plugin, Module loadable) { + super(plugin, loadable); + } + +} diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleLoadEvent.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleEvent.java similarity index 50% rename from bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleLoadEvent.java rename to bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleEvent.java index 7667ddb..4c51bb4 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleLoadEvent.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleEvent.java @@ -1,6 +1,4 @@ -package uk.codingbadgers.bFundamentals.module.loader; - -import java.util.jar.JarFile; +package uk.codingbadgers.bFundamentals.module.events; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; @@ -8,19 +6,10 @@ import uk.codingbadgers.bFundamentals.module.Module; -public class ModuleLoadEvent extends Event { - +public class ModuleEvent extends Event { + private static final HandlerList handlers = new HandlerList(); - private final Plugin plugin; - private final Module loadable; - private final JarFile jarFile; - - public ModuleLoadEvent(Plugin plugin, Module loadable, JarFile jarFile) { - this.plugin = plugin; - this.loadable = loadable; - this.jarFile = jarFile; - } - + @Override public HandlerList getHandlers() { return handlers; @@ -29,31 +18,21 @@ public HandlerList getHandlers() { public static HandlerList getHandlerList() { return handlers; } - - /** - * Gets the JAR file of the loaded loadable - * - * @return The JAR file - */ - public JarFile getJarFile() { - return jarFile; + + private final Plugin plugin; + private final Module loadable; + + public ModuleEvent(Plugin plugin, Module loadable) { + this.plugin = plugin; + this.loadable = loadable; } - - /** - * Gets the loaded Module - * - * @return The Loadable - */ + public Module getModule() { return loadable; } - - /** - * Gets the plugin calling this event - * - * @return The plugin calling the event - */ + public Plugin getPlugin() { return plugin; } -} \ No newline at end of file + +} diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleLoadEvent.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleLoadEvent.java new file mode 100644 index 0000000..f7e761a --- /dev/null +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleLoadEvent.java @@ -0,0 +1,34 @@ +package uk.codingbadgers.bFundamentals.module.events; + +import java.util.jar.JarFile; + +import org.bukkit.event.HandlerList; +import org.bukkit.plugin.Plugin; + +import uk.codingbadgers.bFundamentals.module.Module; + +public class ModuleLoadEvent extends ModuleEvent { + + private static final HandlerList handlers = new HandlerList(); + + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + private final JarFile jarFile; + + public ModuleLoadEvent(Plugin plugin, Module loadable, JarFile jarFile) { + super(plugin, loadable); + this.jarFile = jarFile; + } + + public JarFile getJarFile() { + return jarFile; + } +} \ No newline at end of file diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleLoader.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleLoader.java index 3901dbf..00adf80 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleLoader.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleLoader.java @@ -6,6 +6,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; @@ -30,14 +31,15 @@ import uk.codingbadgers.bFundamentals.module.ModuleDescription; import uk.codingbadgers.bFundamentals.module.ModuleHelpTopic; import uk.codingbadgers.bFundamentals.module.annotation.ModuleInfo; +import uk.codingbadgers.bFundamentals.module.events.ModuleLoadEvent; /** * The ModuleLoader. */ public class ModuleLoader { - private Map loaders; - private Map> classes; + private Map loaders = new HashMap(); + private Map> classes = new HashMap>(); private List m_modules; /** @@ -92,7 +94,7 @@ public Module loadModule(File file) { ModuleClassLoader loader = new ModuleClassLoader(this, urls, getClass().getClassLoader()); JarFile jarFile = new JarFile(file); - ModuleDescription ldf = null; + ModuleDescription moduledescription = null; Set> modules = new HashSet>(); modules.addAll(ClassFinder.findModules(loader, urls)); @@ -100,7 +102,7 @@ public Module loadModule(File file) { // Old system, left for backwards compatibility if (jarFile.getEntry("path.yml") != null) { JarEntry element = jarFile.getJarEntry("path.yml"); - ldf = new ModuleDescription(jarFile.getInputStream(element)); + moduledescription = new ModuleDescription(jarFile.getInputStream(element)); } if (modules.size() == 0) { @@ -108,19 +110,20 @@ public Module loadModule(File file) { throw new ClassNotFoundException("Could not find a main class in jar " + file.getName() + "."); } - if (bFundamentals.getConfigurationManager().isDebugEnabled()) + if (bFundamentals.getConfigurationManager().isDebugEnabled()) { getLogger().log(Level.INFO, "Loading " + modules.size() + " modules for jar " + file.getName()); - + } + for (Class clazz : modules) { if (bFundamentals.getConfigurationManager().isDebugEnabled()) getLogger().log(Level.INFO, "Loading module " + clazz.getName()); - ModuleDescription description = ldf; + ModuleDescription description = moduledescription; if (clazz.isAnnotationPresent(ModuleInfo.class)) { ModuleInfo info = clazz.getAnnotation(ModuleInfo.class); - description = new ModuleDescription(info.value(), info.version(), clazz.getName(), info.description(), info.authors()); + description = new ModuleDescription(info, clazz.getName()); } if (description == null) { @@ -160,6 +163,7 @@ public Module loadModule(File file) { } catch (Exception e) { ExceptionHandler.handleException(e); getLogger().log(Level.WARNING, "Unknown cause."); + getLogger().log(Level.WARNING, e.getMessage()); getLogger().log(Level.WARNING, "The JAR file " + file.getName() + " failed to load."); } From f3266c2cc291fbae0662bc50d4639d51be01365b Mon Sep 17 00:00:00 2001 From: James Fitzpatrick Date: Sun, 8 Sep 2013 15:14:07 +0100 Subject: [PATCH 05/10] Fixed merge fail --- .../module/loader/ClassFinder.java | 25 ++ .../module/loader/FileExtensionFilter.java | 17 + .../module/loader/ModuleLoader.java | 376 ++++++++++++++++++ 3 files changed, 418 insertions(+) create mode 100644 bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ClassFinder.java create mode 100644 bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/FileExtensionFilter.java create mode 100644 bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleLoader.java diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ClassFinder.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ClassFinder.java new file mode 100644 index 0000000..5127dc9 --- /dev/null +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ClassFinder.java @@ -0,0 +1,25 @@ +package uk.codingbadgers.bFundamentals.module.loader; + +import java.net.URL; +import java.util.Set; + +import org.bukkit.event.Listener; +import org.reflections.Reflections; +import org.reflections.util.ConfigurationBuilder; + +import uk.codingbadgers.bFundamentals.module.Module; +import uk.codingbadgers.bFundamentals.module.ModuleClassLoader; + +public class ClassFinder { + + public static Set> findModules(ModuleClassLoader loader, URL[] url) { + Reflections reflect = new Reflections(new ConfigurationBuilder().addUrls(url).addClassLoader(loader).addClassLoader(ClassFinder.class.getClassLoader())); + return reflect.getSubTypesOf(Module.class); + } + + public static Set> findListeners(ModuleClassLoader loader, URL[] url) { + Reflections reflect = new Reflections(new ConfigurationBuilder().addUrls(url).addClassLoader(loader).addClassLoader(ClassFinder.class.getClassLoader())); + return reflect.getSubTypesOf(Listener.class); + } + +} \ No newline at end of file diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/FileExtensionFilter.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/FileExtensionFilter.java new file mode 100644 index 0000000..64bebe2 --- /dev/null +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/FileExtensionFilter.java @@ -0,0 +1,17 @@ +package uk.codingbadgers.bFundamentals.module.loader; + +import java.io.File; +import java.io.FileFilter; + +public final class FileExtensionFilter implements FileFilter { + + private final String extension; + + public FileExtensionFilter(String extension) { + this.extension = extension; + } + + public boolean accept(File file) { + return file.getName().endsWith(extension); + } +} \ No newline at end of file diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleLoader.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleLoader.java new file mode 100644 index 0000000..00adf80 --- /dev/null +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleLoader.java @@ -0,0 +1,376 @@ +package uk.codingbadgers.bFundamentals.module.loader; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.bukkit.Bukkit; +import org.bukkit.configuration.serialization.ConfigurationSerializable; +import org.bukkit.configuration.serialization.ConfigurationSerialization; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; + +import uk.codingbadgers.bFundamentals.bFundamentals; +import uk.codingbadgers.bFundamentals.error.ExceptionHandler; +import uk.codingbadgers.bFundamentals.module.Module; +import uk.codingbadgers.bFundamentals.module.ModuleClassLoader; +import uk.codingbadgers.bFundamentals.module.ModuleDescription; +import uk.codingbadgers.bFundamentals.module.ModuleHelpTopic; +import uk.codingbadgers.bFundamentals.module.annotation.ModuleInfo; +import uk.codingbadgers.bFundamentals.module.events.ModuleLoadEvent; + +/** + * The ModuleLoader. + */ +public class ModuleLoader { + + private Map loaders = new HashMap(); + private Map> classes = new HashMap>(); + private List m_modules; + + /** + * Instantiates a new module loader. + */ + public ModuleLoader() { + m_modules = new LinkedList(); + if (getModuleDir().mkdir()) { + bFundamentals.log(Level.INFO, "Creating Module Directory..."); + } + } + + /** + * Gets the directory of the modules. + * + * @return the module dir + */ + public File getModuleDir() { + return new File(bFundamentals.getInstance().getDataFolder(), "modules"); + } + + /** + * Loads all the modules in the base modules directory. + */ + public void load() { + + List files = Arrays.asList(getModuleDir().listFiles(new FileExtensionFilter(".jar"))); + for (File file : files) { + loadModule(file); + } + + sort(); + + for (Module module : m_modules) { + try { + module.onLoad(); + module.log(Level.INFO, module.getName() + " v:" + module.getVersion() + " has been loaded successfuly"); + } catch (Exception ex) { + ExceptionHandler.handleException(ex); + } + } + + bFundamentals.log(Level.INFO, "Loaded " + m_modules.size() + " modules."); + } + + public Module loadModule(File file) { + Module result = null; + + try { + URL[] urls = new URL[] { file.toURI().toURL() }; + + ModuleClassLoader loader = new ModuleClassLoader(this, urls, getClass().getClassLoader()); + + JarFile jarFile = new JarFile(file); + ModuleDescription moduledescription = null; + Set> modules = new HashSet>(); + + modules.addAll(ClassFinder.findModules(loader, urls)); + + // Old system, left for backwards compatibility + if (jarFile.getEntry("path.yml") != null) { + JarEntry element = jarFile.getJarEntry("path.yml"); + moduledescription = new ModuleDescription(jarFile.getInputStream(element)); + } + + if (modules.size() == 0) { + jarFile.close(); + throw new ClassNotFoundException("Could not find a main class in jar " + file.getName() + "."); + } + + if (bFundamentals.getConfigurationManager().isDebugEnabled()) { + getLogger().log(Level.INFO, "Loading " + modules.size() + " modules for jar " + file.getName()); + } + + for (Class clazz : modules) { + + if (bFundamentals.getConfigurationManager().isDebugEnabled()) + getLogger().log(Level.INFO, "Loading module " + clazz.getName()); + + ModuleDescription description = moduledescription; + + if (clazz.isAnnotationPresent(ModuleInfo.class)) { + ModuleInfo info = clazz.getAnnotation(ModuleInfo.class); + description = new ModuleDescription(info, clazz.getName()); + } + + if (description == null) { + throw new IOException("Description not found for module " + file.getName() + "."); + } + + result = clazz.newInstance(); + + if (m_modules.contains(result)) { + getLogger().log(Level.WARNING, "The loadable " + file.getName() + " is already loaded, make sure to disable the module first"); + getLogger().log(Level.WARNING, "The JAR file " + file.getName() + " failed to load"); + jarFile.close(); + return null; + } + + result.setFile(file); + result.setDesciption(description); + result.setJarFile(jarFile); + result.setDatafolder(new File(getModuleDir(), result.getName())); + result.init(); + + ModuleLoadEvent event = new ModuleLoadEvent(bFundamentals.getInstance(), result, jarFile); + Bukkit.getServer().getPluginManager().callEvent(event); + + m_modules.add(result); + loaders.put(result.getName(), loader); + } + + } catch (ClassCastException e) { + e.printStackTrace(); + getLogger().log(Level.WARNING, "The JAR file " + file.getName() + " is in the wrong directory."); + getLogger().log(Level.WARNING, "The JAR file " + file.getName() + " failed to load."); + } catch (ClassNotFoundException e) { + getLogger().log(Level.WARNING, "Invalid path.yml."); + getLogger().log(Level.WARNING, e.getMessage()); + getLogger().log(Level.WARNING, "The JAR file " + file.getName() + " failed to load."); + } catch (Exception e) { + ExceptionHandler.handleException(e); + getLogger().log(Level.WARNING, "Unknown cause."); + getLogger().log(Level.WARNING, e.getMessage()); + getLogger().log(Level.WARNING, "The JAR file " + file.getName() + " failed to load."); + } + + return result; + } + + private Logger getLogger() { + return bFundamentals.getInstance().getLogger(); + } + + /** + * Loads a module with a given name + * + * @param fileName + * the files name + */ + public void load(String fileName) { + File module = new File(getModuleDir() + File.separator + fileName + ".jar"); + load(module); + } + + /** + * Loads a module with a jar file + * + * @param file + * the jar file for this module + */ + public void load(File file) { + if (getModule(file) != null) { + throw new IllegalArgumentException("Module " + file.getName() + " is already loaded"); + } + + Module result = loadModule(file); + + if (result == null) { + return; + } + + m_modules.add(result); + + result.onLoad(); + result.log(Level.INFO, result.getName() + " v:" + result.getVersion() + " has been loaded successfuly"); + } + + /** + * Unloads the modules. + */ + public void unload() { + disable(); + m_modules.clear(); + } + + /** + * Unload a specific module. + * + * @param module + * the module + */ + public void unload(Module module) { + try { + module.setEnabled(false); + for (Listener listener : module.getListeners()) { + HandlerList.unregisterAll(listener); + } + m_modules.remove(module); + } catch (Exception ex) { + ExceptionHandler.handleException(ex); + } + } + + /** + * Run on enable in all modules. + */ + public void enable() { + for (Module module : m_modules) { + try { + module.setEnabled(true); + Bukkit.getHelpMap().addTopic(new ModuleHelpTopic(module)); + } catch (Exception ex) { + ExceptionHandler.handleException(ex); + } + } + } + + /** + * run on disable in all modules. + */ + public void disable() { + List modules = new ArrayList(m_modules); + for (Module module : modules) { + try { + unload(module); + } catch (Exception ex) { + ExceptionHandler.handleException(ex); + } + } + } + + /** + * Gets the modules. + * + * @return the modules + */ + public List getModules() { + return m_modules; + } + + /** + * Update all the loaded modules if an updater is set + */ + public void update() { + if (!bFundamentals.getConfigurationManager().isAutoUpdateEnabled()) { + return; + } + + for (Module module : m_modules) { + module.update(); + } + } + + /** + * Gets the module from its name. + * + * @param string + * the string + * @return the module + */ + public Module getModule(String string) { + Iterator itr = m_modules.iterator(); + while (itr.hasNext()) { + Module module = itr.next(); + if (module.getName().equalsIgnoreCase(string)) { + return module; + } + } + return null; + } + + /** + * Gets the module from its file. + * + * @param file + * the file + * @return the module + */ + public Module getModule(File file) { + Iterator itr = m_modules.iterator(); + while (itr.hasNext()) { + Module module = itr.next(); + if (module.getFile().getPath().equalsIgnoreCase(file.getPath())) { + return module; + } + } + return null; + } + + public Class getClassByName(String name) { + Class cachedClass = classes.get(name); + + if (cachedClass != null) { + return cachedClass; + } else { + for (String current : loaders.keySet()) { + ModuleClassLoader loader = loaders.get(current); + try { + cachedClass = loader.findClass(name, false); + } catch (ClassNotFoundException cnfe) { + } + + if (cachedClass != null) { + return cachedClass; + } + } + } + return null; + } + + public void setClass(String name, Class clazz) { + if (!classes.containsKey(name)) { + classes.put(name, clazz); + + if (ConfigurationSerializable.class.isAssignableFrom(clazz)) { + Class serializable = clazz.asSubclass(ConfigurationSerializable.class); + ConfigurationSerialization.registerClass(serializable); + } + } + } + + public void sort() { + List sortedLoadables = new ArrayList(); + List names = new ArrayList(); + + for (Module t : m_modules) { + names.add(t.getName()); + } + + Collections.sort(names); + + for (String name : names) { + for (Module t : m_modules) { + if (t.getName().equals(name)) { + sortedLoadables.add(t); + } + } + } + + m_modules = sortedLoadables; + } + +} From 5d6ed4807772f12b18e6e0a3aaec31f2cb318448 Mon Sep 17 00:00:00 2001 From: James Fitzpatrick Date: Tue, 17 Sep 2013 18:49:57 +0100 Subject: [PATCH 06/10] Added method to get class load via Module. Added auto registering of listeners onEnable (If a listener is already loaded it will be skipped) Made the modules directory configurable. --- .../BukkitConfigurationManager.java | 45 ++++--- .../bFundamentals/ConfigManager.java | 7 ++ .../bFundamentals/error/ExceptionHandler.java | 5 +- .../bFundamentals/module/Module.java | 112 +++++++++++++++--- .../module/loader/ModuleLoader.java | 22 ++-- .../bFundamentals/TestConfigManager.java | 5 + 6 files changed, 142 insertions(+), 54 deletions(-) diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/BukkitConfigurationManager.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/BukkitConfigurationManager.java index f4bd670..8570b89 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/BukkitConfigurationManager.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/BukkitConfigurationManager.java @@ -40,6 +40,7 @@ public class BukkitConfigurationManager implements ConfigManager { protected String m_logPrefix = null; protected DatabaseSettings m_databaseSettings = null; protected String m_crashPass; + protected File m_moduleDir; /* (non-Javadoc) * @see uk.codingbadgers.bFundamentals.ConfigManager#loadConfiguration(java.io.File) @@ -48,10 +49,14 @@ public class BukkitConfigurationManager implements ConfigManager { public void loadConfiguration(File configFile) throws IOException { FileConfiguration config = YamlConfiguration.loadConfiguration(configFile); + config.options().header("bFundamentals configuration"); + config.addDefault("general.language", "UK"); config.addDefault("general.debug", false); config.addDefault("general.crash.password", "Password"); + config.addDefault("module.loading.dir", "${plugindir}/modules"); + config.addDefault("module.update.enabled", false); config.addDefault("module.update.download", false); config.addDefault("module.update.apply", false); @@ -66,7 +71,8 @@ public void loadConfiguration(File configFile) throws IOException { config.addDefault("database.password", ""); config.addDefault("database.port", 3306); config.addDefault("database.updateRate", 5); - + + config.options().copyHeader(true); config.options().copyDefaults(true); config.save(configFile); @@ -74,6 +80,8 @@ public void loadConfiguration(File configFile) throws IOException { m_debug = config.getBoolean("general.debug"); m_crashPass = config.getString("general.crash.password", "Password"); + m_moduleDir = parseDirectory(config.getString("module.loading.dir")); + m_autoUpdate = config.getBoolean("module.update.enabled"); m_autoDownload = config.getBoolean("module.update.download"); m_autoApply = config.getBoolean("module.update.apply"); @@ -92,68 +100,55 @@ public void loadConfiguration(File configFile) throws IOException { } - /* (non-Javadoc) - * @see uk.codingbadgers.bFundamentals.ConfigManager#getDatabaseSettings() - */ + private File parseDirectory(String string) { + string = string.replace("${plugindir}", bFundamentals.getInstance().getDataFolder().getAbsolutePath()); + string = string.replace("${basedir}", new File(".").getAbsolutePath()); + return new File(string); + } + @Override public DatabaseSettings getDatabaseSettings() { return m_databaseSettings; } - /* (non-Javadoc) - * @see uk.codingbadgers.bFundamentals.ConfigManager#getLanguage() - */ @Override public String getLanguage() { return m_language; } - /* (non-Javadoc) - * @see uk.codingbadgers.bFundamentals.ConfigManager#isDebugEnabled() - */ @Override public boolean isDebugEnabled() { return m_debug; } - /* (non-Javadoc) - * @see uk.codingbadgers.bFundamentals.ConfigManager#isAutoUpdateEnabled() - */ @Override public boolean isAutoUpdateEnabled() { return m_autoUpdate; } - /* (non-Javadoc) - * @see uk.codingbadgers.bFundamentals.ConfigManager#isAutoDownloadEnabled() - */ @Override public boolean isAutoDownloadEnabled() { return m_autoDownload; } - /* (non-Javadoc) - * @see uk.codingbadgers.bFundamentals.ConfigManager#isAutoInstallEnabled() - */ @Override public boolean isAutoInstallEnabled() { return m_autoApply; } - /* (non-Javadoc) - * @see uk.codingbadgers.bFundamentals.ConfigManager#getLogPrefix() - */ @Override public String getLogPrefix() { return m_logPrefix; } - /* (non-Javadoc) - * @see uk.codingbadgers.bFundamentals.ConfigManager#getCrashPassword() - */ @Override public String getCrashPassword() { return m_crashPass; } + @Override + public File getModuleDirectory() { + return m_moduleDir; + } + } diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/ConfigManager.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/ConfigManager.java index 8aab7af..ff3a110 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/ConfigManager.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/ConfigManager.java @@ -86,4 +86,11 @@ public interface ConfigManager { */ public abstract String getCrashPassword(); + /** + * Gets the current module directory. + * + * @return the module directory + */ + public abstract File getModuleDirectory(); + } \ No newline at end of file diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/error/ExceptionHandler.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/error/ExceptionHandler.java index 554d337..d86d0d4 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/error/ExceptionHandler.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/error/ExceptionHandler.java @@ -18,6 +18,9 @@ package uk.codingbadgers.bFundamentals.error; import java.lang.Thread.UncaughtExceptionHandler; +import java.util.logging.Level; + +import uk.codingbadgers.bFundamentals.bFundamentals; public class ExceptionHandler implements UncaughtExceptionHandler { @@ -29,7 +32,7 @@ public class ExceptionHandler implements UncaughtExceptionHandler { } public static boolean handleException(Throwable e) { - e.printStackTrace(); + bFundamentals.getInstance().getLogger().log(Level.WARNING, null, e); ReportExceptionRunnable run = new ReportExceptionRunnable(e); return run.run(); } diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/Module.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/Module.java index 702b4cd..c5504d9 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/Module.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/Module.java @@ -26,14 +26,18 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Set; import java.io.FileInputStream; import java.io.InputStreamReader; +import java.net.URL; import java.util.HashMap; import java.util.jar.JarFile; import java.util.logging.Level; import java.util.logging.Logger; import java.util.zip.ZipEntry; +import net.milkbowl.vault.chat.Chat; +import net.milkbowl.vault.economy.Economy; import net.milkbowl.vault.permission.Permission; import org.apache.commons.io.IOUtils; @@ -45,6 +49,7 @@ import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; +import org.bukkit.event.HandlerList; import org.bukkit.event.Listener; import uk.codingbadgers.bFundamentals.bFundamentals; @@ -56,6 +61,7 @@ import uk.codingbadgers.bFundamentals.module.annotation.ModuleInfo; import uk.codingbadgers.bFundamentals.module.events.ModuleDisableEvent; import uk.codingbadgers.bFundamentals.module.events.ModuleEnableEvent; +import uk.codingbadgers.bFundamentals.module.loader.ClassFinder; import uk.codingbadgers.bFundamentals.module.loader.ModuleLoader; import uk.codingbadgers.bFundamentals.update.UpdateThread; import uk.codingbadgers.bFundamentals.update.Updater; @@ -85,6 +91,7 @@ public abstract class Module implements Listener { private List> m_configFiles; private List m_listeners = new ArrayList(); private Map m_languageMap = new HashMap(); + private ModuleClassLoader m_loader; /** * Instantiates a new module with default settings. @@ -283,6 +290,24 @@ public final Permission getPermissions() { return bFundamentals.getPermissions(); } + /** + * Gets the vault chat instance. + * + * @return the vault chat instance + */ + public final Chat getChat() { + return bFundamentals.getChat(); + } + + /** + * Gets the vault economy instance. + * + * @return the vault economy instance + */ + public final Economy getEconomy() { + return bFundamentals.getEconomy(); + } + /** * The enable method for this module, called on enabling the module via * {@link #setEnabled(boolean)} this is used to register commands, events @@ -323,6 +348,22 @@ public final void setEnabled(boolean enabled) { onEnable(); m_enabled = true; + + try { + Set> listeners = ClassFinder.findListeners(m_loader, new URL[] {m_file.toURI().toURL()}); + debugConsole("Loading " + listeners.size() + " listeners"); + + for (Class clazz : listeners) { + try { + debugConsole("Loading Listener (" + clazz.getName() + ")"); + register(clazz.newInstance()); + } catch (Exception ex) { + log(Level.WARNING, clazz.getName() + " does not have atleast one public no argument constructor."); + } + } + } catch (Exception ex) { + } + } else { if (!m_enabled) { return; @@ -333,6 +374,9 @@ public final void setEnabled(boolean enabled) { onDisable(); ModuleCommandHandler.deregisterCommand(this); + for (Listener listener : getListeners()) { + HandlerList.unregisterAll(listener); + } m_enabled = false; } } @@ -364,15 +408,6 @@ public boolean onCommand(CommandSender sender, String label, String[] args) { return false; } - /** - * Gets the version of this module loaded from the path.yml file. - * - * @return the module version - */ - public final String getVersion() { - return getDesciption().getVersion(); - } - /** * Register a command to this module. * @@ -441,8 +476,7 @@ public final void debugConsole(String message) { * file should be {@code static} and have a {@link Element} * annotation associated with it. * - * @param clazz - * the config class + * @param clazz the config class */ public final void registerConfig(Class clazz) { if (m_configFiles == null) { @@ -459,13 +493,17 @@ public final void registerConfig(Class clazz) { m_configFiles.add(clazz); } + /* Start Loading specific methods */ + /** * Set the datafolder. * * @param dataFolder the data folder - * @return the file */ public final void setDatafolder(File dataFolder) { + if (m_dataFolder != null) { + throw new IllegalStateException("Data folder already set"); + } dataFolder.mkdirs(); this.m_dataFolder = dataFolder; } @@ -474,9 +512,11 @@ public final void setDatafolder(File dataFolder) { * Set the file for this loadable. * * @param file the file - * @return the file */ public final void setFile(File file) { + if (m_file != null) { + throw new IllegalStateException("File already set"); + } this.m_file = file; } @@ -484,9 +524,11 @@ public final void setFile(File file) { * Set the jar file. * * @param jar the jar - * @return the jar file */ public final void setJarFile(JarFile jar) { + if (m_jar != null) { + throw new IllegalStateException("Jar file already set"); + } this.m_jar = jar; } @@ -494,12 +536,28 @@ public final void setJarFile(JarFile jar) { * Set the {@link ModuleDescription} for this module. * * @param ldf the loadable description file - * @return the loadable description file */ public final void setDesciption(ModuleDescription ldf) { + if (m_description != null) { + throw new IllegalStateException("Description already set"); + } this.m_description = ldf; } + /** + * Sets the {@link ModuleClassLoader} for this module + * + * @param loader the current class loader for this module + */ + public final void setClassLoader(ModuleClassLoader loader) { + if (m_loader != null) { + throw new IllegalStateException("Class loader already set"); + } + this.m_loader = loader; + } + + /* End Loading specific methods */ + /** * Gets the config. * @@ -531,6 +589,15 @@ public final File getFile() { return m_file; } + /** + * Gets the name of the Loadable. + * + * @return The name + */ + public final ModuleClassLoader getClassLoader() { + return m_loader; + } + /** * Gets the name of the Loadable. * @@ -540,6 +607,15 @@ public final String getName() { return getDesciption().getName(); } + /** + * Gets the version of this module loaded from the path.yml file. + * + * @return the module version + */ + public final String getVersion() { + return getDesciption().getVersion(); + } + /** * Gets an embedded resource in this plugin. * @@ -580,15 +656,17 @@ public final void reloadConfig() { /** * Saves the config. */ - public final void saveConfig() { + public final boolean saveConfig() { if (m_config == null || m_configFile == null) { - return; + return false; } try { m_config.save(m_configFile); } catch (IOException e) { + return false; } + return true; } /** diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleLoader.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleLoader.java index 00adf80..b14ff41 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleLoader.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleLoader.java @@ -47,7 +47,7 @@ public class ModuleLoader { */ public ModuleLoader() { m_modules = new LinkedList(); - if (getModuleDir().mkdir()) { + if (bFundamentals.getConfigurationManager().getModuleDirectory().mkdir()) { bFundamentals.log(Level.INFO, "Creating Module Directory..."); } } @@ -56,9 +56,10 @@ public ModuleLoader() { * Gets the directory of the modules. * * @return the module dir + * @deprecated {@link uk.codingbadgers.bFundamentals.ConfigManager.getModuleDirectory)} */ public File getModuleDir() { - return new File(bFundamentals.getInstance().getDataFolder(), "modules"); + return bFundamentals.getConfigurationManager().getModuleDirectory(); } /** @@ -66,7 +67,7 @@ public File getModuleDir() { */ public void load() { - List files = Arrays.asList(getModuleDir().listFiles(new FileExtensionFilter(".jar"))); + List files = Arrays.asList(bFundamentals.getConfigurationManager().getModuleDirectory().listFiles(new FileExtensionFilter(".jar"))); for (File file : files) { loadModule(file); } @@ -116,8 +117,9 @@ public Module loadModule(File file) { for (Class clazz : modules) { - if (bFundamentals.getConfigurationManager().isDebugEnabled()) - getLogger().log(Level.INFO, "Loading module " + clazz.getName()); + if (bFundamentals.getConfigurationManager().isDebugEnabled()) { + getLogger().log(Level.INFO, "Loading clazz " + clazz.getName()); + } ModuleDescription description = moduledescription; @@ -142,7 +144,8 @@ public Module loadModule(File file) { result.setFile(file); result.setDesciption(description); result.setJarFile(jarFile); - result.setDatafolder(new File(getModuleDir(), result.getName())); + result.setDatafolder(new File(bFundamentals.getConfigurationManager().getModuleDirectory(), result.getName())); + result.setClassLoader(loader); result.init(); ModuleLoadEvent event = new ModuleLoadEvent(bFundamentals.getInstance(), result, jarFile); @@ -157,7 +160,7 @@ public Module loadModule(File file) { getLogger().log(Level.WARNING, "The JAR file " + file.getName() + " is in the wrong directory."); getLogger().log(Level.WARNING, "The JAR file " + file.getName() + " failed to load."); } catch (ClassNotFoundException e) { - getLogger().log(Level.WARNING, "Invalid path.yml."); + //getLogger().log(Level.WARNING, "Invalid path.yml."); Path.yml's are now deprecated getLogger().log(Level.WARNING, e.getMessage()); getLogger().log(Level.WARNING, "The JAR file " + file.getName() + " failed to load."); } catch (Exception e) { @@ -181,7 +184,7 @@ private Logger getLogger() { * the files name */ public void load(String fileName) { - File module = new File(getModuleDir() + File.separator + fileName + ".jar"); + File module = new File(bFundamentals.getConfigurationManager().getModuleDirectory() + File.separator + fileName + ".jar"); load(module); } @@ -225,9 +228,6 @@ public void unload() { public void unload(Module module) { try { module.setEnabled(false); - for (Listener listener : module.getListeners()) { - HandlerList.unregisterAll(listener); - } m_modules.remove(module); } catch (Exception ex) { ExceptionHandler.handleException(ex); diff --git a/bFundamentals/test/uk/thecodingbadgers/bFundamentals/TestConfigManager.java b/bFundamentals/test/uk/thecodingbadgers/bFundamentals/TestConfigManager.java index e6f87cb..903d1ec 100644 --- a/bFundamentals/test/uk/thecodingbadgers/bFundamentals/TestConfigManager.java +++ b/bFundamentals/test/uk/thecodingbadgers/bFundamentals/TestConfigManager.java @@ -65,6 +65,11 @@ public String getLogPrefix() { throw new UnsupportedOperationException(); } + @Override + public File getModuleDirectory() { + throw new UnsupportedOperationException(); + } + @Override public String getCrashPassword() { return "PASSWORD"; From cf7952ac59498a8b2cfc35b41da2510b3ac157c3 Mon Sep 17 00:00:00 2001 From: James Fitzpatrick Date: Tue, 17 Sep 2013 18:58:39 +0100 Subject: [PATCH 07/10] Updated licensing --- .../banimalcare/AnimalCommand.java | 17 +++++++++++++++++ .../bFundamentals/module/ModuleClassLoader.java | 17 +++++++++++++++++ .../bFundamentals/module/ModuleDescription.java | 17 +++++++++++++++++ .../module/annotation/ModuleInfo.java | 17 +++++++++++++++++ .../module/events/ModuleDisableEvent.java | 17 +++++++++++++++++ .../module/events/ModuleEnableEvent.java | 17 +++++++++++++++++ .../module/events/ModuleEvent.java | 17 +++++++++++++++++ .../module/events/ModuleLoadEvent.java | 17 +++++++++++++++++ .../module/loader/ClassFinder.java | 17 +++++++++++++++++ .../module/loader/FileExtensionFilter.java | 17 +++++++++++++++++ .../module/loader/ModuleLoader.java | 17 +++++++++++++++++ .../bFundamentals/utils/CollectionUtils.java | 17 +++++++++++++++++ 12 files changed, 204 insertions(+) diff --git a/bAnimalCare/src/uk/codingbadgers/banimalcare/AnimalCommand.java b/bAnimalCare/src/uk/codingbadgers/banimalcare/AnimalCommand.java index b24efb3..219fecd 100644 --- a/bAnimalCare/src/uk/codingbadgers/banimalcare/AnimalCommand.java +++ b/bAnimalCare/src/uk/codingbadgers/banimalcare/AnimalCommand.java @@ -1,3 +1,20 @@ +/** + * bAnimalCare 1.2-SNAPSHOT + * Copyright (C) 2013 CodingBadgers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package uk.codingbadgers.banimalcare; import org.bukkit.command.CommandSender; diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/ModuleClassLoader.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/ModuleClassLoader.java index 640a5c1..b83146d 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/ModuleClassLoader.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/ModuleClassLoader.java @@ -1,3 +1,20 @@ +/** + * bFundamentals 1.2-SNAPSHOT + * Copyright (C) 2013 CodingBadgers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package uk.codingbadgers.bFundamentals.module; import java.net.URL; diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/ModuleDescription.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/ModuleDescription.java index 0cc1ad0..e147ec1 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/ModuleDescription.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/ModuleDescription.java @@ -1,3 +1,20 @@ +/** + * bFundamentals 1.2-SNAPSHOT + * Copyright (C) 2013 CodingBadgers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package uk.codingbadgers.bFundamentals.module; import java.io.InputStream; diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/annotation/ModuleInfo.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/annotation/ModuleInfo.java index 40ba502..69846da 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/annotation/ModuleInfo.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/annotation/ModuleInfo.java @@ -1,3 +1,20 @@ +/** + * bFundamentals 1.2-SNAPSHOT + * Copyright (C) 2013 CodingBadgers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package uk.codingbadgers.bFundamentals.module.annotation; import java.lang.annotation.Documented; diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleDisableEvent.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleDisableEvent.java index e49bc79..be3c647 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleDisableEvent.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleDisableEvent.java @@ -1,3 +1,20 @@ +/** + * bFundamentals 1.2-SNAPSHOT + * Copyright (C) 2013 CodingBadgers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package uk.codingbadgers.bFundamentals.module.events; import org.bukkit.plugin.Plugin; diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleEnableEvent.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleEnableEvent.java index a863d99..cc72b17 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleEnableEvent.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleEnableEvent.java @@ -1,3 +1,20 @@ +/** + * bFundamentals 1.2-SNAPSHOT + * Copyright (C) 2013 CodingBadgers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package uk.codingbadgers.bFundamentals.module.events; import org.bukkit.plugin.Plugin; diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleEvent.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleEvent.java index 4c51bb4..9869bf4 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleEvent.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleEvent.java @@ -1,3 +1,20 @@ +/** + * bFundamentals 1.2-SNAPSHOT + * Copyright (C) 2013 CodingBadgers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package uk.codingbadgers.bFundamentals.module.events; import org.bukkit.event.Event; diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleLoadEvent.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleLoadEvent.java index f7e761a..8bcc9ef 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleLoadEvent.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleLoadEvent.java @@ -1,3 +1,20 @@ +/** + * bFundamentals 1.2-SNAPSHOT + * Copyright (C) 2013 CodingBadgers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package uk.codingbadgers.bFundamentals.module.events; import java.util.jar.JarFile; diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ClassFinder.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ClassFinder.java index 5127dc9..c2f9116 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ClassFinder.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ClassFinder.java @@ -1,3 +1,20 @@ +/** + * bFundamentals 1.2-SNAPSHOT + * Copyright (C) 2013 CodingBadgers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package uk.codingbadgers.bFundamentals.module.loader; import java.net.URL; diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/FileExtensionFilter.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/FileExtensionFilter.java index 64bebe2..44e8ea5 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/FileExtensionFilter.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/FileExtensionFilter.java @@ -1,3 +1,20 @@ +/** + * bFundamentals 1.2-SNAPSHOT + * Copyright (C) 2013 CodingBadgers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package uk.codingbadgers.bFundamentals.module.loader; import java.io.File; diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleLoader.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleLoader.java index b14ff41..430fbeb 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleLoader.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleLoader.java @@ -1,3 +1,20 @@ +/** + * bFundamentals 1.2-SNAPSHOT + * Copyright (C) 2013 CodingBadgers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package uk.codingbadgers.bFundamentals.module.loader; import java.io.File; diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/utils/CollectionUtils.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/utils/CollectionUtils.java index 9a2e696..aa58d49 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/utils/CollectionUtils.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/utils/CollectionUtils.java @@ -1,3 +1,20 @@ +/** + * bFundamentals 1.2-SNAPSHOT + * Copyright (C) 2013 CodingBadgers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package uk.codingbadgers.bFundamentals.utils; import java.util.List; From 9d1f2b5036a9a3ecaca030b38252346b89c23010 Mon Sep 17 00:00:00 2001 From: James Fitzpatrick Date: Tue, 17 Sep 2013 19:31:33 +0100 Subject: [PATCH 08/10] Updated javadoc --- .../bFundamentals/error/ExceptionHandler.java | 13 +++++ .../bFundamentals/module/Module.java | 19 +++++-- .../module/ModuleDescription.java | 5 +- .../module/annotation/ModuleInfo.java | 27 ++++++++- .../module/events/ModuleDisableEvent.java | 10 ++++ .../module/events/ModuleEnableEvent.java | 10 ++++ .../module/events/ModuleEvent.java | 29 +++++++++- .../module/events/ModuleLoadEvent.java | 25 +++++++++ .../module/loader/ClassFinder.java | 19 ++++++- .../module/loader/FileExtensionFilter.java | 11 ++++ .../{ => loader}/ModuleClassLoader.java | 33 ++++++++++- .../module/loader/ModuleLoader.java | 56 +++++++++++++------ 12 files changed, 225 insertions(+), 32 deletions(-) rename bFundamentals/src/uk/codingbadgers/bFundamentals/module/{ => loader}/ModuleClassLoader.java (74%) diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/error/ExceptionHandler.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/error/ExceptionHandler.java index d86d0d4..2b8b342 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/error/ExceptionHandler.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/error/ExceptionHandler.java @@ -22,6 +22,10 @@ import uk.codingbadgers.bFundamentals.bFundamentals; +/** + * The Class ExceptionHandler, handles exceptions generated by bFundamentals + * and any sub modules. + */ public class ExceptionHandler implements UncaughtExceptionHandler { private static final ExceptionHandler instance; @@ -31,12 +35,21 @@ public class ExceptionHandler implements UncaughtExceptionHandler { Thread.setDefaultUncaughtExceptionHandler(instance); } + /** + * Handle an exception. + * + * @param e the exception caught + * @return true, if successful + */ public static boolean handleException(Throwable e) { bFundamentals.getInstance().getLogger().log(Level.WARNING, null, e); ReportExceptionRunnable run = new ReportExceptionRunnable(e); return run.run(); } + /* (non-Javadoc) + * @see java.lang.Thread.UncaughtExceptionHandler#uncaughtException(java.lang.Thread, java.lang.Throwable) + */ @Override public void uncaughtException(Thread t, Throwable e) { handleException(e); diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/Module.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/Module.java index c5504d9..9b73c3f 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/Module.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/Module.java @@ -62,6 +62,7 @@ import uk.codingbadgers.bFundamentals.module.events.ModuleDisableEvent; import uk.codingbadgers.bFundamentals.module.events.ModuleEnableEvent; import uk.codingbadgers.bFundamentals.module.loader.ClassFinder; +import uk.codingbadgers.bFundamentals.module.loader.ModuleClassLoader; import uk.codingbadgers.bFundamentals.module.loader.ModuleLoader; import uk.codingbadgers.bFundamentals.update.UpdateThread; import uk.codingbadgers.bFundamentals.update.Updater; @@ -102,6 +103,9 @@ public Module() { m_debug = bFundamentals.getConfigurationManager().isDebugEnabled(); } + /** + * Initialise this module + */ public final void init() { m_log = new ModuleLogger(this); } @@ -111,6 +115,9 @@ protected final void setUpdater(Updater updater) { log(Level.INFO, "Set new updater to " + m_updater.getUpdater().getUpdater()); } + /** + * If enabled, check if this module needs a update + */ public final void update() { if (m_updater == null) { log(Level.INFO, "Updater is null, cannot check for updates"); @@ -604,7 +611,7 @@ public final ModuleClassLoader getClassLoader() { * @return The name */ public final String getName() { - return getDesciption().getName(); + return getDescription().getName(); } /** @@ -613,7 +620,7 @@ public final String getName() { * @return the module version */ public final String getVersion() { - return getDesciption().getVersion(); + return getDescription().getVersion(); } /** @@ -655,6 +662,8 @@ public final void reloadConfig() { /** * Saves the config. + * + * @return if the config was saved successfully */ public final boolean saveConfig() { if (m_config == null || m_configFile == null) { @@ -670,11 +679,11 @@ public final boolean saveConfig() { } /** - * Gets the desciption. + * Gets the description. * - * @return the desciption + * @return the description */ - public final ModuleDescription getDesciption() { + public final ModuleDescription getDescription() { return this.m_description; } diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/ModuleDescription.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/ModuleDescription.java index e147ec1..88458b9 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/ModuleDescription.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/ModuleDescription.java @@ -31,7 +31,7 @@ /** * The Class LoadableDescriptionFile, represents the data stored in the - * about a module, either by a path.yml file of a {@link Loadable} or a + * about a module, either by a path.yml file of a {@link Module} or a * {@link ModuleInfo} annotation. * * @author James Fitzpatrick @@ -66,7 +66,8 @@ public ModuleDescription(InputStream istream) { * Instantiates a new module description from the data in a * {@link ModuleInfo} annotation. * - * @param istream the input stream that this file is loaded from + * @param info the {@link ModuleInfo} annotation + * @param mainclass the mainclass loaded */ public ModuleDescription(ModuleInfo info, String mainclass) { this.name = info.value(); diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/annotation/ModuleInfo.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/annotation/ModuleInfo.java index 69846da..a971033 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/annotation/ModuleInfo.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/annotation/ModuleInfo.java @@ -23,17 +23,40 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** + * The Annotation ModuleInfo, defines the module information for a class. + */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface ModuleInfo { + /** + * The module's name. + * + * @return the module's name + */ String value(); - + + /** + * The module's version. + * + * @return the module's version + */ String version() default "1.0"; - + + /** + * The module's authors. + * + * @return the module's authors + */ String[] authors() default {"Unkown"}; + /** + * The module's description. + * + * @return the module's description + */ String description() default ""; } diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleDisableEvent.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleDisableEvent.java index be3c647..c3dc664 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleDisableEvent.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleDisableEvent.java @@ -21,8 +21,18 @@ import uk.codingbadgers.bFundamentals.module.Module; +/** + * The ModuleDisableEvent, called when a module is disabled via + * {@link Module#setEnabled(boolean)}. + */ public class ModuleDisableEvent extends ModuleEvent { + /** + * Instantiates a new module disable event. + * + * @param plugin the plugin + * @param loadable the loadable + */ public ModuleDisableEvent(Plugin plugin, Module loadable) { super(plugin, loadable); } diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleEnableEvent.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleEnableEvent.java index cc72b17..0d95f63 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleEnableEvent.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleEnableEvent.java @@ -21,8 +21,18 @@ import uk.codingbadgers.bFundamentals.module.Module; +/** + * The ModuleEnableEvent, called when a module is enabled via + * {@link Module#setEnabled(boolean)}. + */ public class ModuleEnableEvent extends ModuleEvent { + /** + * Instantiates a new module enable event. + * + * @param plugin the plugin + * @param loadable the loadable + */ public ModuleEnableEvent(Plugin plugin, Module loadable) { super(plugin, loadable); } diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleEvent.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleEvent.java index 9869bf4..ded11e7 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleEvent.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleEvent.java @@ -23,15 +23,26 @@ import uk.codingbadgers.bFundamentals.module.Module; -public class ModuleEvent extends Event { +/** + * A module event, represents an event that . + */ +public abstract class ModuleEvent extends Event { private static final HandlerList handlers = new HandlerList(); + /* (non-Javadoc) + * @see org.bukkit.event.Event#getHandlers() + */ @Override public HandlerList getHandlers() { return handlers; } + /** + * Gets the handler list. + * + * @return the handler list + */ public static HandlerList getHandlerList() { return handlers; } @@ -39,15 +50,31 @@ public static HandlerList getHandlerList() { private final Plugin plugin; private final Module loadable; + /** + * Instantiates a new module event. + * + * @param plugin the plugin + * @param loadable the module involved in the event + */ public ModuleEvent(Plugin plugin, Module loadable) { this.plugin = plugin; this.loadable = loadable; } + /** + * Gets the module involved in the event. + * + * @return the module + */ public Module getModule() { return loadable; } + /** + * Gets the plugin. + * + * @return the plugin + */ public Plugin getPlugin() { return plugin; } diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleLoadEvent.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleLoadEvent.java index 8bcc9ef..4b8e07f 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleLoadEvent.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleLoadEvent.java @@ -23,28 +23,53 @@ import org.bukkit.plugin.Plugin; import uk.codingbadgers.bFundamentals.module.Module; +import uk.codingbadgers.bFundamentals.module.loader.ModuleLoader; +/** + * The ModuleLoadEvent, called when a module is loaded via + * {@link ModuleLoader#loadModule(java.io.File)}. + */ public class ModuleLoadEvent extends ModuleEvent { private static final HandlerList handlers = new HandlerList(); + /* (non-Javadoc) + * @see uk.codingbadgers.bFundamentals.module.events.ModuleEvent#getHandlers() + */ @Override public HandlerList getHandlers() { return handlers; } + /** + * Gets the handler list. + * + * @return the handler list + */ public static HandlerList getHandlerList() { return handlers; } private final JarFile jarFile; + /** + * Instantiates a new module load event. + * + * @param plugin the plugin + * @param loadable the loadable + * @param jarFile the jar file + */ public ModuleLoadEvent(Plugin plugin, Module loadable, JarFile jarFile) { super(plugin, loadable); this.jarFile = jarFile; } + /** + * Gets the jar file. + * + * @return the jar file + */ public JarFile getJarFile() { return jarFile; } diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ClassFinder.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ClassFinder.java index c2f9116..ffa8aab 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ClassFinder.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ClassFinder.java @@ -25,15 +25,32 @@ import org.reflections.util.ConfigurationBuilder; import uk.codingbadgers.bFundamentals.module.Module; -import uk.codingbadgers.bFundamentals.module.ModuleClassLoader; +/** + * The Class ClassFinder, used to find specific types of classes quickly for + * module auto loading and registration. + */ public class ClassFinder { + /** + * Find all the module classes in a class loader. + * + * @param loader the loader + * @param url the urls to check + * @return all classes that extend {@link Module} in that loader + */ public static Set> findModules(ModuleClassLoader loader, URL[] url) { Reflections reflect = new Reflections(new ConfigurationBuilder().addUrls(url).addClassLoader(loader).addClassLoader(ClassFinder.class.getClassLoader())); return reflect.getSubTypesOf(Module.class); } + /** + * Find all the listener classes in a class loader. + * + * @param loader the loader + * @param url the urls to check + * @return all classes that implement {@link Listener} in that loader + */ public static Set> findListeners(ModuleClassLoader loader, URL[] url) { Reflections reflect = new Reflections(new ConfigurationBuilder().addUrls(url).addClassLoader(loader).addClassLoader(ClassFinder.class.getClassLoader())); return reflect.getSubTypesOf(Listener.class); diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/FileExtensionFilter.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/FileExtensionFilter.java index 44e8ea5..e3368bd 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/FileExtensionFilter.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/FileExtensionFilter.java @@ -20,14 +20,25 @@ import java.io.File; import java.io.FileFilter; +/** + * The Class FileExtensionFilter. + */ public final class FileExtensionFilter implements FileFilter { private final String extension; + /** + * Instantiates a new file extension filter. + * + * @param extension the extension to test for + */ public FileExtensionFilter(String extension) { this.extension = extension; } + /* (non-Javadoc) + * @see java.io.FileFilter#accept(java.io.File) + */ public boolean accept(File file) { return file.getName().endsWith(extension); } diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/ModuleClassLoader.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleClassLoader.java similarity index 74% rename from bFundamentals/src/uk/codingbadgers/bFundamentals/module/ModuleClassLoader.java rename to bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleClassLoader.java index b83146d..45139de 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/ModuleClassLoader.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleClassLoader.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package uk.codingbadgers.bFundamentals.module; +package uk.codingbadgers.bFundamentals.module.loader; import java.net.URL; import java.net.URLClassLoader; @@ -25,12 +25,21 @@ import org.apache.commons.lang.Validate; -import uk.codingbadgers.bFundamentals.module.loader.ModuleLoader; +/** + * The ModuleClassLoader, used to load classes for modules. + */ public class ModuleClassLoader extends URLClassLoader { private final ModuleLoader loader; private final Map> classes = new HashMap>(); + /** + * Instantiates a new module class loader. + * + * @param moduleLoader the module loader + * @param urls the urls of the module + * @param parent the parent + */ public ModuleClassLoader(final ModuleLoader moduleLoader, final URL[] urls, final ClassLoader parent) { super(urls, parent); Validate.notNull(moduleLoader, "Loader cannot be null"); @@ -47,10 +56,19 @@ protected Class findClass(String name) throws ClassNotFoundException { return findClass(name, true); } + /** + * Find a class. + * + * @param name the name of the class in the format for {@link Class#forName(String)} + * @param checkGlobal whether or not to check the global cache + * @return the class loaded + * @throws ClassNotFoundException the class not found exception + */ public Class findClass(String name, boolean checkGlobal) throws ClassNotFoundException { if (name.startsWith("org.bukkit.") || name.startsWith("net.minecraft.")) { throw new ClassNotFoundException(name); } + Class result = classes.get(name); if (result == null) { @@ -68,10 +86,19 @@ public Class findClass(String name, boolean checkGlobal) throws ClassNotFound classes.put(name, result); } - + + if (result == null) { + throw new ClassNotFoundException(name); + } + return result; } + /** + * Gets the cache of all the classes loaded by this loader. + * + * @return the cache + */ public Set getClasses() { return classes.keySet(); } diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleLoader.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleLoader.java index 430fbeb..ff40ea7 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleLoader.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleLoader.java @@ -38,20 +38,20 @@ import org.bukkit.Bukkit; import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.configuration.serialization.ConfigurationSerialization; -import org.bukkit.event.HandlerList; -import org.bukkit.event.Listener; import uk.codingbadgers.bFundamentals.bFundamentals; import uk.codingbadgers.bFundamentals.error.ExceptionHandler; import uk.codingbadgers.bFundamentals.module.Module; -import uk.codingbadgers.bFundamentals.module.ModuleClassLoader; import uk.codingbadgers.bFundamentals.module.ModuleDescription; import uk.codingbadgers.bFundamentals.module.ModuleHelpTopic; import uk.codingbadgers.bFundamentals.module.annotation.ModuleInfo; import uk.codingbadgers.bFundamentals.module.events.ModuleLoadEvent; +// TODO: Auto-generated Javadoc /** - * The ModuleLoader. + * The ModuleLoader, used to load bFundamentals {@link Module}'s at runtime, + * will automatically find any classes that extend {@link Module} in jars in + * the module directory and load them in. */ public class ModuleLoader { @@ -73,7 +73,7 @@ public ModuleLoader() { * Gets the directory of the modules. * * @return the module dir - * @deprecated {@link uk.codingbadgers.bFundamentals.ConfigManager.getModuleDirectory)} + * @deprecated {@link uk.codingbadgers.bFundamentals.ConfigManager#getModuleDirectory()} */ public File getModuleDir() { return bFundamentals.getConfigurationManager().getModuleDirectory(); @@ -103,6 +103,12 @@ public void load() { bFundamentals.log(Level.INFO, "Loaded " + m_modules.size() + " modules."); } + /** + * Load a module into the server. + * + * @param file the module's jar file + * @return the module instance + */ public Module loadModule(File file) { Module result = null; @@ -195,10 +201,9 @@ private Logger getLogger() { } /** - * Loads a module with a given name - * - * @param fileName - * the files name + * Loads a module with a given name. + * + * @param fileName the files name */ public void load(String fileName) { File module = new File(bFundamentals.getConfigurationManager().getModuleDirectory() + File.separator + fileName + ".jar"); @@ -206,10 +211,9 @@ public void load(String fileName) { } /** - * Loads a module with a jar file - * - * @param file - * the jar file for this module + * Loads a module with a jar file. + * + * @param file the jar file for this module */ public void load(File file) { if (getModule(file) != null) { @@ -289,7 +293,7 @@ public List getModules() { } /** - * Update all the loaded modules if an updater is set + * Update all the loaded modules if an updater is set. */ public void update() { if (!bFundamentals.getConfigurationManager().isAutoUpdateEnabled()) { @@ -337,7 +341,14 @@ public Module getModule(File file) { return null; } - public Class getClassByName(String name) { + /** + * Gets a class by its name from any of the module class loads. + * + * @param name the full class name, in the format for {@link Class#forName(String)} + * @return the class specified by its name + * @throws ClassNotFoundException if the specific class cannot be found + */ + Class getClassByName(String name) throws ClassNotFoundException { Class cachedClass = classes.get(name); if (cachedClass != null) { @@ -355,10 +366,16 @@ public Class getClassByName(String name) { } } } - return null; + throw new ClassNotFoundException(name); } - public void setClass(String name, Class clazz) { + /** + * Sets a class for a specific name in the internal cache. + * + * @param name the name + * @param clazz the class + */ + void setClass(String name, Class clazz) { if (!classes.containsKey(name)) { classes.put(name, clazz); @@ -369,7 +386,10 @@ public void setClass(String name, Class clazz) { } } - public void sort() { + /** + * Sort the modules by name in the module list. + */ + void sort() { List sortedLoadables = new ArrayList(); List names = new ArrayList(); From 6c55a95afad045b4827f27631314dbe33f0a3f00 Mon Sep 17 00:00:00 2001 From: James Fitzpatrick Date: Thu, 26 Sep 2013 16:43:56 +0100 Subject: [PATCH 09/10] General Cleanup --- .../bFundamentals/module/Module.java | 3 - .../module/ModuleDescription.java | 148 +++++++++--------- .../module/events/ModuleLoadEvent.java | 1 - .../bFundamentals/utils/CollectionUtils.java | 10 ++ 4 files changed, 85 insertions(+), 77 deletions(-) diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/Module.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/Module.java index 9b73c3f..5ff0b0f 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/Module.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/Module.java @@ -57,13 +57,10 @@ import uk.codingbadgers.bFundamentals.commands.ModuleCommandHandler; import uk.codingbadgers.bFundamentals.config.ConfigFactory; import uk.codingbadgers.bFundamentals.config.ConfigFile; -import uk.codingbadgers.bFundamentals.config.annotation.Element; -import uk.codingbadgers.bFundamentals.module.annotation.ModuleInfo; import uk.codingbadgers.bFundamentals.module.events.ModuleDisableEvent; import uk.codingbadgers.bFundamentals.module.events.ModuleEnableEvent; import uk.codingbadgers.bFundamentals.module.loader.ClassFinder; import uk.codingbadgers.bFundamentals.module.loader.ModuleClassLoader; -import uk.codingbadgers.bFundamentals.module.loader.ModuleLoader; import uk.codingbadgers.bFundamentals.update.UpdateThread; import uk.codingbadgers.bFundamentals.update.Updater; import uk.thecodingbadgers.bDatabaseManager.Database.BukkitDatabase; diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/ModuleDescription.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/ModuleDescription.java index 88458b9..5ba1022 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/ModuleDescription.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/ModuleDescription.java @@ -30,103 +30,105 @@ import uk.codingbadgers.bFundamentals.utils.CollectionUtils; /** - * The Class LoadableDescriptionFile, represents the data stored in the - * about a module, either by a path.yml file of a {@link Module} or a - * {@link ModuleInfo} annotation. + * The Class LoadableDescriptionFile, represents the data stored in the about a + * module, either by a path.yml file of a {@link Module} or a {@link ModuleInfo} + * annotation. * * @author James Fitzpatrick */ public class ModuleDescription { - - private final String name; - private final String version; - private final String description; - private final String mainClass; + + private final String name; + private final String version; + private final String description; + private final String mainClass; private final List authors; private final Collection dependencies; - - /** - * Instantiates a new module description from the data in a path.yml - * file. - * - * @param istream the input stream that this file is loaded from - */ - public ModuleDescription(InputStream istream) { - YamlConfiguration ldf = YamlConfiguration.loadConfiguration(istream); - - name = ldf.getString("name", "Unknown Module"); - version = ldf.getString("version", "0.0"); - description = ldf.getString("description", ""); - mainClass = ldf.getString("main-class"); - authors = CollectionUtils.toImmutableList(ldf.getStringList("authors")); - dependencies = Collections.unmodifiableCollection(ldf.getStringList("dependencies")); - } - /** - * Instantiates a new module description from the data in a - * {@link ModuleInfo} annotation. - * - * @param info the {@link ModuleInfo} annotation - * @param mainclass the mainclass loaded - */ - public ModuleDescription(ModuleInfo info, String mainclass) { - this.name = info.value(); - this.version = info.version(); - this.mainClass = mainclass; - this.description = info.description(); - this.authors = CollectionUtils.toImmutableList(Arrays.asList(info.authors())); - this.dependencies = Collections.unmodifiableCollection(new ArrayList()); + /** + * Instantiates a new module description from the data in a path.yml file. + * + * @param istream + * the input stream that this file is loaded from + */ + public ModuleDescription(InputStream istream) { + YamlConfiguration ldf = YamlConfiguration.loadConfiguration(istream); + + name = ldf.getString("name", "Unknown Module"); + version = ldf.getString("version", "0.0"); + description = ldf.getString("description", ""); + mainClass = ldf.getString("main-class"); + authors = CollectionUtils.toImmutableList(ldf.getStringList("authors")); + dependencies = Collections.unmodifiableCollection(ldf.getStringList("dependencies")); + } + + /** + * Instantiates a new module description from the data in a + * {@link ModuleInfo} annotation. + * + * @param info + * the {@link ModuleInfo} annotation + * @param mainclass + * the mainclass loaded + */ + public ModuleDescription(ModuleInfo info, String mainclass) { + this.name = info.value(); + this.version = info.version(); + this.mainClass = mainclass; + this.description = info.description(); + this.authors = CollectionUtils.toImmutableList(Arrays.asList(info.authors())); + this.dependencies = Collections.unmodifiableCollection(new ArrayList()); + } + + /** + * Gets the name of this module. + * + * @return the name of this module + */ + public String getName() { + return name; + } + + /** + * Gets the version of this module. + * + * @return the version of this module + */ + public String getVersion() { + return version; + } + + /** + * Gets the description for this module. + * + * @return the description of this module + */ + public String getDescription() { + return description; } /** - * Gets the name of this module. - * - * @return the name of this module - */ - public String getName() { - return name; - } - - /** - * Gets the version of this module. - * - * @return the version of this module - */ - public String getVersion() { - return version; - } - - /** - * Gets the description for this module. - * - * @return the description of this module - */ - public String getDescription() { - return description; - } - - /** * Gets the main class of this module. * * @return the fully qualified name of the main class of this module * @deprecated Main classes should not have to be defined anymore */ - public String getMainClass() { - return mainClass; - } + public String getMainClass() { + return mainClass; + } /** * Gets the authors of this module. - * + * * @return a immutable list of the authors of this module */ public List getAuthors() { return authors; } - + /** - * Gets the module dependencies of this loadable, this module will load after - * all of the dependencies have module. + * Gets the module dependencies of this loadable, this module will load + * after all of the dependencies have module. * * @return a unmodifiable collection of the dependencies */ diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleLoadEvent.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleLoadEvent.java index 4b8e07f..ead4cde 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleLoadEvent.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/events/ModuleLoadEvent.java @@ -23,7 +23,6 @@ import org.bukkit.plugin.Plugin; import uk.codingbadgers.bFundamentals.module.Module; -import uk.codingbadgers.bFundamentals.module.loader.ModuleLoader; /** * The ModuleLoadEvent, called when a module is loaded via diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/utils/CollectionUtils.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/utils/CollectionUtils.java index aa58d49..507dba3 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/utils/CollectionUtils.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/utils/CollectionUtils.java @@ -21,8 +21,18 @@ import com.google.common.collect.ImmutableList.Builder; +/** + * The Utility class for using google collections. + */ public class CollectionUtils { + /** + * Create a immutable copy of a list. + * + * @param the generic type of the list + * @param list the list to create a copy of + * @return a immutable copy of the list + */ public static List toImmutableList(List list) { Builder builder = new Builder(); builder.addAll(list); From ccbc1b60ee44e7d27ab0169ad94a9c2872838c51 Mon Sep 17 00:00:00 2001 From: James Fitzpatrick Date: Sun, 13 Oct 2013 13:40:02 +0100 Subject: [PATCH 10/10] Updated module loading exception handling --- bFundamentals/pom.xml | 4 +- .../module/loader/ClassFinder.java | 3 +- .../module/loader/ModuleClassLoader.java | 2 + .../module/loader/ModuleLoader.java | 40 +++++++++++-------- 4 files changed, 30 insertions(+), 19 deletions(-) diff --git a/bFundamentals/pom.xml b/bFundamentals/pom.xml index a9539b8..6256a98 100644 --- a/bFundamentals/pom.xml +++ b/bFundamentals/pom.xml @@ -55,7 +55,9 @@ commons-*:* - org.jnbt:jNBT + org.jnbt:jNBT + org.javassist:javassist + org.reflections:reflections org.apache.httpcomponents:* diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ClassFinder.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ClassFinder.java index ffa8aab..1f12b2a 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ClassFinder.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ClassFinder.java @@ -22,6 +22,7 @@ import org.bukkit.event.Listener; import org.reflections.Reflections; +import org.reflections.util.ClasspathHelper; import org.reflections.util.ConfigurationBuilder; import uk.codingbadgers.bFundamentals.module.Module; @@ -40,7 +41,7 @@ public class ClassFinder { * @return all classes that extend {@link Module} in that loader */ public static Set> findModules(ModuleClassLoader loader, URL[] url) { - Reflections reflect = new Reflections(new ConfigurationBuilder().addUrls(url).addClassLoader(loader).addClassLoader(ClassFinder.class.getClassLoader())); + Reflections reflect = new Reflections(new ConfigurationBuilder().setUrls(ClasspathHelper.forClassLoader(loader)).addClassLoader(loader)); return reflect.getSubTypesOf(Module.class); } diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleClassLoader.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleClassLoader.java index 45139de..4261c65 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleClassLoader.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleClassLoader.java @@ -69,6 +69,8 @@ public Class findClass(String name, boolean checkGlobal) throws ClassNotFound throw new ClassNotFoundException(name); } + System.out.println("Finding class " + name); + Class result = classes.get(name); if (result == null) { diff --git a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleLoader.java b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleLoader.java index ff40ea7..d5fecec 100644 --- a/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleLoader.java +++ b/bFundamentals/src/uk/codingbadgers/bFundamentals/module/loader/ModuleLoader.java @@ -47,11 +47,10 @@ import uk.codingbadgers.bFundamentals.module.annotation.ModuleInfo; import uk.codingbadgers.bFundamentals.module.events.ModuleLoadEvent; -// TODO: Auto-generated Javadoc /** * The ModuleLoader, used to load bFundamentals {@link Module}'s at runtime, - * will automatically find any classes that extend {@link Module} in jars in - * the module directory and load them in. + * it will automatically find any classes that extend {@link Module} in jars + * in the module directory and load them in. */ public class ModuleLoader { @@ -123,7 +122,7 @@ public Module loadModule(File file) { modules.addAll(ClassFinder.findModules(loader, urls)); - // Old system, left for backwards compatibility + // Old system descriptive system, left for backwards compatibility if (jarFile.getEntry("path.yml") != null) { JarEntry element = jarFile.getJarEntry("path.yml"); moduledescription = new ModuleDescription(jarFile.getInputStream(element)); @@ -178,19 +177,26 @@ public Module loadModule(File file) { loaders.put(result.getName(), loader); } - } catch (ClassCastException e) { - e.printStackTrace(); - getLogger().log(Level.WARNING, "The JAR file " + file.getName() + " is in the wrong directory."); - getLogger().log(Level.WARNING, "The JAR file " + file.getName() + " failed to load."); - } catch (ClassNotFoundException e) { - //getLogger().log(Level.WARNING, "Invalid path.yml."); Path.yml's are now deprecated - getLogger().log(Level.WARNING, e.getMessage()); - getLogger().log(Level.WARNING, "The JAR file " + file.getName() + " failed to load."); - } catch (Exception e) { - ExceptionHandler.handleException(e); - getLogger().log(Level.WARNING, "Unknown cause."); - getLogger().log(Level.WARNING, e.getMessage()); - getLogger().log(Level.WARNING, "The JAR file " + file.getName() + " failed to load."); + } catch (Throwable e) { + if (e instanceof Error && !(e instanceof NoClassDefFoundError)) { + getLogger().log(Level.WARNING, "The JAR file " + file.getName() + " failed to load because of a serious error"); + getLogger().log(Level.WARNING, e.getClass().getName()); + } else { + getLogger().log(Level.WARNING, "The JAR file " + file.getName() + " failed to load."); + } + + if (e instanceof ClassCastException) { + getLogger().log(Level.WARNING, "The JAR file " + file.getName() + " is in the wrong directory."); + } else if (e instanceof ClassNotFoundException || e instanceof NoClassDefFoundError) { + getLogger().log(Level.WARNING, "Could not find class " + e.getMessage()); + getLogger().log(Level.WARNING, "Are you missing a required dependecy?"); + } else if (e instanceof RuntimeException) { + getLogger().log(Level.WARNING, "Unknown cause", e); + } else { + getLogger().log(Level.WARNING, "Unknown cause."); + getLogger().log(Level.WARNING, e.getMessage()); + ExceptionHandler.handleException(e); + } } return result;