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