disco.cpp

00001 /*
00002   Copyright (c) 2004-2007 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 
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 && stanza->hasChild( "query" ) )
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             query->addAttribute( "node", node );
00082             new Tag( query, "feature", "var", XMLNS_DISCO_INFO );
00083 
00084             DiscoNodeHandlerMap::const_iterator it = m_nodeHandlers.find( node );
00085             if( it != m_nodeHandlers.end() )
00086             {
00087               std::string name;
00088               DiscoNodeHandlerList::const_iterator in = (*it).second.begin();
00089               for( ; in != (*it).second.end(); ++in )
00090               {
00091                 const StringMap& identities = (*in)->handleDiscoNodeIdentities( node, name );
00092                 StringMap::const_iterator im = identities.begin();
00093                 for( ; im != identities.end(); ++im )
00094                 {
00095                   Tag *i = new Tag( query, "identity" );
00096                   i->addAttribute( "category", (*im).first );
00097                   i->addAttribute( "type", (*im).second );
00098                   i->addAttribute( "name", name );
00099                 }
00100                 const StringList& features = (*in)->handleDiscoNodeFeatures( node );
00101                 StringList::const_iterator fi = features.begin();
00102                 for( ; fi != features.end(); ++fi )
00103                 {
00104                   Tag *f = new Tag( query, "feature" );
00105                   f->addAttribute( "var", (*fi) );
00106                 }
00107               }
00108             }
00109           }
00110           else
00111           {
00112             Tag *i = new Tag( query, "identity" );
00113             i->addAttribute( "category", m_identityCategory );
00114             i->addAttribute( "type", m_identityType );
00115             i->addAttribute( "name", m_versionName );
00116 
00117             StringList::const_iterator it = m_features.begin();
00118             for( ; it != m_features.end(); ++it )
00119             {
00120               Tag *f = new Tag( query, "feature" );
00121               f->addAttribute( "var", (*it) );
00122             }
00123           }
00124 
00125           m_parent->send( iq );
00126         }
00127         else if( stanza->xmlns() == XMLNS_DISCO_ITEMS && stanza->hasChild( "query" ) )
00128         {
00129           Tag *iq = new Tag( "iq" );
00130           iq->addAttribute( "id", stanza->id() );
00131           iq->addAttribute( "to", stanza->from().full() );
00132           iq->addAttribute( "from", m_parent->jid().full() );
00133           iq->addAttribute( "type", "result" );
00134           Tag *query = new Tag( iq, "query" );
00135           query->addAttribute( "xmlns", XMLNS_DISCO_ITEMS );
00136 
00137           DiscoNodeHandlerMap::const_iterator it;
00138           Tag *q = stanza->findChild( "query" );
00139           const std::string& node = q->findAttribute( "node" );
00140           query->addAttribute( "node", node );
00141           it = m_nodeHandlers.find( node );
00142           if( it != m_nodeHandlers.end() )
00143           {
00144             DiscoNodeHandlerList::const_iterator in = (*it).second.begin();
00145             for( ; in != (*it).second.end(); ++in )
00146             {
00147               const DiscoNodeItemList& items = (*in)->handleDiscoNodeItems( node );
00148               DiscoNodeItemList::const_iterator it = items.begin();
00149               for( ; it != items.end(); ++it )
00150               {
00151                 Tag *i = new Tag( query, "item" );
00152                 i->addAttribute( "jid",  (*it).jid.empty() ? m_parent->jid().full() : (*it).jid );
00153                 i->addAttribute( "node", (*it).node );
00154                 i->addAttribute( "name", (*it).name );
00155               }
00156             }
00157           }
00158 
00159           m_parent->send( iq );
00160         }
00161         return true;
00162         break;
00163 
00164       case StanzaIqSet:
00165       {
00166         bool res = false;
00167         DiscoHandlerList::const_iterator it = m_discoHandlers.begin();
00168         for( ; it != m_discoHandlers.end(); ++it )
00169         {
00170           if( (*it)->handleDiscoSet( stanza ) )
00171             res = true;
00172         }
00173         return res;
00174         break;
00175       }
00176 
00177       default:
00178         break;
00179     }
00180     return false;
00181   }
00182 
00183   bool Disco::handleIqID( Stanza *stanza, int context )
00184   {
00185     DiscoHandlerMap::iterator it = m_track.find( stanza->id() );
00186     if( it != m_track.end() )
00187     {
00188       switch( stanza->subtype() )
00189       {
00190         case StanzaIqResult:
00191           switch( context )
00192           {
00193             case GET_DISCO_INFO:
00194               (*it).second.dh->handleDiscoInfoResult( stanza, (*it).second.context );
00195               break;
00196             case GET_DISCO_ITEMS:
00197               (*it).second.dh->handleDiscoItemsResult( stanza, (*it).second.context );
00198               break;
00199            }
00200         break;
00201 
00202         case StanzaIqError:
00203           (*it).second.dh->handleDiscoError( stanza, (*it).second.context );
00204           break;
00205 
00206         default:
00207           break;
00208       }
00209 
00210       m_track.erase( it );
00211     }
00212 
00213     return false;
00214   }
00215 
00216   void Disco::addFeature( const std::string& feature )
00217   {
00218     m_features.push_back( feature );
00219   }
00220 
00221   void Disco::removeFeature( const std::string& feature )
00222   {
00223     m_features.remove( feature );
00224   }
00225 
00226   void Disco::getDiscoInfo( const JID& to, const std::string& node, DiscoHandler *dh, int context,
00227                             const std::string& tid )
00228   {
00229     const std::string& id = tid.empty() ? m_parent->getID() : tid;
00230 
00231     Tag *iq = new Tag( "iq" );
00232     iq->addAttribute( "id", id );
00233     iq->addAttribute( "to", to.full() );
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 JID& to, const std::string& node, DiscoHandler *dh, int context,
00250                              const std::string& tid )
00251   {
00252     const std::string& id = tid.empty() ? m_parent->getID() : tid;
00253 
00254     Tag *iq = new Tag( "iq" );
00255     iq->addAttribute( "id", id );
00256     iq->addAttribute( "to", to.full() );
00257     iq->addAttribute( "from", m_parent->jid().full() );
00258     iq->addAttribute( "type", "get" );
00259     Tag *q = new Tag( iq, "query" );
00260     q->addAttribute( "xmlns", XMLNS_DISCO_ITEMS );
00261     if( !node.empty() )
00262       q->addAttribute( "node", node );
00263 
00264     DiscoHandlerContext ct;
00265     ct.dh = dh;
00266     ct.context = context;
00267     m_track[id] = ct;
00268     m_parent->trackID( this, id, GET_DISCO_ITEMS );
00269     m_parent->send( iq );
00270   }
00271 
00272   void Disco::setVersion( const std::string& name, const std::string& version, const std::string& os )
00273   {
00274     m_versionName = name;
00275     m_versionVersion = version;
00276     m_versionOs = os;
00277   }
00278 
00279   void Disco::setIdentity( const std::string& category, const std::string& type )
00280   {
00281     m_identityCategory = category;
00282     m_identityType = type;
00283   }
00284 
00285   void Disco::registerDiscoHandler( DiscoHandler *dh )
00286   {
00287     m_discoHandlers.push_back( dh );
00288   }
00289 
00290   void Disco::removeDiscoHandler( DiscoHandler *dh )
00291   {
00292     m_discoHandlers.remove( dh );
00293   }
00294 
00295   void Disco::registerNodeHandler( DiscoNodeHandler *nh, const std::string& node )
00296   {
00297     m_nodeHandlers[node].push_back( nh );
00298   }
00299 
00300   void Disco::removeNodeHandler( DiscoNodeHandler *nh, const std::string& node )
00301   {
00302     DiscoNodeHandlerMap::iterator it = m_nodeHandlers.find( node );
00303     if( it != m_nodeHandlers.end() )
00304     {
00305       (*it).second.remove( nh );
00306       if( !(*it).second.size() )
00307       {
00308         m_nodeHandlers.erase( it );
00309       }
00310     }
00311   }
00312 
00313 }

Generated on Sat Nov 10 08:50:27 2007 for gloox by  doxygen 1.5.3-20071008