gloox
1.0
|
00001 /* 00002 Copyright (c) 2006-2009 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 "dataform.h" 00019 #include "iq.h" 00020 00021 namespace gloox 00022 { 00023 00024 // Search::Query ---- 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 // ---- ~Search::Query ---- 00110 00111 // ---- Search ---- 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 }