00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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 }