Diff

core/modulemanager.lua @ 754:01abf314fac0

Automated merge with http://waqas.ath.cx:8000/
author Matthew Wild <mwild1@gmail.com>
date Thu, 29 Jan 2009 17:54:37 +0000
parent 748:172c43d735e9
child 758:b1885732e979
line wrap: on
line diff
--- a/core/modulemanager.lua	Thu Jan 29 22:37:25 2009 +0500
+++ b/core/modulemanager.lua	Thu Jan 29 17:54:37 2009 +0000
@@ -29,10 +29,12 @@
 local multitable_new = require "util.multitable".new;
 local register_actions = require "core.actions".register;
 
+local hosts = hosts;
+
 local loadfile, pcall = loadfile, pcall;
 local setmetatable, setfenv, getfenv = setmetatable, setfenv, getfenv;
 local pairs, ipairs = pairs, ipairs;
-local t_insert = table.insert;
+local t_insert, t_concat = table.insert, table.concat;
 local type = type;
 local next = next;
 local rawget = rawget;
@@ -107,7 +109,7 @@
 	end
 	
 
-	local mod, err = loadfile(plugin_dir.."mod_"..module_name..".lua");
+	local mod, err = loadfile(get_module_filename(module_name));
 	if not mod then
 		log("error", "Unable to load module '%s': %s", module_name or "nil", err or "nil");
 		return nil, err;
@@ -132,18 +134,22 @@
 	return true;
 end
 
+function get_module(host, name)
+	return modulemap[host] and modulemap[host][name];
+end
+
 function is_loaded(host, name)
 	return modulemap[host] and modulemap[host][name] and true;
 end
 
 function unload(host, name, ...)
-	local mod = modulemap[host] and modulemap[host][name];
+	local mod = get_module(host, name); 
 	if not mod then return nil, "module-not-loaded"; end
 	
-	if type(mod.module.unload) == "function" then
-		local ok, err = pcall(mod.module.unload, ...)
+	if module_has_method(mod, "unload") then
+		local ok, err = call_module_method(mod, "unload");
 		if (not ok) and err then
-			log("warn", "Non-fatal error unloading module '%s' from '%s': %s", name, host, err);
+			log("warn", "Non-fatal error unloading module '%s' on '%s': %s", name, host, err);
 		end
 	end
 	modulemap[host][name] = nil;
@@ -161,36 +167,45 @@
 end
 
 function reload(host, name, ...)
-	local mod = modulemap[host] and modulemap[host][name];
+	local mod = get_module(host, name);
 	if not mod then return nil, "module-not-loaded"; end
 
-	local _mod, err = loadfile(plugin_dir.."mod_"..name..".lua"); -- checking for syntax errors
+	local _mod, err = loadfile(get_module_filename(name)); -- checking for syntax errors
 	if not _mod then
 		log("error", "Unable to load module '%s': %s", module_name or "nil", err or "nil");
 		return nil, err;
 	end
 
 	local saved;
-	if type(mod.module.save) == "function" then
-		local ok, err = pcall(mod.module.save)
-		if (not ok) and err then
-			log("warn", "Non-fatal error unloading module '%s' from '%s': %s", name, host, err);
+
+	if module_has_method(mod, "save") then
+		local ok, ret, err = call_module_method(mod, "save");
+		if ok then
+			saved = ret;
 		else
-			saved = err;
+			log("warn", "Error saving module '%s:%s' state: %s", host, module, ret);
+			if not config.get(host, "core", "force_module_reload") then
+				log("warn", "Aborting reload due to error, set force_module_reload to ignore this");
+				return nil, "save-state-failed";
+			else
+				log("warn", "Continuing with reload (using the force)");
+			end
 		end
 	end
 
 	unload(host, name, ...);
-	if load(host, name, ...) then
-		mod = modulemap[host] and modulemap[host][name];
-		if type(mod.module.restore) == "function" then
-			local ok, err = pcall(mod.module.restore, saved or {})
+	local ok, err = load(host, name, ...);
+	if ok then
+		mod = get_module(host, name);
+		if module_has_method(mod, "restore") then
+			local ok, err = call_module_method(mod, "restore", saved or {})
 			if (not ok) and err then
-				log("warn", "Non-fatal error unloading module '%s' from '%s': %s", name, host, err);
+				log("warn", "Error restoring module '%s' from '%s': %s", name, host, err);
 			end
 		end
 		return true;
 	end
+	return ok, err;
 end
 
 function handle_stanza(host, origin, stanza)
@@ -214,6 +229,25 @@
 	end
 end
 
+function module_has_method(module, method)
+	return type(module.module[method]) == "function";
+end
+
+function call_module_method(module, method, ...)
+	if module_has_method(module, method) then	
+		local f = module.module[method];
+		return pcall(f, ...);
+	else
+		return false, "no-such-method";
+	end
+end
+
+local _modulepath = { plugin_dir, "mod_", nil, ".lua"};
+function get_module_filename(name)
+	_modulepath[3] = name;
+	return t_concat(_modulepath);
+end
+
 ----- API functions exposed to modules -----------
 -- Must all be in api.* 
 
@@ -227,6 +261,14 @@
 	return self.host;
 end
 
+function api:get_host_type()
+	return hosts[self.host].type;
+end
+
+function api:set_global()
+	self.host = "*";
+end
+
 local function _add_handler(module, origin_type, tag, xmlns, handler)
 	local handlers = stanza_handlers:get(module.host, origin_type, tag, xmlns);
 	local msg = (tag == "iq") and "namespace" or "payload namespace";