disco.cpp

00001 /*
00002   Copyright (c) 2004-2006 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 )
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 }

Generated on Tue May 1 14:20:20 2007 for gloox by  doxygen 1.5.1