gloox  1.0.27
pubsubevent.cpp
1 /*
2  Copyright (c) 2007-2023 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 #include "pubsubevent.h"
14 #include "tag.h"
15 #include "util.h"
16 
17 namespace gloox
18 {
19 
20  namespace PubSub
21  {
22 
23  static const char* eventTypeValues[] = {
24  "collection",
25  "configuration",
26  "delete",
27  "items",
28  "items",
29  "purge",
30  "subscription"
31  };
32 
34  : retract( right.retract ), item( right.item ),
35  payload( right.payload ? right.payload->clone() : 0 )
36  {
37  }
38 
40  : StanzaExtension( ExtPubSubEvent ), m_type( PubSub::EventUnknown ),
41  m_subscriptionIDs( 0 ), m_config( 0 ),
42  m_itemOperations( 0 )
43  {
44  }
45 
46  Event::Event( const Tag* event )
47  : StanzaExtension( ExtPubSubEvent ), m_type( PubSub::EventUnknown ),
48  m_subscriptionIDs( 0 ), m_config( 0 ), m_itemOperations( 0 ), m_subscription( false )
49  {
50  if( !event || event->name() != "event" )
51  return;
52 
53  const TagList& events = event->children();
54  TagList::const_iterator it = events.begin();
55  const Tag* tag = 0;
56  for( ; it != events.end(); ++it )
57  {
58  tag = (*it);
59  PubSub::EventType type = static_cast<PubSub::EventType>( util::lookup( tag->name(), eventTypeValues ) );
60 
61  switch( type )
62  {
64  tag = tag->findChild( "node" );
65  if( tag )
66  {
67  m_node = tag->findAttribute( "id" );
68  if( ( m_config = tag->findChild( "x" ) ) )
69  m_config = m_config->clone();
70  }
71  break;
72 
75  case PubSub::EventPurge:
76  m_node = tag->findAttribute( "node" );
78  && ( m_config = tag->findChild( "x" ) ) )
79  m_config = m_config->clone();
80  break;
81 
82  case PubSub::EventItems:
84  {
85  if( !m_itemOperations )
86  m_itemOperations = new ItemOperationList();
87 
88  m_node = tag->findAttribute( "node" );
89  const TagList& items = tag->children();
90  TagList::const_iterator itt = items.begin();
91  for( ; itt != items.end(); ++itt )
92  {
93  tag = (*itt);
94  bool retract = false;
95  if( tag->name() == "retract" )
96  {
97  retract = true;
99  }
100  ItemOperation* op = new ItemOperation( retract,
101  tag->findAttribute( "id" ),
102  tag->clone() );
103  m_itemOperations->push_back( op );
104  }
105  break;
106  }
107 
108  case EventSubscription:
109  {
110  m_node = tag->findAttribute( "node" );
111  m_jid.setJID( tag->findAttribute( "jid" ) );
112  m_subscription = tag->hasAttribute( "subscription", "subscribed" );
113  break;
114  }
115 
117  if( type == PubSub::EventUnknown )
118  {
119  if( tag->name() != "headers" || m_subscriptionIDs != 0 )
120  {
121  m_valid = false;
122  return;
123  }
124 
125  m_subscriptionIDs = new StringList();
126 
127  const TagList& headers = tag->children();
128  TagList::const_iterator ith = headers.begin();
129  for( ; ith != headers.end(); ++ith )
130  {
131  const std::string& name = (*ith)->findAttribute( "name" );
132  if( name == "pubsub#subid" )
133  m_subscriptionIDs->push_back( (*ith)->cdata() );
134  else if( name == "pubsub#collection" )
135  m_collection = (*ith)->cdata();
136  }
137  }
138 
139  default:
140  continue;
141  }
142  m_type = type;
143  }
144 
145  m_valid = true;
146  }
147 
148  Event::Event( const std::string& node, PubSub::EventType type )
149  : StanzaExtension( ExtPubSubEvent ), m_type( type ),
150  m_node( node ), m_subscriptionIDs( 0 ), m_config( 0 ),
151  m_itemOperations( 0 )
152  {
153  if( type != PubSub::EventUnknown )
154  m_valid = true;
155  }
156 
158  {
159  delete m_subscriptionIDs;
160  delete m_config;
161  if( m_itemOperations )
162  {
163  ItemOperationList::iterator it = m_itemOperations->begin();
164  for( ; it != m_itemOperations->end(); ++it )
165  {
166  delete (*it)->payload;
167  delete (*it);
168  }
169  delete m_itemOperations;
170  }
171  }
172 
174  {
175  if( !m_itemOperations )
176  m_itemOperations = new ItemOperationList();
177 
178  m_itemOperations->push_back( op );
179  }
180 
181  const std::string& Event::filterString() const
182  {
183  static const std::string filter = "/message/event[@xmlns='" + XMLNS_PUBSUB_EVENT + "']";
184  return filter;
185  }
186 
187  Tag* Event::tag() const
188  {
189  if( !m_valid )
190  return 0;
191 
192  Tag* event = new Tag( "event", XMLNS, XMLNS_PUBSUB_EVENT );
193  Tag* child = new Tag( event, util::lookup( m_type, eventTypeValues ) );
194 
195  Tag* item = 0;
196 
197  switch( m_type )
198  {
200  {
201  item = new Tag( child, "node", "id", m_node );
202  item->addChildCopy( m_config );
203  break;
204  }
205 
206  case PubSub::EventPurge:
207  case PubSub::EventDelete:
209  child->addAttribute( "node", m_node );
210  if( m_type == PubSub::EventConfigure )
211  child->addChildCopy( m_config );
212  break;
213 
214  case PubSub::EventItems:
216  {
217  child->addAttribute( "node", m_node );
218  if( m_itemOperations )
219  {
220 // Tag* item;
221  ItemOperation* op;
222  ItemOperationList::const_iterator itt = m_itemOperations->begin();
223  for( ; itt != m_itemOperations->end(); ++itt )
224  {
225  op = (*itt);
226 // item = new Tag( child, op->retract ? "retract" : "item", "id", op->item );
227  if( op->payload )
228  child->addChildCopy( op->payload );
229  }
230  }
231  break;
232  }
233 
234  case EventSubscription:
235  {
236  child->addAttribute( "node", m_node );
237  child->addAttribute( "jid", m_jid.full() );
238  child->addAttribute( "subscription", m_subscription ? "subscribed" : "none" );
239  break;
240  }
241 
242  default:
243  delete event;
244  return 0;
245  }
246 
247  if( m_subscriptionIDs || !m_collection.empty() )
248  {
249  Tag* headers = new Tag( event, "headers", XMLNS, "http://jabber.org/protocol/shim" );
250 
251  if( m_subscriptionIDs )
252  {
253  StringList::const_iterator it = m_subscriptionIDs->begin();
254  for( ; it != m_subscriptionIDs->end(); ++it )
255  (new Tag( headers, "header", "name", "pubsub#subid" ))->setCData( (*it) );
256  }
257 
258  if( !m_collection.empty() )
259  (new Tag( headers, "header", "name", "pubsub#collection" ))->setCData( m_collection );
260  }
261 
262  return event;
263  }
264 
266  {
267  Event* e = new Event( m_node, m_type );
268  e->m_subscriptionIDs = m_subscriptionIDs ? new StringList( *m_subscriptionIDs ) : 0;
269  e->m_config = m_config ? m_config->clone() : 0;
270  if( m_itemOperations )
271  {
272  e->m_itemOperations = new ItemOperationList();
273  ItemOperationList::const_iterator it = m_itemOperations->begin();
274  for( ; it != m_itemOperations->end(); ++it )
275  e->m_itemOperations->push_back( new ItemOperation( *(*it) ) );
276  }
277  else
278  e->m_itemOperations = 0;
279 
280  e->m_collection = m_collection;
281  return e;
282  }
283 
284  }
285 
286 }
bool setJID(const std::string &jid)
Definition: jid.cpp:21
const std::string & full() const
Definition: jid.h:61
This is an implementation of a PubSub Notification as a StanzaExtension.
Definition: pubsubevent.h:35
PubSub::EventType type() const
Definition: pubsubevent.h:100
std::list< ItemOperation * > ItemOperationList
Definition: pubsubevent.h:69
virtual StanzaExtension * clone() const
const ItemOperationList & items() const
Definition: pubsubevent.h:114
const std::string & filterString() const
void addItem(ItemOperation *op)
This class abstracts a stanza extension, which is usually an XML child element in a specific namespac...
This is an abstraction of an XML element.
Definition: tag.h:47
Tag * findChild(const std::string &name) const
Definition: tag.cpp:624
void addChildCopy(const Tag *child)
Definition: tag.cpp:439
bool addAttribute(Attribute *attr)
Definition: tag.cpp:354
bool hasAttribute(const std::string &name, const std::string &value=EmptyString) const
Definition: tag.cpp:602
const std::string & findAttribute(const std::string &name) const
Definition: tag.cpp:589
const std::string & name() const
Definition: tag.h:394
Tag * clone() const
Definition: tag.cpp:670
const TagList & children() const
Definition: tag.cpp:510
@ EventItems
Definition: pubsub.h:86
@ EventCollection
Definition: pubsub.h:83
@ EventPurge
Definition: pubsub.h:88
@ EventDelete
Definition: pubsub.h:85
@ EventItemsRetract
Definition: pubsub.h:87
@ EventUnknown
Definition: pubsub.h:90
@ EventSubscription
Definition: pubsub.h:89
@ EventConfigure
Definition: pubsub.h:84
The namespace for the gloox library.
Definition: adhoc.cpp:28
std::list< Tag * > TagList
Definition: tag.h:26
std::list< std::string > StringList
Definition: gloox.h:1251
const std::string XMLNS_PUBSUB_EVENT
Definition: gloox.cpp:79
const std::string XMLNS
Definition: gloox.cpp:122
@ ExtPubSubEvent
ItemOperation(bool remove, const std::string &itemid, const Tag *pld=0)
Definition: pubsubevent.h:51