gloox 1.0.24
search.cpp
1/*
2 Copyright (c) 2006-2019 by Jakob Schröter <js@camaya.net>
3 This file is part of the gloox library. http://camaya.net/gloox
4
5 This software is distributed under a license. The full license
6 agreement can be found in the file LICENSE in this distribution.
7 This software may not be copied, modified, sold or distributed
8 other than expressed in the named license agreement.
9
10 This software is distributed without any warranty.
11*/
12
13
14
15#include "search.h"
16
17#include "clientbase.h"
18#include "dataform.h"
19#include "iq.h"
20
21namespace gloox
22{
23
24 // Search::Query ----
25 Search::Query::Query( DataForm* form )
26 : StanzaExtension( ExtSearch ), m_form( form ), m_fields( 0 )
27 {
28 }
29
30 Search::Query::Query( int fields, const SearchFieldStruct& values )
31 : StanzaExtension( ExtSearch ), m_form( 0 ), m_fields( fields ), m_values( values )
32 {
33 }
34
35 Search::Query::Query( const Tag* tag )
36 : StanzaExtension( ExtSearch ), m_form( 0 ), m_fields( 0 )
37 {
38 if( !tag || tag->name() != "query" || tag->xmlns() != XMLNS_SEARCH )
39 return;
40
41 const TagList& l = tag->children();
42 TagList::const_iterator it = l.begin();
43 for( ; it != l.end(); ++it )
44 {
45 if( (*it)->name() == "instructions" )
46 {
47 m_instructions = (*it)->cdata();
48 }
49 else if( (*it)->name() == "item" )
50 {
51 m_srl.push_back( new SearchFieldStruct( (*it) ) );
52 }
53 else if( (*it)->name() == "first" )
54 m_fields |= SearchFieldFirst;
55 else if( (*it)->name() == "last" )
56 m_fields |= SearchFieldLast;
57 else if( (*it)->name() == "email" )
58 m_fields |= SearchFieldEmail;
59 else if( (*it)->name() == "nick" )
60 m_fields |= SearchFieldNick;
61 else if( !m_form && (*it)->name() == "x" && (*it)->xmlns() == XMLNS_X_DATA )
62 m_form = new DataForm( (*it) );
63 }
64 }
65
66 Search::Query::~Query()
67 {
68 delete m_form;
69 SearchResultList::iterator it = m_srl.begin();
70 for( ; it != m_srl.end(); ++it )
71 delete (*it);
72 }
73
74 const std::string& Search::Query::filterString() const
75 {
76 static const std::string filter = "/iq/query[@xmlns='" + XMLNS_SEARCH + "']";
77 return filter;
78 }
79
80 Tag* Search::Query::tag() const
81 {
82 Tag* t = new Tag( "query" );
83 t->setXmlns( XMLNS_SEARCH );
84 if( m_form )
85 t->addChild( m_form->tag() );
86 else if( m_fields )
87 {
88 if( !m_instructions.empty() )
89 new Tag( t, "instructions", m_instructions );
90 if( m_fields & SearchFieldFirst )
91 new Tag( t, "first", m_values.first() );
92 if( m_fields & SearchFieldLast )
93 new Tag( t, "last", m_values.last() );
94 if( m_fields & SearchFieldNick )
95 new Tag( t, "nick", m_values.nick() );
96 if( m_fields & SearchFieldEmail )
97 new Tag( t, "email", m_values.email() );
98 }
99 else if( !m_srl.empty() )
100 {
101 SearchResultList::const_iterator it = m_srl.begin();
102 for( ; it != m_srl.end(); ++it )
103 {
104 t->addChild( (*it)->tag() );
105 }
106 }
107 return t;
108 }
109 // ---- ~Search::Query ----
110
111 // ---- Search ----
112 Search::Search( ClientBase* parent )
113 : m_parent( parent )
114 {
115 if( m_parent )
116 m_parent->registerStanzaExtension( new Query() );
117 }
118
120 {
121 if( m_parent )
122 {
123 m_parent->removeIDHandler( this );
124 m_parent->removeStanzaExtension( ExtRoster );
125 }
126 }
127
128 void Search::fetchSearchFields( const JID& directory, SearchHandler* sh )
129 {
130 if( !m_parent || !directory || !sh )
131 return;
132
133 const std::string& id = m_parent->getID();
134 IQ iq( IQ::Get, directory, id );
135 iq.addExtension( new Query() );
136 m_track[id] = sh;
137 m_parent->send( iq, this, FetchSearchFields );
138 }
139
140 void Search::search( const JID& directory, DataForm* form, SearchHandler* sh )
141 {
142 if( !m_parent || !directory || !sh )
143 return;
144
145 const std::string& id = m_parent->getID();
146 IQ iq( IQ::Set, directory, id );
147 iq.addExtension( new Query( form ) );
148
149 m_track[id] = sh;
150 m_parent->send( iq, this, DoSearch );
151 }
152
153 void Search::search( const JID& directory, int fields, const SearchFieldStruct& values, SearchHandler* sh )
154 {
155 if( !m_parent || !directory || !sh )
156 return;
157
158 const std::string& id = m_parent->getID();
159
160 IQ iq( IQ::Set, directory, id );
161 iq.addExtension( new Query( fields, values ) );
162
163 m_track[id] = sh;
164 m_parent->send( iq, this, DoSearch );
165 }
166
167 void Search::handleIqID( const IQ& iq, int context )
168 {
169 TrackMap::iterator it = m_track.find( iq.id() );
170 if( it != m_track.end() )
171 {
172 switch( iq.subtype() )
173 {
174 case IQ::Result:
175 {
176 const Query* q = iq.findExtension<Query>( ExtSearch );
177 if( !q )
178 return;
179
180 switch( context )
181 {
182 case FetchSearchFields:
183 {
184 if( q->form() )
185 {
186 (*it).second->handleSearchFields( iq.from(), q->form() );
187 }
188 else
189 {
190 (*it).second->handleSearchFields( iq.from(), q->fields(), q->instructions() );
191 }
192 break;
193 }
194 case DoSearch:
195 {
196 if( q->form() )
197 {
198 (*it).second->handleSearchResult( iq.from(), q->form() );
199 }
200 else
201 {
202 (*it).second->handleSearchResult( iq.from(), q->result() );
203 }
204 break;
205 }
206 }
207 break;
208 }
209 case IQ::Error:
210 (*it).second->handleSearchError( iq.from(), iq.error() );
211 break;
212
213 default:
214 break;
215 }
216
217 m_track.erase( it );
218 }
219
220 return;
221 }
222
223}
This is the common base class for a Jabber/XMPP Client and a Jabber Component.
Definition: clientbase.h:79
const std::string getID()
void removeIDHandler(IqHandler *ih)
bool removeStanzaExtension(int ext)
void send(Tag *tag)
void registerStanzaExtension(StanzaExtension *ext)
An abstraction of a XEP-0004 Data Form.
Definition: dataform.h:57
An abstraction of an IQ stanza.
Definition: iq.h:34
IqType subtype() const
Definition: iq.h:74
@ Set
Definition: iq.h:46
@ Error
Definition: iq.h:49
@ Result
Definition: iq.h:48
@ Get
Definition: iq.h:45
An abstraction of a JID.
Definition: jid.h:31
A virtual interface that enables objects to receive Jabber Search (XEP-0055) results.
void fetchSearchFields(const JID &directory, SearchHandler *sh)
Definition: search.cpp:128
virtual void handleIqID(const IQ &iq, int context)
Definition: search.cpp:167
void search(const JID &directory, DataForm *form, SearchHandler *sh)
Definition: search.cpp:140
void addExtension(const StanzaExtension *se)
Definition: stanza.cpp:52
const std::string & id() const
Definition: stanza.h:63
const Error * error() const
Definition: stanza.cpp:47
const JID & from() const
Definition: stanza.h:51
const StanzaExtension * findExtension(int type) const
Definition: stanza.cpp:57
The namespace for the gloox library.
Definition: adhoc.cpp:28
@ SearchFieldNick
@ SearchFieldEmail
@ SearchFieldLast
@ SearchFieldFirst
std::list< Tag * > TagList
Definition: tag.h:31
const std::string XMLNS_SEARCH
Definition: gloox.cpp:47