package com.w67clement.mineapi.system.modules;
import com.w67clement.mineapi.MineAPI;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import org.apache.commons.lang.Validate;
import org.bukkit.ChatColor;
import org.bukkit.plugin.InvalidDescriptionException;
import org.yaml.snakeyaml.error.YAMLException;
public class ModuleLoader
{
private HashMap<String, Module> modules = new HashMap<String, Module>();
private ClassLoader loader;
private MineAPI mineapi;
public ModuleLoader(ClassLoader loader, MineAPI mineapi)
{
this.loader = loader;
this.mineapi = mineapi;
}
public Module loadModule(File file) throws InvalidModuleException
{
if (!file.exists())
{
throw new InvalidModuleException(new FileNotFoundException(file.getPath() + " does not exist"));
}
ModuleInformations description = null;
try
{
description = getDescription(file);
MineAPI.sendMessageToConsole(MineAPI.PREFIX + ChatColor.GREEN + "Loading " + ChatColor.DARK_GREEN + description.getName());
}
catch (InvalidDescriptionException e)
{
throw new InvalidModuleException(e);
}
try
{
Method method = URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{URL.class});
method.setAccessible(true);
method.invoke(loader, file.toURI().toURL());
}
catch (NoSuchMethodException | SecurityException
| IllegalAccessException | IllegalArgumentException
| InvocationTargetException | MalformedURLException e1)
{
e1.printStackTrace();
}
try
{
Class<?> moduleClass = this.loader.loadClass(description.getMain());
Constructor<?> moduleConstructor = moduleClass.getConstructor(new Class<?>[]{});
Module obj = (Module) moduleConstructor.newInstance(new Object[]{});
obj.setModuleInformations(description);
obj.setMineAPI(mineapi);
modules.put(description.getName(), obj);
return obj;
}
catch (ClassNotFoundException | NoSuchMethodException
| SecurityException | InstantiationException
| IllegalAccessException | IllegalArgumentException
| InvocationTargetException e)
{
throw new InvalidModuleException(e);
}
}
public void enableModule(Module module)
{
MineAPI.sendMessageToConsole(MineAPI.PREFIX + ChatColor.GREEN + "Enabling " + ChatColor.DARK_GREEN + module.getName());
module.onEnable();
module.setEnabled(true);
}
public void disableModule(Module module)
{
MineAPI.sendMessageToConsole(MineAPI.PREFIX + ChatColor.GREEN + "Disabling " + ChatColor.DARK_GREEN + module.getName());
module.onDisable();
module.setEnabled(false);
}
public ModuleInformations getDescription(File file) throws InvalidDescriptionException
{
Validate.notNull(file, "File cannot be null");
JarFile jar = null;
InputStream stream = null;
try
{
jar = new JarFile(file);
JarEntry entry = jar.getJarEntry("module.yml");
if (entry == null)
{
throw new InvalidDescriptionException(new FileNotFoundException("Jar does not contain module.yml"));
}
stream = jar.getInputStream(entry);
return new ModuleInformations(stream);
}
catch (IOException ex)
{
throw new InvalidDescriptionException(ex);
}
catch (YAMLException ex)
{
throw new InvalidDescriptionException(ex);
}
finally
{
if (jar != null)
{
try
{
jar.close();
}
catch (IOException e)
{
}
}
if (stream != null)
{
try
{
stream.close();
}
catch (IOException e)
{
}
}
}
}
public HashMap<String, Module> getModules()
{
return modules;
}
}