pubsubevent.cpp
/*
Copyright (c) 2007-2023 by Jakob Schröter <js@camaya.net>
This file is part of the gloox library. http://camaya.net/gloox
This software is distributed under a license. The full license
agreement can be found in the file LICENSE in this distribution.
This software may not be copied, modified, sold or distributed
other than expressed in the named license agreement.
This software is distributed without any warranty.
*/
#include "pubsubevent.h"
#include "tag.h"
#include "util.h"
namespace gloox
{
namespace PubSub
{
static const char* eventTypeValues[] = {
"collection",
"configuration",
"delete",
"items",
"items",
"purge",
"subscription"
};
Event::ItemOperation::ItemOperation( const ItemOperation& right )
: retract( right.retract ), item( right.item ),
payload( right.payload ? right.payload->clone() : 0 )
{
}
Event::Event()
: StanzaExtension( ExtPubSubEvent ), m_type( PubSub::EventUnknown ),
m_subscriptionIDs( 0 ), m_config( 0 ),
m_itemOperations( 0 )
{
}
Event::Event( const Tag* event )
: StanzaExtension( ExtPubSubEvent ), m_type( PubSub::EventUnknown ),
m_subscriptionIDs( 0 ), m_config( 0 ), m_itemOperations( 0 ), m_subscription( false )
{
if( !event || event->name() != "event" )
return;
const TagList& events = event->children();
TagList::const_iterator it = events.begin();
const Tag* tag = 0;
for( ; it != events.end(); ++it )
{
tag = (*it);
PubSub::EventType type = static_cast<PubSub::EventType>( util::lookup( tag->name(), eventTypeValues ) );
switch( type )
{
case PubSub::EventCollection:
tag = tag->findChild( "node" );
if( tag )
{
m_node = tag->findAttribute( "id" );
if( ( m_config = tag->findChild( "x" ) ) )
m_config = m_config->clone();
}
break;
case PubSub::EventConfigure:
case PubSub::EventDelete:
case PubSub::EventPurge:
m_node = tag->findAttribute( "node" );
if( type == PubSub::EventConfigure
&& ( m_config = tag->findChild( "x" ) ) )
m_config = m_config->clone();
break;
case PubSub::EventItems:
case PubSub::EventItemsRetract:
{
if( !m_itemOperations )
m_itemOperations = new ItemOperationList();
m_node = tag->findAttribute( "node" );
const TagList& items = tag->children();
TagList::const_iterator itt = items.begin();
for( ; itt != items.end(); ++itt )
{
tag = (*itt);
bool retract = false;
if( tag->name() == "retract" )
{
retract = true;
type = PubSub::EventItemsRetract;
}
ItemOperation* op = new ItemOperation( retract,
tag->findAttribute( "id" ),
tag->clone() );
m_itemOperations->push_back( op );
}
break;
}
case EventSubscription:
{
m_node = tag->findAttribute( "node" );
m_jid.setJID( tag->findAttribute( "jid" ) );
m_subscription = tag->hasAttribute( "subscription", "subscribed" );
break;
}
case PubSub::EventUnknown:
if( type == PubSub::EventUnknown )
{
if( tag->name() != "headers" || m_subscriptionIDs != 0 )
{
m_valid = false;
return;
}
m_subscriptionIDs = new StringList();
const TagList& headers = tag->children();
TagList::const_iterator ith = headers.begin();
for( ; ith != headers.end(); ++ith )
{
const std::string& name = (*ith)->findAttribute( "name" );
if( name == "pubsub#subid" )
m_subscriptionIDs->push_back( (*ith)->cdata() );
else if( name == "pubsub#collection" )
m_collection = (*ith)->cdata();
}
}
default:
continue;
}
m_type = type;
}
m_valid = true;
}
Event::Event( const std::string& node, PubSub::EventType type )
: StanzaExtension( ExtPubSubEvent ), m_type( type ),
m_node( node ), m_subscriptionIDs( 0 ), m_config( 0 ),
m_itemOperations( 0 )
{
if( type != PubSub::EventUnknown )
m_valid = true;
}
Event::~Event()
{
delete m_subscriptionIDs;
delete m_config;
if( m_itemOperations )
{
ItemOperationList::iterator it = m_itemOperations->begin();
for( ; it != m_itemOperations->end(); ++it )
{
delete (*it)->payload;
delete (*it);
}
delete m_itemOperations;
}
}
void Event::addItem( ItemOperation* op )
{
if( !m_itemOperations )
m_itemOperations = new ItemOperationList();
m_itemOperations->push_back( op );
}
const std::string& Event::filterString() const
{
static const std::string filter = "/message/event[@xmlns='" + XMLNS_PUBSUB_EVENT + "']";
return filter;
}
Tag* Event::tag() const
{
if( !m_valid )
return 0;
Tag* event = new Tag( "event", XMLNS, XMLNS_PUBSUB_EVENT );
Tag* child = new Tag( event, util::lookup( m_type, eventTypeValues ) );
Tag* item = 0;
switch( m_type )
{
case PubSub::EventCollection:
{
item = new Tag( child, "node", "id", m_node );
item->addChildCopy( m_config );
break;
}
case PubSub::EventPurge:
case PubSub::EventDelete:
case PubSub::EventConfigure:
child->addAttribute( "node", m_node );
if( m_type == PubSub::EventConfigure )
child->addChildCopy( m_config );
break;
case PubSub::EventItems:
case PubSub::EventItemsRetract:
{
child->addAttribute( "node", m_node );
if( m_itemOperations )
{
// Tag* item;
ItemOperation* op;
ItemOperationList::const_iterator itt = m_itemOperations->begin();
for( ; itt != m_itemOperations->end(); ++itt )
{
op = (*itt);
// item = new Tag( child, op->retract ? "retract" : "item", "id", op->item );
if( op->payload )
child->addChildCopy( op->payload );
}
}
break;
}
case EventSubscription:
{
child->addAttribute( "node", m_node );
child->addAttribute( "jid", m_jid.full() );
child->addAttribute( "subscription", m_subscription ? "subscribed" : "none" );
break;
}
default:
delete event;
return 0;
}
if( m_subscriptionIDs || !m_collection.empty() )
{
Tag* headers = new Tag( event, "headers", XMLNS, "http://jabber.org/protocol/shim" );
if( m_subscriptionIDs )
{
StringList::const_iterator it = m_subscriptionIDs->begin();
for( ; it != m_subscriptionIDs->end(); ++it )
(new Tag( headers, "header", "name", "pubsub#subid" ))->setCData( (*it) );
}
if( !m_collection.empty() )
(new Tag( headers, "header", "name", "pubsub#collection" ))->setCData( m_collection );
}
return event;
}
StanzaExtension* Event::clone() const
{
Event* e = new Event( m_node, m_type );
e->m_subscriptionIDs = m_subscriptionIDs ? new StringList( *m_subscriptionIDs ) : 0;
e->m_config = m_config ? m_config->clone() : 0;
if( m_itemOperations )
{
e->m_itemOperations = new ItemOperationList();
ItemOperationList::const_iterator it = m_itemOperations->begin();
for( ; it != m_itemOperations->end(); ++it )
e->m_itemOperations->push_back( new ItemOperation( *(*it) ) );
}
else
e->m_itemOperations = 0;
e->m_collection = m_collection;
return e;
}
}
}
gloox::Event::Event
Event(EventType type)
Definition event.h:46
gloox::PubSub::Event::type
PubSub::EventType type() const
Definition pubsubevent.h:100
gloox::PubSub::Event::node
const std::string & node() const
Definition pubsubevent.h:128
gloox::PubSub::Event::ItemOperationList
std::list< ItemOperation * > ItemOperationList
Definition pubsubevent.h:69
gloox::PubSub::Event::clone
virtual StanzaExtension * clone() const
Definition pubsubevent.cpp:265
gloox::PubSub::Event::Event
Event()
Definition pubsubevent.cpp:39
gloox::PubSub::Event::~Event
virtual ~Event()
Definition pubsubevent.cpp:157
gloox::PubSub::Event::filterString
const std::string & filterString() const
Definition pubsubevent.cpp:181
gloox::PubSub::Event::addItem
void addItem(ItemOperation *op)
Definition pubsubevent.cpp:173
gloox::PubSub::Event::tag
Tag * tag() const
Definition pubsubevent.cpp:187
gloox::StanzaExtension::StanzaExtension
StanzaExtension(int type)
Definition stanzaextension.h:211
gloox::Tag
This is an abstraction of an XML element.
Definition tag.h:47
gloox::Tag::name
const std::string & name() const
Definition tag.h:394
gloox::Tag::addChildCopy
void addChildCopy(const Tag *child)
Definition tag.cpp:439
gloox::Tag::addAttribute
bool addAttribute(Attribute *attr)
Definition tag.cpp:354
gloox::Tag::clone
Tag * clone() const
Definition tag.cpp:670
gloox::Tag::children
const TagList & children() const
Definition tag.cpp:510
gloox::PubSub
Namespace holding all the Pubsub-related structures and definitions.
Definition pubsub.h:28
gloox::PubSub::EventType
EventType
Definition pubsub.h:82
gloox::PubSub::EventItems
@ EventItems
Definition pubsub.h:86
gloox::PubSub::EventCollection
@ EventCollection
Definition pubsub.h:83
gloox::PubSub::EventPurge
@ EventPurge
Definition pubsub.h:88
gloox::PubSub::EventDelete
@ EventDelete
Definition pubsub.h:85
gloox::PubSub::EventItemsRetract
@ EventItemsRetract
Definition pubsub.h:87
gloox::PubSub::EventUnknown
@ EventUnknown
Definition pubsub.h:90
gloox::PubSub::EventSubscription
@ EventSubscription
Definition pubsub.h:89
gloox::PubSub::EventConfigure
@ EventConfigure
Definition pubsub.h:84
gloox
The namespace for the gloox library.
Definition adhoc.cpp:28
gloox::TagList
std::list< Tag * > TagList
Definition tag.h:31
gloox::StringList
std::list< std::string > StringList
Definition gloox.h:1251
gloox::XMLNS_PUBSUB_EVENT
const std::string XMLNS_PUBSUB_EVENT
Definition gloox.cpp:79
gloox::XMLNS
const std::string XMLNS
Definition gloox.cpp:122
gloox::ExtPubSubEvent
@ ExtPubSubEvent
Definition stanzaextension.h:86
gloox::PubSub::Event::ItemOperation
Definition pubsubevent.h:42
gloox::PubSub::Event::ItemOperation::ItemOperation
ItemOperation(bool remove, const std::string &itemid, const Tag *pld=0)
Definition pubsubevent.h:51