25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-10-31 15:21:38 +01:00
xmpp.chapril.org-ejabberd/mod_pubsub_ng/pubsub_options.erl

3370 lines
119 KiB
Erlang

%%% ====================================================================
%%% ``The contents of this file are subject to the Erlang Public License,
%%% Version 1.1, (the "License"); you may not use this file except in
%%% compliance with the License. You should have received a copy of the
%%% Erlang Public License along with this software. If not, it can be
%%% retrieved via the world wide web at http://www.erlang.org/.
%%%
%%% Software distributed under the License is distributed on an "AS IS"
%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%%% the License for the specific language governing rights and limitations
%%% under the License.
%%%
%%% The Initial Developer of the Original Code is ProcessOne.
%%% Portions created by ProcessOne are Copyright 2006-2013, ProcessOne
%%% All Rights Reserved.''
%%% This software is copyright 2006-2013, ProcessOne.
%%%
%%% @copyright 2006-2013 ProcessOne
%%% @author Karim Gemayel <karim.gemayel@process-one.net>
%%% [http://www.process-one.net/]
%%% @version {@vsn}, {@date} {@time}
%%% @end
%%% ====================================================================
%%% @headerfile "pubsub_dev.hrl"
-module(pubsub_options).
-author('karim.gemayel@process-one.net').
-compile(export_all).
-include("pubsub_dev.hrl").
-import(xml,
[
get_tag_cdata/1,
get_tag_attr_s/2,
remove_cdata/1
]).
-import(pubsub_tools,
[
get_entity_roster/1,
is_jid/1
]).
%% --------------------------------------------------------------------
%% Documentation / type definitions.
%% --------------------------------------------------------------------
%% Node Options
% pubsub#node_config FORM_TYPE
% Defined options values
%-- Access Model --%
-export_type([
access_model/0,
access_model_open/0,
access_model_presence/0,
access_model_roster/0,
access_model_authorize/0,
access_model_whitelist/0
]).
%% @type access_model_open() = 'open'.
-type(access_model_open() :: 'open').
%% @type access_model_presence() = 'presence'.
-type(access_model_presence() :: 'presence').
%% @type access_model_roster() = 'roster'.
-type(access_model_roster() :: 'roster').
%% @type access_model_authorize() = 'authorize'.
-type(access_model_authorize() :: 'authorize').
%% @type access_model_whitelist() = 'whitelist'.
-type(access_model_whitelist() :: 'whitelist').
%% @type access_model() = Open | Presence | Roster | Authorize | Whitelist
%% Open = pubsub_options:access_model_open()
%% Presence = pubsub_options:access_model_presence()
%% Roster = pubsub_options:access_model_roster()
%% Authorize = pubsub_options:access_model_authorize()
%% Whitelist = pubsub_options:access_model_whitelist().
-type(access_model() :: pubsub_options:access_model_open()
| pubsub_options:access_model_presence()
| pubsub_options:access_model_roster()
| pubsub_options:access_model_authorize()
| pubsub_options:access_model_whitelist()
).
%%
%-- Children_Association_Policy --%
-export_type([
children_association_policy/0,
%%
children_association_policy_all/0,
children_association_policy_owners/0,
children_association_policy_whitelist/0
]).
%% @type children_association_policy_all() = 'all'.
-type(children_association_policy_all() :: 'all').
%% @type children_association_policy_owners() = 'owners'.
-type(children_association_policy_owners() :: 'owners').
%% @type children_association_policy_whitelist() = 'whitelist'.
-type(children_association_policy_whitelist() :: 'whitelist').
%% @type children_association_policy() = All | Owners | Whitelist
%% All = pubsub_options:children_association_policy_all()
%% Owners = pubsub_options:children_association_policy_owners()
%% Whitelist = pubsub_options:children_association_policy_whitelist().
-type(children_association_policy()
:: pubsub_options:children_association_policy_all()
| pubsub_options:children_association_policy_owners()
| pubsub_options:children_association_policy_whitelist()
).
%%
%-- ItemReply -- %%
-export_type([
item_reply/0,
item_reply_owner/0,
item_reply_publisher/0
]).
%% @type(item_reply_owner() = 'owner').
-type(item_reply_owner() :: 'owner').
%% @type(item_reply_publisher() = 'publisher').
-type(item_reply_publisher() :: 'publisher').
%% @type(item_reply() = Owner | Publisher).
-type(item_reply() :: pubsub_options:item_reply_owner()
| pubsub_options:item_reply_publisher()
).
-export_type([
language/0,
description/0,
title/0
]).
-type(language() :: binary()).
-type(description() :: binary()).
-type(title() :: binary()).
%%
%-- Node types --%%
-export_type([
node_type/0,
node_type_leaf/0,
node_type_collection/0
]).
%% @type node_type_collection() = 'collection'.
-type(node_type_collection() :: 'collection').
%% @type node_type_leaf() = 'leaf'.
-type(node_type_leaf() :: 'leaf').
%% @type node_type() = Leaf | Collection
%% Leaf = pubsub_options:node_type_leaf()
%% Collection = pubsub_options:node_type_collection()
-type(node_type() :: pubsub_options:node_type_leaf()
| pubsub_options:node_type_collection()
).
%%
%-- Notification Types --%%
-export_type([
notification_type/0,
notification_type_chat/0,
notification_type_headline/0,
notification_type_normal/0
]).
-type(notification_type_chat() :: 'chat').
-type(notification_type_headline() :: 'headline').
-type(notification_type_normal() :: 'normal').
-type(notification_type()
:: pubsub_options:notification_type_headline()
| pubsub_options:notification_type_normal()
%| pubsub_options:notification_type_chat()
).
%%
%-- Publish Model --%
-export_type([
publish_model/0,
publish_model_publishers/0,
publish_model_subscribers/0,
publish_model_open/0
]).
%% @type publish_model_publishers() = 'publishers'.
-type(publish_model_publishers() :: 'publishers').
%% @type publish_model_subscribers() = 'subscribers'.
-type(publish_model_subscribers() :: 'subscribers').
%% @type publish_model_open() = 'open'.
-type(publish_model_open() :: 'open').
%% @type publish_model() = Publishers | Subscribers | Open
%% Publishers = pubsub_options:publish_model_publishers()
%% Subscribers = pubsub_options:publish_model_subscribers()
%% Open = pubsub_options:publish_model_open()
-type(publish_model() :: pubsub_options:publish_model_publishers()
| pubsub_options:publish_model_subscribers()
| pubsub_options:publish_model_open()
).
-export_type([
roster_group/0,
roster_groups/0,
roster_groups_allowed/0,
rosters_groups_allowed/0
]).
-type(roster_group() :: binary()).
-type(roster_groups() :: [pubsub_options:roster_group()]).
-type(roster_groups_allowed()
:: {Node_Owner::xmpp_jid:usr_bare(),
Roster_Groups::pubsub_options:roster_groups()}
).
-type(rosters_groups_allowed()
:: [Roster_Group_Allowed::pubsub_options:roster_groups_allowed()]
).
%%
%-- Send Last Published Item --%
-export_type([
send_last_published_item/0,
%%
send_last_published_item_never/0,
send_last_published_item_on_sub/0,
send_last_published_item_on_sub_and_presence/0
]).
%% @type send_last_published_item_never() = 'never'.
-type(send_last_published_item_never() :: 'never').
%% @type send_last_published_item_on_sub() = 'on_sub'.
-type(send_last_published_item_on_sub() :: 'on_sub').
%% @type send_last_published_item_on_sub_and_presence() = 'on_sub_and_presence'.
-type(send_last_published_item_on_sub_and_presence() :: 'on_sub_and_presence').
%% @type send_last_published_item() = Never | On_Sub | On_Sub_And_Presence
%% Never = pubsub_options:send_last_published_item_never()
%% On_Sub = pubsub_options:send_last_published_item_on_sub()
%% On_Sub_And_Presence = pubsub_options:send_last_published_item_on_sub_and_presence().
-type(send_last_published_item()
:: pubsub_options:send_last_published_item_never()
| pubsub_options:send_last_published_item_on_sub()
| pubsub_options:send_last_published_item_on_sub_and_presence()
).
%%
-export_type([
option_node_access_model/0,
option_node_children_association_policy/0,
option_node_children_association_whitelist/0,
option_node_children/0,
option_node_children_max/0,
option_node_collections/0,
option_node_children_max_collections/0,
option_node_children_max_multi_collections/0,
option_node_contact/0,
option_node_deliver_notifications/0,
option_node_deliver_payloads/0,
option_node_description/0,
option_node_item_expire/0,
option_node_itemreply/0,
option_node_language/0,
option_node_max_items/0,
option_node_max_payload_size/0,
option_node_node_type_leaf/0,
option_node_node_type_collection/0,
option_node_node_type/0,
option_node_notification_type/0,
option_node_notify_config/0,
option_node_notify_delete/0,
option_node_notify_retract/0,
option_node_notify_sub/0,
option_node_persist_items/0,
option_node_presence_based_delivery/0,
option_node_publish_model/0,
option_node_purge_offline/0,
option_node_roster_groups_allowed/0,
option_node_send_last_published_item/0,
option_node_tempsub/0,
option_node_subscribe/0,
option_node_title/0,
option_node_type/0
]).
-type(option_node_access_model() ::
{Key :: 'access_model',
Value :: pubsub_options:access_model()}
).
%-type(option_node_body_xslt() ::
% {Key :: 'body_xslt(',
% Value :: binary()}
%).
-type(option_node_children_association_policy() ::
{Key :: 'children_association_policy',
Value :: pubsub_options:children_association_policy()}
).
-type(option_node_children_association_whitelist() ::
{Key :: 'children_association_whitelist',
Value :: [Jid_Entity::xmpp_jid:raw_jid_entity_bare()]}
).
-type(option_node_children() ::
{Key :: 'children',
Value :: [NodeId::exmpp_pubsub:nodeId()]}
).
-type(option_node_children_max() ::
{Key :: 'children_max',
Value :: undefined | non_neg_integer()}
).
-type(option_node_children_max_collections() ::
{Key :: 'children_max',
Value :: undefined | 0..1}
).
-type(option_node_children_max_multi_collections() ::
{Key :: 'children_max',
Value :: undefined | non_neg_integer()}
).
-type(option_node_collections() ::
{Key :: 'collection',
Value :: [NodeId::exmpp_pubsub:nodeId()]}
).
-type(option_node_contact() ::
{Key :: 'contact',
Value :: [Jid_Entity::xmpp_jid:raw_jid_entity()]}
).
%-type(option_node_dataform_xslt() ::
% {Key :: 'dataform_xslt',
% Value :: binary()}
%).
-type(option_node_deliver_notifications() ::
{Key :: 'deliver_notifications',
Value :: boolean()}
).
-type(option_node_deliver_payloads() ::
{Key :: 'deliver_payloads',
Value :: boolean()}
).
-type(option_node_description() ::
{Key :: 'description',
Value :: undefined | pubsub_options:description()}
).
-type(option_node_item_expire() ::
{Key :: 'item_expire',
Value :: undefined | non_neg_integer()}
).
-type(option_node_itemreply() ::
{Key :: 'itemreply',
Value :: pubsub_options:item_reply()}
).
-type(option_node_language() ::
{Key :: 'language',
Value :: undefined | pubsub_options:language()}
).
-type(option_node_max_items() ::
{Key :: 'max_items',
Value :: undefined | non_neg_integer()}
).
-type(option_node_max_payload_size() ::
{Key :: 'max_payload_size',
Value :: undefined | non_neg_integer()}
).
-type(option_node_node_type_leaf() ::
{Key :: 'node_type',
Value :: pubsub_options:node_type_leaf()}
).
-type(option_node_node_type_collection() ::
{Key :: 'node_type',
Value :: pubsub_options:node_type_collection()}
).
-type(option_node_node_type()
:: pubsub_options:option_node_node_type_leaf()
| pubsub_options:option_node_node_type_collection()
).
-type(option_node_notification_type() ::
{Key :: 'notification_type',
Value :: pubsub_options:notification_type()}
).
-type(option_node_notify_config() ::
{Key :: 'notify_config',
Value :: boolean()}
).
-type(option_node_notify_delete() ::
{Key :: 'notify_delete',
Value :: boolean()}
).
-type(option_node_notify_retract() ::
{Key :: 'notify_retract',
Value :: boolean()}
).
-type(option_node_notify_sub() ::
{Key :: 'notify_sub',
Value :: boolean()}
).
-type(option_node_persist_items() ::
{Key :: 'persist_items',
Value :: boolean()}
).
-type(option_node_presence_based_delivery() ::
{Key :: 'presence_based_delivery',
Value :: boolean()}
).
-type(option_node_publish_model() ::
{Key :: 'publish_model',
Value :: pubsub_options:publish_model()}
).
-type(option_node_purge_offline() ::
{Key :: 'purge_offline',
Value :: boolean()}
).
-type(option_node_roster_groups_allowed() ::
{Key :: 'roster_groups_allowed',
Value :: pubsub_options:rosters_groups_allowed()}
).
-type(option_node_send_last_published_item() ::
{Key :: 'send_last_published_item',
Value :: pubsub_options:send_last_published_item()}
).
-type(option_node_tempsub() ::
{Key :: 'tempsub',
Value :: boolean()}
).
-type(option_node_subscribe() ::
{Key :: 'subscribe',
Value :: boolean()}
).
-type(option_node_title() ::
{Key :: 'title',
Value :: undefined | pubsub_options:title()}
).
-type(option_node_type() ::
{Key :: 'type',
Value :: undefined | binary()}
).
%-- Node Option Type (local or remote user ; leaf or collection node) --%
-export_type([
option_node/0,
options_node/0,
%%
option_node_leaf/0,
option_node_collection/0,
%%
options_node_leaf/0,
options_node_collection/0
]).
-type(option_node_leaf()
:: pubsub_options:option_node_access_model()
| pubsub_options:option_node_collections()
| pubsub_options:option_node_contact()
| pubsub_options:option_node_deliver_notifications()
| pubsub_options:option_node_deliver_payloads()
| pubsub_options:option_node_description()
| pubsub_options:option_node_item_expire()
| pubsub_options:option_node_itemreply()
| pubsub_options:option_node_language()
| pubsub_options:option_node_max_items()
| pubsub_options:option_node_max_payload_size()
| pubsub_options:option_node_node_type_leaf()
| pubsub_options:option_node_notification_type()
| pubsub_options:option_node_notify_config()
| pubsub_options:option_node_notify_delete()
| pubsub_options:option_node_notify_retract()
| pubsub_options:option_node_notify_sub()
| pubsub_options:option_node_persist_items()
| pubsub_options:option_node_presence_based_delivery()
| pubsub_options:option_node_publish_model()
| pubsub_options:option_node_purge_offline()
| pubsub_options:option_node_roster_groups_allowed()
| pubsub_options:option_node_send_last_published_item()
| pubsub_options:option_node_tempsub()
| pubsub_options:option_node_subscribe()
| pubsub_options:option_node_title()
| pubsub_options:option_node_type()
).
%%
-type(option_node_collection()
:: pubsub_options:option_node_access_model()
| pubsub_options:option_node_children_association_policy()
| pubsub_options:option_node_children_association_whitelist()
| pubsub_options:option_node_children()
| pubsub_options:option_node_children_max()
| pubsub_options:option_node_collections()
| pubsub_options:option_node_contact()
| pubsub_options:option_node_deliver_notifications()
| pubsub_options:option_node_deliver_payloads()
| pubsub_options:option_node_description()
| pubsub_options:option_node_item_expire()
| pubsub_options:option_node_itemreply()
| pubsub_options:option_node_language()
| pubsub_options:option_node_max_items()
| pubsub_options:option_node_max_payload_size()
| pubsub_options:option_node_node_type_collection()
| pubsub_options:option_node_notification_type()
| pubsub_options:option_node_notify_config()
| pubsub_options:option_node_notify_delete()
| pubsub_options:option_node_notify_retract()
| pubsub_options:option_node_notify_sub()
| pubsub_options:option_node_persist_items()
| pubsub_options:option_node_presence_based_delivery()
| pubsub_options:option_node_publish_model()
| pubsub_options:option_node_purge_offline()
| pubsub_options:option_node_roster_groups_allowed()
| pubsub_options:option_node_send_last_published_item()
| pubsub_options:option_node_tempsub()
| pubsub_options:option_node_subscribe()
| pubsub_options:option_node_title()
| pubsub_options:option_node_type()
).
%%
-type(option_node()
:: pubsub_options:option_node_leaf()
| pubsub_options:option_node_collection()
).
%%
-type(options_node_leaf()
:: [pubsub_options:option_node_leaf(),...]
).
%%
-type(options_node_collection()
:: [pubsub_options:option_node_collection(),...]
).
%%
-type(options_node()
:: pubsub_options:options_node_leaf()
| pubsub_options:options_node_collection()
).
%-- Publish-Options --%
%% pubsub#publish-options FORM_TYPE
-export_type([
option_item_access_model/0,
option_item_deliver_notifications/0,
option_item_deliver_payloads/0,
option_item_item_expire/0,
option_item_itemreply/0,
%%option_item_max_payload_size/0,
option_item_notification_type/0,
option_item_notify_config/0,
option_item_notify_retract/0,
option_item_persist_items/0,
option_item_presence_based_delivery/0,
option_item_publish_model/0,
option_item_purge_offline/0,
option_item_roster_groups_allowed/0,
option_item_send_last_published_item/0,
option_item_type/0
]).
-type(option_item_access_model() ::
{Key :: 'access_model',
Value :: pubsub_options:access_model()}
).
-type(option_item_deliver_notifications() ::
{Key :: 'deliver_notifications',
Value :: boolean()}
).
-type(option_item_deliver_payloads() ::
{Key :: 'deliver_payloads',
Value :: boolean()}
).
-type(option_item_item_expire() ::
{Key :: 'item_expire',
Value :: undefined | non_neg_integer()}
).
-type(option_item_itemreply() ::
{Key :: 'itemreply',
Value :: pubsub_options:item_reply()}
).
%-type(option_item_max_payload_size() ::
% {Key :: 'max_payload_size',
% Value :: undefined | non_neg_integer()}
%).
-type(option_item_notification_type() ::
{Key :: 'notification_type',
Value :: pubsub_options:notification_type()}
).
-type(option_item_notify_config() ::
{Key :: 'notify_config',
Value :: boolean()}
).
-type(option_item_notify_retract() ::
{Key :: 'notify_retract',
Value :: boolean()}
).
-type(option_item_persist_items() ::
{Key :: 'persist_items',
Value :: boolean()}
).
-type(option_item_presence_based_delivery() ::
{Key :: 'presence_based_delivery',
Value :: boolean()}
).
-type(option_item_publish_model() ::
{Key :: 'publish_model',
Value :: pubsub_options:publish_model()}
).
-type(option_item_purge_offline() ::
{Key :: 'purge_offline',
Value :: boolean()}
).
-type(option_item_roster_groups_allowed() ::
{Key :: 'roster_groups_allowed',
Value :: pubsub_options:rosters_groups_allowed()}
).
-type(option_item_send_last_published_item() ::
{Key :: 'send_last_published_item',
Value :: pubsub_options:send_last_published_item()}
).
-type(option_item_type() ::
{Key :: 'type',
Value :: undefined | binary()}
).
-export_type([
option_item/0,
options_item/0
]).
-type(option_item()
:: pubsub_options:option_item_access_model()
| pubsub_options:option_item_deliver_notifications()
| pubsub_options:option_item_deliver_payloads()
| pubsub_options:option_item_item_expire()
| pubsub_options:option_item_itemreply()
%% | pubsub_options:option_item_max_payload_size()
| pubsub_options:option_item_notification_type()
| pubsub_options:option_item_notify_config()
| pubsub_options:option_item_notify_retract()
| pubsub_options:option_item_persist_items()
| pubsub_options:option_item_presence_based_delivery()
| pubsub_options:option_item_publish_model()
| pubsub_options:option_item_purge_offline()
| pubsub_options:option_item_roster_groups_allowed()
| pubsub_options:option_item_send_last_published_item()
| pubsub_options:option_item_type()
).
%%
-type(options_item()
:: [pubsub_options:option_item(),...]
).
%-- Subscription Options --%%
-export_type([
option_subscription_deliver/0,
option_subscription_expire/0,
option_subscription_expire_presence/0,
option_subscription_expire_datetime/0,
option_subscription_include_body/0,
option_subscription_show_values/0,
option_subscription_subscription_type/0,
option_subscription_subscription_depth/0
]).
%%
-type(option_subscription_deliver() ::
{Key :: 'deliver',
Value :: boolean()}
).
%-type(option_subscription_digest() ::
% {Key :: 'digest',
% Value :: boolean()}
%).
%-type(option_subscription_digest_frequency() ::
% {Key :: 'digest_frequency',
% Value :: undefined | non_neg_integer()}
%).
-type(option_subscription_expire_presence() ::
{Key :: 'expire',
Value :: undefined | 'presence'}
).
-type(option_subscription_expire_datetime() ::
{Key :: 'expire',
Value :: undefined | erlang:timestamp()}
).
-type(option_subscription_expire()
:: pubsub_options:option_subscription_expire_presence()
| pubsub_options:option_subscription_expire_datetime()
).
-type(option_subscription_include_body() ::
{Key :: 'include_body',
Value :: boolean()}
).
-type(option_subscription_show_values() ::
{Key :: 'show-values',
Value :: ['away' | 'chat' | 'dnd' | 'online' | 'xa']}
).
-type(option_subscription_subscription_type() ::
{Key :: 'subscription_type',
Value :: 'all' | 'items' | 'nodes'}
).
-type(option_subscription_subscription_depth() ::
{Key :: 'subscription_depth',
Value :: 'all' | exmpp_pubsub:level()}
).
-export_type([
option_subscription/0,
%%
option_subscription_leaf/0,
option_subscription_collection/0,
%%
option_subscription_leaf_local/0,
option_subscription_leaf_remote/0,
%%
option_subscription_collection_local/0,
option_subscription_collection_remote/0
]).
%%
-type(option_subscription_leaf_local()
:: pubsub_options:option_subscription_deliver()
| pubsub_options:option_subscription_expire()
% | pubsub_options:option_subscription_include_body()
| pubsub_options:option_subscription_show_values()
).
%%
-type(option_subscription_leaf_remote()
:: pubsub_options:option_subscription_deliver()
% | pubsub_options:option_subscription_expire_datetime()
% | pubsub_options:option_subscription_include_body()
).
%%
-type(option_subscription_collection_local()
:: pubsub_options:option_subscription_deliver()
| pubsub_options:option_subscription_expire()
| pubsub_options:option_subscription_expire_presence()
| pubsub_options:option_subscription_expire_datetime()
%| pubsub_options:option_subscription_include_body()
| pubsub_options:option_subscription_show_values()
| pubsub_options:option_subscription_subscription_type()
| pubsub_options:option_subscription_subscription_depth()
).
%%
-type(option_subscription_collection_remote()
:: pubsub_options:option_subscription_deliver()
| pubsub_options:option_subscription_expire_datetime()
| pubsub_options:option_subscription_include_body()
| pubsub_options:option_subscription_subscription_type()
| pubsub_options:option_subscription_subscription_depth()
).
%%
-type(option_subscription_leaf()
:: pubsub_options:option_subscription_leaf_local()
| pubsub_options:option_subscription_leaf_remote()
).
%%
-type(option_subscription_collection()
:: pubsub_options:option_subscription_collection_local()
| pubsub_options:option_subscription_collection_remote()
).
%%
-type(option_subscription()
:: pubsub_options:option_subscription_leaf()
| pubsub_options:option_subscription_collection()
).
-export_type([
options_subscription/0,
%%
options_subscription_leaf/0,
options_subscription_collection/0,
%%
options_subscription_local/0,
options_subscription_remote/0,
%%
options_subscription_leaf_local/0,
options_subscription_leaf_remote/0,
%%
options_subscription_collection_local/0,
options_subscription_collection_remote/0
]).
%%
-type(options_subscription_leaf_local()
:: [pubsub_options:options_subscription_leaf_local(),...]
).
%%
-type(options_subscription_leaf_remote()
:: [pubsub_options:options_subscription_leaf_remote(),...]
).
%%
-type(options_subscription_collection_local()
:: [pubsub_options:options_subscription_collection_local(),...]
).
%%
-type(options_subscription_collection_remote()
:: [pubsub_options:options_subscription_collection_remote(),...]
).
%%
-type(options_subscription_leaf()
:: pubsub_options:options_subscription_leaf_local()
| pubsub_options:options_subscription_leaf_remote()
).
%%
-type(options_subscription_collection()
:: pubsub_options:options_subscription_collection_local()
| pubsub_options:options_subscription_collection_remote()
).
%%
-type(options_subscription_local()
:: pubsub_options:options_subscription_leaf_local()
| pubsub_options:options_subscription_collection_local()
).
%%
-type(options_subscription_remote()
:: pubsub_options:options_subscription_leaf_remote()
| pubsub_options:options_subscription_collection_remote()
).
-type(options_subscription()
:: pubsub_options:options_subscription_leaf()
| pubsub_options:options_subscription_collection()
).
%% --------------------------------------------------------------------
%% Functions.
%% --------------------------------------------------------------------
xmlns(Xmlel) ->
get_tag_attr_s(<<"xmlns">>, Xmlel).
-define(Is_Xmlel_Field(Xmlel),
(
Xmlel#xmlel.name == <<"field">>
)).
-define(Is_Xmlel_Value(Xmlel),
(
Xmlel#xmlel.name == <<"value">> andalso
Xmlel#xmlel.attrs == []
)).
-define(Is_Xmlel_X(Xmlel),
(
Xmlel#xmlel.name == <<"x">>
)).
-define(Is_Xmlel_X_Submit(Xmlel),
(
%Xmlel#xmlel.ns == 'jabber:x:data' andalso
Xmlel#xmlel.name == <<"x">> % andalso
% Xmlel#xmlel.attrs == [#xmlattr{name = <<"type">>, value = <<"submit">>}]
)).
-define(Is_Xmlel_X_Form(Xmlel),
(
%Xmlel#xmlel.ns == 'jabber:x:data' andalso
Xmlel#xmlel.name == <<"x">> andalso
Xmlel#xmlel.attrs == [{<<"type">>, <<"form">>}]
)).
%%
%%
-define(Is_Default_Subscribe_Option(Option),
(
Option == {'deliver', true}
orelse
Option == {'expire', undefined}
orelse
Option == {'include_body', false}
orelse
Option == {'show-values', ['away' , 'chat' , 'dnd' , 'online' , 'xa']}
)).
%%
-spec(trim_subscription_options/1 ::
(
Subscription_Options::pubsub_options:options_subscription())
-> Subscription_Options::pubsub_options:options_subscription()
).
trim_subscription_options(Subscription_Options) ->
trim_subscription_options(Subscription_Options, []).
%%
-spec(trim_subscription_options/2 ::
(
Options :: [] | pubsub_options:options_subscription(),
Subscription_Options :: [] | pubsub_options:options_subscription())
-> Subscription_Options :: [] | pubsub_options:options_subscription()
).
trim_subscription_options([] = _Options, Subscription_Options) ->
Subscription_Options;
%%
trim_subscription_options([Option | Options], Subscription_Options)
when ?Is_Default_Subscribe_Option(Option) ->
trim_subscription_options(Options, Subscription_Options);
%%
trim_subscription_options([Option | Options], Subscription_Options) ->
trim_subscription_options(Options, [Option | Subscription_Options]).
%%
-spec(parse_xmlel_x/5 ::
(
Plugin :: exmpp_pubsub:plugin(),
Pubsub_Features :: exmpp_pubsub:pubsub_features(),
Entity :: xmpp_jid:usr_entity(),
Form_Type :: 'node_config' | 'publish-options',
Xmlels :: [Xmlel_X::xmlel(),...]
| [Xmlel::xmlel()]
| [])
-> {ok,
Options :: pubsub_options:options_node()
| pubsub_options:options_item()}
%%%
| {error, 'not-acceptable'}
| {error, 'feature-not-implemented', 'collections'}
%%%
| {error, 'invalid-options'}
| {error, 'jid-malformed'}
%
| {error, 'not-acceptable'}
| {error, 'not-acceptable', 'unsupported-access-model'}
%
| {error, 'feature-not-implemented', 'collections'}
| {error, 'feature-not-implemented', 'multi-collections'}
).
parse_xmlel_x(Plugin, _Pubsub_Features, _Entity, 'node_config', []) ->
{ok, Plugin:node_options('leaf')};
parse_xmlel_x(_Plugin, _Pubsub_Features, _Entity, 'publish-options', []) ->
{ok, []};
%%
parse_xmlel_x(Plugin, Pubsub_Features, {U,S,_} = _Entity, Form_Type, [Xmlel_X])
when ?Is_Xmlel_X(Xmlel_X) ->
case
{xmlns(Xmlel_X),
options_type(remove_cdata(Xmlel_X#xmlel.children), Pubsub_Features)}
of
{?NS_XDATA, {ok, 'node_config' = Form_Type, Node_Type, Xmlels}} ->
parse_xmlels_field(Form_Type, Node_Type, Pubsub_Features,
{U,S,undefined}, Xmlels, Plugin:node_options(Node_Type));
%%
{?NS_XDATA, {ok, 'publish-options' = Form_Type, Node_Type, Xmlels}} ->
parse_xmlels_field(Form_Type, Node_Type, Pubsub_Features,
{U,S,undefined}, Xmlels, Plugin:item_options());
%%
{?NS_XDATA, Error} ->
Error;
_ ->
{error, 'invalid-options'}
end;
parse_xmlel_x(_Plugin, _Pubsub_Features, _Entity, _Form_Type, _Xmlels) ->
{error, 'invalid-options'}.
%%
-spec(parse_xmlel_x/7 ::
(
Plugin :: exmpp_pubsub:plugin(),
Pubsub_Features :: exmpp_pubsub:pubsub_features(),
Entity :: xmpp_jid:usr_entity(),
Entity_Type :: 'local' | 'remote',
Form_Type :: 'subscribe_options',
Node_Type :: 'leaf' | 'collection',
Xmlels :: [Xmlel_X::xmlel(),...]
| [Xmlel::xmlel()]
| [])
-> {ok,
Subscription_Options :: [] | pubsub_options:options_subscription_leaf()}
%%%
| {error, 'invalid-options'}
| {error, 'not-acceptable'}
).
parse_xmlel_x(Plugin, _Pubsub_Features, _Entity, Entity_Type, 'subscribe_options',
Node_Type, []) ->
{ok, Plugin:subscription_options(Entity_Type, Node_Type)};
%%
parse_xmlel_x(Plugin, Pubsub_Features, {U,S,_} = _Entity, Entity_Type,
'subscribe_options' = Form_Type, Node_Type, [Xmlel_X])
when ?Is_Xmlel_X(Xmlel_X) ->
case
{xmlns(Xmlel_X),
options_type(remove_cdata(Xmlel_X#xmlel.children), 'subscribe_options', [])}
of
{?NS_XDATA, {ok, 'subscribe_options', Xmlels}} ->
parse_xmlels_field(Form_Type, Node_Type, Pubsub_Features,
{U,S,undefined}, Entity_Type, Xmlels,
Plugin:default_subscription_options(Entity_Type, Node_Type));
{?NS_XDATA, Error} ->
Error;
_ ->
{error, 'invalid-options'}
end;
%%
parse_xmlel_x(_Plugin, _Pubsub_Features, _Entity, _Entity_Type, 'subscribe_options',
_Node_Type, _Xmlels) ->
{error, 'invalid-options'}.
%%
-spec(options_type/3 ::
(
Xmlels :: [Xmlel_Field::xmlel()]
| [Xmlel::xmlel()],
Form_Type :: 'subscribe_options',
Xmlels_Fields :: [Xmlel_Field::xmlel()]
| [Xmlel::xmlel()])
-> {ok,
Form_Type :: 'subscribe_options',
Xmlels_Field :: [Xmlel_Field::xmlel()]
| [Xmlel::xmlel()]}
%%%
| {error, 'not-acceptable'}
).
options_type([] = _Xmlels_Field, 'subscribe_options', _Xmlels) ->
{error, 'not-acceptable'};
%%
options_type([Xmlel_Field | Xmlels_Field], 'subscribe_options', Xmlels)
when ?Is_Xmlel_Field(Xmlel_Field) ->
case {xmlns(Xmlel_Field), get_tag_attr_s(<<"var">>, Xmlel_Field)} of
{_, <<>>} ->
{error, 'not-acceptable'};
{?NS_XDATA, <<"FORM_TYPE">>} ->
case remove_cdata(Xmlel_Field#xmlel.children) of
[Xmlel_Value] when ?Is_Xmlel_Value(Xmlel_Value) ->
case {xmlns(Xmlel_Value), get_tag_cdata(Xmlel_Value)} of
{?NS_XDATA, ?NS_PUBSUB_SUBSCRIBE_OPTIONS} ->
{ok, 'subscribe_options', Xmlels ++ Xmlels_Field};
_ ->
{error, 'not-acceptable'}
end;
_ ->
{error, 'not-acceptable'}
end;
{?NS_XDATA, _} ->
options_type(Xmlels_Field, 'subscribe_options',
[Xmlel_Field | Xmlels]);
_ ->
{error, 'not-acceptable'}
end.
%%
-spec(options_type/2 ::
(
Xmlels :: [Xmlel_Field::xmlel()]
| [Xmlel::xmlel()],
Pubsub_Features :: exmpp_pubsub:pubsub_features())
-> {ok,
Form_Type :: 'node_config' | 'publish-options',
Node_Type :: 'leaf' | 'collection',
Xmlels_Field :: [Xmlel_Field::xmlel()]
| [Xmlel::xmlel()]}
%%%
| {error, 'not-acceptable'}
| {error, 'feature-not-implemented', 'collections'}
).
options_type(Xmlels, Pubsub_Features) ->
options_type(Xmlels,
lists:member(<<"collections">>, Pubsub_Features), undefined, undefined, []).
%%
-spec(options_type/5 ::
(
Xmlels :: [Xmlel_Field::xmlel()]
| [Xmlel::xmlel()],
Collections :: boolean(),
Form_Type :: undefined | 'node_config' | 'publish-options',
Node_Type :: undefined | 'leaf' | 'collection',
Xmlels_Fields :: [Xmlel_Field::xmlel()]
| [Xmlel::xmlel()])
-> {ok,
Form_Type :: 'node_config' | 'publish-options',
Node_Type :: 'leaf' | 'collection',
Xmlels_Field :: [Xmlel_Field::xmlel()]
| [Xmlel::xmlel()]}
%%%
| {error, 'not-acceptable'}
| {error, 'feature-not-implemented', 'collections'}
).
options_type([] = _Xmlels, _Collections, Form_Type, undefined = _Node_Type,
Xmlels_Field)
when Form_Type =/= undefined ->
{ok, Form_Type, 'leaf', Xmlels_Field};
%%
options_type([] = _Xmlels, _Collections, Form_Type, Node_Type, Xmlels_Field)
when Form_Type =/= undefined ->
{ok, Form_Type, Node_Type, Xmlels_Field};
%%
options_type([] = _Xmlels, _Collections, undefined = _Form_Type, _Node_Type,
_Xmlels_Field) ->
{error, 'bad-options'};
%%
options_type(Xmlels, _Collections, Form_Type, Node_Type, Xmlels_Field)
when Form_Type =/= undefined andalso Node_Type =/= undefined ->
{ok, Form_Type, Node_Type, Xmlels ++ Xmlels_Field};
%%
options_type([Xmlel_Field | Xmlels_Field], Collections, Form_Type, Node_Type,
Xmlels)
when ?Is_Xmlel_Field(Xmlel_Field) ->
case {xmlns(Xmlel_Field), get_tag_attr_s(<<"var">>, Xmlel_Field)} of
{_, <<>>} ->
{error, 'not-acceptable'};
{?NS_XDATA, <<"FORM_TYPE">>} ->
case remove_cdata(Xmlel_Field#xmlel.children) of
[Xmlel_Value] when ?Is_Xmlel_Value(Xmlel_Value) ->
case {xmlns(Xmlel_Value), get_tag_cdata(Xmlel_Value)} of
{?NS_XDATA, ?NS_PUBSUB_NODE_CONFIG} ->
options_type(Xmlels_Field, Collections, 'node_config',
Node_Type, Xmlels);
{?NS_XDATA, ?NS_PUBSUB_PUBLISH_OPTIONS} ->
options_type(Xmlels_Field, Collections,
'publish-options', Node_Type, Xmlels);
_ ->
{error, 'not-acceptable'}
end;
_ ->
{error, 'not-acceptable'}
end;
{?NS_XDATA, <<"pubsub#node_type">>} ->
case remove_cdata(Xmlel_Field#xmlel.children) of
[Xmlel_Value] when ?Is_Xmlel_Value(Xmlel_Value) ->
case {xmlns(Xmlel_Value), get_tag_cdata(Xmlel_Value)} of
{?NS_XDATA, <<"leaf">>} ->
options_type(Xmlels_Field, Collections, Form_Type,
'leaf', Xmlels);
{?NS_XDATA, <<"collection">>} ->
case Collections of
true ->
options_type(Xmlels_Field, Collections,
Form_Type, 'collection', Xmlels);
false ->
{error,
'feature-not-implemented', 'collections'}
end;
_ ->
{error, 'not-acceptable'}
end
end;
{?NS_XDATA, _Xmlattr} ->
options_type(Xmlels_Field, Collections, Form_Type, Node_Type,
[Xmlel_Field | Xmlels]);
_ ->
{error, 'not-acceptable'}
end.
%%
-spec(parse_xmlels_field/6 ::
(
Options_Type :: 'node_config' | 'publish-options',
Node_Type :: 'leaf' | 'collection',
Pubsub_Features :: exmpp_pubsub:pubsub_features(),
Entity :: xmpp_jid:usr_entity(),
Xmlels :: [Xmlel_Field::xmlel()]
| [Xmlel::xmlel()],
Options :: pubsub_options:options_node()
| pubsub_options:options_item()
%%
| {error, 'invalid-options'}
| {error, 'jid-malformed'}
%
| {error, 'not-acceptable'}
| {error, 'not-acceptable', 'unsupported-access-model'}
%
| {error, 'feature-not-implemented', 'collections'}
| {error, 'feature-not-implemented', 'multi-collections'})
-> {ok,
Options :: pubsub_options:options_node()
| pubsub_options:options_item()}
%%%
| {error, 'invalid-options'}
| {error, 'jid-malformed'}
%
| {error, 'not-acceptable'}
| {error, 'not-acceptable', 'unsupported-access-model'}
%
| {error, 'feature-not-implemented', 'collections'}
| {error, 'feature-not-implemented', 'multi-collections'}
).
%%
parse_xmlels_field(_Options_Type, _Node_Type, _Pubsub_Features, _Entity,
_Xmlels, Error)
when is_tuple(Error) ->
Error;
parse_xmlels_field(_Options_Type, _Node_Type, _Pubsub_Features, _Entity,
[] = _Xmlels, Options) ->
{ok, Options};
%%
parse_xmlels_field(Options_Type, Node_Type, Pubsub_Features, Entity,
[Xmlel_Field | Xmlels], Options)
when ?Is_Xmlel_Field(Xmlel_Field) ->
case xmlns(Xmlel_Field) of
?NS_XDATA ->
parse_xmlels_field(Options_Type, Node_Type, Pubsub_Features, Entity,
Xmlels,
parse_xmlel_field_attrs(
get_tag_attr_s(<<"var">>, Xmlel_Field),
Options_Type, Node_Type, Pubsub_Features, Entity,
remove_cdata(Xmlel_Field#xmlel.children),
Options));
_ ->
{error, 'invalid-options'}
end;
%%
parse_xmlels_field(_Options_Type, _Node_Type, _Pubsub_Feature, _Entity,
_Xmlels, _Options) ->
{error, 'invalid-options'}.
%%
-spec(parse_xmlels_field/7 ::
(
Options_Type :: 'subscribe_options',
Node_Type :: 'leaf' | 'collection',
Pubsub_Features :: exmpp_pubsub:pubsub_features(),
Entity :: xmpp_jid:usr_entity(),
Entity_Type :: 'local' | 'remote',
Xmlels :: [Xmlel_Field::xmlel()]
| [Xmlel::xmlel()],
Options :: pubsub_options:options_subscription()
%
| {error, 'invalid-options'}
| {error, 'not-acceptable'})
-> {ok,
Options :: pubsub_options:options_node()
| pubsub_options:options_item()}
%%%
| {error, 'invalid-options'}
| {error, 'not-acceptable'}
).
%%
parse_xmlels_field(_Options_Type, _Node_Type, _Pubsub_Features, _Entity,
_Entity_Type, _Xmlels, Error)
when is_tuple(Error) ->
Error;
parse_xmlels_field(_Options_Type, _Node_Type, _Pubsub_Features, _Entity,
_Entity_Type, [] = _Xmlels, Options) ->
{ok, trim_subscription_options(Options)};
%%
parse_xmlels_field(Options_Type, Node_Type, Pubsub_Features, Entity,
Entity_Type, [Xmlel_Field | Xmlels], Options)
when ?Is_Xmlel_Field(Xmlel_Field) ->
case xmlns(Xmlel_Field) of
?NS_XDATA ->
parse_xmlels_field(Options_Type, Node_Type, Pubsub_Features, Entity,
Entity_Type,
Xmlels,
parse_xmlel_field_attrs(
get_tag_attr_s(<<"var">>, Xmlel_Field),
Options_Type, Node_Type, Pubsub_Features, Entity, Entity_Type,
remove_cdata(Xmlel_Field#xmlel.children),
Options));
_ ->
{error, 'invalid-options'}
end;
%%
parse_xmlels_field(_Options_Type, _Node_Type, _Pubsub_Feature, _Entity,
_Entity_Type, _Xmlels, _Options) ->
{error, 'invalid-options'}.
%%
-spec(parse_xmlel_field_attrs/7 ::
(
Pubsub_Option :: binary(),
Options_Type :: 'node_config' | 'publish-options',
Node_Type :: 'leaf' | 'collection',
Pubsub_Features :: exmpp_pubsub:pubsub_features(),
Entity :: xmpp_jid:usr_entity(),
Xmlels :: [Xmlel_Value::xmlel(),...]
| [Xmlel::xmlel(),...],
Options :: pubsub_options:options_node()
| pubsub_options:options_item())
-> Options :: pubsub_options:options_node()
| pubsub_options:options_item()
%%%
| {error, 'invalid-options'}
| {error, 'jid-malformed'}
%
| {error, 'not-acceptable'}
| {error, 'not-acceptable', 'unsupported-access-model'}
%
| {error, 'feature-not-implemented', 'collections'}
| {error, 'feature-not-implemented', 'multi-collections'}
).
parse_xmlel_field_attrs(<<"pubsub#roster_groups_allowed">>, Options_Type,
Node_Type, Pubsub_Features, Entity, Xmlels, Options)
when (Options_Type == 'node_config' orelse Options_Type == 'publish-options')
andalso (Node_Type == 'leaf' orelse Node_Type == 'collection') ->
case lists:member(<<"access-roster">>, Pubsub_Features) of
true ->
case
case Options_Type of
'node_config' ->
parse_pubsub_option_node(<<"roster_groups_allowed">>,
Node_Type, Pubsub_Features, Xmlels);
'publish-options' ->
parse_pubsub_option_item(<<"roster_groups_allowed">>,
Pubsub_Features, Xmlels)
end
of
{ok, Roster_Groups_Allowed} ->
case lists:keyfind('roster_groups_allowed', 1, Options) of
false ->
[{Entity, Roster_Groups_Allowed} | Options];
{'roster_groups_allowed', Rosters_Groups_Allowed} ->
lists:keyreplace('roster_groups_allowed', 1, Options,
{'roster_groups_allowed',
_New_Rosters_Groups_Allowed =
case
lists:keyreplace(Entity, 1,
Rosters_Groups_Allowed,
{Entity, Roster_Groups_Allowed})
of
Rosters_Groups_Allowed ->
[{Entity, Roster_Groups_Allowed}
| Rosters_Groups_Allowed];
New_Rosters_Groups_Allowed ->
New_Rosters_Groups_Allowed
end})
end;
Error ->
Error
end;
false ->
{error, 'invalid-options'}
end;
%%
parse_xmlel_field_attrs(<<"pubsub#", Pubsub_Option/binary>>,
'node_config' = _Options_Type, Node_Type, Pubsub_Features, _Entity, Xmlels,
Node_Options) ->
case
lists:keymember(
Key = list_to_atom(binary_to_list(Pubsub_Option)), 1, Node_Options)
of
true ->
case
parse_pubsub_option_node(Pubsub_Option, Node_Type,
Pubsub_Features, Xmlels)
of
{ok, Value} ->
lists:keyreplace(Key, 1, Node_Options, {Key, Value});
Error ->
Error
end;
false ->
Node_Options%{error, 'invalid-options'}
end;
%%
parse_xmlel_field_attrs(<<"pubsub#", Pubsub_Option/binary>>,
'publish-options' = _Options_Type, _Node_Type, Pubsub_Features, _Entity, Xmlels,
Item_Options) ->
case parse_pubsub_option_item(Pubsub_Option, Pubsub_Features, Xmlels) of
{ok, Value}
when Value == undefined
orelse Value == [] ->
lists:keydelete(_Key = list_to_atom(binary_to_list(Pubsub_Option)),
1, Item_Options);
{ok, Value} ->
Key = list_to_atom(binary_to_list(Pubsub_Option)),
case lists:keyreplace(Key, 1, Item_Options, {Key, Value}) of
Item_Options -> [{Key, Value} | Item_Options];
New_Item_Options -> New_Item_Options
end;
Error ->
Error
end;
%%
parse_xmlel_field_attrs(_Xmlattr_value, _Options_Type, _Node_Type,
_Pubsub_Features, _Entity, _Xmlels, _Options) ->
{error, 'invalid-options'}.
%%
-spec(parse_xmlel_field_attrs/8 ::
(
Pubsub_Option :: binary(),
Options_Type :: 'subscribe_options',
Node_Type :: 'leaf' | 'collection',
Pubsub_Features :: exmpp_pubsub:pubsub_features(),
Entity :: xmpp_jid:usr_entity(),
Entity_Type :: 'local' | 'remote',
Xmlels :: [Xmlel_Value::xmlel(),...]
| [Xmlel::xmlel(),...],
Subscription_Options :: pubsub_options:options_subscription())
-> Subscription_Options :: pubsub_options:options_subscription()
%%%
| {error, 'invalid-options'}
).
parse_xmlel_field_attrs(<<"pubsub#", Pubsub_Option/binary>>,
'subscribe_options' = _Options_Type, Node_Type, Pubsub_Features, _Entity,
Entity_Type, Xmlels, Subscription_Options) ->
case
lists:keymember(Key = list_to_atom(binary_to_list(Pubsub_Option)), 1,
Subscription_Options)
of
true ->
case
parse_pubsub_option_subscription(Pubsub_Option, Node_Type,
Entity_Type, Pubsub_Features, Xmlels)
of
{ok, Value}
when ?Is_Default_Subscribe_Option({Key, Value}) ->
lists:keydelete(Key, 1, Subscription_Options);
{ok, Value} ->
lists:keyreplace(Key, 1, Subscription_Options, {Key, Value});
Error ->
Error
end;
false ->
{error, 'invalid-options'}
end;
%%
parse_xmlel_field_attrs(_Xmlattr_value, _Options_Type, _Node_Type,
_Pubsub_Features, _Entity, _Entity_Type, _Xmlels, _Options) ->
{error, 'invalid-options'}.
%%
%%
-spec(parse_pubsub_option_node/4 ::
(
Pubsub_Option :: binary(),
Node_Type :: 'collection' | 'leaf',
Pubsub_Features :: exmpp_pubsub:pubsub_features(),
Xmlels :: [Xmlel_Value::xmlel()]
| [Xmlel::xmlel()])
-> {ok, Access_Model :: pubsub_options:access_model()}
% | {ok, Body_XSLT :: undefined | binary()}
| {ok, Children_Association_Policy :: 'all' | 'owners' | 'whitelist'}
| {ok, Children_Association_Whitelist :: [Jid::xmpp_jid:raw_jid_entity_bare()]}
| {ok, Children :: [Child_NodeId::exmpp_pubsub:nodeId()]}
| {ok, Children_Max :: undefined | non_neg_integer()}
| {ok, Collection :: [Parent_NodeId::exmpp_pubsub:nodeId()]}
| {ok, Contact :: [Jid::xmpp_jid:raw_jid_entity()]}
% | {ok, Dataform_XSLT :: undefined | binary()}
| {ok, Deliver_Notifications :: boolean()}
| {ok, Deliver_Payloads :: boolean()}
| {ok, Description :: undefined | binary()}
| {ok, Item_Expire :: undefined | non_neg_integer()}
| {ok, ItemReply :: pubsub_options:item_reply()}
| {ok, Language :: undefined | binary()}
| {ok, Max_Items :: undefined | non_neg_integer()}
| {ok, Max_Payload_Size :: undefined | non_neg_integer()}
| {ok, Node_Type :: pubsub_options:node_type()}
| {ok, Notification_Type :: pubsub_options:notification_type()}
| {ok, Notify_Config :: boolean()}
| {ok, Notify_Delete :: boolean()}
| {ok, Notify_Retract :: boolean()}
| {ok, Notify_Sub :: boolean()}
| {ok, Persist_Items :: boolean()}
| {ok, Presence_Based_Delivery :: boolean()}
| {ok, Publish_Model :: pubsub_options:publish_model()}
| {ok, Purge_Offline :: boolean()}
| {ok, Rosters_Groups_Allowed :: pubsub_options:rosters_groups_allowed()}
| {ok, Send_Last_Published_Item :: pubsub_options:send_last_published_item()}
| {ok, Tempsub :: boolean()}
| {ok, Subscribe :: boolean()}
| {ok, Title :: undefined | binary()}
| {ok, Type :: undefined | atom()}
%%%
| {error, 'invalid-options'}
| {error, 'jid-malformed'}
%
| {error, 'not-acceptable'}
| {error, 'not-acceptable', 'unsupported-access-model'}
%
| {error, 'feature-not-implemented', 'collections'}
| {error, 'feature-not-implemented', 'multi-collections'}
).
parse_pubsub_option_node(<<"access_model">> = _Pubsub_Option, Node_Type,
Pubsub_Features, Xmlels)
when Node_Type == 'collection' orelse Node_Type == 'leaf' ->
parse_xmlel_value({'access_model', Pubsub_Features}, Xmlels);
%%
%%parse_pubsub_option_node(<<"pubsub#body_xslt">> = _Pubsub_Option,
%% 'leaf' = _Node_Type, Pusbub_Features, Xmlels) ->
%% case lists:member(<<"publish">>, Pubsub_Features) of
%% true ->
%% parse_xmlel_value('text-single', Xmlels);
%% false ->
%% {error, 'invalid-options'}
%% end;
%%
parse_pubsub_option_node(<<"children_association_policy">> = _Pubsub_Option,
'collection' = _Node_Type, _Pubsub_Features, Xmlels) ->
parse_xmlel_value({'list-single', 'atom',
_Default_Values = ['all', 'owners', 'whitelist']}, Xmlels);
%%
parse_pubsub_option_node(<<"children_association_whitelist">> = _Pubsub_Option,
'collection' = _Node_Type, _Pubsub_Features, [] = _Xmlels) ->
{ok, []};
parse_pubsub_option_node(<<"children_association_whitelist">> = _Pubsub_Option,
'collection' = _Node_Type, _Pubsub_Features, Xmlels) ->
parse_xmlel_value({'jid-multi', 'bare'}, Xmlels);
%%
%%
parse_pubsub_option_node(<<"children">> = _Pubsub_Option,
'collection' = _Node_Type, _Pubsub_Features, [] = Xmlels) ->
parse_xmlel_value('text-multi', Xmlels);
parse_pubsub_option_node(<<"children">> = _Pubsub_Option,
'collection' = _Node_Type, _Pubsub_Features, [_] = Xmlels) ->
parse_xmlel_value('text-multi', Xmlels);
parse_pubsub_option_node(<<"children">> = _Pubsub_Option,
'collection' = _Node_Type, Pubsub_Features, Xmlels) ->
case lists:member(<<"multi-collections">>, Pubsub_Features) of
true -> parse_xmlel_value('text-multi', Xmlels);
false -> {error, 'feature-not-implemented', 'multi-collections'}
end;
%%
%%
parse_pubsub_option_node(<<"children_max">> = _Pubsub_Option,
'collection' = _Node_Type, _Pubsub_Features, [] = _Xmlels) ->
{ok, undefined};
parse_pubsub_option_node(<<"children_max">> = _Pubsub_Option,
'collection' = _Node_Type, Pubsub_Features, [Xmlel_Value])
when ?Is_Xmlel_Value(Xmlel_Value) ->
case {xmlns(Xmlel_Value), get_tag_cdata(Xmlel_Value)} of
{?NS_XDATA, <<>>} ->
{ok, undefined};
{?NS_XDATA, CData} ->
case catch list_to_integer(binary_to_list(CData)) of
Integer when Integer == 0 orelse Integer == 1 ->
{ok, Integer};
Integer when is_integer(Integer) andalso Integer > 1 ->
case
lists:member(<<"multi-collections">>, Pubsub_Features)
of
true -> {ok, Integer};
false -> {error, 'not-acceptable'}
end;
_ ->
{error, 'not-acceptable'}
end;
_ ->
{error, 'not-acceptable'}
end;
parse_pubsub_option_node(<<"children_max">> = _Pubsub_Option,
'collection' = _Node_Type, _Pubsub_Features, _Xmlels) ->
{error, 'not-acceptable'};
%%
parse_pubsub_option_node(<<"collection">> = _Pubsub_Option, Node_Type,
Pubsub_Features, [] = _Xmlels)
when Node_Type == 'collection' orelse Node_Type == 'leaf' ->
case lists:member(<<"collections">>, Pubsub_Features) of
true -> {ok, []};
false -> {error, 'feature-not-implemented', 'collections'}
end;
parse_pubsub_option_node(<<"collection">> = _Pubsub_Option, Node_Type,
Pubsub_Features, [_] = Xmlels)
when Node_Type == 'collection' orelse Node_Type == 'leaf' ->
case lists:member(<<"collections">>, Pubsub_Features) of
true -> parse_xmlel_value('text-multi', Xmlels);
false -> {error, 'feature-not-implemented', 'collections'}
end;
parse_pubsub_option_node(<<"collection">> = _Pubsub_Option, Node_Type,
Pubsub_Features, Xmlels)
when Node_Type == 'collection' orelse Node_Type == 'leaf' ->
case lists:member(<<"collections">>, Pubsub_Features) of
true ->
case lists:member(<<"multi-collections">>, Pubsub_Features) of
true -> parse_xmlel_value('text-multi', Xmlels);
false -> {error, 'feature-not-implemented', 'multi-collections'}
end;
false ->
{error, 'feature-not-implemented', 'collections'}
end;
%%
parse_pubsub_option_node(<<"contact">> = _Pubsub_Option, Node_Type,
_Pubsub_Features, [] = _Xmlels)
when Node_Type == 'collection' orelse Node_Type == 'leaf' ->
{ok, []};
parse_pubsub_option_node(<<"contact">> = _Pubsub_Option, Node_Type,
_Pubsub_Features, Xmlels)
when Node_Type == 'collection' orelse Node_Type == 'leaf' ->
parse_xmlel_value({'jid-multi', 'full'}, Xmlels);
%%
%%parse_pubsub_option_node(<<"pubsub#dataform_xslt">> = _Pubsub_Option,
%% 'leaf' = _Node_Type, Pusbub_Features, Xmlels) ->
%% case lists:member(<<"publish">>, Pubsub_Features) of
%% true ->
%% parse_xmlel_value('text-single', Xmlels);
%% false ->
%% {error, 'invalid-options'}
%% end;
%%
parse_pubsub_option_node(<<"deliver_notifications">> = _Pubsub_Option,
'leaf' = _Node_Type, Pubsub_Features, Xmlels) ->
case lists:member(<<"subscribe">>, Pubsub_Features) of
true -> parse_xmlel_value('boolean', Xmlels);
false -> {error, 'invalid-options'}
end;
%%
parse_pubsub_option_node(<<"deliver_payloads">> = _Pubsub_Option, Node_Type,
Pubsub_Features, Xmlels)
when Node_Type == 'collection' orelse Node_Type == 'leaf' ->
case lists:member(<<"subscribe">>, Pubsub_Features) of
true -> parse_xmlel_value('boolean', Xmlels);
false -> {error, 'invalid-options'}
end;
%%
parse_pubsub_option_node(<<"description">> = _Pubsub_Option, Node_Type,
_Pubsub_Features, [] = _Xmlels)
when Node_Type == 'collection' orelse Node_Type == 'leaf' ->
{ok, undefined};
parse_pubsub_option_node(<<"description">> = _Pubsub_Option, Node_Type,
_Pubsub_Features, Xmlels)
when Node_Type == 'collection' orelse Node_Type == 'leaf' ->
parse_xmlel_value('text-single', Xmlels);
%%
parse_pubsub_option_node(<<"item_expire">> = _Pubsub_Option, 'leaf' = _Node_Type,
Pubsub_Features, [] = _Xmlels) ->
case lists:member(<<"publish">>, Pubsub_Features) of
true -> {ok, undefined};
false -> {error, 'invalid-options'}
end;
parse_pubsub_option_node(<<"item_expire">> = _Pubsub_Option, 'leaf' = _Node_Type,
Pubsub_Features, Xmlels) ->
case lists:member(<<"publish">>, Pubsub_Features) of
true -> parse_xmlel_value({'text-single', 'integer'}, Xmlels);
false -> {error, 'invalid-options'}
end;
%%
parse_pubsub_option_node(<<"itemreply">> = _Pubsub_Option, 'leaf' = _Node_Type,
Pubsub_Features, Xmlels) ->
case lists:member(<<"publish">>, Pubsub_Features) of
true ->
parse_xmlel_value({'list-single', 'atom',
_Default_Values = ['owner', 'publisher']}, Xmlels);
false ->
{error, 'invalid-options'}
end;
%%
parse_pubsub_option_node(<<"language">> = _Pubsub_Option, Node_Type,
_Pubsub_Features, [] = _Xmlels)
when Node_Type == 'collection' orelse Node_Type == 'leaf' ->
{ok, undefined};
parse_pubsub_option_node(<<"language">> = _Pubsub_Option, Node_Type,
_Pubsub_Features, Xmlels)
when Node_Type == 'collection' orelse Node_Type == 'leaf' ->
parse_xmlel_value('text-single', Xmlels);
%%
parse_pubsub_option_node(<<"max_items">> = _Pubsub_Option, 'leaf' = _Node_Type,
Pubsub_Features, [] = _Xmlels) ->
case lists:member(<<"publish">>, Pubsub_Features) of
true -> {ok, undefined};
false -> {error, 'invalid-options'}
end;
parse_pubsub_option_node(<<"max_items">> = _Pubsub_Option, 'leaf' = _Node_Type,
Pubsub_Features, Xmlels) ->
case lists:member(<<"publish">>, Pubsub_Features) of
true -> parse_xmlel_value({'text-single', 'integer'}, Xmlels);
false -> {error, 'invalid-options'}
end;
%%
parse_pubsub_option_node(<<"max_payload_size">> = _Pubsub_Option,
'leaf' = _Node_Type, Pubsub_Features, [] = _Xmlels) ->
case lists:member(<<"publish">>, Pubsub_Features) of
true -> {ok, undefined};
false -> {error, 'invalid-options'}
end;
parse_pubsub_option_node(<<"max_payload_size">> = _Pubsub_Option,
'leaf' = _Node_Type, Pubsub_Features, Xmlels) ->
case lists:member(<<"publish">>, Pubsub_Features) of
true -> parse_xmlel_value({'text-single', 'integer'}, Xmlels);
false -> {error, 'invalid-options'}
end;
%%
parse_pubsub_option_node(<<"notification_type">> = _Pubsub_Option, Node_Type,
Pubsub_Features, Xmlels)
when Node_Type == 'collection' orelse Node_Type == 'leaf' ->
case lists:member(<<"publish">>, Pubsub_Features) of
true ->
parse_xmlel_value({'list-single', 'atom',
_Default_Values = ['headline', 'normal']}, Xmlels);
false ->
{error, 'invalid-options'}
end;
%%
parse_pubsub_option_node(<<"notify_config">> = _Pubsub_Option, Node_Type,
Pubsub_Features, Xmlels)
when Node_Type == 'collection' orelse Node_Type == 'leaf' ->
case lists:member(<<"config-node">>, Pubsub_Features) of
true -> parse_xmlel_value('boolean', Xmlels);
false -> {error, 'invalid-options'}
end;
%%
parse_pubsub_option_node(<<"notify_delete">> = _Pubsub_Option, Node_Type,
Pubsub_Features, Xmlels)
when Node_Type == 'collection' orelse Node_Type == 'leaf' ->
case lists:member(<<"delete-nodes">>, Pubsub_Features) of
true -> parse_xmlel_value('boolean', Xmlels);
false -> {error, 'invalid-options'}
end;
%%
parse_pubsub_option_node(<<"notify_retract">> = _Pubsub_Option,
'leaf' = _Node_Type, Pubsub_Features, Xmlels) ->
case lists:member(<<"delete-items">>, Pubsub_Features) of
true -> parse_xmlel_value('boolean', Xmlels);
false -> {error, 'invalid-options'}
end;
%%
parse_pubsub_option_node(<<"notify_sub">> = _Pubsub_Option, Node_Type,
Pubsub_Features, Xmlels)
when Node_Type == 'collection' orelse Node_Type == 'leaf' ->
case lists:member(<<"subscribe">>, Pubsub_Features) of
true -> parse_xmlel_value('boolean', Xmlels);
false -> {error, 'invalid-options'}
end;
%%
parse_pubsub_option_node(<<"persist_items">> = _Pubsub_Option,
'leaf' = _Node_Type, Pubsub_Features, Xmlels) ->
case lists:member(<<"persistent-items">>, Pubsub_Features) of
true -> parse_xmlel_value('boolean', Xmlels);
false -> {error, 'invalid-options'}
end;
%%
parse_pubsub_option_node(<<"presence_based_delivery">> = _Pubsub_Option,
Node_Type, Pubsub_Features, Xmlels)
when Node_Type == 'collection' orelse Node_Type == 'leaf' ->
case lists:member(<<"presence-notifications">>, Pubsub_Features) of
true -> parse_xmlel_value('boolean', Xmlels);
false -> {error, 'invalid-options'}
end;
%%
parse_pubsub_option_node(<<"publish_model">> = _Pubsub_Option,
'leaf' = _Node_Type, Pubsub_Features, Xmlels) ->
case lists:member(<<"publish">>, Pubsub_Features) of
true ->
parse_xmlel_value({'list-single', 'atom',
_Default_Values = ['open', 'publishers', 'subscribers']},
Xmlels);
false ->
{error, 'invalid-options'}
end;
%%
parse_pubsub_option_node(<<"purge_offline">> = _Pubsub_Option,
'leaf' = _Node_Type, Pubsub_Features, Xmlels) ->
case lists:member(<<"purge-nodes">>, Pubsub_Features) of
true -> parse_xmlel_value('boolean', Xmlels);
false -> {error, 'invalid-options'}
end;
%%
parse_pubsub_option_node(<<"roster_groups_allowed">> = _Pubsub_Option,
Node_Type, Pubsub_Features, [] = _Xmlels)
when Node_Type == 'collection' orelse Node_Type == 'leaf' ->
case lists:member(<<"access-roster">>, Pubsub_Features) of
true -> {ok, []};
false -> {error, 'invalid-options'}
end;
parse_pubsub_option_node(<<"roster_groups_allowed">> = _Pubsub_Option,
Node_Type, Pubsub_Features, Xmlels)
when Node_Type == 'collection' orelse Node_Type == 'leaf' ->
case lists:member(<<"access-roster">>, Pubsub_Features) of
true -> parse_xmlel_value('list-multi', Xmlels);
false -> {error, 'invalid-options'}
end;
%%
parse_pubsub_option_node(<<"send_last_published_item">> = _Pubsub_Option,
'leaf' = _Node_Type, Pubsub_Features, Xmlels) ->
case lists:member(<<"last-published">>, Pubsub_Features) of
true ->
parse_xmlel_value({'list-single', 'atom',
_Default_Values = case
lists:member(<<"presence-notifications">>, Pubsub_Features)
of
true -> ['never', 'on_sub', 'on_sub_and_presence'];
false -> ['never', 'on_sub']
end},
Xmlels);
false ->
{error, 'invalid-options'}
end;
%%
parse_pubsub_option_node(<<"tempsub">> = _Pubsub_Option, Node_Type,
Pubsub_Features, Xmlels)
when Node_Type == 'collection' orelse Node_Type == 'leaf' ->
case lists:member(<<"subscribe">>, Pubsub_Features) of
true ->
case lists:member(<<"presence-notifications">>, Pubsub_Features) of
true -> parse_xmlel_value('boolean', Xmlels);
false -> {error, 'invalid-options'}
end;
false ->
{error, 'invalid-options'}
end;
%%
parse_pubsub_option_node(<<"subscribe">> = _Pubsub_Option, Node_Type,
Pubsub_Features, Xmlels)
when Node_Type == 'collection' orelse Node_Type == 'leaf' ->
case lists:member(<<"subscribe">>, Pubsub_Features) of
true -> parse_xmlel_value('boolean', Xmlels);
false -> {error, 'invalid-options'}
end;
%%
parse_pubsub_option_node(<<"title">> = _Pubsub_Option, Node_Type,
_Pubsub_Features, [] = _Xmlels)
when Node_Type == 'collection' orelse Node_Type == 'leaf' ->
{ok, undefined};
parse_pubsub_option_node(<<"title">> = _Pubsub_Option, Node_Type,
_Pubsub_Features, Xmlels)
when Node_Type == 'collection' orelse Node_Type == 'leaf' ->
parse_xmlel_value('text-single', Xmlels);
%%
parse_pubsub_option_node(<<"type">> = _Pubsub_Option,
'leaf' = _Node_Type, Pubsub_Features, [] = _Xmlels) ->
case lists:member(<<"publish">>, Pubsub_Features) of
true -> {ok, undefined};
false -> {error, 'invalid-options'}
end;
parse_pubsub_option_node(<<"type">> = _Pubsub_Option,
'leaf' = _Node_Type, Pubsub_Features, Xmlels) ->
case lists:member(<<"publish">>, Pubsub_Features) of
true -> parse_xmlel_value({'text-single', 'atom'}, Xmlels);
false -> {error, 'invalid-options'}
end;
%%
parse_pubsub_option_node(_Pubsub_Option, _Node_Type, _Pubsub_Features, _Xmlels) ->
{error, 'invalid-options'}.
%%
%%
-spec(parse_pubsub_option_item/3 ::
(
Pubsub_Option :: binary(),
Pubsub_Features :: exmpp_pubsub:pubsub_features(),
Xmlels :: [Xmlel_Value::xmlel()]
| [Xmlel::xmlel()])
-> {ok, Access_Model :: pubsub_options:access_model()}
% | {ok, Body_XSLT :: undefined | binary()}
% | {ok, Dataform_XSLT :: undefined | binary()}
| {ok, Deliver_Notifications :: boolean()}
| {ok, Deliver_Payloads :: boolean()}
| {ok, Item_Expire :: undefined | non_neg_integer()}
| {ok, ItemReply :: pubsub_options:item_reply()}
%% | {ok, Max_Payload_Size :: undefined | non_neg_integer()}
| {ok, Notification_Type :: pubsub_options:notification_type()}
| {ok, Notify_Config :: boolean()}
| {ok, Notify_Retract :: boolean()}
| {ok, Persist_Items :: boolean()}
| {ok, Presence_Based_Delivery :: boolean()}
% | {ok, Publish_Model :: pubsub_options:publish_model()}
| {ok, Purge_Offline :: boolean()}
| {ok, Rosters_Groups_Allowed :: pubsub_options:rosters_groups_allowed()}
| {ok, Send_Last_Published_Item :: pubsub_options:send_last_published_item()}
| {ok, Type :: undefined | atom()}
%%%
| {error, 'invalid-options'}
%
| {error, 'not-acceptable'}
| {error, 'not-acceptable', 'unsupported-access-model'}
).
parse_pubsub_option_item(<<"access_model">> = _Pubsub_Option, Pubsub_Features,
Xmlels) ->
parse_xmlel_value({'access_model', Pubsub_Features}, Xmlels);
%%
%%parse_pubsub_option_item(<<"pubsub#body_xslt">> = _Pubsub_Option,
%% Pusbub_Features, Xmlels) ->
%% case lists:member(<<"publish">>, Pubsub_Features) of
%% true ->
%% parse_xmlel_value('text-single', Xmlels);
%% false ->
%% {error, 'invalid-options'}
%% end;
%%
%%parse_pubsub_option_item(<<"pubsub#dataform_xslt">> = _Pubsub_Option,
%% Pusbub_Features, Xmlels) ->
%% case lists:member(<<"publish">>, Pubsub_Features) of
%% true ->
%% parse_xmlel_value('text-single', Xmlels);
%% false ->
%% {error, 'invalid-options'}
%% end;
%%
parse_pubsub_option_item(<<"deliver_notifications">> = _Pubsub_Option,
Pubsub_Features, Xmlels) ->
case lists:member(<<"subscribe">>, Pubsub_Features) of
true -> parse_xmlel_value('boolean', Xmlels);
false -> {error, 'invalid-options'}
end;
%%
parse_pubsub_option_item(<<"deliver_payloads">> = _Pubsub_Option,
Pubsub_Features, Xmlels) ->
case lists:member(<<"subscribe">>, Pubsub_Features) of
true -> parse_xmlel_value('boolean', Xmlels);
false -> {error, 'invalid-options'}
end;
%%
parse_pubsub_option_item(<<"item_expire">> = _Pubsub_Option, Pubsub_Features,
[] = _Xmlels) ->
case lists:member(<<"publish">>, Pubsub_Features) of
true -> {ok, undefined};
false -> {error, 'invalid-options'}
end;
parse_pubsub_option_item(<<"item_expire">> = _Pubsub_Option, Pubsub_Features,
Xmlels) ->
case lists:member(<<"publish">>, Pubsub_Features) of
true -> parse_xmlel_value({'text-single', 'integer'}, Xmlels);
false -> {error, 'invalid-options'}
end;
%%
parse_pubsub_option_item(<<"itemreply">> = _Pubsub_Option, Pubsub_Features,
Xmlels) ->
case lists:member(<<"publish">>, Pubsub_Features) of
true ->
parse_xmlel_value({'list-single', 'atom',
_Default_Values = ['owner', 'publisher']}, Xmlels);
false ->
{error, 'invalid-options'}
end;
%%
%parse_pubsub_option_item(<<"max_payload_size">> = _Pubsub_Option,
% Pubsub_Features, Xmlels) ->
% case lists:member(<<"publish">>, Pubsub_Features) of
% true ->
% parse_xmlel_value({'text-single', 'integer'}, Xmlels);
% false ->
% {error, 'invalid-options'}
% end;
%%
parse_pubsub_option_item(<<"notification_type">> = _Pubsub_Option,
Pubsub_Features, Xmlels) ->
case lists:member(<<"publish">>, Pubsub_Features) of
true ->
parse_xmlel_value({'list-single', 'atom',
_Default_Values = ['headline', 'normal']}, Xmlels);
false ->
{error, 'invalid-options'}
end;
%%
parse_pubsub_option_item(<<"notify_config">> = _Pubsub_Option, Pubsub_Features,
Xmlels) ->
case lists:member(<<"config-node">>, Pubsub_Features) of
true -> parse_xmlel_value('boolean', Xmlels);
false -> {error, 'invalid-options'}
end;
%%
parse_pubsub_option_item(<<"notify_retract">> = _Pubsub_Option, Pubsub_Features,
Xmlels) ->
case lists:member(<<"delete-items">>, Pubsub_Features) of
true -> parse_xmlel_value('boolean', Xmlels);
false -> {error, 'invalid-options'}
end;
%%
parse_pubsub_option_item(<<"persist_items">> = _Pubsub_Option, Pubsub_Features,
Xmlels) ->
case lists:member(<<"persistent-items">>, Pubsub_Features) of
true -> parse_xmlel_value('boolean', Xmlels);
false -> {error, 'invalid-options'}
end;
%%
parse_pubsub_option_item(<<"presence_based_delivery">> = _Pubsub_Option,
Pubsub_Features, Xmlels) ->
case lists:member(<<"presence-notifications">>, Pubsub_Features) of
true -> parse_xmlel_value('boolean', Xmlels);
false -> {error, 'invalid-options'}
end;
%%
%parse_pubsub_option_item(<<"publish_model">> = _Pubsub_Option,
% Pubsub_Features, Xmlels) ->
% case lists:member(<<"publish">>, Pubsub_Features) of
% true ->
% parse_xmlel_value({'list-single', 'atom',
% _Default_Values = ['open', 'publishers', 'subscribers']},
% Xmlels);
% false ->
% {error, 'invalid-options'}
% end;
%%
parse_pubsub_option_item(<<"purge_offline">> = _Pubsub_Option, Pubsub_Features,
Xmlels) ->
case lists:member(<<"purge-nodes">>, Pubsub_Features) of
true -> parse_xmlel_value('boolean', Xmlels);
false -> {error, 'invalid-options'}
end;
%%
parse_pubsub_option_item(<<"roster_groups_allowed">> = _Pubsub_Option,
Pubsub_Features, [] = _Xmlels) ->
case lists:member(<<"access-roster">>, Pubsub_Features) of
true -> {ok, []};
false -> {error, 'invalid-options'}
end;
parse_pubsub_option_item(<<"roster_groups_allowed">> = _Pubsub_Option,
Pubsub_Features, Xmlels) ->
case lists:member(<<"access-roster">>, Pubsub_Features) of
true -> parse_xmlel_value('list-multi', Xmlels);
false -> {error, 'invalid-options'}
end;
%%
parse_pubsub_option_item(<<"send_last_published_item">> = _Pubsub_Option,
Pubsub_Features, Xmlels) ->
case lists:member(<<"last-published">>, Pubsub_Features) of
true ->
parse_xmlel_value({'list-single', 'atom',
_Default_Values = case
lists:member(<<"presence-notifications">>, Pubsub_Features)
of
true -> ['never', 'on_sub', 'on_sub_and_presence'];
false -> ['never', 'on_sub']
end},
Xmlels);
false ->
{error, 'invalid-options'}
end;
%%
parse_pubsub_option_item(<<"type">> = _Pubsub_Option, Pubsub_Features,
[] = _Xmlels) ->
case lists:member(<<"publish">>, Pubsub_Features) of
true -> {ok, undefined};
false -> {error, 'invalid-options'}
end;
parse_pubsub_option_item(<<"type">> = _Pubsub_Option, Pubsub_Features, Xmlels) ->
case lists:member(<<"publish">>, Pubsub_Features) of
true -> parse_xmlel_value({'text-single', 'atom'}, Xmlels);
false -> {error, 'invalid-options'}
end;
%%
parse_pubsub_option_item(_Pubsub_Option, _Pubsub_Features, _Xmlels) ->
{error, 'invalid-options'}.
%%
%%
-spec(parse_pubsub_option_subscription/5 ::
(
Pubsub_Option :: binary(),
Node_Type :: 'collection' | 'leaf',
Entity_Type :: 'local' | 'remote',
Pubsub_Features :: exmpp_pubsub:pubsub_features(),
Xmlels :: [Xmlel_Value::xmlel()]
| [Xmlel::xmlel()])
->
% {ok, Digest :: boolean()}
% | {ok, Digest_Frequency :: undefined | non_neg_integer()}
{ok, Deliver :: boolean()}
| {ok, Expire :: undefined | 'presence' | erlang:timestamp()}
% | {ok, Include_Body :: boolean()}
| {ok, Show_Values :: ['away' | 'chat' | 'dnd' | 'online' | 'xa']}
% | {ok, Subscription_Type :: 'all' | 'items' | 'nodes'}
% | {ok, Subscription_Depth :: 'all' | non_neg_integer()}
%%%
| {error, 'invalid-options'}
%
| {error, 'not-acceptable'}
).
%% parse_pubsub_option_subscription(<<"digest">> = _Pubsub_Option,
%% 'leaf' = _Node_Type, _Entity_Type, Pubsub_Features, Xmlels) ->
%% case lists:member(<<"subscribe">>, Pubsub_Features) of
%% true ->
%% parse_xmlel_value('boolean', Xmlels);
%% false ->
%% {error, 'invalid-options'}
%% end;
%%
%% parse_pubsub_option_subscription(<<"digest_frequency">> = _Pubsub_Option,
%% 'leaf' = _Node_Type, _Entity_Type, Pubsub_Features, Xmlels) ->
%% case lists:member(<<"subscribe">>, Pubsub_Features) of
%% true ->
%% parse_xmlel_value({'text-single', 'integer'}, Xmlels);
%% false ->
%% {error, 'invalid-options'}
%% end;
%%
parse_pubsub_option_subscription(<<"deliver">> = _Pubsub_Option, Node_Type,
_Entity_Type, Pubsub_Features, Xmlels)
when Node_Type == 'collection' orelse Node_Type == 'leaf' ->
case lists:member(<<"subscribe">>, Pubsub_Features) of
true -> parse_xmlel_value('boolean', Xmlels);
false -> {error, 'invalid-options'}
end;
%%
parse_pubsub_option_subscription(<<"expire">> = _Pubsub_Option, Node_Type,
'local' = _Entity_Type, Pubsub_Features, [] = _Xmlels)
when Node_Type == 'collection' orelse Node_Type == 'leaf' ->
case
lists:member(<<"presence-notifications">>, Pubsub_Features)
orelse
lists:member(<<"leased-subscriptions">>, Pubsub_Features)
of
true -> {ok, undefined};
false -> {error, 'invalid-options'}
end;
parse_pubsub_option_subscription(<<"expire">> = _Pubsub_Option, Node_Type,
'local' = _Entity_Type, Pubsub_Features, [Xmlel_Value])
when Node_Type == 'collection' orelse Node_Type == 'leaf'
andalso ?Is_Xmlel_Value(Xmlel_Value) ->
case {xmlns(Xmlel_Value), get_tag_cdata(Xmlel_Value)} of
{?NS_XDATA, <<>>} ->
{ok, undefined};
{?NS_XDATA, <<"presence">>} ->
case lists:member(<<"presence-notifications">>, Pubsub_Features) of
true -> {ok, 'presence'};
false -> {error, 'invalid-options'}
end;
{?NS_XDATA, CData} ->
case lists:member(<<"leased-subscriptions">>, Pubsub_Features) of
true ->
case jlib:datetime_string_to_timestamp(CData) of
undefined -> {error, 'not-acceptable'};
DateTime -> {ok, DateTime}
end;
false ->
{error, 'invalid-options'}
end;
_ ->
{error, 'invalid-options'}
end;
%
parse_pubsub_option_subscription(<<"expire">> = _Pubsub_Option, Node_Type,
'remote' = _Entity_Type, Pubsub_Features, [] = _Xmlels)
when Node_Type == 'collection' orelse Node_Type == 'leaf' ->
case lists:member(<<"leased-subscriptions">>, Pubsub_Features) of
true -> {ok, undefined};
false -> {error, 'invalid-options'}
end;
parse_pubsub_option_subscription(<<"expire">> = _Pubsub_Option, Node_Type,
'remote' = _Entity_Type, Pubsub_Features, [Xmlel_Value])
when Node_Type == 'collection' orelse Node_Type == 'leaf'
andalso ?Is_Xmlel_Value(Xmlel_Value) ->
case {xmlns(Xmlel_Value), get_tag_cdata(Xmlel_Value)} of
{?NS_XDATA, <<>>} ->
{ok, undefined};
{?NS_XDATA, <<"presence">>} ->
{error, 'invalid-options'};
{?NS_XDATA, CData} ->
case lists:member(<<"leased-subscriptions">>, Pubsub_Features) of
true ->
case jlib:datetime_string_to_timestamp(CData) of
undefined -> {error, 'not-acceptable'};
DateTime -> {ok, DateTime}
end;
false ->
{error, 'invalid-options'}
end;
_ ->
{error, 'invalid-options'}
end;
%%
%parse_pubsub_option_subscription(<<"include_body">> = _Pubsub_Option,
% 'leaf' = _Node_Type, _Entity_Type, Pubsub_Features, Xmlels) ->
% case lists:member(<<"subscribe">>, Pubsub_Features) of
% true ->
% parse_xmlel_value('boolean', Xmlels);
% false ->
% {error, 'invalid-options'}
% end;
%%
parse_pubsub_option_subscription(<<"show-values">> = _Pubsub_Option, Node_Type,
'local' = _Entity_Type, Pubsub_Features, [] = _Xmlels)
when Node_Type == 'collection' orelse Node_Type == 'leaf' ->
case lists:member(<<"presence-notifications">>, Pubsub_Features) of
true -> {ok, []};
false -> {error, 'invalid-options'}
end;
parse_pubsub_option_subscription(<<"show-values">> = _Pubsub_Option, Node_Type,
'local' = _Entity_Type, Pubsub_Features, Xmlels)
when Node_Type == 'collection' orelse Node_Type == 'leaf' ->
case lists:member(<<"presence-notifications">>, Pubsub_Features) of
true ->
parse_xmlel_value({'list-multi', 'atom',
_Default_Values = ['away' ,'chat', 'dnd', 'online', 'xa']},
Xmlels);
false ->
{error, 'invalid-options'}
end;
%%
parse_pubsub_option_subscription(<<"show-values">> = _Pubsub_Option, _Node_Type,
'remote' = _Entity_Type, _Pubsub_Features, _Xmlels) ->
{error, 'invalid-options'};
%%
%parse_pubsub_option_subscription(<<"subscription_type">> = _Pubsub_Option,
% 'collection' = _Node_Type, _Entity_Type, _Pubsub_Features, Xmlels) ->
% parse_xmlel_value({'list-single', 'atom',
% _Default_Values = ['all', 'items', 'nodes']}, Xmlels);
%%
%parse_pubsub_option_subscription(<<"subscription_depth">> = _Pubsub_Option,
% 'collection' = _Node_Type, _Entity_Type, _Pubsub_Features, Xmlels) ->
% case Xmlels of
% [] ->
% {ok, 0};
% [Xmlel_Value] when ?Is_Xmlel_Value(Xmlel_Value) ->
% case {Xmlns(Xmlel_Value), get_tag_cdata(Xmlel_Value)} of
% {?NS_XDATA, <<>>} ->
% {ok, 0};
% {?NS_XDATA, <<"all">>} ->
% {ok, 'all'};
% {?NS_XDATA, CData} ->
% case catch list_to_integer(binary_to_list(CData)) of
% Integer
% when is_integer(Integer) andalso Integer > -1 ->
% {ok, Integer};
% _Error ->
% {error, 'not-acceptable'}
% end;
% _ ->
% {error, 'not-acceptable'}
% end;
% _Xmlels ->
% {error, 'not-acceptable'}
% end;
%%
parse_pubsub_option_subscription(_Pubsub_Option, _Node_Type, _Entity_Type,
_Pubsub_Features, _Xmlels) ->
{error, 'invalid-options'}.
-spec(parse_xmlel_value/2 ::
(
DataType :: {'jid-multi', 'bare'}
| {'jid-multi', 'full'}
| {'list-multi', 'atom', Default_Values::[Default_Value::atom(),...]}
| 'list-multi'
| 'text-multi'
| {'access_model', Pubsub_Features::exmpp_pubsub:pubsub_features()}
| 'boolean'
| 'text-single'
| {'text-single', 'atom'}
| {'text-single', 'integer'}
| {'list-single', 'atom', Default_Values::[Default_Value::atom(),...]},
Xmlels :: [Xmlel_Value::xmlel()]
| [Xmlel::xmlel()])
-> %%
{ok, Values :: []
| [Value::binary()]
| [Value::atom()]
| [Value::xmpp_jid:raw_jid_entity_bare()]
| [Value::xmpp_jid:raw_jid_entity()]}
| {ok, Value :: atom()
| binary()
| boolean()
| non_neg_integer()
| undefined}
%%%
| {error, 'invalid-options'}
| {error, 'jid-malformed'}
| {error, 'not-acceptable'}
| {error, 'not-acceptable', 'unsupported-access-model'}
).
%%
parse_xmlel_value({'jid-multi', 'bare'}, [] = _Xmlels) ->
{ok, []};
%%
parse_xmlel_value({'jid-multi', 'bare'}, Xmlels) ->
parse_xmlel_value({'jid-multi', 'bare'}, Xmlels, []);
%%
parse_xmlel_value({'jid-multi', 'full'}, [] = _Xmlels) ->
{ok, []};
%%
parse_xmlel_value({'jid-multi', 'full'}, Xmlels) ->
parse_xmlel_value({'jid-multi', 'full'}, Xmlels, []);
%%
%%
parse_xmlel_value({'list-multi', 'atom', _Default_Values}, [] = _Xmlels) ->
{error, 'not-acceptable'};
%%
parse_xmlel_value({'list-multi', 'atom', Default_Values}, Xmlels) ->
parse_xmlel_value({'list-multi', 'atom', Default_Values}, Xmlels, []);
%%
parse_xmlel_value('list-multi', Xmlels) ->
parse_xmlel_value('list-multi', Xmlels, []);
%%
%%
parse_xmlel_value('text-multi', [] = _Xmlels) ->
{ok, []};
%%
parse_xmlel_value('text-multi', Xmlels) ->
parse_xmlel_value('text-multi', Xmlels, []);
%%
parse_xmlel_value({'access_model', Pubsub_Features}, [Xmlel_Value])
when ?Is_Xmlel_Value(Xmlel_Value) ->
case {xmlns(Xmlel_Value), get_tag_cdata(Xmlel_Value)} of
{?NS_XDATA, <<"authorize">>} ->
case lists:member(<<"access-authorize">>, Pubsub_Features) of
true ->
{ok, 'authorize'};
false ->
{error, 'not-acceptable', 'unsupported-access-model'}
end;
%%
{?NS_XDATA, <<"open">>} ->
case lists:member(<<"access-open">>, Pubsub_Features) of
true ->
{ok, 'open'};
false ->
{error, 'not-acceptable', 'unsupported-access-model'}
end;
%%
{?NS_XDATA, <<"presence">>} ->
case lists:member(<<"access-presence">>, Pubsub_Features) of
true ->
{ok, 'presence'};
false ->
{error, 'not-acceptable', 'unsupported-access-model'}
end;
%%
{?NS_XDATA, <<"roster">>} ->
case lists:member(<<"access-roster">>, Pubsub_Features) of
true ->
{ok, 'roster'};
false ->
{error, 'not-acceptable', 'unsupported-access-model'}
end;
%%
{?NS_XDATA, <<"whitelist">>} ->
case lists:member(<<"access-whitelist">>, Pubsub_Features) of
true ->
{ok, 'whitelist'};
false ->
{error, 'not-acceptable', 'unsupported-access-model'}
end;
%%
_ ->
{error, 'not-acceptable'}
end;
parse_xmlel_value({'access_model', _Pubsub_Features}, _Xmlels) ->
{error, 'not-acceptable'};
%%
%%
parse_xmlel_value('boolean', [Xmlel_Value])
when ?Is_Xmlel_Value(Xmlel_Value) ->
case {xmlns(Xmlel_Value), get_tag_cdata(Xmlel_Value)} of
{?NS_XDATA, False}
when False == <<"0">>
orelse False == <<"false">> ->
{ok, false};
{?NS_XDATA, True}
when True == <<"1">>
orelse True == <<"true">> ->
{ok, true};
_ ->
{error, 'not-acceptable'}
end;
parse_xmlel_value('boolean', _Xmlels) ->
{error, 'not-acceptable'};
%%
%%
parse_xmlel_value('text-single', [] = _Xmlels) ->
{ok, undefined};
parse_xmlel_value('text-single', [Xmlel_Value])
when ?Is_Xmlel_Value(Xmlel_Value) ->
case {xmlns(Xmlel_Value), get_tag_cdata(Xmlel_Value)} of
{?NS_XDATA, <<>>} -> {ok, undefined};
{?NS_XDATA, CData} -> {ok, CData};
_ -> {error, 'not-acceptable'}
end;
parse_xmlel_value('text-single', _Xmlels) ->
{error, 'not-acceptable'};
%%
%%
parse_xmlel_value({'text-single', 'atom'}, [] = _Xmlels) ->
{ok, undefined};
parse_xmlel_value({'text-single', 'atom'}, [Xmlel_Value])
when ?Is_Xmlel_Value(Xmlel_Value) ->
case {xmlns(Xmlel_Value), get_tag_cdata(Xmlel_Value)} of
{?NS_XDATA, <<>>} -> {ok, undefined};
{?NS_XDATA, CData} -> {ok, list_to_atom(binary_to_list(CData))};
_ -> {error, 'not-acceptable'}
end;
parse_xmlel_value({'text-single', 'atom'}, _Xmlels) ->
{error, 'not-acceptable'};
%%
%%
parse_xmlel_value({'text-single', 'integer'}, [] = _Xmlels) ->
{ok, undefined};
parse_xmlel_value({'text-single', 'integer'}, [Xmlel_Value])
when ?Is_Xmlel_Value(Xmlel_Value) ->
case {xmlns(Xmlel_Value), get_tag_cdata(Xmlel_Value)} of
{?NS_XDATA, <<>>} ->
{ok, undefined};
{?NS_XDATA, CData} ->
case catch list_to_integer(binary_to_list(CData)) of
Integer when is_integer(Integer) andalso Integer > -1 ->
{ok, Integer};
_ ->
{error, 'not-acceptable'}
end;
_ ->
{error, 'not-acceptable'}
end;
parse_xmlel_value({'text-single', 'integer'}, _Xmlels) ->
{error, 'not-acceptable'};
%%
%%
parse_xmlel_value({'list-single', 'atom', Default_Values}, [Xmlel_Value])
when ?Is_Xmlel_Value(Xmlel_Value) ->
case {xmlns(Xmlel_Value), get_tag_cdata(Xmlel_Value)} of
{_, <<>>} ->
{error, 'not-acceptable'};
{?NS_XDATA, CData} ->
case
lists:member(Value = list_to_atom(binary_to_list(CData)),
Default_Values)
of
true ->
{ok, Value};
false ->
{error, 'not-acceptable'}
end;
_ ->
{error, 'not-acceptable'}
end;
parse_xmlel_value({'list-single', 'atom', _Default_Values}, _Xmlels) ->
{error, 'not-acceptable'};
%%
parse_xmlel_value({_DataType, _Default_Values}, _Xmlels) ->
{error, 'not-acceptable'}.
%%
%%
-spec(parse_xmlel_value/3 ::
(
DataType :: {'list-multi', 'atom', Default_Values::[Default_Value::atom(),...]}
| 'list-multi'
| 'text-multi'
| {'jid-multi', 'full'}
| {'jid-multi', 'bare'},
Xmlels :: [Xmlel_Value::xmlel()]
| [Xmlel::xmlel()],
Values :: [Value::binary()]
| [Value::atom()]
| [Value::xmpp_jid:raw_jid_entity_bare()]
| [Value::xmpp_jid:raw_jid_entity_full()])
-> {ok,
Values :: [Value::binary()]
| [Value::atom()]
| [Value::xmpp_jid:raw_jid_entity_bare()]
| [Value::xmpp_jid:raw_jid_entity_full()]}
%%%
| {error, 'not-acceptable'}
| {error, 'jid-malformed'}
).
parse_xmlel_value(_DataType, _Xmlels = [], Values) ->
{ok, lists:usort(Values)};
%%
%%
parse_xmlel_value({'list-multi', 'atom', Default_Values},
[Xmlel_Value | Xmlels], Values)
when ?Is_Xmlel_Value(Xmlel_Value) ->
case {xmlns(Xmlel_Value), get_tag_cdata(Xmlel_Value)} of
{?NS_XDATA, <<>>} ->
parse_xmlel_value({'list-multi', 'atom', Default_Values},
Xmlels, Values);
{?NS_XDATA, CData} ->
case
lists:member(Value = list_to_atom(binary_to_list(CData)),
Default_Values)
of
true ->
parse_xmlel_value({'list-multi', 'atom', Default_Values},
Xmlels, [Value | Values]);
false ->
{error, 'not-acceptable'}
end;
_ ->
{error, 'not-acceptable'}
end;
%%
%%
parse_xmlel_value('list-multi', [Xmlel_Value | Xmlels], Values)
when ?Is_Xmlel_Value(Xmlel_Value) ->
parse_xmlel_value('list-multi', Xmlels,
case {xmlns(Xmlel_Value), get_tag_cdata(Xmlel_Value)} of
{?NS_XDATA, <<>>} -> Values;
{?NS_XDATA, CData} -> [CData | Values];
_ -> {error, 'not-acceptable'}
end);
%%
%%
parse_xmlel_value('text-multi', [Xmlel_Value | Xmlels] , Values)
when ?Is_Xmlel_Value(Xmlel_Value) ->
parse_xmlel_value('text-multi', Xmlels,
case {xmlns(Xmlel_Value), get_tag_cdata(Xmlel_Value)} of
{?NS_XDATA, <<>>} -> Values;
{?NS_XDATA, CData} -> [_Value = CData | Values];
_ -> {error, 'not-acceptable'}
end);
%%
%%
parse_xmlel_value({'jid-multi', 'full'}, [Xmlel_Value | Xmlels], Values)
when ?Is_Xmlel_Value(Xmlel_Value) ->
case {xmlns(Xmlel_Value), get_tag_cdata(Xmlel_Value)} of
{?NS_XDATA, <<>>} ->
parse_xmlel_value({'jid-multi', 'full'}, Xmlels, Values);
{?NS_XDATA, CData} ->
case is_jid(CData) of
#jid{} = Jid ->
parse_xmlel_value({'jid-multi', 'full'}, Xmlels,
[jlib:jid_to_string(Jid) | Values]);
Error ->
Error
end;
_ ->
{error, 'not-acceptable'}
end;
%%
parse_xmlel_value({'jid-multi', 'bare'}, [Xmlel_Value | Xmlels], Values)
when ?Is_Xmlel_Value(Xmlel_Value) ->
case {xmlns(Xmlel_Value), get_tag_cdata(Xmlel_Value)} of
{?NS_XDATA, <<>>} ->
parse_xmlel_value({'jid-multi', 'bare'}, Xmlels, Values);
{?NS_XDATA, CData} ->
case is_jid(CData) of
#jid{} = Jid ->
parse_xmlel_value({'jid-multi', 'bare'}, Xmlels,
[jlib:jid_to_string(Jid#jid{resource = <<>>, lresource = <<>>})
| Values]);
Error ->
Error
end;
_ ->
{error, 'not-acceptable'}
end;
%%
parse_xmlel_value(_Data_Type, _Xmlels, _Values) ->
{error, 'not-acceptable'}.
%%
%%
-spec(xdata_x/6 ::
(
Options_Type :: 'node_config' | 'subscribe_options',
Form_Type :: 'form' | 'result',
Pubsub_Features :: exmpp_pubsub:pubsub_features(),
Host :: xmpp_jid:raw_jid_component_bare(),
Entity :: xmpp_jid:usr_bare(),
Options :: pubsub_options:options_node()
| pubsub_options:options_subscription())
-> Xmlel_X::xmlel()
).
xdata_x('node_config', 'form', Pubsub_Features, Host, Entity, Node_Options) ->
xmpp_xdata:xmlel_x(<<"form">>,
_Xmlels_Field = [
xmpp_xdata:xmlel_field(<<"FORM_TYPE">>, <<"hidden">>,
[?NS_PUBSUB_NODE_CONFIG])
|xdata_field(Pubsub_Features, Host, Entity, Node_Options, [])
]);
xdata_x('subscribe_options', 'form', Pubsub_Features, Host, Entity,
Subscription_Options) ->
xmpp_xdata:xmlel_x(<<"form">>,
_Xmlels_Field = [
xmpp_xdata:xmlel_field(<<"FORM_TYPE">>, <<"hidden">>,
[?NS_PUBSUB_SUBSCRIBE_OPTIONS])
|xdata_field(Pubsub_Features, Host, Entity, Subscription_Options, [])
]);
xdata_x('subscribe_options', 'result', Pubsub_Features, Host, Entity,
Subscription_Options) ->
xmpp_xdata:xmlel_x(<<"result">>,
_Xmlels_Field = [
xmpp_xdata:xmlel_field(<<"FORM_TYPE">>, <<"hidden">>,
[?NS_PUBSUB_SUBSCRIBE_OPTIONS])
|xdata_field(Pubsub_Features, Host, Entity, Subscription_Options, [])
]).
%%
%%
-spec(xdata_x/7 ::
(
Options_Type :: 'subscribe_options',
Form_Type :: 'form',
Pubsub_Features :: exmpp_pubsub:pubsub_features(),
Host :: xmpp_jid:raw_jid_component_bare(),
Entity :: xmpp_jid:usr_bare(),
Subscription_Options :: [] | pubsub_options:options_subscription(),
Default_Subscription_Options :: pubsub_options:options_subscription())
-> Xmlel_X::xmlel()
).
%%
xdata_x('subscribe_options', 'form', Pubsub_Features, Host, Entity,
Subscription_Options, Default_Subscription_Options) ->
xmpp_xdata:xmlel_x(<<"form">>,
_Xmlels_Field = [
xmpp_xdata:xmlel_field(<<"FORM_TYPE">>, <<"hidden">>,
[?NS_PUBSUB_SUBSCRIBE_OPTIONS])
|xdata_field(Pubsub_Features, Host, Entity,
filter_subscription_options(Subscription_Options,
Default_Subscription_Options, []),
[])
]).
%%
-spec(filter_subscription_options/3 ::
(
Options :: [] | pubsub_options:options_subscription(),
Default_Subscription_Options :: pubsub_options:options_subscription(),
Subscription_Options :: [] | pubsub_options:options_subscription())
-> Subscription_Options::pubsub_options:options_subscription()
).
filter_subscription_options([] = _Options, Default_Subscription_Options,
Subscription_Options) ->
Default_Subscription_Options ++ Subscription_Options;
%%
filter_subscription_options([{Key, Value} | Options], Default_Subscription_Options,
Subscription_Options) ->
filter_subscription_options(Options,
lists:keydelete(Key, 1, Default_Subscription_Options),
[{Key, Value} | Subscription_Options]).
-define(Label_Deliver, <<"Enable delivery ?">>).
-define(Label_Digest, <<"Receive digest notifications ?">>).
-define(Label_Digest_Frequency, <<"Receive digest notifications (approx. one per day)?">>).
-define(Label_Expire, <<"Requested lease period">>).
-define(Label_Include_Body, <<"Receive message body in addition to payload ?">>).
-define(Label_Show_Values, <<"Select the presence types which are allowed to receive event notifications">>).
%%
%% pubsub#subscribe_options
%%
-spec(xdata_field/5 ::
(
Pubsub_Features :: exmpp_pubsub:pubsub_features(),
Host :: xmpp_jid:raw_jid_component_bare(),
Entity :: xmpp_jid:usr_bare(),
Options :: [] | pubsub_options:options_subscription(),
Xmlels_Field :: [] | [Xmlel_Field::xmlel(),...])
-> Xmlels_Field::[Xmlel_Field::xmlel(),...]
).
%%
xdata_field(_Pubsub_Features, _Host, _Entity, [] = _Options, Xmlels_Field) ->
lists:sort(Xmlels_Field);
%% 'pubsub#deliver'
xdata_field(Pubsub_Features, Host, Entity, [{'deliver', Deliver} | Options],
Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_boolean(
<<"pubsub#deliver">>,
<<"Enable delivery?">>,
xdata_value('boolean', Deliver))
| Xmlels_Field]);
%% 'pubsub#digest'
xdata_field(Pubsub_Features, Host, Entity, [{'digest', Digest} | Options],
Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_boolean(
<<"pubsub#digest">>,
<<"Receive digest notifications (approx. one per day)?">>,
xdata_value('boolean', Digest))
| Xmlels_Field]);
%% 'pubsub#digest_frequency'
xdata_field(Pubsub_Features, Host, Entity,
[{'digest_frequency', Digest_Frequency} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_text_single(
<<"pubsub#digest_frequency">>,
<<"Receive digest notifications (approx. one per day)?">>,
xdata_value('integer', Digest_Frequency))
| Xmlels_Field]);
%% 'pubsub#expire'
xdata_field(Pubsub_Features, Host, Entity,
[{'expire', Expire} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_text_single(
<<"pubsub#expire">>,
<<"Requested lease period">>,
case is_atom(Expire) of
true -> xdata_value('atom', Expire);
false -> xdata_value('date', Expire)
end)
| Xmlels_Field]);
%% 'pubsub#include_body'
xdata_field(Pubsub_Features, Host, Entity,
[{'include_body', Include_Body} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_boolean(
<<"pubsub#include_body">>,
<<"Receive message body in addition to payload?">>,
xdata_value('boolean', Include_Body))
| Xmlels_Field]);
%% 'pubsub#show-values'
xdata_field(Pubsub_Features, Host, Entity,
[{'show-values', Show_Values} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_list_multi(
<<"pubsub#show-values">>,
<<"Select the presence types which are allowed to receive event notifications">>,
lists:map(fun
('away') -> <<"away">>;
('chat') -> <<"chat">>;
('dnd') -> <<"dnd">>;
('online') -> <<"online">>;
('xa') -> <<"xa">>
end, Show_Values),
[{<<"away">>, <<"Away">>},
{<<"chat">>, <<"Want to Chat">>},
{<<"dnd">>, <<"Do Not Disturb">>},
{<<"online">>, <<"Available">>},
{<<"xa">>, <<"Extended Away">>}])
| Xmlels_Field]);
%% 'pubsub#subscription_type'
xdata_field(Pubsub_Features, Host, Entity,
[{'subscription_type', Subscription_Type} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_list_single(
<<"pubsub#subscription_type">>,
<<"Subscription Type">>,
case Subscription_Type of
undefined -> <<"items">>;
'items' -> <<"items">>;
'nodes' -> <<"nodes">>;
'all' -> <<"all">>
end,
[{<<"items">>, <<"Receive notification of items only">>},
{<<"nodes">>, <<"Receive notification of new nodes only">>},
{<<"all">>, <<"Receive notification of items and nodes">>}])
| Xmlels_Field]);
%% 'pubsub#subscription_depth'
xdata_field(Pubsub_Features, Host, Entity,
[{'subscription_depth', Subscription_Depth} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_list_single(
<<"pubsub#subscription_depth">>,
<<"How far to traverse the node graph for notifications">>,
case Subscription_Depth of
undefined -> <<"1">>;
'all' -> <<"all">>;
_ -> xdata_value('integer', Subscription_Depth)
end,
[{<<"1">>, <<"Receive notification from direct child nodes only">>},
{<<"all">>, <<"Receive notification from all descendent nodes">>}])
| Xmlels_Field]);
%%
%% pubsub#node_config
%%
%% 'pubsub#access_model'
xdata_field(Pubsub_Features, Host, Entity,
[{'access_model', Access_Model} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_list_single(
<<"pubsub#access_model">>,
<<"Specify the subscriber model">>,
case Access_Model of
% undefined -> <<"open">>;
'authorize' -> <<"authorize">>;
'open' -> <<"open">>;
'presence' -> <<"presence">>;
'roster' -> <<"roster">>;
'whitelist' -> <<"whitelist">>
end,
xdata_access_model(Pubsub_Features,
['authorize', 'open', 'presence', 'roster', 'whitelist']))
| Xmlels_Field]);
%% 'pubsub#body_xslt'
xdata_field(Pubsub_Features, Host, Entity,
[{'body_xslt', Xslt} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_text_single(
<<"pubsub#body_xslt">>,
<<"The URL of an XSL transformation which can be applied to "
"payloads in order to generate an appropriate message body element">>,
Xslt)
| Xmlels_Field]);
%% 'pubsub#children_association_policy'
xdata_field(Pubsub_Features, Host, Entity,
[{'children_association_policy', Children_Association_Policy} | Options],
Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_list_single(
<<"pubsub#children_association_policy">>,
<<"Who may associate leaf nodes with a collection">>,
case Children_Association_Policy of
undefined -> <<"owners">>;
'owners' -> <<"owners">>;
'all' -> <<"all">>;
'whitelist' -> <<"whitelist">>
end,
[{<<"all">>, <<"Anyone may associate leaf nodes with the collection">>},
{<<"owners">>, <<"Only collection node owners may associate leaf"
" nodes with the collection">>},
{<<"whitelist">>, <<"Only those on a whitelist may associate leaf "
"nodes with the collection">>}])
| Xmlels_Field]);
%% 'pubsub#children_association_whitelist'
xdata_field(Pubsub_Features, Host, Entity,
[{'children_association_whitelist', Children_Association_Whitelist}
| Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_jid_multi(
<<"pubsub#children_association_whitelist">>,
<<"The list of JIDs that may associate leaf nodes with a collection">>,
Children_Association_Whitelist)
| Xmlels_Field]);
%% 'pubsub#children'
xdata_field(Pubsub_Features, Host, Entity,
[{'children', Children} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_text_multi(
<<"pubsub#children">>,
<<"The child nodes (leaf or collection) associated with a collection">>,
Children)
| Xmlels_Field]);
%% 'pubsub#children_max'
xdata_field(Pubsub_Features, Host, Entity,
[{'children_max', Children_Max} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_text_single(
<<"pubsub#children_max">>,
<<"The maximum number of child nodes that can be associated with a collection">>,
xdata_value('integer', Children_Max))
| Xmlels_Field]);
%% 'pubsub#collection'
xdata_field(Pubsub_Features, Host, Entity,
[{'collection', Collection} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_text_multi(
<<"pubsub#collection">>,
<<"The collection(s) with which a node is affiliated">>,
Collection)
| Xmlels_Field]);
%% 'pubsub#contact'
xdata_field(Pubsub_Features, Host, Entity,
[{'contact', Contacts} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_jid_multi(
<<"pubsub#contact">>,
<<"The JIDs of those to contact with questions">>,
Contacts)
| Xmlels_Field]);
%% 'pubsub#dataform_xslt'
xdata_field(Pubsub_Features, Host, Entity,
[{'dataform_xslt', Dataform_Xslt} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_text_single(
<<"pubsub#dataform_xslt">>,
<<"Payload XSLT">>,
xdata_value({'text-multi', 'atom'}, Dataform_Xslt))
| Xmlels_Field]);
%% 'pubsub#deliver_notifications'
xdata_field(Pubsub_Features, Host, Entity,
[{'deliver_notifications', Deliver_Notifications} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_boolean(
<<"pubsub#deliver_notifications">>,
<<"Whether to deliver event notifications">>,
xdata_value('boolean', Deliver_Notifications))
| Xmlels_Field]);
%% 'pubsub#deliver_payloads'
xdata_field(Pubsub_Features, Host, Entity,
[{'deliver_payloads', Deliver_Payloads} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_boolean(
<<"pubsub#deliver_payloads">>,
<<"Whether to deliver payloads with event notifications">>,
xdata_value('boolean', Deliver_Payloads))
| Xmlels_Field]);
%% 'pubsub#description'
xdata_field(Pubsub_Features, Host, Entity,
[{'description', Description} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_text_single(
<<"pubsub#description">>,
<<"A description of the node">>,
Description)
| Xmlels_Field]);
%% 'pubsub#item_expire'
xdata_field(Pubsub_Features, Host, Entity,
[{'item_expire', Item_Expire} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_text_single(
<<"pubsub#item_expire">>,
<<"Number of seconds after which to automatically purge items">>,
xdata_value('integer', Item_Expire))
| Xmlels_Field]);
%% 'pubsub#itemreply'
xdata_field(Pubsub_Features, Host, Entity,
[{'itemreply', ItemReply} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_list_single(
<<"pubsub#itemreply">>,
<<"Whether owners or publisher should receive replies to items">>,
case ItemReply of
undefined -> <<"publisher">>;
'owner' -> <<"owner">>;
'publisher' -> <<"publisher">>
end,
[{<<"owner">>, <<"Statically specify a replyto of the node owner(s)">>},
{<<"publisher">>, <<"Dynamically specify a replyto of the item publisher">>}])
| Xmlels_Field]);
%% 'pubsub#language'
xdata_field(Pubsub_Features, Host, Entity,
[{'language', Language} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_list_single(
<<"pubsub#language">>,
<<"The default language of the node">>,
case Language of
undefined -> <<"en">>;
_Language -> Language
end,
[{<<"en">>, <<"English">>}
%{<<"es">>, <<"Español">>},
%{<<"fr">>, <<"Français">>},
%{<<"pl">>, <<"Polski">>},
%{<<"ru">>, <<"Русский">>}
])
| Xmlels_Field]);
%% 'pubsub#max_items'
xdata_field(Pubsub_Features, Host, Entity,
[{'max_items', Max_Items} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_text_single(
<<"pubsub#max_items">>,
<<"The maximum number of items to persist">>,
xdata_value('integer', Max_Items))
| Xmlels_Field]);
%% 'pubsub#max_payload_size'
xdata_field(Pubsub_Features, Host, Entity,
[{'max_payload_size', Max_Payload_Size} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_text_single(
<<"pubsub#max_payload_size">>,
<<"The maximum payload size in bytes">>,
xdata_value('integer', Max_Payload_Size))
| Xmlels_Field]);
%% 'pubsub#node_type'
xdata_field(Pubsub_Features, Host, Entity,
[{'node_type', Node_Type} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host,
Entity, Options,
[case lists:member(<<"collections">>, Pubsub_Features) of
true ->
xmpp_xdata:xmlel_field_list_single(
<<"pubsub#node_type">>,
<<"Whether the node is a leaf (default) or a collection">>,
case Node_Type of
undefined -> <<"leaf">>;
'leaf' -> <<"leaf">>;
'collection' -> <<"collection">>
end,
[{<<"leaf">>, <<"The node is a leaf node (default)">>},
{<<"collection">>, <<"The node is a collection node">>}]);
false ->
%% Collections not supported -> non-modifiable field
% xmpp_xdata:xmlel_field_fixed(
% <<"pubsub#node_type">>,
% <<"The node is a leaf node (default)">>,
% <<"leaf">>)
xmpp_xdata:xmlel_field_list_single(
<<"pubsub#node_type">>,
<<"Whether the node is a leaf (default) or a collection">>,
<<"leaf">>,
[{<<"leaf">>, <<"The node is a leaf node (default)">>}])
end
|Xmlels_Field]);
%% 'pubsub#notification_type'
xdata_field(Pubsub_Features, Host, Entity,
[{'notification_type', Notification_Type} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_list_single(
<<"pubsub#notification_type">>,
<<"Specify the delivery style for event notifications">>,
case Notification_Type of
undefined -> <<"headline">>;
'headline' -> <<"headline">>;
'normal' -> <<"normal">>;
'chat' -> <<"chat">>
end,
[{<<"headline">>, <<"Messages of type headline">>},
{<<"normal">>, <<"Messages of type normal">>}
%{<<"chat">>, <<"Messages of type chat">>}
%{<<"presence">>, <<"Presence">>}
%{<<"iq">>, <<"Iq">>}
])
| Xmlels_Field]);
%% 'pubsub#notify_config'
xdata_field(Pubsub_Features, Host, Entity,
[{'notify_config', Notify_Config} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_boolean(
<<"pubsub#notify_config">>,
<<"Notify owners and subscribers when the node configuration changes">>,
xdata_value('boolean', Notify_Config))
| Xmlels_Field]);
%% 'pubsub#notify_delete'
xdata_field(Pubsub_Features, Host, Entity,
[{'notify_delete', Notify_Delete} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_boolean(
<<"pubsub#notify_delete">>,
<<"Notify owners and subscribers when the node is deleted">>,
xdata_value('boolean', Notify_Delete))
| Xmlels_Field]);
%% 'pubsub#notify_retract'
xdata_field(Pubsub_Features, Host, Entity,
[{'notify_retract', Notify_Retract} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_boolean(
<<"pubsub#notify_retract">>,
<<"Notify subscribers when items are removed from the node">>,
xdata_value('boolean', Notify_Retract))
| Xmlels_Field]);
%% 'pubsub#notify_sub'
xdata_field(Pubsub_Features, Host, Entity,
[{'notify_sub', Notify_Sub} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_boolean(
<<"pubsub#notify_sub">>,
<<"Notify owners about new subscribers and unsubscribes">>,
xdata_value('boolean', Notify_Sub))
| Xmlels_Field]);
%% 'pubsub#persist_items'
xdata_field(Pubsub_Features, Host, Entity,
[{'persist_items', Persist_Items} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_boolean(
<<"pubsub#persist_items">>,
<<"Persist items to storage">>,
xdata_value('boolean', Persist_Items))
| Xmlels_Field]);
%% 'pubsub#presence_based_delivery'
xdata_field(Pubsub_Features, Host, Entity,
[{'presence_based_delivery', Presence_Based_Delivery} | Options]
, Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_boolean(
<<"pubsub#presence_based_delivery">>,
<<"Deliver event notifications only to available users">>,
xdata_value('boolean', Presence_Based_Delivery))
| Xmlels_Field]);
%% 'pubsub#publish_model'
xdata_field(Pubsub_Features, Host, Entity,
[{'publish_model', Publish_Model} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_list_single(
<<"pubsub#publish_model">>,
<<"Specify the publisher model">>,
case Publish_Model of
% undefined -> <<"open">>;
'open' -> <<"open">>;
'publishers' -> <<"publishers">>;
'subscribers' -> <<"subscribers">>
end,
[{<<"publishers">>, <<"Only publishers may publish">>},
{<<"subscribers">>, <<"Subscribers may publish">>},
{<<"open">>, <<"Anyone may publish">>}])
| Xmlels_Field]);
%% 'pubsub#purge_offline'
xdata_field(Pubsub_Features, Host, Entity,
[{'purge_offline', Purge_Offline} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_boolean(
<<"pubsub#purge_offline">>,
<<"Purge all items when the relevant publisher goes offline ?">>,
xdata_value('boolean', Purge_Offline))
| Xmlels_Field]);
%% 'pubsub#roster_groups_allowed'
xdata_field(Pubsub_Features, Host, Entity,
[{'roster_groups_allowed', Rosters_Groups_Allowed} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_list_multi(
<<"pubsub#roster_groups_allowed">>,
<<"Roster group(s) allowed to subscribe and retrieve items">>,
case lists:keyfind(Entity, 1, Rosters_Groups_Allowed) of
false -> [];
{_Entity, Roster_Groups} -> Roster_Groups
end,
xdata_roster(Host, Entity))
| Xmlels_Field]);
%% 'pubsub#send_last_published_item'
xdata_field(Pubsub_Features, Host, Entity,
[{'send_last_published_item', Send_Last_Published_Item} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_list_single(
<<"pubsub#send_last_published_item">>,
<<"When to send the last published item">>,
case Send_Last_Published_Item of
undefined -> <<"on_sub_and_presence">>;
'never' -> <<"never">>;
'on_sub_and_presence' -> <<"on_sub_and_presence">>;
'on_sub' -> <<"on_sub">>
end,
[{<<"never">>, <<"Never">>},
{<<"on_sub">>, <<"When a new subscription is processed">>},
{<<"on_sub_and_presence">>, <<"When a new subscription is processed "
"and whenever a subscriber comes online">>}])
| Xmlels_Field]);
%% 'pubsub#subscribe'
xdata_field(Pubsub_Features, Host, Entity,
[{'subscribe', Subscribe} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_boolean(
<<"pubsub#subscribe">>,
<<"Whether to allow subscriptions">>,
xdata_value('boolean', Subscribe))
| Xmlels_Field]);
%% 'pubsub#tempsub'
xdata_field(Pubsub_Features, Host, Entity,
[{'tempsub', Tempsub} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_boolean(
<<"pubsub#tempsub">>,
<<"Make all subscriptions temporary, based on subscriber presence">>,
xdata_value('boolean', Tempsub))
| Xmlels_Field]);
%% 'pubsub#title'
xdata_field(Pubsub_Features, Host, Entity,
[{'title', Title} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_text_single(
<<"pubsub#title">>,
<<"A friendly name for the node">>,
Title)
| Xmlels_Field]);
%% 'pubsub#type'
xdata_field(Pubsub_Features, Host, Entity,
[{'type', Type} | Options], Xmlels_Field) ->
xdata_field(Pubsub_Features, Host, Entity, Options,
[xmpp_xdata:xmlel_field_text_single(
<<"pubsub#type">>,
<<"Specify the type of payload data to be provided at this node">>,
Type)
| Xmlels_Field]).
%%
-spec(xdata_value/2 ::
(
DataType :: 'atom'
| 'boolean'
| 'date'
| 'integer'
| {'text-multi', 'atom'},
Value :: undefined
| atom()
| boolean()
| erlang:timestamp()
| non_neg_integer()
| [atom()])
-> Xdata_Value :: binary() | [binary(),...]
).
xdata_value(_, undefined) -> undefined;
%%
xdata_value('atom', Value) -> list_to_binary(atom_to_list(Value));
%%
xdata_value('boolean', false) -> <<"false">>;
xdata_value('boolean', true) -> <<"true">>;
%%
xdata_value('date', TimeStamp) ->
{DateTime, _} = jlib:timestamp_to_iso(calendar:now_to_datetime(TimeStamp), utc),
list_to_binary(DateTime ++ "Z");
%%
xdata_value('integer', Value) -> list_to_binary(integer_to_list(Value));
%%
xdata_value({'text-multi', 'atom'}, Values) ->
[list_to_binary(atom_to_list(Value)) || Value <- Values].
%%
-spec(xdata_access_model/3 ::
(
Access_Model :: pubsub_options:access_model(),
Pubsub_Feature :: boolean(),
Access_Models :: [{binary(), binary()}])
-> Access_Models :: [{binary(), binary()}]
).
xdata_access_model(_Access_Model, false, Access_Models) ->
Access_Models;
%%
xdata_access_model('authorize' = _Access_Model, true, Access_Models) ->
[{<<"authorize">>, <<"Subscription requests must be approved and only "
"subscribers may retrieve items">>}
| Access_Models];
%%
xdata_access_model('open' = _Access_Model, true, Access_Models) ->
[{<<"open">>, <<"Anyone may subscribe and retrieve items">>}
| Access_Models];
%%
xdata_access_model('presence' = _Access_Model, true, Access_Models) ->
[{<<"presence">>, <<"Anyone with a presence subscription of both or from may "
"subscribe and retrieve items">>}
| Access_Models];
%%
xdata_access_model('roster' = _Access_Model, true, Access_Models) ->
[{<<"roster">>, <<"Anyone in the specified roster group(s) may subscribe and "
"retrieve items">>}
| Access_Models];
%%
xdata_access_model('whitelist' = _Access_Model, true, Access_Models) ->
[{<<"whitelist">>, <<"Only those on a whitelist may subscribe and retrieve items">>}
| Access_Models].
%%
-spec(xdata_access_model/2 ::
(
Pubsub_Features :: exmpp_pubsub:pubsub_features(),
Default_Access_Model :: ['authorize'|'open'|'presence'|'roster'|'whitelist',...])
-> Access_Models :: [{binary(), binary()},...]
).
xdata_access_model(Pubsub_Features, Default_Access_Models) ->
lists:foldr(fun
('authorize', Access_Models) ->
xdata_access_model('authorize',
lists:member(<<"access-authorize">>, Pubsub_Features), Access_Models);
%%
('open', Access_Models) ->
xdata_access_model('open',
lists:member(<<"access-open">>, Pubsub_Features), Access_Models);
%%
('presence', Access_Models) ->
xdata_access_model('presence',
lists:member(<<"access-presence">>, Pubsub_Features), Access_Models);
%%
('roster', Access_Models) ->
xdata_access_model('roster',
lists:member(<<"access-roster">>, Pubsub_Features), Access_Models);
%%
('whitelist', Access_Models) ->
xdata_access_model('whitelist',
lists:member(<<"access-whitelist">>, Pubsub_Features), Access_Models)
%
end, [], Default_Access_Models).
%%
%% Local Entity
-spec(xdata_roster/2 ::
(
Host :: binary(),
Entity :: xmpp_jid:usr_bare())
-> Roster_Groups :: [Roster_Group::binary()]
).
xdata_roster(Host, {_, Host, _} = Entity) ->
_Roster_Groups = lists:usort(lists:foldl(fun
(#roster{groups = Groups}, Roster_Groups) ->
lists:foldl(fun
(Group, Roster_Groups_Bis) ->
[Group | Roster_Groups_Bis]
end, Roster_Groups, Groups)
end, [], _Roster = get_entity_roster(Entity)));
%% Remote Entity
xdata_roster(_Host, _Entity) ->
[].