pubsubevent.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "pubsubevent.h"
00014 #include "tag.h"
00015 #include "util.h"
00016
00017 namespace gloox
00018 {
00019
00020 namespace PubSub
00021 {
00022
00023 static const char* eventTypeValues[] = {
00024 "collection",
00025 "configuration",
00026 "delete",
00027 "items",
00028 "items",
00029 "purge",
00030 "subscription"
00031 };
00032
00033 Event::ItemOperation::ItemOperation( const ItemOperation& right )
00034 : retract( right.retract ), item( right.item ),
00035 payload( right.payload ? right.payload->clone() : 0 )
00036 {
00037 }
00038
00039 Event::Event( const Tag* event )
00040 : StanzaExtension( ExtPubSubEvent ), m_type( PubSub::EventUnknown ),
00041 m_subscriptionIDs( 0 ), m_config( 0 ), m_itemOperations( 0 ), m_subscription( false )
00042 {
00043 if( !event || event->name() != "event" )
00044 return;
00045
00046 const TagList& events = event->children();
00047 TagList::const_iterator it = events.begin();
00048 const Tag* tag = 0;
00049 for( ; it != events.end(); ++it )
00050 {
00051 tag = (*it);
00052 PubSub::EventType type = (PubSub::EventType)util::lookup( tag->name(), eventTypeValues );
00053
00054 switch( type )
00055 {
00056 case PubSub::EventCollection:
00057 tag = tag->findChild( "node" );
00058 if( tag )
00059 {
00060 m_node = tag->findAttribute( "id" );
00061 if( ( m_config = tag->findChild( "x" ) ) )
00062 m_config = m_config->clone();
00063 }
00064 break;
00065
00066 case PubSub::EventConfigure:
00067 case PubSub::EventDelete:
00068 case PubSub::EventPurge:
00069 m_node = tag->findAttribute( "node" );
00070 if( type == PubSub::EventConfigure
00071 && ( m_config = tag->findChild( "x" ) ) )
00072 m_config = m_config->clone();
00073 break;
00074
00075 case PubSub::EventItems:
00076 case PubSub::EventItemsRetract:
00077 {
00078 if( !m_itemOperations )
00079 m_itemOperations = new ItemOperationList();
00080
00081 m_node = tag->findAttribute( "node" );
00082 const TagList& items = tag->children();
00083 TagList::const_iterator itt = items.begin();
00084 for( ; itt != items.end(); ++itt )
00085 {
00086 tag = (*itt);
00087 bool retract = false;
00088 if( tag->name() == "retract" )
00089 {
00090 retract = true;
00091 type = PubSub::EventItemsRetract;
00092 }
00093 ItemOperation* op = new ItemOperation( retract,
00094 tag->findAttribute( "id" ),
00095 tag->clone() );
00096 m_itemOperations->push_back( op );
00097 }
00098 break;
00099 }
00100
00101 case EventSubscription:
00102 {
00103 m_node = tag->findAttribute( "node" );
00104 m_jid.setJID( tag->findAttribute( "jid" ) );
00105 m_subscription = tag->hasAttribute( "subscription", "subscribed" );
00106 break;
00107 }
00108
00109 case PubSub::EventUnknown:
00110 if( type == PubSub::EventUnknown )
00111 {
00112 if( tag->name() != "headers" || m_subscriptionIDs != 0 )
00113 {
00114 m_valid = false;
00115 return;
00116 }
00117
00118 m_subscriptionIDs = new StringList();
00119
00120 const TagList& headers = tag->children();
00121 TagList::const_iterator ith = headers.begin();
00122 for( ; ith != headers.end(); ++ith )
00123 {
00124 const std::string& name = (*ith)->findAttribute( "name" );
00125 if( name == "pubsub#subid" )
00126 m_subscriptionIDs->push_back( (*ith)->cdata() );
00127 else if( name == "pubsub#collection" )
00128 m_collection = (*ith)->cdata();
00129 }
00130 }
00131
00132 default:
00133 continue;
00134 }
00135 m_type = type;
00136 }
00137
00138 m_valid = true;
00139 }
00140
00141 Event::Event( const std::string& node, PubSub::EventType type )
00142 : StanzaExtension( ExtPubSubEvent ), m_type( type ),
00143 m_node( node ), m_subscriptionIDs( 0 ), m_config( 0 ),
00144 m_itemOperations( 0 )
00145 {
00146 if( type != PubSub::EventUnknown )
00147 m_valid = true;
00148 }
00149
00150 Event::~Event()
00151 {
00152 delete m_subscriptionIDs;
00153 delete m_config;
00154 if( m_itemOperations )
00155 {
00156 ItemOperationList::iterator it = m_itemOperations->begin();
00157 for( ; it != m_itemOperations->end(); ++it )
00158 {
00159 delete (*it)->payload;
00160 delete (*it);
00161 }
00162 delete m_itemOperations;
00163 }
00164 }
00165
00166 void Event::addItem( ItemOperation* op )
00167 {
00168 if( !m_itemOperations )
00169 m_itemOperations = new ItemOperationList();
00170
00171 m_itemOperations->push_back( op );
00172 }
00173
00174 const std::string& Event::filterString() const
00175 {
00176 static const std::string filter = "/message/event[@xmlns='" + XMLNS_PUBSUB_EVENT + "']";
00177 return filter;
00178 }
00179
00180 Tag* Event::tag() const
00181 {
00182 if( !m_valid )
00183 return 0;
00184
00185 Tag* event = new Tag( "event", XMLNS, XMLNS_PUBSUB_EVENT );
00186 Tag* child = new Tag( event, util::lookup( m_type, eventTypeValues ) );
00187
00188 Tag* item = 0;
00189
00190 switch( m_type )
00191 {
00192 case PubSub::EventCollection:
00193 {
00194 item = new Tag( child, "node", "id", m_node );
00195 item->addChildCopy( m_config );
00196 break;
00197 }
00198
00199 case PubSub::EventPurge:
00200 case PubSub::EventDelete:
00201 case PubSub::EventConfigure:
00202 child->addAttribute( "node", m_node );
00203 if( m_type == PubSub::EventConfigure )
00204 child->addChildCopy( m_config );
00205 break;
00206
00207 case PubSub::EventItems:
00208 case PubSub::EventItemsRetract:
00209 {
00210 child->addAttribute( "node", m_node );
00211 if( m_itemOperations )
00212 {
00213
00214 ItemOperation* op;
00215 ItemOperationList::const_iterator itt = m_itemOperations->begin();
00216 for( ; itt != m_itemOperations->end(); ++itt )
00217 {
00218 op = (*itt);
00219
00220 if( op->payload )
00221 child->addChildCopy( op->payload );
00222 }
00223 }
00224 break;
00225 }
00226
00227 case EventSubscription:
00228 {
00229 child->addAttribute( "node", m_node );
00230 child->addAttribute( "jid", m_jid.full() );
00231 child->addAttribute( "subscription", m_subscription ? "subscribed" : "none" );
00232 break;
00233 }
00234
00235 default:
00236 delete event;
00237 return 0;
00238 }
00239
00240 if( m_subscriptionIDs || !m_collection.empty() )
00241 {
00242 Tag* headers = new Tag( event, "headers", XMLNS, "http://jabber.org/protocol/shim" );
00243 StringList::const_iterator it = m_subscriptionIDs->begin();
00244 for( ; it != m_subscriptionIDs->end(); ++it )
00245 {
00246 (new Tag( headers, "header", "name", "pubsub#subid" ))->setCData( (*it) );
00247 }
00248
00249 if( !m_collection.empty() )
00250 (new Tag( headers, "header", "name", "pubsub#collection" ) )
00251 ->setCData( m_collection );
00252 }
00253
00254 return event;
00255 }
00256
00257 StanzaExtension* Event::clone() const
00258 {
00259 Event* e = new Event( m_node, m_type );
00260 e->m_subscriptionIDs = m_subscriptionIDs ? new StringList( *m_subscriptionIDs ) : 0;
00261 e->m_config = m_config ? m_config->clone() : 0;
00262 if( m_itemOperations )
00263 {
00264 e->m_itemOperations = new ItemOperationList();
00265 ItemOperationList::const_iterator it = m_itemOperations->begin();
00266 for( ; it != m_itemOperations->end(); ++it )
00267 e->m_itemOperations->push_back( new ItemOperation( *(*it) ) );
00268 }
00269 else
00270 e->m_itemOperations = 0;
00271
00272 e->m_collection = m_collection;
00273 return e;
00274 }
00275
00276 }
00277
00278 }