gloox  1.0.1
pubsubevent.cpp
1 /*
2  Copyright (c) 2007-2012 by Jakob Schroeter <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 
39  Event::Event( const Tag* event )
40  : StanzaExtension( ExtPubSubEvent ), m_type( PubSub::EventUnknown ),
41  m_subscriptionIDs( 0 ), m_config( 0 ), m_itemOperations( 0 ), m_subscription( false )
42  {
43  if( !event || event->name() != "event" )
44  return;
45 
46  const TagList& events = event->children();
47  TagList::const_iterator it = events.begin();
48  const Tag* tag = 0;
49  for( ; it != events.end(); ++it )
50  {
51  tag = (*it);
52  PubSub::EventType type = (PubSub::EventType)util::lookup( tag->name(), eventTypeValues );
53 
54  switch( type )
55  {
57  tag = tag->findChild( "node" );
58  if( tag )
59  {
60  m_node = tag->findAttribute( "id" );
61  if( ( m_config = tag->findChild( "x" ) ) )
62  m_config = m_config->clone();
63  }
64  break;
65 
68  case PubSub::EventPurge:
69  m_node = tag->findAttribute( "node" );
70  if( type == PubSub::EventConfigure
71  && ( m_config = tag->findChild( "x" ) ) )
72  m_config = m_config->clone();
73  break;
74 
75  case PubSub::EventItems:
77  {
78  if( !m_itemOperations )
79  m_itemOperations = new ItemOperationList();
80 
81  m_node = tag->findAttribute( "node" );
82  const TagList& items = tag->children();
83  TagList::const_iterator itt = items.begin();
84  for( ; itt != items.end(); ++itt )
85  {
86  tag = (*itt);
87  bool retract = false;
88  if( tag->name() == "retract" )
89  {
90  retract = true;
92  }
93  ItemOperation* op = new ItemOperation( retract,
94  tag->findAttribute( "id" ),
95  tag->clone() );
96  m_itemOperations->push_back( op );
97  }
98  break;
99  }
100 
101  case EventSubscription:
102  {
103  m_node = tag->findAttribute( "node" );
104  m_jid.setJID( tag->findAttribute( "jid" ) );
105  m_subscription = tag->hasAttribute( "subscription", "subscribed" );
106  break;
107  }
108 
110  if( type == PubSub::EventUnknown )
111  {
112  if( tag->name() != "headers" || m_subscriptionIDs != 0 )
113  {
114  m_valid = false;
115  return;
116  }
117 
118  m_subscriptionIDs = new StringList();
119 
120  const TagList& headers = tag->children();
121  TagList::const_iterator ith = headers.begin();
122  for( ; ith != headers.end(); ++ith )
123  {
124  const std::string& name = (*ith)->findAttribute( "name" );
125  if( name == "pubsub#subid" )
126  m_subscriptionIDs->push_back( (*ith)->cdata() );
127  else if( name == "pubsub#collection" )
128  m_collection = (*ith)->cdata();
129  }
130  }
131 
132  default:
133  continue;
134  }
135  m_type = type;
136  }
137 
138  m_valid = true;
139  }
140 
141  Event::Event( const std::string& node, PubSub::EventType type )
142  : StanzaExtension( ExtPubSubEvent ), m_type( type ),
143  m_node( node ), m_subscriptionIDs( 0 ), m_config( 0 ),
144  m_itemOperations( 0 )
145  {
146  if( type != PubSub::EventUnknown )
147  m_valid = true;
148  }
149 
151  {
152  delete m_subscriptionIDs;
153  delete m_config;
154  if( m_itemOperations )
155  {
156  ItemOperationList::iterator it = m_itemOperations->begin();
157  for( ; it != m_itemOperations->end(); ++it )
158  {
159  delete (*it)->payload;
160  delete (*it);
161  }
162  delete m_itemOperations;
163  }
164  }
165 
167  {
168  if( !m_itemOperations )
169  m_itemOperations = new ItemOperationList();
170 
171  m_itemOperations->push_back( op );
172  }
173 
174  const std::string& Event::filterString() const
175  {
176  static const std::string filter = "/message/event[@xmlns='" + XMLNS_PUBSUB_EVENT + "']";
177  return filter;
178  }
179 
180  Tag* Event::tag() const
181  {
182  if( !m_valid )
183  return 0;
184 
185  Tag* event = new Tag( "event", XMLNS, XMLNS_PUBSUB_EVENT );
186  Tag* child = new Tag( event, util::lookup( m_type, eventTypeValues ) );
187 
188  Tag* item = 0;
189 
190  switch( m_type )
191  {
193  {
194  item = new Tag( child, "node", "id", m_node );
195  item->addChildCopy( m_config );
196  break;
197  }
198 
199  case PubSub::EventPurge:
200  case PubSub::EventDelete:
202  child->addAttribute( "node", m_node );
203  if( m_type == PubSub::EventConfigure )
204  child->addChildCopy( m_config );
205  break;
206 
207  case PubSub::EventItems:
209  {
210  child->addAttribute( "node", m_node );
211  if( m_itemOperations )
212  {
213 // Tag* item;
214  ItemOperation* op;
215  ItemOperationList::const_iterator itt = m_itemOperations->begin();
216  for( ; itt != m_itemOperations->end(); ++itt )
217  {
218  op = (*itt);
219 // item = new Tag( child, op->retract ? "retract" : "item", "id", op->item );
220  if( op->payload )
221  child->addChildCopy( op->payload );
222  }
223  }
224  break;
225  }
226 
227  case EventSubscription:
228  {
229  child->addAttribute( "node", m_node );
230  child->addAttribute( "jid", m_jid.full() );
231  child->addAttribute( "subscription", m_subscription ? "subscribed" : "none" );
232  break;
233  }
234 
235  default:
236  delete event;
237  return 0;
238  }
239 
240  if( m_subscriptionIDs || !m_collection.empty() )
241  {
242  Tag* headers = new Tag( event, "headers", XMLNS, "http://jabber.org/protocol/shim" );
243  StringList::const_iterator it = m_subscriptionIDs->begin();
244  for( ; it != m_subscriptionIDs->end(); ++it )
245  {
246  (new Tag( headers, "header", "name", "pubsub#subid" ))->setCData( (*it) );
247  }
248 
249  if( !m_collection.empty() )
250  (new Tag( headers, "header", "name", "pubsub#collection" ) )
251  ->setCData( m_collection );
252  }
253 
254  return event;
255  }
256 
258  {
259  Event* e = new Event( m_node, m_type );
260  e->m_subscriptionIDs = m_subscriptionIDs ? new StringList( *m_subscriptionIDs ) : 0;
261  e->m_config = m_config ? m_config->clone() : 0;
262  if( m_itemOperations )
263  {
264  e->m_itemOperations = new ItemOperationList();
265  ItemOperationList::const_iterator it = m_itemOperations->begin();
266  for( ; it != m_itemOperations->end(); ++it )
267  e->m_itemOperations->push_back( new ItemOperation( *(*it) ) );
268  }
269  else
270  e->m_itemOperations = 0;
271 
272  e->m_collection = m_collection;
273  return e;
274  }
275 
276  }
277 
278 }