From 62db0309421b9152361aa946c6b9319b8274edd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chmielowski?= Date: Fri, 4 Nov 2016 12:57:57 +0100 Subject: [PATCH] Merge mod_opt_type from db sub-modules to main module mod_opt_type --- src/ejabberd_config.erl | 33 +++++++++++++++++++++++---------- src/gen_mod.erl | 39 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 11 deletions(-) diff --git a/src/ejabberd_config.erl b/src/ejabberd_config.erl index 517f2fd2f..af26767f8 100644 --- a/src/ejabberd_config.erl +++ b/src/ejabberd_config.erl @@ -29,16 +29,16 @@ -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) -> diff --git a/src/gen_mod.erl b/src/gen_mod.erl index c4306577c..aaf452aeb 100644 --- a/src/gen_mod.erl +++ b/src/gen_mod.erl @@ -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 _ ->