1 |
|
%% @doc Stores a table of custom IQ-handlers for mod_muc_room. |
2 |
|
-module(mod_muc_iq). |
3 |
|
-behaviour(gen_iq_component). |
4 |
|
|
5 |
|
-export([start_link/0, |
6 |
|
process_iq/5, |
7 |
|
register_iq_handler/3, |
8 |
|
unregister_iq_handler/2, |
9 |
|
sync/0]). |
10 |
|
|
11 |
|
%% gen_server callbacks |
12 |
|
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, |
13 |
|
terminate/2, code_change/3]). |
14 |
|
|
15 |
|
-ignore_xref([code_change/3, handle_call/3, handle_cast/2, handle_info/2, init/1, |
16 |
|
start_link/0, terminate/2]). |
17 |
|
|
18 |
|
-compile({inline, [srv_name/0, tbl_name/0]}). |
19 |
|
|
20 |
|
-include("mongoose.hrl"). |
21 |
|
-include("jlib.hrl"). |
22 |
|
|
23 |
|
-record(state, {}). |
24 |
|
|
25 |
|
%% @private |
26 |
|
srv_name() -> |
27 |
443 |
ejabberd_mod_muc_iq. |
28 |
|
|
29 |
|
tbl_name() -> |
30 |
894 |
ejabberd_mod_muc_iq_table. |
31 |
|
|
32 |
|
%%==================================================================== |
33 |
|
%% API |
34 |
|
%%==================================================================== |
35 |
|
|
36 |
|
-spec start_link() -> 'ignore' | {'error', _} | {'ok', pid()}. |
37 |
|
start_link() -> |
38 |
53 |
gen_server:start_link({local, srv_name()}, ?MODULE, [], []). |
39 |
|
|
40 |
|
%% @doc Handle custom IQ. |
41 |
|
%% Called from mod_muc_room. |
42 |
|
-spec process_iq(jid:lserver(), jid:jid(), jid:jid(), mongoose_acc:t(), |
43 |
|
jlib:iq()) -> mongoose_acc:t() | {mongoose_acc:t(), error}. |
44 |
|
process_iq(MucHost, From, RoomJID, Acc, IQ = #iq{xmlns = XMLNS}) -> |
45 |
451 |
case ets:lookup(tbl_name(), {XMLNS, MucHost}) of |
46 |
|
[{_, IQHandler}] -> |
47 |
451 |
gen_iq_component:handle(IQHandler, Acc, From, RoomJID, IQ); |
48 |
:-( |
[] -> {Acc, error} |
49 |
|
end. |
50 |
|
|
51 |
|
-spec register_iq_handler(jid:lserver(), binary(), mongoose_iq_handler:t()) -> ok. |
52 |
|
register_iq_handler(MucHost, XMLNS, IQHandler) -> |
53 |
130 |
gen_server:cast(srv_name(), |
54 |
|
{register_iq_handler, MucHost, XMLNS, IQHandler}). |
55 |
|
|
56 |
|
-spec unregister_iq_handler(jid:lserver(), binary()) -> ok. |
57 |
|
unregister_iq_handler(MucHost, XMLNS) -> |
58 |
130 |
gen_server:cast(srv_name(), |
59 |
|
{unregister_iq_handler, MucHost, XMLNS}). |
60 |
|
|
61 |
|
-spec sync() -> ok. |
62 |
|
sync() -> |
63 |
130 |
gen_server:call(srv_name(), sync). |
64 |
|
|
65 |
|
%%==================================================================== |
66 |
|
%% gen_server callbacks |
67 |
|
%%==================================================================== |
68 |
|
|
69 |
|
init([]) -> |
70 |
53 |
ets:new(tbl_name(), [named_table, protected]), |
71 |
53 |
{ok, #state{}}. |
72 |
|
|
73 |
|
handle_call(sync, _From, State) -> |
74 |
130 |
{reply, ok, State}; |
75 |
|
handle_call(_Request, _From, State) -> |
76 |
:-( |
{reply, ok, State}. |
77 |
|
|
78 |
|
handle_cast({register_iq_handler, MucHost, XMLNS, IQHandler}, State) -> |
79 |
130 |
ets:insert(tbl_name(), {{XMLNS, MucHost}, IQHandler}), |
80 |
130 |
{noreply, State}; |
81 |
|
handle_cast({unregister_iq_handler, MucHost, XMLNS}, State) -> |
82 |
130 |
case ets:lookup(tbl_name(), {XMLNS, MucHost}) of |
83 |
|
[{_, IQHandler}] -> |
84 |
130 |
gen_iq_component:stop_iq_handler(IQHandler), |
85 |
130 |
ets:delete(tbl_name(), {XMLNS, MucHost}); |
86 |
|
_ -> |
87 |
:-( |
ok |
88 |
|
end, |
89 |
130 |
{noreply, State}; |
90 |
|
handle_cast(_Msg, State) -> |
91 |
:-( |
{noreply, State}. |
92 |
|
|
93 |
|
handle_info(_Msg, State) -> |
94 |
:-( |
{noreply, State}. |
95 |
|
|
96 |
|
terminate(_Reason, _State) -> |
97 |
:-( |
ok. |
98 |
|
|
99 |
|
code_change(_OldVsn, State, _Extra) -> |
100 |
:-( |
{ok, State}. |