00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "disco.h"
00015 #include "discohandler.h"
00016 #include "clientbase.h"
00017 #include "disconodehandler.h"
00018
00019
00020 namespace gloox
00021 {
00022
00023 Disco::Disco( ClientBase *parent )
00024 : m_parent( parent )
00025 {
00026 addFeature( XMLNS_VERSION );
00027 addFeature( XMLNS_DISCO_INFO );
00028 addFeature( XMLNS_DISCO_ITEMS );
00029 if( m_parent )
00030 {
00031 m_parent->registerIqHandler( this, XMLNS_DISCO_INFO );
00032 m_parent->registerIqHandler( this, XMLNS_DISCO_ITEMS );
00033 m_parent->registerIqHandler( this, XMLNS_VERSION );
00034 }
00035 }
00036
00037 Disco::~Disco()
00038 {
00039 if( m_parent )
00040 {
00041 m_parent->removeIqHandler( XMLNS_DISCO_INFO );
00042 m_parent->removeIqHandler( XMLNS_DISCO_ITEMS );
00043 m_parent->removeIqHandler( XMLNS_VERSION );
00044 }
00045 }
00046
00047 bool Disco::handleIq( Stanza *stanza )
00048 {
00049 switch( stanza->subtype() )
00050 {
00051 case StanzaIqGet:
00052 if( stanza->xmlns() == XMLNS_VERSION )
00053 {
00054 Tag *iq = new Tag( "iq" );
00055 iq->addAttribute( "id", stanza->id() );
00056 iq->addAttribute( "from", m_parent->jid().full() );
00057 iq->addAttribute( "to", stanza->from().full() );
00058 iq->addAttribute( "type", "result" );
00059 Tag *query = new Tag( iq, "query" );
00060 query->addAttribute( "xmlns", XMLNS_VERSION );
00061 new Tag( query, "name", m_versionName );
00062 new Tag( query, "version", m_versionVersion );
00063 new Tag( query, "os", m_versionOs );
00064
00065 m_parent->send( iq );
00066 }
00067 else if( stanza->xmlns() == XMLNS_DISCO_INFO )
00068 {
00069 Tag *iq = new Tag( "iq" );
00070 iq->addAttribute( "id", stanza->id() );
00071 iq->addAttribute( "from", m_parent->jid().full() );
00072 iq->addAttribute( "to", stanza->from().full() );
00073 iq->addAttribute( "type", "result" );
00074 Tag *query = new Tag( iq, "query" );
00075 query->addAttribute( "xmlns", XMLNS_DISCO_INFO );
00076
00077 Tag *q = stanza->findChild( "query" );
00078 const std::string node = q->findAttribute( "node" );
00079 if( !node.empty() )
00080 {
00081 DiscoNodeHandlerMap::const_iterator it = m_nodeHandlers.find( node );
00082 if( it != m_nodeHandlers.end() )
00083 {
00084 std::string name;
00085 StringMap identities =
00086 (*it).second->handleDiscoNodeIdentities( node, name );
00087 StringMap::const_iterator im = identities.begin();
00088 for( ; im != identities.end(); ++im )
00089 {
00090 Tag *i = new Tag( query, "identity" );
00091 i->addAttribute( "category", (*im).first );
00092 i->addAttribute( "type", (*im).second );
00093 i->addAttribute( "name", name );
00094 }
00095 StringList features = (*it).second->handleDiscoNodeFeatures( node );
00096 StringList::const_iterator fi = features.begin();
00097 for( ; fi != features.end(); ++fi )
00098 {
00099 Tag *f = new Tag( query, "feature" );
00100 f->addAttribute( "var", (*fi) );
00101 }
00102 }
00103 }
00104 else
00105 {
00106 Tag *i = new Tag( query, "identity" );
00107 i->addAttribute( "category", m_identityCategory );
00108 i->addAttribute( "type", m_identityType );
00109 i->addAttribute( "name", m_versionName );
00110
00111 StringList::const_iterator it = m_features.begin();
00112 for( ; it != m_features.end(); ++it )
00113 {
00114 Tag *f = new Tag( query, "feature" );
00115 f->addAttribute( "var", (*it).c_str() );
00116 }
00117 }
00118
00119 m_parent->send( iq );
00120 }
00121 else if( stanza->xmlns() == XMLNS_DISCO_ITEMS )
00122 {
00123 Tag *iq = new Tag( "iq" );
00124 iq->addAttribute( "id", stanza->id() );
00125 iq->addAttribute( "to", stanza->from().full() );
00126 iq->addAttribute( "from", m_parent->jid().full() );
00127 iq->addAttribute( "type", "result" );
00128 Tag *query = new Tag( iq, "query" );
00129 query->addAttribute( "xmlns", XMLNS_DISCO_ITEMS );
00130
00131 StringMap items;
00132 DiscoNodeHandlerMap::const_iterator it;
00133 Tag *q = stanza->findChild( "query" );
00134 const std::string node = q->findAttribute( "node" );
00135 if( !node.empty() )
00136 {
00137 it = m_nodeHandlers.find( node );
00138 if( it != m_nodeHandlers.end() )
00139 {
00140 items = (*it).second->handleDiscoNodeItems( node );
00141 }
00142 }
00143 else
00144 {
00145 it = m_nodeHandlers.begin();
00146 for( ; it != m_nodeHandlers.end(); ++it )
00147 {
00148 items = (*it).second->handleDiscoNodeItems( "" );
00149 }
00150 }
00151
00152 if( items.size() )
00153 {
00154 StringMap::const_iterator it = items.begin();
00155 for( ; it != items.end(); ++it )
00156 {
00157 if( !(*it).first.empty() && !(*it).second.empty() )
00158 {
00159 Tag *i = new Tag( query, "item" );
00160 i->addAttribute( "jid", m_parent->jid().full() );
00161 i->addAttribute( "node", (*it).first );
00162 i->addAttribute( "name", (*it).second );
00163 }
00164 }
00165 }
00166
00167 m_parent->send( iq );
00168 }
00169 return true;
00170 break;
00171
00172 case StanzaIqSet:
00173 {
00174 bool res = false;
00175 DiscoHandlerList::const_iterator it = m_discoHandlers.begin();
00176 for( ; it != m_discoHandlers.end(); ++it )
00177 {
00178 if( (*it)->handleDiscoSet( stanza ) )
00179 res = true;
00180 }
00181 return res;
00182 break;
00183 }
00184
00185 default:
00186 break;
00187 }
00188 return false;
00189 }
00190
00191 bool Disco::handleIqID( Stanza *stanza, int context )
00192 {
00193 DiscoHandlerMap::const_iterator it = m_track.find( stanza->id() );
00194 if( it != m_track.end() )
00195 {
00196 switch( stanza->subtype() )
00197 {
00198 case StanzaIqResult:
00199 switch( context )
00200 {
00201 case GET_DISCO_INFO:
00202 (*it).second.dh->handleDiscoInfoResult( stanza, (*it).second.context );
00203 break;
00204 case GET_DISCO_ITEMS:
00205 (*it).second.dh->handleDiscoItemsResult( stanza, (*it).second.context );
00206 break;
00207 }
00208 break;
00209
00210 case StanzaIqError:
00211 (*it).second.dh->handleDiscoError( stanza, (*it).second.context );
00212 break;
00213
00214 default:
00215 break;
00216 }
00217 }
00218
00219 return false;
00220 }
00221
00222 void Disco::addFeature( const std::string& feature )
00223 {
00224 m_features.push_back( feature );
00225 }
00226
00227 void Disco::getDiscoInfo( const std::string& to, const std::string& node, DiscoHandler *dh, int context )
00228 {
00229 std::string id = m_parent->getID();
00230
00231 Tag *iq = new Tag( "iq" );
00232 iq->addAttribute( "id", id );
00233 iq->addAttribute( "to", to );
00234 iq->addAttribute( "from", m_parent->jid().full() );
00235 iq->addAttribute( "type", "get" );
00236 Tag *q = new Tag( iq, "query" );
00237 q->addAttribute( "xmlns", XMLNS_DISCO_INFO );
00238 if( !node.empty() )
00239 q->addAttribute( "node", node );
00240
00241 DiscoHandlerContext ct;
00242 ct.dh = dh;
00243 ct.context = context;
00244 m_track[id] = ct;
00245 m_parent->trackID( this, id, GET_DISCO_INFO );
00246 m_parent->send( iq );
00247 }
00248
00249 void Disco::getDiscoItems( const std::string& to, const std::string& node, DiscoHandler *dh, int context )
00250 {
00251 std::string id = m_parent->getID();
00252
00253 Tag *iq = new Tag( "iq" );
00254 iq->addAttribute( "id", id );
00255 iq->addAttribute( "to", to );
00256 iq->addAttribute( "from", m_parent->jid().full() );
00257 iq->addAttribute( "type", "get" );
00258 Tag *q = new Tag( iq, "query" );
00259 q->addAttribute( "xmlns", XMLNS_DISCO_ITEMS );
00260 if( !node.empty() )
00261 q->addAttribute( "node", node );
00262
00263 DiscoHandlerContext ct;
00264 ct.dh = dh;
00265 ct.context = context;
00266 m_track[id] = ct;
00267 m_parent->trackID( this, id, GET_DISCO_ITEMS );
00268 m_parent->send( iq );
00269 }
00270
00271 void Disco::setVersion( const std::string& name, const std::string& version, const std::string& os )
00272 {
00273 m_versionName = name;
00274 m_versionVersion = version;
00275 m_versionOs = os;
00276 }
00277
00278 void Disco::setIdentity( const std::string& category, const std::string& type )
00279 {
00280 m_identityCategory = category;
00281 m_identityType = type;
00282 }
00283
00284 void Disco::registerDiscoHandler( DiscoHandler *dh )
00285 {
00286 m_discoHandlers.push_back( dh );
00287 }
00288
00289 void Disco::removeDiscoHandler( DiscoHandler *dh )
00290 {
00291 m_discoHandlers.remove( dh );
00292 }
00293
00294 void Disco::registerNodeHandler( DiscoNodeHandler *nh, const std::string& node )
00295 {
00296 m_nodeHandlers[node] = nh;
00297 }
00298
00299 void Disco::removeNodeHandler( const std::string& node )
00300 {
00301 m_nodeHandlers.erase( node );
00302 }
00303
00304 }