gloox
1.0
|
00001 /* 00002 Copyright (c) 2007-2009 by Jakob Schroeter <js@camaya.net> 00003 This file is part of the gloox library. http://camaya.net/gloox 00004 00005 This software is distributed under a license. The full license 00006 agreement can be found in the file LICENSE in this distribution. 00007 This software may not be copied, modified, sold or distributed 00008 other than expressed in the named license agreement. 00009 00010 This software is distributed without any warranty. 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 // Tag* item; 00214 ItemOperation* op; 00215 ItemOperationList::const_iterator itt = m_itemOperations->begin(); 00216 for( ; itt != m_itemOperations->end(); ++itt ) 00217 { 00218 op = (*itt); 00219 // item = new Tag( child, op->retract ? "retract" : "item", "id", op->item ); 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 }