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 };
00031
00032 Event::Event( const Tag* event )
00033 : StanzaExtension( ExtPubSubEvent ), m_type( PubSub::EventUnknown ),
00034 m_subscriptionIDs( 0 ), m_config( 0 ), m_itemOperations( 0 )
00035 {
00036 if( !event || event->name() != "event" )
00037 return;
00038
00039 const TagList& events = event->children();
00040 TagList::const_iterator it = events.begin();
00041 const Tag* tag = 0;
00042 for( ; it != events.end(); ++it )
00043 {
00044 tag = (*it);
00045 PubSub::EventType type = (PubSub::EventType)util::lookup( tag->name(), eventTypeValues );
00046
00047 switch( type )
00048 {
00049 case PubSub::EventCollection:
00050 tag = tag->findChild( "node" );
00051 if( tag )
00052 {
00053 m_node = tag->findAttribute( "id" );
00054 if( ( m_config = tag->findChild( "x" ) ) )
00055 m_config = m_config->clone();
00056 }
00057 break;
00058
00059 case PubSub::EventConfigure:
00060 case PubSub::EventDelete:
00061 case PubSub::EventPurge:
00062 m_node = tag->findAttribute( "node" );
00063 if( type == PubSub::EventConfigure
00064 && ( m_config = tag->findChild( "x" ) ) )
00065 m_config = m_config->clone();
00066 break;
00067
00068 case PubSub::EventItems:
00069 case PubSub::EventItemsRetract:
00070 {
00071 if( !m_itemOperations )
00072 m_itemOperations = new ItemOperationList();
00073
00074 m_node = tag->findAttribute( "node" );
00075 const TagList& items = tag->children();
00076 TagList::const_iterator itt = items.begin();
00077 for( ; itt != items.end(); ++itt )
00078 {
00079 tag = (*itt);
00080
00081 const Tag* x = tag->findChild( "entry" );
00082 ItemOperation* op = new ItemOperation( tag->name() == "retract",
00083 tag->findAttribute( "id" ),
00084 x ? x->clone() : 0 );
00085 m_itemOperations->push_back( op );
00086 }
00087 break;
00088 }
00089
00090 case PubSub::EventUnknown:
00091 if( type == PubSub::EventUnknown )
00092 {
00093 if( tag->name() != "headers" || m_subscriptionIDs != 0 )
00094 {
00095 m_valid = false;
00096 return;
00097 }
00098
00099 m_subscriptionIDs = new StringList();
00100
00101 const TagList& headers = tag->children();
00102 TagList::const_iterator ith = headers.begin();
00103 for( ; ith != headers.end(); ++ith )
00104 {
00105 const std::string& name = (*ith)->findAttribute( "name" );
00106 if( name == "pubsub#subid" )
00107 m_subscriptionIDs->push_back( (*ith)->cdata() );
00108 else if( name == "pubsub#collection" )
00109 m_collection = (*ith)->cdata();
00110 }
00111 }
00112
00113 default:
00114 continue;
00115 }
00116 m_type = type;
00117 }
00118
00119 m_valid = true;
00120 }
00121
00122 Event::~Event()
00123 {
00124 delete m_subscriptionIDs;
00125 delete m_config;
00126 if( m_itemOperations )
00127 {
00128 ItemOperationList::iterator it = m_itemOperations->begin();
00129 for( ; it != m_itemOperations->end(); ++it )
00130 {
00131 delete (*it)->payload;
00132 delete (*it);
00133 }
00134 delete m_itemOperations;
00135 }
00136 }
00137
00138 const std::string& Event::filterString() const
00139 {
00140 static const std::string filter = "/message/event[@xmlns='" + XMLNS_PUBSUB_EVENT + "']";
00141 return filter;
00142 }
00143
00144 Tag* Event::tag() const
00145 {
00146 if( !m_valid )
00147 return 0;
00148
00149 Tag* event = new Tag( "event", XMLNS, XMLNS_PUBSUB_EVENT );
00150 Tag* child = new Tag( event , util::lookup( m_type, eventTypeValues ) );
00151
00152 Tag* item = 0;
00153
00154 switch( m_type )
00155 {
00156 case PubSub::EventCollection:
00157 {
00158 item = new Tag( child, "node", "id", m_node );
00159 item->addChildCopy( m_config );
00160 break;
00161 }
00162
00163 case PubSub::EventPurge:
00164 case PubSub::EventDelete:
00165 case PubSub::EventConfigure:
00166 child->addAttribute( "node", m_node );
00167 if( m_type == PubSub::EventConfigure )
00168 child->addChildCopy( m_config );
00169 break;
00170
00171 case PubSub::EventItems:
00172 case PubSub::EventItemsRetract:
00173 {
00174 child->addAttribute( "node", m_node );
00175 if( m_itemOperations )
00176 {
00177 Tag* item;
00178 ItemOperation* op;
00179 ItemOperationList::const_iterator itt = m_itemOperations->begin();
00180 for( ; itt != m_itemOperations->end(); ++itt )
00181 {
00182 op = (*itt);
00183 item = new Tag( child, op->retract ? "retract" : "item", "id", op->item );
00184 if( op->payload )
00185 item->addChildCopy( op->payload );
00186 }
00187 }
00188 break;
00189 }
00190
00191 default:
00192 delete event;
00193 return 0;
00194 }
00195
00196 if( m_subscriptionIDs || !m_collection.empty() )
00197 {
00198 Tag* headers = new Tag( event, "headers", XMLNS, "http://jabber.org/protocol/shim" );
00199 StringList::const_iterator it = m_subscriptionIDs->begin();
00200 for( ; it != m_subscriptionIDs->end(); ++it )
00201 {
00202 (new Tag( headers, "header", "name", "pubsub#subid" ))->setCData( (*it) );
00203 }
00204
00205 if( !m_collection.empty() )
00206 (new Tag( headers, "header", "name", "pubsub#collection" ) )
00207 ->setCData( m_collection );
00208 }
00209
00210 return event;
00211 }
00212
00213 }
00214
00215 }