search.cpp
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 "dataform.h"
00019 #include "iq.h"
00020
00021 namespace gloox
00022 {
00023
00024
00025 Search::Query::Query( DataForm* form )
00026 : StanzaExtension( ExtSearch ), m_form( form ), m_fields( 0 )
00027 {
00028 }
00029
00030 Search::Query::Query( int fields, const SearchFieldStruct& values )
00031 : StanzaExtension( ExtSearch ), m_form( 0 ), m_fields( fields ), m_values( values )
00032 {
00033 }
00034
00035 Search::Query::Query( const Tag* tag )
00036 : StanzaExtension( ExtSearch ), m_form( 0 ), m_fields( 0 )
00037 {
00038 if( !tag || tag->name() != "query" || tag->xmlns() != XMLNS_SEARCH )
00039 return;
00040
00041 const TagList& l = tag->children();
00042 TagList::const_iterator it = l.begin();
00043 for( ; it != l.end(); ++it )
00044 {
00045 if( (*it)->name() == "instructions" )
00046 {
00047 m_instructions = (*it)->cdata();
00048 }
00049 else if( (*it)->name() == "item" )
00050 {
00051 m_srl.push_back( new SearchFieldStruct( (*it) ) );
00052 }
00053 else if( (*it)->name() == "first" )
00054 m_fields |= SearchFieldFirst;
00055 else if( (*it)->name() == "last" )
00056 m_fields |= SearchFieldLast;
00057 else if( (*it)->name() == "email" )
00058 m_fields |= SearchFieldEmail;
00059 else if( (*it)->name() == "nick" )
00060 m_fields |= SearchFieldNick;
00061 else if( !m_form && (*it)->name() == "x" && (*it)->xmlns() == XMLNS_X_DATA )
00062 m_form = new DataForm( (*it) );
00063 }
00064 }
00065
00066 Search::Query::~Query()
00067 {
00068 delete m_form;
00069 SearchResultList::iterator it = m_srl.begin();
00070 for( ; it != m_srl.end(); ++it )
00071 delete (*it);
00072 }
00073
00074 const std::string& Search::Query::filterString() const
00075 {
00076 static const std::string filter = "/iq/query[@xmlns='" + XMLNS_SEARCH + "']";
00077 return filter;
00078 }
00079
00080 Tag* Search::Query::tag() const
00081 {
00082 Tag* t = new Tag( "query" );
00083 t->setXmlns( XMLNS_SEARCH );
00084 if( m_form )
00085 t->addChild( m_form->tag() );
00086 else if( m_fields )
00087 {
00088 if( !m_instructions.empty() )
00089 new Tag( t, "instructions", m_instructions );
00090 if( m_fields & SearchFieldFirst )
00091 new Tag( t, "first", m_values.first() );
00092 if( m_fields & SearchFieldLast )
00093 new Tag( t, "last", m_values.last() );
00094 if( m_fields & SearchFieldNick )
00095 new Tag( t, "nick", m_values.nick() );
00096 if( m_fields & SearchFieldEmail )
00097 new Tag( t, "email", m_values.email() );
00098 }
00099 else if( !m_srl.empty() )
00100 {
00101 SearchResultList::const_iterator it = m_srl.begin();
00102 for( ; it != m_srl.end(); ++it )
00103 {
00104 t->addChild( (*it)->tag() );
00105 }
00106 }
00107 return t;
00108 }
00109
00110
00111
00112 Search::Search( ClientBase* parent )
00113 : m_parent( parent )
00114 {
00115 if( m_parent )
00116 m_parent->registerStanzaExtension( new Query() );
00117 }
00118
00119 Search::~Search()
00120 {
00121 if( m_parent )
00122 {
00123 m_parent->removeIDHandler( this );
00124 m_parent->removeStanzaExtension( ExtRoster );
00125 }
00126 }
00127
00128 void Search::fetchSearchFields( const JID& directory, SearchHandler* sh )
00129 {
00130 if( !m_parent || !directory || !sh )
00131 return;
00132
00133 const std::string& id = m_parent->getID();
00134 IQ iq( IQ::Get, directory, id );
00135 iq.addExtension( new Query() );
00136 m_track[id] = sh;
00137 m_parent->send( iq, this, FetchSearchFields );
00138 }
00139
00140 void Search::search( const JID& directory, DataForm* form, SearchHandler* sh )
00141 {
00142 if( !m_parent || !directory || !sh )
00143 return;
00144
00145 const std::string& id = m_parent->getID();
00146 IQ iq( IQ::Set, directory, id );
00147 iq.addExtension( new Query( form ) );
00148
00149 m_track[id] = sh;
00150 m_parent->send( iq, this, DoSearch );
00151 }
00152
00153 void Search::search( const JID& directory, int fields, const SearchFieldStruct& values, SearchHandler* sh )
00154 {
00155 if( !m_parent || !directory || !sh )
00156 return;
00157
00158 const std::string& id = m_parent->getID();
00159
00160 IQ iq( IQ::Set, directory );
00161 iq.addExtension( new Query( fields, values ) );
00162
00163 m_track[id] = sh;
00164 m_parent->send( iq, this, DoSearch );
00165 }
00166
00167 void Search::handleIqID( const IQ& iq, int context )
00168 {
00169 TrackMap::iterator it = m_track.find( iq.id() );
00170 if( it != m_track.end() )
00171 {
00172 switch( iq.subtype() )
00173 {
00174 case IQ::Result:
00175 {
00176 const Query* q = iq.findExtension<Query>( ExtSearch );
00177 if( !q )
00178 return;
00179
00180 switch( context )
00181 {
00182 case FetchSearchFields:
00183 {
00184 if( q->form() )
00185 {
00186 (*it).second->handleSearchFields( iq.from(), q->form() );
00187 }
00188 else
00189 {
00190 (*it).second->handleSearchFields( iq.from(), q->fields(), q->instructions() );
00191 }
00192 break;
00193 }
00194 case DoSearch:
00195 {
00196 if( q->form() )
00197 {
00198 (*it).second->handleSearchResult( iq.from(), q->form() );
00199 }
00200 else
00201 {
00202 (*it).second->handleSearchResult( iq.from(), q->result() );
00203 }
00204 break;
00205 }
00206 }
00207 break;
00208 }
00209 case IQ::Error:
00210 (*it).second->handleSearchError( iq.from(), iq.error() );
00211 break;
00212
00213 default:
00214 break;
00215 }
00216
00217 m_track.erase( it );
00218 }
00219
00220 return;
00221 }
00222
00223 }