24 local logger = require "util.logger"; |
24 local logger = require "util.logger"; |
25 local log = logger.init("modulemanager"); |
25 local log = logger.init("modulemanager"); |
26 local addDiscoInfoHandler = require "core.discomanager".addDiscoInfoHandler; |
26 local addDiscoInfoHandler = require "core.discomanager".addDiscoInfoHandler; |
27 local eventmanager = require "core.eventmanager"; |
27 local eventmanager = require "core.eventmanager"; |
28 local config = require "core.configmanager"; |
28 local config = require "core.configmanager"; |
|
29 local multitable_new = require "util.multitable".new; |
29 |
30 |
30 |
31 |
31 local loadfile, pcall = loadfile, pcall; |
32 local loadfile, pcall = loadfile, pcall; |
32 local setmetatable, setfenv, getfenv = setmetatable, setfenv, getfenv; |
33 local setmetatable, setfenv, getfenv = setmetatable, setfenv, getfenv; |
33 local pairs, ipairs = pairs, ipairs; |
34 local pairs, ipairs = pairs, ipairs; |
43 |
44 |
44 local api = {}; -- Module API container |
45 local api = {}; -- Module API container |
45 |
46 |
46 local modulemap = {}; |
47 local modulemap = {}; |
47 |
48 |
|
49 local m_handler_info = multitable_new(); |
|
50 local m_stanza_handlers = multitable_new(); |
48 local handler_info = {}; |
51 local handler_info = {}; |
49 local stanza_handlers = {}; |
52 local stanza_handlers = {}; |
50 |
53 |
51 local modulehelpers = setmetatable({}, { __index = _G }); |
54 local modulehelpers = setmetatable({}, { __index = _G }); |
52 |
55 |
113 end |
116 end |
114 end |
117 end |
115 |
118 |
116 end |
119 end |
117 |
120 |
118 function handle_stanza(host, origin, stanza) |
121 function _handle_stanza(host, origin, stanza) |
119 local name, xmlns, origin_type = stanza.name, stanza.attr.xmlns, origin.type; |
122 local name, xmlns, origin_type = stanza.name, stanza.attr.xmlns, origin.type; |
120 |
123 |
121 local handlers = stanza_handlers[host]; |
124 local handlers = stanza_handlers[host]; |
122 if not handlers then |
125 if not handlers then |
123 log("warn", "No handlers for %s", host); |
126 log("warn", "No handlers for %s", host); |
146 end |
149 end |
147 end |
150 end |
148 log("debug", "Stanza unhandled by any modules, xmlns: %s", stanza.attr.xmlns); |
151 log("debug", "Stanza unhandled by any modules, xmlns: %s", stanza.attr.xmlns); |
149 return false; -- we didn't handle it |
152 return false; -- we didn't handle it |
150 end |
153 end |
|
154 function handle_stanza(host, origin, stanza) |
|
155 local name, xmlns, origin_type = stanza.name, stanza.attr.xmlns, origin.type; |
|
156 if name == "iq" and xmlns == "jabber:client" then |
|
157 xmlns = stanza.tags[1].attr.xmlns; |
|
158 log("debug", "Stanza of type %s from %s has xmlns: %s", name, origin_type, xmlns); |
|
159 end |
|
160 local handlers = m_stanza_handlers:get(host, origin_type, name, xmlns); |
|
161 if handlers then |
|
162 log("debug", "Passing stanza to mod_%s", handler_info[handlers[1]].name); |
|
163 (handlers[1])(origin, stanza); |
|
164 return true; |
|
165 else |
|
166 log("debug", "Stanza unhandled by any modules, xmlns: %s", stanza.attr.xmlns); -- we didn't handle it |
|
167 end |
|
168 end |
151 |
169 |
152 ----- API functions exposed to modules ----------- |
170 ----- API functions exposed to modules ----------- |
153 -- Must all be in api.* |
171 -- Must all be in api.* |
154 |
172 |
155 -- Returns the name of the current module |
173 -- Returns the name of the current module |
161 function api:get_host() |
179 function api:get_host() |
162 return self.host; |
180 return self.host; |
163 end |
181 end |
164 |
182 |
165 |
183 |
166 local function _add_iq_handler(module, origin_type, xmlns, handler) |
184 local function __add_iq_handler(module, origin_type, xmlns, handler) |
167 local handlers = stanza_handlers[module.host]; |
185 local handlers = stanza_handlers[module.host]; |
168 handlers[origin_type] = handlers[origin_type] or {}; |
186 handlers[origin_type] = handlers[origin_type] or {}; |
169 handlers[origin_type].iq = handlers[origin_type].iq or {}; |
187 handlers[origin_type].iq = handlers[origin_type].iq or {}; |
170 if not handlers[origin_type].iq[xmlns] then |
188 if not handlers[origin_type].iq[xmlns] then |
171 handlers[origin_type].iq[xmlns]= handler; |
189 handlers[origin_type].iq[xmlns]= handler; |
173 module:log("debug", "I now handle tag 'iq' [%s] with payload namespace '%s'", origin_type, xmlns); |
191 module:log("debug", "I now handle tag 'iq' [%s] with payload namespace '%s'", origin_type, xmlns); |
174 else |
192 else |
175 module:log("warn", "I wanted to handle tag 'iq' [%s] with payload namespace '%s' but mod_%s already handles that", origin_type, xmlns, handler_info[handlers[origin_type].iq[xmlns]].name); |
193 module:log("warn", "I wanted to handle tag 'iq' [%s] with payload namespace '%s' but mod_%s already handles that", origin_type, xmlns, handler_info[handlers[origin_type].iq[xmlns]].name); |
176 end |
194 end |
177 end |
195 end |
|
196 local function _add_iq_handler(module, origin_type, xmlns, handler) |
|
197 local handlers = m_stanza_handlers:get(module.host, origin_type, "iq", xmlns); |
|
198 if not handlers then |
|
199 m_stanza_handlers:add(module.host, origin_type, "iq", xmlns, handler); |
|
200 handler_info[handler] = module; |
|
201 module:log("debug", "I now handle tag 'iq' [%s] with payload namespace '%s'", origin_type, xmlns); |
|
202 else |
|
203 module:log("warn", "I wanted to handle tag 'iq' [%s] with payload namespace '%s' but mod_%s already handles that", origin_type, xmlns, handler_info[handlers[1]].name); |
|
204 end |
|
205 end |
178 |
206 |
179 function api:add_iq_handler(origin_type, xmlns, handler) |
207 function api:add_iq_handler(origin_type, xmlns, handler) |
180 if not (origin_type and handler and xmlns) then return false; end |
208 if not (origin_type and handler and xmlns) then return false; end |
181 if type(origin_type) == "table" then |
209 if type(origin_type) == "table" then |
182 for _, origin_type in ipairs(origin_type) do |
210 for _, origin_type in ipairs(origin_type) do |
196 end); |
224 end); |
197 end |
225 end |
198 |
226 |
199 api.add_event_hook = eventmanager.add_event_hook; |
227 api.add_event_hook = eventmanager.add_event_hook; |
200 |
228 |
201 local function _add_handler(module, origin_type, tag, xmlns, handler) |
229 local function __add_handler(module, origin_type, tag, xmlns, handler) |
202 local handlers = stanza_handlers[module.host]; |
230 local handlers = stanza_handlers[module.host]; |
203 handlers[origin_type] = handlers[origin_type] or {}; |
231 handlers[origin_type] = handlers[origin_type] or {}; |
204 if not handlers[origin_type][tag] then |
232 if not handlers[origin_type][tag] then |
205 handlers[origin_type][tag] = handlers[origin_type][tag] or {}; |
233 handlers[origin_type][tag] = handlers[origin_type][tag] or {}; |
206 handlers[origin_type][tag][xmlns]= handler; |
234 handlers[origin_type][tag][xmlns]= handler; |
208 module:log("debug", "I now handle tag '%s' [%s] with xmlns '%s'", tag, origin_type, xmlns); |
236 module:log("debug", "I now handle tag '%s' [%s] with xmlns '%s'", tag, origin_type, xmlns); |
209 elseif handler_info[handlers[origin_type][tag]] then |
237 elseif handler_info[handlers[origin_type][tag]] then |
210 log("warning", "I wanted to handle tag '%s' [%s] but mod_%s already handles that", tag, origin_type, handler_info[handlers[origin_type][tag]].module.name); |
238 log("warning", "I wanted to handle tag '%s' [%s] but mod_%s already handles that", tag, origin_type, handler_info[handlers[origin_type][tag]].module.name); |
211 end |
239 end |
212 end |
240 end |
|
241 local function _add_handler(module, origin_type, tag, xmlns, handler) |
|
242 local handlers = m_stanza_handlers:get(module.host, origin_type, tag, xmlns); |
|
243 if not handlers then |
|
244 m_stanza_handlers:add(module.host, origin_type, tag, xmlns, handler); |
|
245 handler_info[handler] = module; |
|
246 module:log("debug", "I now handle tag '%s' [%s] with xmlns '%s'", tag, origin_type, xmlns); |
|
247 else |
|
248 module:log("warning", "I wanted to handle tag '%s' [%s] but mod_%s already handles that", tag, origin_type, handler_info[handlers[1]].module.name); |
|
249 end |
|
250 end |
213 |
251 |
214 function api:add_handler(origin_type, tag, xmlns, handler) |
252 function api:add_handler(origin_type, tag, xmlns, handler) |
215 if not (origin_type and tag and xmlns and handler) then return false; end |
253 if not (origin_type and tag and xmlns and handler) then return false; end |
216 if type(origin_type) == "table" then |
254 if type(origin_type) == "table" then |
217 for _, origin_type in ipairs(origin_type) do |
255 for _, origin_type in ipairs(origin_type) do |