search.cpp

00001 /*
00002   Copyright (c) 2006-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 
00015 #include "search.h"
00016 
00017 #include "clientbase.h"
00018 #include "stanza.h"
00019 
00020 namespace gloox
00021 {
00022 
00023   Search::Search( ClientBase *parent )
00024     : m_parent( parent )
00025   {
00026   }
00027 
00028   Search::~Search()
00029   {
00030     m_parent->removeIDHandler( this );
00031   }
00032 
00033   void Search::fetchSearchFields( const JID& directory, SearchHandler *sh )
00034   {
00035     if( !m_parent || !directory || !sh )
00036       return;
00037 
00038     const std::string& id = m_parent->getID();
00039 
00040     Tag *iq = new Tag( "iq" );
00041     iq->addAttribute( "type", "get" );
00042     iq->addAttribute( "id", id );
00043     iq->addAttribute( "to", directory.full() );
00044     Tag *q = new Tag( iq, "query" );
00045     q->addAttribute( "xmlns", XMLNS_SEARCH );
00046 
00047     m_track[id] = sh;
00048     m_parent->trackID( this, id, FetchSearchFields );
00049     m_parent->send( iq );
00050   }
00051 
00052   void Search::search( const JID& directory, const DataForm& form, SearchHandler *sh )
00053   {
00054     if( !m_parent || !directory || !sh )
00055       return;
00056 
00057     const std::string& id = m_parent->getID();
00058 
00059     Tag *iq = new Tag( "iq" );
00060     iq->addAttribute( "id", id );
00061     iq->addAttribute( "type", "set" );
00062     iq->addAttribute( "to", directory.full() );
00063     Tag *q = new Tag( iq, "query" );
00064     q->addAttribute( "xmlns", XMLNS_SEARCH );
00065     q->addChild( form.tag() );
00066 
00067     m_track[id] = sh;
00068     m_parent->trackID( this, id, DoSearch );
00069     m_parent->send( iq );
00070   }
00071 
00072   void Search::search( const JID& directory, int fields, const SearchFieldStruct& values, SearchHandler *sh )
00073   {
00074     if( !m_parent || !directory || !sh )
00075       return;
00076 
00077     const std::string& id = m_parent->getID();
00078 
00079     Tag *iq = new Tag( "iq" );
00080     iq->addAttribute( "id", id );
00081     iq->addAttribute( "type", "set" );
00082     iq->addAttribute( "to", directory.full() );
00083     Tag *q = new Tag( iq, "query" );
00084     q->addAttribute( "xmlns", XMLNS_SEARCH );
00085 
00086     if( fields & SearchFieldFirst )
00087       new Tag( q, "first", values.first );
00088     if( fields & SearchFieldLast )
00089       new Tag( q, "last", values.last );
00090     if( fields & SearchFieldNick )
00091       new Tag( q, "nick", values.nick );
00092     if( fields & SearchFieldEmail )
00093       new Tag( q, "email", values.email );
00094 
00095     m_track[id] = sh;
00096     m_parent->trackID( this, id, DoSearch );
00097     m_parent->send( iq );
00098   }
00099 
00100   bool Search::handleIqID( Stanza *stanza, int context )
00101   {
00102     TrackMap::iterator it = m_track.find( stanza->id() );
00103     if( it != m_track.end() )
00104     {
00105       switch( stanza->subtype() )
00106       {
00107         case StanzaIqResult:
00108           switch( context )
00109           {
00110             case FetchSearchFields:
00111             {
00112               Tag *q = stanza->findChild( "query" );
00113               if( q && q->hasAttribute( "xmlns", XMLNS_SEARCH ) )
00114               {
00115                 Tag *x = q->findChild( "x", "xmlns", XMLNS_X_DATA );
00116                 if( x )
00117                 {
00118                   DataForm *df = new DataForm( x );
00119                   (*it).second->handleSearchFields( stanza->from(), df );
00120                 }
00121                 else
00122                 {
00123                   int fields = 0;
00124                   std::string instructions;
00125 
00126                   if( q->hasChild( "first" ) )
00127                     fields |= SearchFieldFirst;
00128                   if( q->hasChild( "last" ) )
00129                     fields |= SearchFieldLast;
00130                   if( q->hasChild( "nick" ) )
00131                     fields |= SearchFieldNick;
00132                   if( q->hasChild( "email" ) )
00133                     fields |= SearchFieldEmail;
00134                   if( q->hasChild( "instructions" ) )
00135                     instructions = q->findChild( "instructions" )->cdata();
00136 
00137                   (*it).second->handleSearchFields( stanza->from(), fields, instructions );
00138                 }
00139               }
00140               break;
00141             }
00142             case DoSearch:
00143             {
00144               Tag *q = stanza->findChild( "query" );
00145               if( q && q->hasAttribute( "xmlns", XMLNS_SEARCH ) )
00146               {
00147                 Tag *x = q->findChild( "x", "xmlns", XMLNS_X_DATA );
00148                 if( x )
00149                 {
00150                   DataForm *df = new DataForm( x );
00151                   (*it).second->handleSearchResult( stanza->from(), df );
00152                 }
00153                 else
00154                 {
00155                   SearchResultList e;
00156                   SearchFieldStruct s;
00157                   const Tag::TagList &l = q->children();
00158                   Tag::TagList::const_iterator itl = l.begin();
00159                   for( ; itl != l.end(); ++itl )
00160                   {
00161                     if( (*itl)->name() == "item" )
00162                     {
00163                       s.jid.setJID( (*itl)->findAttribute( "jid" ) );
00164                       Tag *t = 0;
00165                       if( ( t = (*itl)->findChild( "first" ) ) != 0 )
00166                         s.first = t->cdata();
00167                       if( ( t = (*itl)->findChild( "last" ) ) != 0 )
00168                         s.last = t->cdata();
00169                       if( ( t = (*itl)->findChild( "nick" ) ) != 0 )
00170                         s.nick = t->cdata();
00171                       if( ( t = (*itl)->findChild( "email" ) ) != 0 )
00172                         s.email = t->cdata();
00173                       e.push_back( s );
00174                     }
00175                   }
00176 
00177                   (*it).second->handleSearchResult( stanza->from(), e );
00178                 }
00179               }
00180               break;
00181             }
00182           }
00183           break;
00184         case StanzaIqError:
00185           (*it).second->handleSearchError( stanza->from(), stanza );
00186           break;
00187 
00188         default:
00189           break;
00190       }
00191 
00192       m_track.erase( it );
00193     }
00194 
00195     return false;
00196   }
00197 
00198 }

Generated on Sun Apr 27 11:08:13 2008 for gloox by  doxygen 1.5.5