]> granicus.if.org Git - ejabberd/commitdiff
Merge mod_opt_type from db sub-modules to main module mod_opt_type
authorPaweł Chmielowski <pchmielowski@process-one.net>
Fri, 4 Nov 2016 11:57:57 +0000 (12:57 +0100)
committerPaweł Chmielowski <pchmielowski@process-one.net>
Fri, 4 Nov 2016 11:58:08 +0000 (12:58 +0100)
src/ejabberd_config.erl
src/gen_mod.erl

index 517f2fd2fc0f10cf04de9554a038a38730e38b39..af26767f8cae8ea7f1a8edf8ef38128e64fe7bd4 100644 (file)
 -export([start/0, load_file/1, reload_file/0, read_file/1,
         add_global_option/2, add_local_option/2,
         get_global_option/2, get_local_option/2,
-         get_global_option/3, get_local_option/3,
-         get_option/2, get_option/3, add_option/2, has_option/1,
-         get_vh_by_auth_method/1, is_file_readable/1,
-         get_version/0, get_myhosts/0, get_mylang/0,
-         get_ejabberd_config_path/0, is_using_elixir_config/0,
-         prepare_opt_val/4, convert_table_to_binary/5,
-         transform_options/1, collect_options/1, default_db/2,
-         convert_to_yaml/1, convert_to_yaml/2, v_db/2,
-         env_binary_to_list/2, opt_type/1, may_hide_data/1,
-        is_elixir_enabled/0]).
+        get_global_option/3, get_local_option/3,
+        get_option/2, get_option/3, add_option/2, has_option/1,
+        get_vh_by_auth_method/1, is_file_readable/1,
+        get_version/0, get_myhosts/0, get_mylang/0,
+        get_ejabberd_config_path/0, is_using_elixir_config/0,
+        prepare_opt_val/4, convert_table_to_binary/5,
+        transform_options/1, collect_options/1, default_db/2,
+        convert_to_yaml/1, convert_to_yaml/2, v_db/2,
+        env_binary_to_list/2, opt_type/1, may_hide_data/1,
+        is_elixir_enabled/0, v_dbs/1, v_dbs_mods/1]).
 
 -export([start/2]).
 
@@ -893,6 +893,19 @@ v_db(Mod, Type) ->
        [] -> erlang:error(badarg)
     end.
 
+-spec v_dbs(module()) -> [atom()].
+
+v_dbs(Mod) ->
+    lists:flatten(ets:match(module_db, {Mod, '$1'})).
+
+-spec v_dbs_mods(module()) -> [module()].
+
+v_dbs_mods(Mod) ->
+    lists:map(fun([M]) ->
+                     binary_to_atom(<<(atom_to_binary(Mod, utf8))/binary, "_",
+                                      (atom_to_binary(M, utf8))/binary>>, utf8)
+             end, ets:match(module_db, {Mod, '$1'})).
+
 -spec default_db(binary(), module()) -> atom().
 
 default_db(Host, Module) ->
index c4306577c72e0ae027ac7bda8fa9992d66f15f0f..aaf452aeb65870580ce012b741381981741c5252 100644 (file)
@@ -308,10 +308,47 @@ get_opt_host(Host, Opts, Default) ->
     Val = get_opt(host, Opts, fun iolist_to_binary/1, Default),
     ejabberd_regexp:greplace(Val, <<"@HOST@">>, Host).
 
+
+get_module_mod_opt_type_fun(Module) ->
+    DBSubMods = ejabberd_config:v_dbs_mods(Module),
+    fun(Opt) ->
+           Res = lists:foldl(fun(Mod, {Funs, ArgsList, _} = Acc) ->
+                                     case catch Mod:mod_opt_type(Opt) of
+                                         Fun when is_function(Fun) ->
+                                             {[Fun | Funs], ArgsList, true};
+                                         L when is_list(L) ->
+                                             {Funs, L ++ ArgsList, true};
+                                         _ ->
+                                             Acc
+                                     end
+                             end, {[], [], false}, [Module | DBSubMods]),
+           case Res of
+               {[], [], false} ->
+                   throw({'EXIT', {undef, mod_opt_type}});
+               {[], Args, _} -> Args;
+               {Funs, _, _} ->
+                   fun(Val) ->
+                           lists:any(fun(F) ->
+                                             try F(Val) of
+                                                 _ ->
+                                                     true
+                                             catch {replace_with, _NewVal} = E ->
+                                                     throw(E);
+                                                   {invalid_syntax, _Error} = E2 ->
+                                                     throw(E2);
+                                                   _:_ ->
+                                                     false
+                                             end
+                                     end, Funs)
+                   end
+           end
+    end.
+
 validate_opts(Module, Opts) ->
+    ModOptFun = get_module_mod_opt_type_fun(Module),
     lists:filtermap(
       fun({Opt, Val}) ->
-             case catch Module:mod_opt_type(Opt) of
+             case catch ModOptFun(Opt) of
                  VFun when is_function(VFun) ->
                      try VFun(Val) of
                          _ ->