1 |
|
%%% ==================================================================== |
2 |
|
%%% ``The contents of this file are subject to the Erlang Public License, |
3 |
|
%%% Version 1.1, (the "License"); you may not use this file except in |
4 |
|
%%% compliance with the License. You should have received a copy of the |
5 |
|
%%% Erlang Public License along with this software. If not, it can be |
6 |
|
%%% retrieved via the world wide web at http://www.erlang.org/. |
7 |
|
%%% |
8 |
|
%%% Software distributed under the License is distributed on an "AS IS" |
9 |
|
%%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See |
10 |
|
%%% the License for the specific language governing rights and limitations |
11 |
|
%%% under the License. |
12 |
|
%%% |
13 |
|
%%% The Initial Developer of the Original Code is ProcessOne. |
14 |
|
%%% Portions created by ProcessOne are Copyright 2006-2015, ProcessOne |
15 |
|
%%% All Rights Reserved.'' |
16 |
|
%%% This software is copyright 2006-2015, ProcessOne. |
17 |
|
%%% |
18 |
|
%%% |
19 |
|
%%% @copyright 2006-2015 ProcessOne |
20 |
|
%%% @author Christophe Romain <christophe.romain@process-one.net> |
21 |
|
%%% [http://www.process-one.net/] |
22 |
|
%%% @end |
23 |
|
%%% ==================================================================== |
24 |
|
|
25 |
|
%%% @private |
26 |
|
%%% @doc <p>The module <strong>{@module}</strong> defines the PubSub node |
27 |
|
%%% plugin behaviour. This behaviour is used to check that a PubSub plugin |
28 |
|
%%% respects the current ejabberd PubSub plugin API.</p> |
29 |
|
|
30 |
|
-module(gen_pubsub_node). |
31 |
|
|
32 |
|
-include("jlib.hrl"). |
33 |
|
|
34 |
|
-type(host() :: mod_pubsub:host()). |
35 |
|
-type(nodeId() :: mod_pubsub:nodeId()). |
36 |
|
-type(nodeIdx() :: mod_pubsub:nodeIdx()). |
37 |
|
-type(itemId() :: mod_pubsub:itemId()). |
38 |
|
-type(pubsubNode() :: mod_pubsub:pubsubNode()). |
39 |
|
-type(pubsubItem() :: mod_pubsub:pubsubItem()). |
40 |
|
-type(subOptions() :: mod_pubsub:subOptions()). |
41 |
|
-type(affiliation() :: mod_pubsub:affiliation()). |
42 |
|
-type(subscription() :: mod_pubsub:subscription()). |
43 |
|
-type(subId() :: mod_pubsub:subId()). |
44 |
|
-type(accessModel() :: mod_pubsub:accessModel()). |
45 |
|
-type(publishModel() :: mod_pubsub:publishModel()). |
46 |
|
-type(payload() :: mod_pubsub:payload()). |
47 |
|
-type(publishOptions() :: mod_pubsub:publishOptions()). |
48 |
|
-type(get_authorised_item_options() :: #{access_model := accessModel(), |
49 |
|
presence_permission := boolean(), |
50 |
|
roster_permission := boolean(), |
51 |
|
rsm := none | jlib:rsm_in(), |
52 |
|
max_items => non_neg_integer(), |
53 |
|
item_ids => [itemId()], |
54 |
|
subscription_id => subId()}). |
55 |
|
-type(get_item_options() :: #{rsm => none | jlib:rsm_in(), |
56 |
|
max_items => undefined | non_neg_integer(), |
57 |
|
item_ids => undefined | [itemId()]}). |
58 |
|
|
59 |
|
-export([based_on/1, |
60 |
|
terminate/3, |
61 |
|
options/1, |
62 |
|
features/1, |
63 |
|
node_to_path/2 |
64 |
|
]). |
65 |
|
|
66 |
|
-ignore_xref([behaviour_info/1, node_to_path/2]). |
67 |
|
|
68 |
|
-export_type([get_item_options/0]). |
69 |
|
|
70 |
|
%% -------------------------------------------------------- |
71 |
|
%% Callbacks |
72 |
|
%% -------------------------------------------------------- |
73 |
|
|
74 |
|
%% @doc |
75 |
|
%% This function is to call the base node module in case the target node doesn't |
76 |
|
%% implement an optional callback |
77 |
|
-callback based_on() -> node_flat | node_hometree | node_dag | node_push | node_pep | none. |
78 |
|
|
79 |
|
-callback init(Host :: binary(), ServerHost :: binary(), Opts :: [any()]) -> atom(). |
80 |
|
|
81 |
|
-callback terminate(Host :: host(), ServerHost :: binary()) -> atom(). |
82 |
|
|
83 |
|
-callback options() -> [{atom(), any()}]. |
84 |
|
|
85 |
|
-callback features() -> [binary()]. |
86 |
|
|
87 |
|
-callback create_node_permission(Host :: host(), |
88 |
|
ServerHost :: binary(), |
89 |
|
Node :: nodeId(), |
90 |
|
ParentNode :: nodeId(), |
91 |
|
Owner :: jid:jid(), |
92 |
|
Access :: atom()) -> |
93 |
|
{result, boolean()}. |
94 |
|
|
95 |
|
-callback create_node(NodeIdx :: nodeIdx(), Owner :: jid:jid()) -> {result, {default, broadcast}}. |
96 |
|
|
97 |
|
-callback delete_node(Nodes :: [pubsubNode(), ...]) -> |
98 |
|
{result, |
99 |
|
{default, broadcast, |
100 |
|
[{pubsubNode(), |
101 |
|
[{jid:ljid(), [{subscription(), subId()}]}, ...]}, ...] |
102 |
|
} |
103 |
|
} |
104 |
|
| |
105 |
|
{result, |
106 |
|
{[], |
107 |
|
[{pubsubNode(), |
108 |
|
[{jid:ljid(), [{subscription(), subId()}]}, ...]}, ...] |
109 |
|
} |
110 |
|
}. |
111 |
|
|
112 |
|
-callback purge_node(NodeIdx :: nodeIdx(), Owner :: jid:jid()) -> |
113 |
|
{result, {default, broadcast}} | {error, exml:element()}. |
114 |
|
|
115 |
|
-callback subscribe_node(NodeIdx :: nodeIdx(), |
116 |
|
Sender :: jid:jid(), |
117 |
|
Subscriber :: jid:ljid(), |
118 |
|
AccessModel :: accessModel(), |
119 |
|
SendLast :: 'never' | 'on_sub' | 'on_sub_and_presence', |
120 |
|
PresenceSubscription :: boolean(), |
121 |
|
RosterGroup :: boolean(), |
122 |
|
Options :: subOptions()) -> |
123 |
|
{result, {default, subscribed, subId()}} | |
124 |
|
{result, {default, subscribed, subId(), send_last}} | |
125 |
|
{result, {default, pending, subId()}} | |
126 |
|
{error, exml:element()}. |
127 |
|
|
128 |
|
-callback unsubscribe_node(NodeIdx :: nodeIdx(), |
129 |
|
Sender :: jid:jid(), |
130 |
|
Subscriber :: jid:jid(), |
131 |
|
SubId :: subId()) -> |
132 |
|
{result, default} | {error, exml:element()}. |
133 |
|
|
134 |
|
-callback publish_item(ServerHost :: jid:server(), |
135 |
|
NodeId :: nodeIdx(), |
136 |
|
Publisher :: jid:jid(), |
137 |
|
PublishModel :: publishModel(), |
138 |
|
MaxItems :: non_neg_integer(), |
139 |
|
ItemId :: <<>> | itemId(), |
140 |
|
ItemPublisher :: boolean(), |
141 |
|
Payload :: payload(), |
142 |
|
PublishOptions :: publishOptions()) -> |
143 |
|
{result, {default, broadcast, [itemId()]}} | {error, exml:element()}. |
144 |
|
|
145 |
|
-callback delete_item(NodeIdx :: nodeIdx(), |
146 |
|
Publisher :: jid:jid(), |
147 |
|
PublishModel :: publishModel(), |
148 |
|
ItemId :: <<>> | itemId()) -> |
149 |
|
{result, {default, broadcast}} | {error, exml:element()}. |
150 |
|
|
151 |
|
-callback remove_extra_items(NodeIdx :: nodeIdx(), |
152 |
|
MaxItems :: unlimited | non_neg_integer(), |
153 |
|
ItemIds :: [itemId()]) -> |
154 |
|
{result, {[itemId()], [itemId()]}}. |
155 |
|
|
156 |
|
-callback get_node_affiliations(NodeIdx :: nodeIdx()) -> {result, [{jid:ljid(), affiliation()}]}. |
157 |
|
|
158 |
|
-callback get_entity_affiliations(Host :: host(), Owner :: jid:jid()) -> |
159 |
|
{result, [{pubsubNode(), affiliation()}]}. |
160 |
|
|
161 |
|
-callback get_affiliation(NodeIdx :: nodeIdx(), Owner :: jid:jid()) -> {result, affiliation()}. |
162 |
|
|
163 |
|
-callback set_affiliation(NodeIdx :: nodeIdx(), Owner :: jid:jid(), Affiliation :: affiliation()) -> |
164 |
|
ok | {error, exml:element()}. |
165 |
|
|
166 |
|
-callback get_node_subscriptions(NodeIdx :: nodeIdx()) -> |
167 |
|
{result, [{jid:ljid(), subscription(), subId(), subOptions()}]}. |
168 |
|
|
169 |
|
-callback get_entity_subscriptions(Host :: host(), Key :: jid:jid()) -> |
170 |
|
{result, [{pubsubNode(), subscription(), subId(), jid:ljid()}]}. |
171 |
|
|
172 |
|
-callback get_subscriptions(NodeIdx :: nodeIdx(), Owner :: jid:jid()) -> |
173 |
|
{result, [{subscription(), subId(), subOptions()}]}. |
174 |
|
|
175 |
|
-callback get_pending_nodes(Host :: host(), Owner :: jid:jid()) -> {result, [nodeId()]}. |
176 |
|
|
177 |
|
-callback get_items_if_authorised(NodeIdx :: nodeIdx(), JID :: jid:jid(), get_authorised_item_options()) -> |
178 |
|
{result, {[pubsubItem()], none | jlib:rsm_out()}} | {error, exml:element()}. |
179 |
|
|
180 |
|
-callback get_items(NodeIdx :: nodeIdx(), From :: jid:jid(), get_item_options()) -> |
181 |
|
{result, {[pubsubItem()], none | jlib:rsm_out()}}. |
182 |
|
|
183 |
|
-callback get_item(NodeIdx :: nodeIdx(), |
184 |
|
ItemId :: itemId(), |
185 |
|
JID :: jid:jid(), |
186 |
|
AccessModel :: accessModel(), |
187 |
|
PresenceSubscription :: boolean(), |
188 |
|
RosterGroup :: boolean(), |
189 |
|
SubId :: subId()) -> |
190 |
|
{result, pubsubItem()} | {error, exml:element()}. |
191 |
|
|
192 |
|
-callback get_item(NodeIdx :: nodeIdx(), ItemId :: itemId()) -> |
193 |
|
{result, pubsubItem()} | {error, exml:element()}. |
194 |
|
|
195 |
|
-callback set_item(Item :: pubsubItem()) -> ok. |
196 |
|
|
197 |
|
-callback get_item_name(Host :: host(), ServerHost :: binary(), Node :: nodeId()) -> itemId(). |
198 |
|
|
199 |
|
-callback node_to_path(Node :: nodeId()) -> [nodeId()]. |
200 |
|
|
201 |
|
-callback path_to_node(Path :: [nodeId()]) -> nodeId(). |
202 |
|
|
203 |
|
-callback should_delete_when_owner_removed() -> boolean(). |
204 |
|
|
205 |
|
-callback remove_user(LUser :: jid:luser(), LServer :: jid:lserver()) -> any(). |
206 |
|
|
207 |
|
-optional_callbacks([create_node_permission/6, |
208 |
|
create_node/2, |
209 |
|
delete_node/1, |
210 |
|
purge_node/2, |
211 |
|
subscribe_node/8, |
212 |
|
unsubscribe_node/4, |
213 |
|
publish_item/9, |
214 |
|
delete_item/4, |
215 |
|
remove_extra_items/3, |
216 |
|
get_node_affiliations/1, |
217 |
|
get_entity_affiliations/2, |
218 |
|
get_affiliation/2, |
219 |
|
set_affiliation/3, |
220 |
|
get_node_subscriptions/1, |
221 |
|
get_entity_subscriptions/2, |
222 |
|
get_subscriptions/2, |
223 |
|
get_pending_nodes/2, |
224 |
|
get_items_if_authorised/3, |
225 |
|
get_items/3, |
226 |
|
get_item/7, |
227 |
|
get_item/2, |
228 |
|
set_item/1, |
229 |
|
get_item_name/3, |
230 |
|
path_to_node/1, |
231 |
|
should_delete_when_owner_removed/0, |
232 |
|
remove_user/2]). |
233 |
|
|
234 |
|
%% -------------------------------------------------------- |
235 |
|
%% API |
236 |
|
%% -------------------------------------------------------- |
237 |
|
based_on(Mod) -> |
238 |
2777 |
Mod:based_on(). |
239 |
|
|
240 |
|
terminate(Mod, Host, ServerHost) -> |
241 |
49 |
Mod:terminate(Host, ServerHost). |
242 |
|
|
243 |
|
options(Mod) -> |
244 |
224 |
Mod:options(). |
245 |
|
|
246 |
|
features(Mod) -> |
247 |
1227 |
Mod:features(). |
248 |
|
|
249 |
|
node_to_path(Mod, Node) -> |
250 |
:-( |
Mod:node_to_path(Node). |
251 |
|
|