]> granicus.if.org Git - ejabberd/commitdiff
Rewrite mod_stats to use XML generator
authorEvgeniy Khramtsov <ekhramtsov@process-one.net>
Sun, 31 Jul 2016 11:51:16 +0000 (14:51 +0300)
committerEvgeniy Khramtsov <ekhramtsov@process-one.net>
Sun, 31 Jul 2016 11:51:16 +0000 (14:51 +0300)
include/xmpp_codec.hrl
src/mod_stats.erl
src/xmpp_codec.erl
tools/xmpp_codec.spec

index acbc81e4ad80c692de1f466a43595c8afa1b6814..e3eb31285c7a753cab72f9a0b0a67406c8245d0b 100644 (file)
                     nick :: binary()}).
 -type muc_actor() :: #muc_actor{}.
 
+-record(stat_error, {code :: integer(),
+                     reason = <<>> :: binary()}).
+-type stat_error() :: #stat_error{}.
+
 -record(stat, {name :: binary(),
-               units :: binary(),
-               value :: binary(),
-               error = [] :: [{integer(),'undefined' | binary()}]}).
+               units = <<>> :: binary(),
+               value = <<>> :: binary(),
+               error :: #stat_error{}}).
 -type stat() :: #stat{}.
 
 -record(addresses, {list = [] :: [#address{}]}).
 -record(stream_features, {sub_els = [] :: [any()]}).
 -type stream_features() :: #stream_features{}.
 
--record(stats, {stat = [] :: [#stat{}]}).
+-record(stats, {list = [] :: [#stat{}],
+                node = <<>> :: binary()}).
 -type stats() :: #stats{}.
 
 -record(pubsub_items, {node :: binary(),
                         feature_register() |
                         register() |
                         sm_r() |
+                        stat_error() |
                         error() |
                         stream_error() |
                         muc_user() |
index 99059839a085ae7cfd850de326f6388fb4f8b8f6..c4b8ddb15a847f2b46396e93fbb3d20005214828 100644 (file)
 
 -behaviour(gen_mod).
 
--export([start/2, stop/1, process_local_iq/3,
-        mod_opt_type/1, depends/2]).
+-export([start/2, stop/1, process_iq/1, mod_opt_type/1, depends/2]).
 
 -include("ejabberd.hrl").
 -include("logger.hrl").
--include("jlib.hrl").
+-include("xmpp.hrl").
 
 start(Host, Opts) ->
     IQDisc = gen_mod:get_opt(iqdisc, Opts, fun gen_iq_handler:check_type/1,
                              one_queue),
-    gen_iq_handler:add_iq_handler(ejabberd_local, Host,
-                                 ?NS_STATS, ?MODULE, process_local_iq, IQDisc).
+    gen_iq_handler:add_iq_handler(ejabberd_local, Host, ?NS_STATS,
+                                 ?MODULE, process_iq, IQDisc).
 
 stop(Host) ->
-    gen_iq_handler:remove_iq_handler(ejabberd_local, Host,
-                                    ?NS_STATS).
+    gen_iq_handler:remove_iq_handler(ejabberd_local, Host, ?NS_STATS).
 
 depends(_Host, _Opts) ->
     [].
 
-process_local_iq(_From, To,
-                #iq{id = _ID, type = Type, xmlns = XMLNS,
-                    sub_el = SubEl, lang = Lang} =
-                    IQ) ->
-    case Type of
-      set ->
-         Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
-         IQ#iq{type = error, sub_el = [SubEl, ?ERRT_NOT_ALLOWED(Lang, Txt)]};
-      get ->
-         #xmlel{children = Els} = SubEl,
-         Node = str:tokens(fxml:get_tag_attr_s(<<"node">>, SubEl),
-                           <<"/">>),
-         Names = get_names(Els, []),
-         case get_local_stats(To#jid.server, Node, Names, Lang) of
-           {result, Res} ->
-               IQ#iq{type = result,
-                     sub_el =
-                         [#xmlel{name = <<"query">>,
-                                 attrs = [{<<"xmlns">>, XMLNS}],
-                                 children = Res}]};
-           {error, Error} ->
-               IQ#iq{type = error, sub_el = [SubEl, Error]}
-         end
+process_iq(#iq{type = set, lang = Lang} = IQ) ->
+    Txt = <<"Value 'set' of 'type' attribute is not allowed">>,
+    xmpp:make_error(IQ, xmpp:err_not_allowed(Txt, Lang));
+process_iq(#iq{type = get, to = To, lang = Lang,
+              sub_els = [#stats{} = Stats]} = IQ) ->
+    Node = str:tokens(Stats#stats.node, <<"/">>),
+    Names = [Name || #stat{name = Name} <- Stats#stats.list],
+    case get_local_stats(To#jid.server, Node, Names, Lang) of
+       {result, List} ->
+           xmpp:make_iq_result(IQ, Stats#stats{list = List});
+       {error, Error} ->
+           xmpp:make_error(IQ, Error)
     end.
 
-get_names([], Res) -> Res;
-get_names([#xmlel{name = <<"stat">>, attrs = Attrs}
-          | Els],
-         Res) ->
-    Name = fxml:get_attr_s(<<"name">>, Attrs),
-    case Name of
-      <<"">> -> get_names(Els, Res);
-      _ -> get_names(Els, [Name | Res])
-    end;
-get_names([_ | Els], Res) -> get_names(Els, Res).
-
--define(STAT(Name),
-       #xmlel{name = <<"stat">>, attrs = [{<<"name">>, Name}],
-              children = []}).
+-define(STAT(Name), #stat{name = Name}).
 
 get_local_stats(_Server, [], [], _Lang) ->
     {result,
@@ -115,7 +89,7 @@ get_local_stats(_Server, [<<"running nodes">>, ENode],
     case search_running_node(ENode) of
       false ->
            Txt = <<"No running node found">>,
-           {error, ?ERRT_ITEM_NOT_FOUND(Lang, Txt)};
+           {error, xmpp:err_item_not_found(Txt, Lang)};
       Node ->
          {result,
           lists:map(fun (Name) -> get_node_stat(Node, Name) end,
@@ -123,27 +97,19 @@ get_local_stats(_Server, [<<"running nodes">>, ENode],
     end;
 get_local_stats(_Server, _, _, Lang) ->
     Txt = <<"No statistics found for this item">>,
-    {error, ?ERRT_FEATURE_NOT_IMPLEMENTED(Lang, Txt)}.
+    {error, xmpp:err_feature_not_implemented(Txt, Lang)}.
 
--define(STATVAL(Val, Unit),
-       #xmlel{name = <<"stat">>,
-              attrs =
-                  [{<<"name">>, Name}, {<<"units">>, Unit},
-                   {<<"value">>, Val}],
-              children = []}).
+-define(STATVAL(Val, Unit), #stat{name = Name, units = Unit, value = Val}).
 
 -define(STATERR(Code, Desc),
-       #xmlel{name = <<"stat">>, attrs = [{<<"name">>, Name}],
-              children =
-                  [#xmlel{name = <<"error">>,
-                          attrs = [{<<"code">>, Code}],
-                          children = [{xmlcdata, Desc}]}]}).
+       #stat{name = Name,
+             error = #stat_error{code = Code, reason = Desc}}).
 
 get_local_stat(Server, [], Name)
     when Name == <<"users/online">> ->
     case catch ejabberd_sm:get_vh_session_list(Server) of
       {'EXIT', _Reason} ->
-         ?STATERR(<<"500">>, <<"Internal Server Error">>);
+         ?STATERR(500, <<"Internal Server Error">>);
       Users ->
          ?STATVAL((iolist_to_binary(integer_to_list(length(Users)))),
                   <<"users">>)
@@ -154,7 +120,7 @@ get_local_stat(Server, [], Name)
           ejabberd_auth:get_vh_registered_users_number(Server)
        of
       {'EXIT', _Reason} ->
-         ?STATERR(<<"500">>, <<"Internal Server Error">>);
+         ?STATERR(500, <<"Internal Server Error">>);
       NUsers ->
          ?STATVAL((iolist_to_binary(integer_to_list(NUsers))),
                   <<"users">>)
@@ -163,7 +129,7 @@ get_local_stat(_Server, [], Name)
     when Name == <<"users/all-hosts/online">> ->
     case catch mnesia:table_info(session, size) of
       {'EXIT', _Reason} ->
-         ?STATERR(<<"500">>, <<"Internal Server Error">>);
+         ?STATERR(500, <<"Internal Server Error">>);
       Users ->
          ?STATVAL((iolist_to_binary(integer_to_list(Users))),
                   <<"users">>)
@@ -178,7 +144,7 @@ get_local_stat(_Server, [], Name)
     ?STATVAL((iolist_to_binary(integer_to_list(NumUsers))),
             <<"users">>);
 get_local_stat(_Server, _, Name) ->
-    ?STATERR(<<"404">>, <<"Not Found">>).
+    ?STATERR(404, <<"Not Found">>).
 
 get_node_stat(Node, Name)
     when Name == <<"time/uptime">> ->
@@ -186,7 +152,7 @@ get_node_stat(Node, Name)
                        [wall_clock])
        of
       {badrpc, _Reason} ->
-         ?STATERR(<<"500">>, <<"Internal Server Error">>);
+         ?STATERR(500, <<"Internal Server Error">>);
       CPUTime ->
          ?STATVAL(list_to_binary(
                      io_lib:format("~.3f",
@@ -198,7 +164,7 @@ get_node_stat(Node, Name)
     case catch ejabberd_cluster:call(Node, erlang, statistics, [runtime])
        of
       {badrpc, _Reason} ->
-         ?STATERR(<<"500">>, <<"Internal Server Error">>);
+         ?STATERR(500, <<"Internal Server Error">>);
       RunTime ->
          ?STATVAL(list_to_binary(
                      io_lib:format("~.3f",
@@ -211,7 +177,7 @@ get_node_stat(Node, Name)
                        dirty_get_my_sessions_list, [])
        of
       {badrpc, _Reason} ->
-         ?STATERR(<<"500">>, <<"Internal Server Error">>);
+         ?STATERR(500, <<"Internal Server Error">>);
       Users ->
          ?STATVAL((iolist_to_binary(integer_to_list(length(Users)))),
                   <<"users">>)
@@ -222,7 +188,7 @@ get_node_stat(Node, Name)
                        [transaction_commits])
        of
       {badrpc, _Reason} ->
-         ?STATERR(<<"500">>, <<"Internal Server Error">>);
+         ?STATERR(500, <<"Internal Server Error">>);
       Transactions ->
          ?STATVAL((iolist_to_binary(integer_to_list(Transactions))),
                   <<"transactions">>)
@@ -233,7 +199,7 @@ get_node_stat(Node, Name)
                        [transaction_failures])
        of
       {badrpc, _Reason} ->
-         ?STATERR(<<"500">>, <<"Internal Server Error">>);
+         ?STATERR(500, <<"Internal Server Error">>);
       Transactions ->
          ?STATVAL((iolist_to_binary(integer_to_list(Transactions))),
                   <<"transactions">>)
@@ -244,7 +210,7 @@ get_node_stat(Node, Name)
                        [transaction_restarts])
        of
       {badrpc, _Reason} ->
-         ?STATERR(<<"500">>, <<"Internal Server Error">>);
+         ?STATERR(500, <<"Internal Server Error">>);
       Transactions ->
          ?STATVAL((iolist_to_binary(integer_to_list(Transactions))),
                   <<"transactions">>)
@@ -255,13 +221,13 @@ get_node_stat(Node, Name)
                        [transaction_log_writes])
        of
       {badrpc, _Reason} ->
-         ?STATERR(<<"500">>, <<"Internal Server Error">>);
+         ?STATERR(500, <<"Internal Server Error">>);
       Transactions ->
          ?STATVAL((iolist_to_binary(integer_to_list(Transactions))),
                   <<"transactions">>)
     end;
 get_node_stat(_, Name) ->
-    ?STATERR(<<"404">>, <<"Not Found">>).
+    ?STATERR(404, <<"Not Found">>).
 
 search_running_node(SNode) ->
     search_running_node(SNode,
index 6fddf97ed52e6a44be953d54b6e240f290819bdc..e0a5d47c9fc946fdadaec1fbec84d326479003cf 100644 (file)
@@ -2222,11 +2222,15 @@ encode({bookmark_url, _, _} = Url) ->
 encode({bookmark_storage, _, _} = Storage) ->
     encode_bookmarks_storage(Storage,
                             [{<<"xmlns">>, <<"storage:bookmarks">>}]);
+encode({stat_error, _, _} = Error) ->
+    encode_stat_error(Error,
+                     [{<<"xmlns">>,
+                       <<"http://jabber.org/protocol/stats">>}]);
 encode({stat, _, _, _, _} = Stat) ->
     encode_stat(Stat,
                [{<<"xmlns">>,
                  <<"http://jabber.org/protocol/stats">>}]);
-encode({stats, _} = Query) ->
+encode({stats, _, _} = Query) ->
     encode_stats(Query,
                 [{<<"xmlns">>,
                   <<"http://jabber.org/protocol/stats">>}]);
@@ -2734,8 +2738,9 @@ get_name({bookmark_conference, _, _, _, _, _}) ->
     <<"conference">>;
 get_name({bookmark_url, _, _}) -> <<"url">>;
 get_name({bookmark_storage, _, _}) -> <<"storage">>;
+get_name({stat_error, _, _}) -> <<"error">>;
 get_name({stat, _, _, _, _}) -> <<"stat">>;
-get_name({stats, _}) -> <<"query">>;
+get_name({stats, _, _}) -> <<"query">>;
 get_name({iq, _, _, _, _, _, _}) -> <<"iq">>;
 get_name({message, _, _, _, _, _, _, _, _, _}) ->
     <<"message">>;
@@ -2939,9 +2944,11 @@ get_ns({bookmark_conference, _, _, _, _, _}) ->
 get_ns({bookmark_url, _, _}) -> <<"storage:bookmarks">>;
 get_ns({bookmark_storage, _, _}) ->
     <<"storage:bookmarks">>;
+get_ns({stat_error, _, _}) ->
+    <<"http://jabber.org/protocol/stats">>;
 get_ns({stat, _, _, _, _}) ->
     <<"http://jabber.org/protocol/stats">>;
-get_ns({stats, _}) ->
+get_ns({stats, _, _}) ->
     <<"http://jabber.org/protocol/stats">>;
 get_ns({iq, _, _, _, _, _, _}) -> <<"jabber:client">>;
 get_ns({message, _, _, _, _, _, _, _, _, _}) ->
@@ -3254,8 +3261,9 @@ pp(bookmark_conference, 5) ->
     [name, jid, autojoin, nick, password];
 pp(bookmark_url, 2) -> [name, url];
 pp(bookmark_storage, 2) -> [conference, url];
+pp(stat_error, 2) -> [code, reason];
 pp(stat, 4) -> [name, units, value, error];
-pp(stats, 1) -> [stat];
+pp(stats, 2) -> [list, node];
 pp(iq, 6) -> [id, type, lang, from, to, sub_els];
 pp(message, 9) ->
     [id, type, lang, from, to, subject, body, thread,
@@ -25097,53 +25105,70 @@ encode_iq_attr_to(_val, _acc) ->
 
 decode_stats(__TopXMLNS, __IgnoreEls,
             {xmlel, <<"query">>, _attrs, _els}) ->
-    Stat = decode_stats_els(__TopXMLNS, __IgnoreEls, _els,
+    List = decode_stats_els(__TopXMLNS, __IgnoreEls, _els,
                            []),
-    {stats, Stat}.
+    Node = decode_stats_attrs(__TopXMLNS, _attrs,
+                             undefined),
+    {stats, List, Node}.
 
-decode_stats_els(__TopXMLNS, __IgnoreEls, [], Stat) ->
-    lists:reverse(Stat);
+decode_stats_els(__TopXMLNS, __IgnoreEls, [], List) ->
+    lists:reverse(List);
 decode_stats_els(__TopXMLNS, __IgnoreEls,
-                [{xmlel, <<"stat">>, _attrs, _} = _el | _els], Stat) ->
+                [{xmlel, <<"stat">>, _attrs, _} = _el | _els], List) ->
     case get_attr(<<"xmlns">>, _attrs) of
       <<"">>
          when __TopXMLNS ==
                 <<"http://jabber.org/protocol/stats">> ->
          decode_stats_els(__TopXMLNS, __IgnoreEls, _els,
-                          [decode_stat(__TopXMLNS, __IgnoreEls, _el) | Stat]);
+                          [decode_stat(__TopXMLNS, __IgnoreEls, _el) | List]);
       <<"http://jabber.org/protocol/stats">> ->
          decode_stats_els(__TopXMLNS, __IgnoreEls, _els,
                           [decode_stat(<<"http://jabber.org/protocol/stats">>,
                                        __IgnoreEls, _el)
-                           | Stat]);
+                           | List]);
       _ ->
-         decode_stats_els(__TopXMLNS, __IgnoreEls, _els, Stat)
+         decode_stats_els(__TopXMLNS, __IgnoreEls, _els, List)
     end;
 decode_stats_els(__TopXMLNS, __IgnoreEls, [_ | _els],
-                Stat) ->
-    decode_stats_els(__TopXMLNS, __IgnoreEls, _els, Stat).
-
-encode_stats({stats, Stat}, _xmlns_attrs) ->
-    _els = lists:reverse('encode_stats_$stat'(Stat, [])),
-    _attrs = _xmlns_attrs,
+                List) ->
+    decode_stats_els(__TopXMLNS, __IgnoreEls, _els, List).
+
+decode_stats_attrs(__TopXMLNS,
+                  [{<<"node">>, _val} | _attrs], _Node) ->
+    decode_stats_attrs(__TopXMLNS, _attrs, _val);
+decode_stats_attrs(__TopXMLNS, [_ | _attrs], Node) ->
+    decode_stats_attrs(__TopXMLNS, _attrs, Node);
+decode_stats_attrs(__TopXMLNS, [], Node) ->
+    decode_stats_attr_node(__TopXMLNS, Node).
+
+encode_stats({stats, List, Node}, _xmlns_attrs) ->
+    _els = lists:reverse('encode_stats_$list'(List, [])),
+    _attrs = encode_stats_attr_node(Node, _xmlns_attrs),
     {xmlel, <<"query">>, _attrs, _els}.
 
-'encode_stats_$stat'([], _acc) -> _acc;
-'encode_stats_$stat'([Stat | _els], _acc) ->
-    'encode_stats_$stat'(_els,
-                        [encode_stat(Stat, []) | _acc]).
+'encode_stats_$list'([], _acc) -> _acc;
+'encode_stats_$list'([List | _els], _acc) ->
+    'encode_stats_$list'(_els,
+                        [encode_stat(List, []) | _acc]).
+
+decode_stats_attr_node(__TopXMLNS, undefined) -> <<>>;
+decode_stats_attr_node(__TopXMLNS, _val) -> _val.
+
+encode_stats_attr_node(<<>>, _acc) -> _acc;
+encode_stats_attr_node(_val, _acc) ->
+    [{<<"node">>, _val} | _acc].
 
 decode_stat(__TopXMLNS, __IgnoreEls,
            {xmlel, <<"stat">>, _attrs, _els}) ->
     Error = decode_stat_els(__TopXMLNS, __IgnoreEls, _els,
-                           []),
+                           undefined),
     {Name, Units, Value} = decode_stat_attrs(__TopXMLNS,
                                             _attrs, undefined, undefined,
                                             undefined),
     {stat, Name, Units, Value, Error}.
 
 decode_stat_els(__TopXMLNS, __IgnoreEls, [], Error) ->
-    lists:reverse(Error);
+    Error;
 decode_stat_els(__TopXMLNS, __IgnoreEls,
                [{xmlel, <<"error">>, _attrs, _} = _el | _els],
                Error) ->
@@ -25152,13 +25177,11 @@ decode_stat_els(__TopXMLNS, __IgnoreEls,
          when __TopXMLNS ==
                 <<"http://jabber.org/protocol/stats">> ->
          decode_stat_els(__TopXMLNS, __IgnoreEls, _els,
-                         [decode_stat_error(__TopXMLNS, __IgnoreEls, _el)
-                          | Error]);
+                         decode_stat_error(__TopXMLNS, __IgnoreEls, _el));
       <<"http://jabber.org/protocol/stats">> ->
          decode_stat_els(__TopXMLNS, __IgnoreEls, _els,
-                         [decode_stat_error(<<"http://jabber.org/protocol/stats">>,
-                                            __IgnoreEls, _el)
-                          | Error]);
+                         decode_stat_error(<<"http://jabber.org/protocol/stats">>,
+                                           __IgnoreEls, _el));
       _ ->
          decode_stat_els(__TopXMLNS, __IgnoreEls, _els, Error)
     end;
@@ -25196,10 +25219,9 @@ encode_stat({stat, Name, Units, Value, Error},
                                                                                 _xmlns_attrs))),
     {xmlel, <<"stat">>, _attrs, _els}.
 
-'encode_stat_$error'([], _acc) -> _acc;
-'encode_stat_$error'([Error | _els], _acc) ->
-    'encode_stat_$error'(_els,
-                        [encode_stat_error(Error, []) | _acc]).
+'encode_stat_$error'(undefined, _acc) -> _acc;
+'encode_stat_$error'(Error, _acc) ->
+    [encode_stat_error(Error, []) | _acc].
 
 decode_stat_attr_name(__TopXMLNS, undefined) ->
     erlang:error({xmpp_codec,
@@ -25209,41 +25231,39 @@ decode_stat_attr_name(__TopXMLNS, _val) -> _val.
 encode_stat_attr_name(_val, _acc) ->
     [{<<"name">>, _val} | _acc].
 
-decode_stat_attr_units(__TopXMLNS, undefined) ->
-    undefined;
+decode_stat_attr_units(__TopXMLNS, undefined) -> <<>>;
 decode_stat_attr_units(__TopXMLNS, _val) -> _val.
 
-encode_stat_attr_units(undefined, _acc) -> _acc;
+encode_stat_attr_units(<<>>, _acc) -> _acc;
 encode_stat_attr_units(_val, _acc) ->
     [{<<"units">>, _val} | _acc].
 
-decode_stat_attr_value(__TopXMLNS, undefined) ->
-    undefined;
+decode_stat_attr_value(__TopXMLNS, undefined) -> <<>>;
 decode_stat_attr_value(__TopXMLNS, _val) -> _val.
 
-encode_stat_attr_value(undefined, _acc) -> _acc;
+encode_stat_attr_value(<<>>, _acc) -> _acc;
 encode_stat_attr_value(_val, _acc) ->
     [{<<"value">>, _val} | _acc].
 
 decode_stat_error(__TopXMLNS, __IgnoreEls,
                  {xmlel, <<"error">>, _attrs, _els}) ->
-    Cdata = decode_stat_error_els(__TopXMLNS, __IgnoreEls,
-                                 _els, <<>>),
+    Reason = decode_stat_error_els(__TopXMLNS, __IgnoreEls,
+                                  _els, <<>>),
     Code = decode_stat_error_attrs(__TopXMLNS, _attrs,
                                   undefined),
-    {Code, Cdata}.
+    {stat_error, Code, Reason}.
 
 decode_stat_error_els(__TopXMLNS, __IgnoreEls, [],
-                     Cdata) ->
-    decode_stat_error_cdata(__TopXMLNS, Cdata);
+                     Reason) ->
+    decode_stat_error_cdata(__TopXMLNS, Reason);
 decode_stat_error_els(__TopXMLNS, __IgnoreEls,
-                     [{xmlcdata, _data} | _els], Cdata) ->
+                     [{xmlcdata, _data} | _els], Reason) ->
     decode_stat_error_els(__TopXMLNS, __IgnoreEls, _els,
-                         <<Cdata/binary, _data/binary>>);
+                         <<Reason/binary, _data/binary>>);
 decode_stat_error_els(__TopXMLNS, __IgnoreEls,
-                     [_ | _els], Cdata) ->
+                     [_ | _els], Reason) ->
     decode_stat_error_els(__TopXMLNS, __IgnoreEls, _els,
-                         Cdata).
+                         Reason).
 
 decode_stat_error_attrs(__TopXMLNS,
                        [{<<"code">>, _val} | _attrs], _Code) ->
@@ -25254,8 +25274,9 @@ decode_stat_error_attrs(__TopXMLNS, [_ | _attrs],
 decode_stat_error_attrs(__TopXMLNS, [], Code) ->
     decode_stat_error_attr_code(__TopXMLNS, Code).
 
-encode_stat_error({Code, Cdata}, _xmlns_attrs) ->
-    _els = encode_stat_error_cdata(Cdata, []),
+encode_stat_error({stat_error, Code, Reason},
+                 _xmlns_attrs) ->
+    _els = encode_stat_error_cdata(Reason, []),
     _attrs = encode_stat_error_attr_code(Code,
                                         _xmlns_attrs),
     {xmlel, <<"error">>, _attrs, _els}.
@@ -25274,10 +25295,10 @@ decode_stat_error_attr_code(__TopXMLNS, _val) ->
 encode_stat_error_attr_code(_val, _acc) ->
     [{<<"code">>, enc_int(_val)} | _acc].
 
-decode_stat_error_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_stat_error_cdata(__TopXMLNS, <<>>) -> <<>>;
 decode_stat_error_cdata(__TopXMLNS, _val) -> _val.
 
-encode_stat_error_cdata(undefined, _acc) -> _acc;
+encode_stat_error_cdata(<<>>, _acc) -> _acc;
 encode_stat_error_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
index 964b631c28010d0448d20bd0bef3e9a2be92aa98..a50b58b59d2cb3314b7e22b9843f8d408d9163b4 100644 (file)
 -xml(stat_error,
      #elem{name = <<"error">>,
            xmlns = <<"http://jabber.org/protocol/stats">>,
-           result = {'$code', '$cdata'},
+           result = {stat_error, '$code', '$reason'},
+          cdata = #cdata{default = <<"">>, label = '$reason'},
            attrs = [#attr{name = <<"code">>,
                           required = true,
                           enc = {enc_int, []},
            result = {stat, '$name', '$units', '$value', '$error'},
            attrs = [#attr{name = <<"name">>,
                           required = true},
-                    #attr{name = <<"units">>},
-                    #attr{name = <<"value">>}],
-           refs = [#ref{name = stat_error,
-                        label = '$error'}]}).
+                    #attr{name = <<"units">>, default = <<"">>},
+                    #attr{name = <<"value">>, default = <<"">>}],
+           refs = [#ref{name = stat_error, label = '$error',
+                       min = 0, max = 1}]}).
 
 -xml(stats,
      #elem{name = <<"query">>,
            xmlns = <<"http://jabber.org/protocol/stats">>,
-           result = {stats, '$stat'},
-           refs = [#ref{name = stat,
-                        label = '$stat'}]}).
+           result = {stats, '$list', '$node'},
+          attrs = [#attr{name = <<"node">>, default = <<"">>}],
+           refs = [#ref{name = stat, label = '$list'}]}).
 
 -xml(iq,
      #elem{name = <<"iq">>,