disco.cpp

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

Generated on Mon Dec 7 13:28:19 2009 for gloox by  doxygen 1.6.1