1 /*
2   Copyright (c) 2007-2019 by Jakob Schröter <js@camaya.net>
3   This file is part of the gloox library. http://camaya.net/gloox
4 
5   This software is distributed under a license. The full license
6   agreement can be found in the file LICENSE in this distribution.
7   This software may not be copied, modified, sold or distributed
8   other than expressed in the named license agreement.
9 
10   This software is distributed without any warranty.
11 */
12 
13 #ifndef PUBSUBMANAGER_H__
14 #define PUBSUBMANAGER_H__
15 
16 #include "pubsub.h"
17 #include "dataform.h"
18 #include "iqhandler.h"
19 #include "mutex.h"
20 
21 #include <map>
22 #include <string>
23 
24 namespace gloox
25 {
26 
27   class ClientBase;
28 
29   namespace PubSub
30   {
31 
32     class ResultHandler;
33 
34     /**
35      * @brief This manager is used to interact with PubSub services (@xep{0060}).
36      *
37      * @note PubSub support in gloox is still relatively young and you are most
38      * welcome to ask questions, criticize the API and so on.
39      *
40      * A ResultHandler is used to receive a request's result. Depending on the
41      * context, this can be a notification that an item has been succesfully
42      * deleted (or not), or the default node configuration for a service.
43      *
44      * To receive PubSub events:
45      * @li Tell ClientBase that you are interested in PubSub events by registering
46      * an empty PubSub::Event StanzaExtension
47      * @code
48      * m_client->registerStanzaExtension( new PubSub::Event() );
49      * @endcode
50      * @li Implement a MessageHandler and register it with ClientBase, or use the MessageSession interface, at your choice,
51      * @li When receiving a Message, check it for a PubSub::Event
52      * @code
53      * const PubSub::Event* pse = msg.findExtension<PubSub::Event>( ExtPubSubEvent );
54      * if( pse )
55      * {
56      *   // use the Event
57      * }
58      * else
59      * {
60      *   // no Event
61      * }
62      * @endcode
63      *
64      * To interact with PubSub services, you will need to
65      * instantiate a PubSub::Manager and
66      * implement the ResultHandler virtual interfaces to be notified of the
67      * result of requests.
68      *
69      * @note A null ResultHandler to a query is not allowed and is a no-op.
70      *
71      * XEP Version: 1.12
72      *
73      * @author Jakob Schröter <js@camaya.net>
74      * @author Vincent Thomasset <vthomasset@gmail.com>
75      *
76      * @since 1.0
77      */
78     class GLOOX_API Manager : public IqHandler
79     {
80       public:
81 
82         /**
83          * Initialize the manager.
84          * @param parent Client to which this manager belongs.
85          */
86         Manager( ClientBase* parent );
87 
88         /**
89          * Default virtual destructor.
90          */
~Manager()91         virtual ~Manager() {}
92 
93         /**
94          * Subscribe to a node.
95          *
96          * @param service Service hosting the node.
97          * @param node ID of the node to subscribe to.
98          * @param handler The ResultHandler.
99          * @param jid JID to subscribe. If empty, the client's JID will be used
100          *        (ie. self subscription).
101          * @param type SubscriptionType of the subscription (Collections only).
102          * @param depth Subscription depth. For 'all', use 0 (Collections only).
103          * @param expire Subscription expiry. Defaults to the empty string.
104          * @return The IQ ID used in the request.
105          *
106          * @see ResultHandler::handleSubscriptionResult
107          */
108         const std::string subscribe( const JID& service, const std::string& node,
109                                      ResultHandler* handler, const JID& jid = JID(),
110                                      SubscriptionObject type = SubscriptionNodes,
111                                      int depth = 1, const std::string& expire = EmptyString );
112 
113         /**
114          * Subscribe to a node and configure options.
115          *
116          * @param service Service hosting the node.
117          * @param node ID of the node to subscribe to.
118          * @param handler The ResultHandler.
119          * @param jid JID to subscribe. If empty, the client's JID will be used
120          *        (ie. self subscription).
121          * @param options The options to configure while subscribing.
122          *        Should be a TypeSubmit form, with a field named FORM_TYPE having the value
123          *        http://jabber.org/protocol/pubsub#subscribe_options
124          *        See @xep{0060}, "Subscribe and Configure".
125          *        Will be owned and deleted by the PubSub object.
126          * @return The IQ ID used in the request.
127          *
128          * @see ResultHandler::handleSubscriptionResult
129          */
130         const std::string subscribe( const JID& service, const std::string& node,
131                                      ResultHandler* handler, const JID& jid,
132                                      DataForm* options );
133 
134         /**
135          * Unsubscribe from a node.
136          *
137          * @param service Service hosting the node.
138          * @param node ID of the node to unsubscribe from.
139          * @param subid An optional, additional subscription ID.
140          * @param handler ResultHandler receiving the result notification.
141          * @param jid JID to unsubscribe. If empty, the client's JID will be
142          * used (ie self unsubscription).
143          * @return The IQ ID used in the request.
144          *
145          * @see ResultHandler::handleUnsubscriptionResult
146          */
147         const std::string unsubscribe( const JID& service,
148                                        const std::string& node,
149                                        const std::string& subid,
150                                        ResultHandler* handler,
151                                        const JID& jid = JID() );
152 
153         /**
154          * Requests the subscription list from a service.
155          *
156          * @param service Service to query.
157          * @param handler The ResultHandler to handle the result.
158          * @return The IQ ID used in the request.
159          *
160          * @see ResultHandler::handleSubscriptions
161          */
getSubscriptions(const JID & service,ResultHandler * handler)162         const std::string getSubscriptions( const JID& service,
163                                             ResultHandler* handler )
164         {
165           return getSubscriptionsOrAffiliations( service,
166                                                  handler,
167                                                  GetSubscriptionList );
168         }
169 
170         /**
171          * Requests the affiliation list from a service.
172          *
173          * @param service Service to query.
174          * @param handler The ResultHandler to handle the result.
175          * @return The IQ ID used in the request.
176          *
177          * @see ResultHandler::handleAffiliations
178          */
getAffiliations(const JID & service,ResultHandler * handler)179         const std::string getAffiliations( const JID& service,
180                                            ResultHandler* handler )
181         {
182           return getSubscriptionsOrAffiliations( service,
183                                                  handler,
184                                                  GetAffiliationList );
185         }
186 
187         /**
188          * Requests subscription options.
189          *
190          * @param service Service to query.
191          * @param jid Subscribed entity.
192          * @param node Node ID of the node.
193          * @param handler The SubscriptionListHandler to handle the result.
194          * @param subid An optional subscription ID.
195          * @return The IQ ID used in the request.
196          *
197          * @see ResultHandler::handleSubscriptionOptions
198          */
199         const std::string getSubscriptionOptions( const JID& service,
200                                                   const JID& jid,
201                                                   const std::string& node,
202                                                   ResultHandler* handler,
203                                                   const std::string& subid = EmptyString)
204           { return subscriptionOptions( GetSubscriptionOptions, service, jid, node, handler, 0, subid ); }
205 
206         /**
207          * Modifies subscription options.
208          *
209          * @param service Service to query.
210          * @param jid Subscribed entity.
211          * @param node Node ID of the node.
212          * @param df New configuration. The DataForm will be owned and deleted by the Manager.
213          * @param handler The handler to handle the result.
214          * @param subid An optional subscription ID.
215          * @return The IQ ID used in the request.
216          *
217          * @see ResultHandler::handleSubscriptionOptionsResult
218          */
219         const std::string setSubscriptionOptions( const JID& service,
220                                                   const JID& jid,
221                                                   const std::string& node,
222                                                   DataForm* df,
223                                                   ResultHandler* handler,
224                                                   const std::string& subid = EmptyString )
225           { return subscriptionOptions( SetSubscriptionOptions, service, jid, node, handler, df, subid ); }
226 
227         /**
228          * Requests the affiliation list for a node.
229          *
230          * @param service Service to query.
231          * @param node Node ID of the node.
232          * @param handler The AffiliationListHandler to handle the result.
233          *
234          * @see ResultHandler::handleAffiliations
235          */
236         void getAffiliations( const JID& service,
237                               const std::string& node,
238                               ResultHandler* handler );
239 
240         /**
241          * Requests items from a node.
242          * @param service Service to query.
243          * @param node Node ID of the node.
244          * @param subid An optional subscription ID.
245          * @param maxItems The optional maximum number of items to return.
246          * @param handler The handler to handle the result.
247          * @return The ID used in the request.
248          */
249         const std::string requestItems( const JID& service,
250                                         const std::string& node,
251                                         const std::string& subid,
252                                         int maxItems,
253                                         ResultHandler* handler);
254 
255         /**
256          * Requests specific items from a node.
257          * @param service Service to query.
258          * @param node Node ID of the node.
259          * @param subid An optional subscription ID.
260          * @param items The list of item IDs to request.
261          * @param handler The handler to handle the result.
262          * @return The ID used in the request.
263          */
264         const std::string requestItems( const JID& service,
265                                         const std::string& node,
266                                         const std::string& subid,
267                                         const ItemList& items,
268                                         ResultHandler* handler);
269 
270         /**
271          * Publish an item to a node. The Tag to publish is destroyed
272          * by the function before returning.
273          *
274          * @param service Service hosting the node.
275          * @param node ID of the node to delete the item from.
276          * @param items One or more items to publish. The items will be owned and deleted by the Manager,
277          * even in the error case (empty string returned).
278          * @param options An optional DataForm containing publish options. The DataForm will be owned and deleted by the Manager.
279          * @param handler The handler to handle the result.
280          * @return The ID used in the request.
281          *
282          * @see ResultHandler::handleItemPublication
283          */
284         const std::string publishItem( const JID& service,
285                                        const std::string& node,
286                                        ItemList& items,
287                                        DataForm* options,
288                                        ResultHandler* handler );
289 
290         /**
291          * Delete an item from a node.
292          *
293          * @param service Service hosting the node.
294          * @param node ID of the node to delete the item from.
295          * @param items A list of items to delete (only ID filled in).
296          * @param notify Whether or not to notify subscribers about the deletion.
297          * @param handler The handler to handle the result.
298          * @return The ID used in the request.
299          *
300          * @see ResultHandler::handleItemDeletation
301          */
302         const std::string deleteItem( const JID& service,
303                                       const std::string& node,
304                                       const ItemList& items,
305                                       bool notify,
306                                       ResultHandler* handler );
307 
308         /**
309          * Creates a new node.
310          *
311          * @param service Service where to create the new node.
312          * @param node The ID of the new node.
313          * @param config An optional DataForm that holds the node configuration.
314          * The DataForm will be owned and deleted by the Manager.
315          * @param handler The handler to handle the result.
316          * @return The ID used in the request.
317          *
318          * @see ResultHandler::handleNodeCreation
319          */
320         const std::string createNode( const JID& service,
321                                       const std::string& node,
322                                       DataForm* config,
323                                       ResultHandler* handler );
324 
325         /**
326          * Deletes a node.
327          *
328          * @param service Service where to create the new node.
329          * @param node Node ID of the new node.
330          * @param handler The handler to handle the result.
331          * @return The ID used in the request.
332          *
333          * @see ResultHandler::handleNodeDeletion
334          */
335         const std::string deleteNode( const JID& service,
336                                       const std::string& node,
337                                       ResultHandler* handler );
338 
339         /**
340          * Retrieves the default configuration for a specific NodeType.
341          *
342          * @param service The queried service.
343          * @param type NodeType to get default configuration for.
344          * @param handler ResultHandler.
345          * @return The ID used in the request.
346          *
347          * @see ResultHandler::handleDefaultNodeConfig
348          */
349         const std::string getDefaultNodeConfig( const JID& service,
350                                                 NodeType type,
351                                                 ResultHandler* handler );
352 
353         /**
354          * Removes all the items from a node.
355          *
356          * @param service Service to query.
357          * @param node Node ID of the node.
358          * @param handler ResultHandler.
359          * @return The ID used in the request.
360          *
361          * @see ResultHandler::handleNodePurge
362          */
363         const std::string purgeNode( const JID& service,
364                                      const std::string& node,
365                                      ResultHandler* handler );
366 
367         /**
368          * Requests the subscriber list for a node.
369          *
370          * @param service Service to query.
371          * @param node Node ID of the node.
372          * @param handler ResultHandler.
373          * @return The ID used in the request.
374          *
375          * @see ResultHandler::handleSubscribers
376          */
getSubscribers(const JID & service,const std::string & node,ResultHandler * handler)377         const std::string getSubscribers( const JID& service,
378                                           const std::string& node,
379                                           ResultHandler* handler )
380           { return subscriberList( GetSubscriberList, service,
381                                    node, SubscriberList(),
382                                    handler ); }
383 
384         /**
385          * Modifies the subscriber list for a node. This function SHOULD only set the
386          * subscriber list to those which needs modification.
387          *
388          * @param service Service to query.
389          * @param node Node ID of the node.
390          * @param list The subscriber list.
391          * @param handler The ResultHandler.
392          * @return The ID used in the request.
393          *
394          * @see ResultHandler::handleSubscribers
395          */
setSubscribers(const JID & service,const std::string & node,const SubscriberList & list,ResultHandler * handler)396         const std::string setSubscribers( const JID& service,
397                                           const std::string& node,
398                                           const SubscriberList& list,
399                                           ResultHandler* handler )
400           { return subscriberList( SetSubscriberList, service,
401                                    node, list, handler ); }
402 
403         /**
404          * Requests the affiliate list for a node.
405          *
406          * @param service Service to query.
407          * @param node Node ID of the node.
408          * @param handler ResultHandler.
409          * @return The ID used in the request.
410          *
411          * @see ResultHandler::handleAffiliates
412          */
getAffiliates(const JID & service,const std::string & node,ResultHandler * handler)413         const std::string getAffiliates( const JID& service,
414                                          const std::string& node,
415                                          ResultHandler* handler )
416           { return affiliateList( GetAffiliateList, service,
417                                   node, AffiliateList(),
418                                   handler ); }
419 
420         /**
421          * Modifies the affiliate list for a node.
422          *
423          * @param service Service to query.
424          * @param node Node ID of the node.
425          * @param list ResultHandler.
426          * @param handler ResultHandler.
427          * @return The ID used in the request.
428          *
429          * @see ResultHandler::handleAffiliatesResult
430          */
setAffiliates(const JID & service,const std::string & node,const AffiliateList & list,ResultHandler * handler)431         const std::string setAffiliates( const JID& service,
432                                          const std::string& node,
433                                          const AffiliateList& list,
434                                          ResultHandler* handler )
435           { return affiliateList( SetAffiliateList, service,
436                                   node, list, handler ); }
437 
438         /**
439          * Retrieve the configuration (options) of a node.
440          *
441          * @param service Service hosting the node.
442          * @param node ID of the node.
443          * @param handler ResultHandler responsible to handle the request result.
444          * @return The ID used in the request.
445          *
446          * @see ResultHandler::handleNodeConfig
447          */
getNodeConfig(const JID & service,const std::string & node,ResultHandler * handler)448         const std::string getNodeConfig( const JID& service,
449                                          const std::string& node,
450                                          ResultHandler* handler )
451           { return nodeConfig( service, node, 0, handler ); }
452 
453         /**
454          * Changes a node's configuration (options).
455          *
456          * @param service Service to query.
457          * @param node Node ID of the node.
458          * @param config The node's configuration DataForm.
459          * @param handler ResultHandler responsible to handle the request result.
460          * @return The ID used in the request.
461          *
462          * @see ResultHandler::handleNodeConfigResult
463          */
setNodeConfig(const JID & service,const std::string & node,DataForm * config,ResultHandler * handler)464         const std::string setNodeConfig( const JID& service,
465                                          const std::string& node,
466                                          DataForm* config,
467                                          ResultHandler* handler  )
468           { return nodeConfig( service, node, config, handler ); }
469 
470         /**
471          * Removes an ID from our tracking lists.
472          * @param id The ID to remove.
473          * @return @b True if the ID was found and removed, @b false otherwise.
474          */
475         bool removeID( const std::string& id );
476 
477         // reimplemented from DiscoHandler
478         void handleDiscoInfoResult( IQ* iq, int context );
479 
480         // reimplemented from DiscoHandler
481         void handleDiscoItemsResult( IQ* iq, int context );
482 
483         // reimplemented from DiscoHandler
484         void handleDiscoError( IQ* iq, int context );
485 
486         // reimplemented from DiscoHandler
handleDiscoSet(IQ *)487         bool handleDiscoSet( IQ* ) { return 0; }
488 
489         // reimplemented from IqHandler.
handleIq(const IQ & iq)490         virtual bool handleIq( const IQ& iq ) { (void)iq; return false; }
491 
492         // reimplemented from IqHandler.
493         virtual void handleIqID( const IQ& iq, int context );
494 
495       private:
496 #ifdef PUBSUBMANAGER_TEST
497       public:
498 #endif
499 
500         enum TrackContext
501         {
502           Subscription,
503           Unsubscription,
504           GetSubscriptionOptions,
505           SetSubscriptionOptions,
506           GetSubscriptionList,
507           GetSubscriberList,
508           SetSubscriberList,
509           GetAffiliationList,       /**< Requests the list of one's own affiliations from a service (XEP-0060 section 5.7) */
510           GetAffiliateList,         /**< Requests the list of affiliates for a node (XEP-0060 section 8.9.1) */
511           SetAffiliateList,         /**< Sets/modifies/deletes the list of affiliates for a node (XEP-0060 section 8.9.2 */
512           GetNodeConfig,
513           SetNodeConfig,
514           DefaultNodeConfig,
515           GetItemList,
516           PublishItem,
517           DeleteItem,
518           CreateNode,
519           DeleteNode,
520           PurgeNodeItems,
521           NodeAssociation,
522           NodeDisassociation,
523           GetFeatureList,
524           DiscoServiceInfos,
525           DiscoNodeInfos,
526           DiscoNodeItems,
527           RequestItems,
528           InvalidContext
529         };
530 
531         class PubSubOwner : public StanzaExtension
532         {
533           public:
534             /**
535              * Creates a new PubSubOwner object that can be used to request the given type.
536              * @param context The requets type.
537              */
538             PubSubOwner( TrackContext context = InvalidContext );
539 
540             /**
541              * Creates a new PubSubOwner object by parsing the given Tag.
542              * @param tag The Tag to parse.
543              */
544             PubSubOwner( const Tag* tag );
545 
546             /**
547              * Virtual destructor.
548              */
549             virtual ~PubSubOwner();
550 
551             /**
552              * Sets the node to use in e.g. subscription requests.
553              * @param node The node to use.
554              */
setNode(const std::string & node)555             void setNode( const std::string& node ) { m_node = node; }
556 
557             /**
558              * Returns the pubsub node.
559              * @return The pubsub node.
560              */
node()561             const std::string& node() const { return m_node; }
562 
563             /**
564              * Sets an options DataForm.
565              * @param options The DataForm.
566              */
setConfig(DataForm * config)567             void setConfig( DataForm* config )
568               { m_form = config; }
569 
570             /**
571              * Returns the config DataForm.
572              * @return The config DataForm.
573              */
config()574             const DataForm* config() const { return m_form; }
575 
576             /**
577              * Sets the subscriber list.
578              * @param subList The subscriber list.
579              */
setSubscriberList(const SubscriberList & subList)580             void setSubscriberList( const SubscriberList& subList )
581               { m_subList = subList; }
582 
583             /**
584              * Sets the affiliate list.
585              * @param affList The affiliate list.
586              */
setAffiliateList(const AffiliateList & affList)587             void setAffiliateList( const AffiliateList& affList )
588               { m_affList = affList; }
589 
590             /**
591              * Returns the list of affiliates. Don't delete the pointer, it is still owned by PubSubOwner.
592              * @return The list of affiliates.
593              */
affiliateList()594             const AffiliateList* affiliateList() const { return &m_affList; }
595 
596             // reimplemented from StanzaExtension
597             virtual const std::string& filterString() const;
598 
599             // reimplemented from StanzaExtension
newInstance(const Tag * tag)600             virtual StanzaExtension* newInstance( const Tag* tag ) const
601             {
602               return new PubSubOwner( tag );
603             }
604 
605             // reimplemented from StanzaExtension
606             virtual Tag* tag() const;
607 
608             // reimplemented from StanzaExtension
clone()609             virtual StanzaExtension* clone() const
610             {
611               PubSubOwner* p = new PubSubOwner();
612               p->m_node = m_node;
613               p->m_ctx = m_ctx;
614               p->m_form = m_form ? new DataForm( *m_form ) : 0;
615               p->m_subList = m_subList;
616               p->m_affList = m_affList;
617               return p;
618             }
619 
620           private:
621             std::string m_node;
622             TrackContext m_ctx;
623             DataForm* m_form;
624             SubscriberList m_subList;
625             AffiliateList m_affList;
626         };
627 
628         class PubSub : public StanzaExtension
629         {
630           public:
631             /**
632              * Creates a new PubSub object that can be used to request the given type.
633              * @param context The requets type.
634              */
635             PubSub( TrackContext context = InvalidContext );
636 
637             /**
638              * Creates a new PubSub object by parsing the given Tag.
639              * @param tag The Tag to parse.
640              */
641             PubSub( const Tag* tag );
642 
643             /**
644              * Virtual destructor.
645              */
646             virtual ~PubSub();
647 
648             /**
649              * Sets the JID to use in e.g. subscription requests.
650              * @param jid The JID to use.
651              */
setJID(const JID & jid)652             void setJID( const JID& jid ) { m_jid = jid; }
653 
654             /**
655              * Returns the pubsub JID (not the service JID).
656              * @return The pubsub JID.
657              */
jid()658             const JID& jid() const { return m_jid; }
659 
660             /**
661              * Sets the node to use in e.g. subscription requests.
662              * @param node The node to use.
663              */
setNode(const std::string & node)664             void setNode( const std::string& node ) { m_node = node; }
665 
666             /**
667              * Returns the pubsub node.
668              * @return The pubsub node.
669              */
node()670             const std::string& node() const { return m_node; }
671 
672             /**
673              * Returns the tracking context.
674              * @return The tracking context value.
675              */
context()676             TrackContext context() const { return m_ctx; }
677 
678             /**
679              * Sets the Subscription ID to use.
680              * @param subid The Subscription ID to use.
681              */
setSubscriptionID(const std::string & subid)682             void setSubscriptionID( const std::string& subid )
683               { m_subid = subid; }
684 
685             /**
686              * Gets the Subscription ID to use.
687              * @return The Subscription ID to use.
688              */
subscriptionID()689             const std::string& subscriptionID() const { return m_subid; }
690 
691             /**
692              * Sets the subscription options.
693              * @param node The node to set the options for.
694              * @param df The DataForm holding the subscription options.
695              * Will be owned and deleted by the PubSub object
696              */
setOptions(const std::string & node,DataForm * df)697             void setOptions( const std::string& node, DataForm* df )
698             {
699               m_options.node = node;
700               if( m_options.df != 0 )
701                 delete m_options.df;
702               m_options.df = df;
703             }
704 
705             /**
706              * Returns the subscription options.
707              * @return The subscription options.
708              */
options()709             const DataForm* options() const
710               { return m_options.df; }
711 
712             /**
713              * Returns the current Items.
714              * @return The current items.
715              */
items()716             const ItemList& items() const { return m_items; }
717 
718             /**
719              * Sets the subscription IDs.
720              * @param ids Subscription IDs.
721              */
setItems(const ItemList & items)722             void setItems( const ItemList& items )
723              { m_items = items; }
724 
725             /**
726              * Sets the maximum number of items to request.
727              * @param maxItems The maximum number of items to request.
728              */
setMaxItems(int maxItems)729             void setMaxItems( int maxItems )
730               { m_maxItems = maxItems; }
731 
732             /**
733              * Returns the subscriptions.
734              * @param The subscriptions.
735              */
subscriptions()736             const SubscriptionMap& subscriptions() const
737               { return m_subscriptionMap; }
738 
739             /**
740              * Returns the affiliations.
741              * @param The affiliations.
742              */
affiliations()743             const AffiliationMap& affiliations() const
744               { return m_affiliationMap; }
745 
746             /**
747              * Sets whether or not a notify element should be included in a 'retract'.
748              * @param notify Indicates whether a notify attribute is included.
749              */
setNotify(bool notify)750             void setNotify( bool notify ) { m_notify = notify; }
751 
752             // reimplemented from StanzaExtension
753             virtual const std::string& filterString() const;
754 
755             // reimplemented from StanzaExtension
newInstance(const Tag * tag)756             virtual StanzaExtension* newInstance( const Tag* tag ) const
757             {
758               return new PubSub( tag );
759             }
760 
761             // reimplemented from StanzaExtension
762             virtual Tag* tag() const;
763 
764             // reimplemented from StanzaExtension
765             virtual StanzaExtension* clone() const;
766 
767           private:
768             AffiliationMap m_affiliationMap;
769             SubscriptionMap m_subscriptionMap;
770             TrackContext m_ctx;
771 
772             struct Options
773             {
774               std::string node;
775               DataForm* df;
776             };
777             Options m_options;
778             JID m_jid;
779             std::string m_node;
780             std::string m_subid;
781             ItemList m_items;
782             int m_maxItems;
783             bool m_notify;
784         };
785 
786         /**
787          * This function sets or requests a node's configuration form
788          * (depending on arguments). Does the actual work for requestNodeConfig
789          * and setNodeConfig.
790          * Requests or changes a node's configuration.
791          * @param service Service to query.
792          * @param node Node ID of the node.
793          * @param config If not NULL, the function will request the node config.
794          * Otherwise, it will set the config based on the form.
795          * @param handler ResultHandler responsible to handle the request result.
796          */
797         const std::string nodeConfig( const JID& service,
798                                       const std::string& node,
799                                       DataForm* config,
800                                       ResultHandler* handler );
801 
802         /**
803          * This function sets or requests a node's subscribers list form
804          * (depending on arguments). Does the actual work for
805          * requestSubscriberList and setSubscriberList.
806          * Requests or changes a node's configuration.
807          * @param ctx The operation to be performed.
808          * @param service Service to query.
809          * @param node Node ID of the node.
810          * @param config If not NULL, the function will request the node config.
811          * Otherwise, it will set the config based on the form.
812          * @param handler ResultHandler responsible to handle the request result.
813          * @return The ID used in the request.
814          */
815         const std::string subscriberList( TrackContext ctx,
816                                           const JID& service,
817                                           const std::string& node,
818                                           const SubscriberList& config,
819                                           ResultHandler* handler );
820 
821         /**
822          * This function sets or requests a node's affiliates list
823          * (depending on arguments). Does the actual work for
824          * requestAffiliateList and setAffiliateList.
825          * Requests or changes a node's configuration.
826          * @param ctx The operation to be performed.
827          * @param service Service to query.
828          * @param node Node ID of the node.
829          * @param config If not NULL, the function will request the node config.
830          * Otherwise, it will set the config based on the form.
831          * @param handler ResultHandler responsible to handle the request result.
832          * @return The ID used in the request.
833          */
834         const std::string affiliateList( TrackContext ctx,
835                                          const JID& service,
836                                          const std::string& node,
837                                          const AffiliateList& config,
838                                          ResultHandler* handler );
839 
840         const std::string subscriptionOptions( TrackContext context,
841                                                const JID& service,
842                                                const JID& jid,
843                                                const std::string& node,
844                                                ResultHandler* handler,
845                                                DataForm* df,
846                                                const std::string& subid = EmptyString );
847 
848         const std::string getSubscriptionsOrAffiliations( const JID& service,
849             ResultHandler* handler,
850             TrackContext context );
851 
852         typedef std::map < std::string, std::string > NodeOperationTrackMap;
853         typedef std::map < std::string, ResultHandler* > ResultHandlerTrackMap;
854 
855         ClientBase* m_parent;
856 
857         NodeOperationTrackMap  m_nopTrackMap;
858         ResultHandlerTrackMap  m_resultHandlerTrackMap;
859 
860         util::Mutex m_trackMapMutex;
861 
862     };
863 
864   }
865 
866 }
867 
868 #endif // PUBSUBMANAGER_H__
869