gloox  0.9.9.12
search.cpp
1 /*
2  Copyright (c) 2006-2008 by Jakob Schroeter <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 "stanza.h"
19 
20 namespace gloox
21 {
22 
24  : m_parent( parent )
25  {
26  }
27 
29  {
30  m_parent->removeIDHandler( this );
31  }
32 
33  void Search::fetchSearchFields( const JID& directory, SearchHandler *sh )
34  {
35  if( !m_parent || !directory || !sh )
36  return;
37 
38  const std::string& id = m_parent->getID();
39 
40  Tag *iq = new Tag( "iq" );
41  iq->addAttribute( "type", "get" );
42  iq->addAttribute( "id", id );
43  iq->addAttribute( "to", directory.full() );
44  Tag *q = new Tag( iq, "query" );
45  q->addAttribute( "xmlns", XMLNS_SEARCH );
46 
47  m_track[id] = sh;
48  m_parent->trackID( this, id, FetchSearchFields );
49  m_parent->send( iq );
50  }
51 
52  void Search::search( const JID& directory, const DataForm& form, SearchHandler *sh )
53  {
54  if( !m_parent || !directory || !sh )
55  return;
56 
57  const std::string& id = m_parent->getID();
58 
59  Tag *iq = new Tag( "iq" );
60  iq->addAttribute( "id", id );
61  iq->addAttribute( "type", "set" );
62  iq->addAttribute( "to", directory.full() );
63  Tag *q = new Tag( iq, "query" );
64  q->addAttribute( "xmlns", XMLNS_SEARCH );
65  q->addChild( form.tag() );
66 
67  m_track[id] = sh;
68  m_parent->trackID( this, id, DoSearch );
69  m_parent->send( iq );
70  }
71 
72  void Search::search( const JID& directory, int fields, const SearchFieldStruct& values, SearchHandler *sh )
73  {
74  if( !m_parent || !directory || !sh )
75  return;
76 
77  const std::string& id = m_parent->getID();
78 
79  Tag *iq = new Tag( "iq" );
80  iq->addAttribute( "id", id );
81  iq->addAttribute( "type", "set" );
82  iq->addAttribute( "to", directory.full() );
83  Tag *q = new Tag( iq, "query" );
84  q->addAttribute( "xmlns", XMLNS_SEARCH );
85 
86  if( fields & SearchFieldFirst )
87  new Tag( q, "first", values.first );
88  if( fields & SearchFieldLast )
89  new Tag( q, "last", values.last );
90  if( fields & SearchFieldNick )
91  new Tag( q, "nick", values.nick );
92  if( fields & SearchFieldEmail )
93  new Tag( q, "email", values.email );
94 
95  m_track[id] = sh;
96  m_parent->trackID( this, id, DoSearch );
97  m_parent->send( iq );
98  }
99 
100  bool Search::handleIqID( Stanza *stanza, int context )
101  {
102  TrackMap::iterator it = m_track.find( stanza->id() );
103  if( it != m_track.end() )
104  {
105  switch( stanza->subtype() )
106  {
107  case StanzaIqResult:
108  switch( context )
109  {
110  case FetchSearchFields:
111  {
112  Tag *q = stanza->findChild( "query" );
113  if( q && q->hasAttribute( "xmlns", XMLNS_SEARCH ) )
114  {
115  Tag *x = q->findChild( "x", "xmlns", XMLNS_X_DATA );
116  if( x )
117  {
118  DataForm *df = new DataForm( x );
119  (*it).second->handleSearchFields( stanza->from(), df );
120  }
121  else
122  {
123  int fields = 0;
124  std::string instructions;
125 
126  if( q->hasChild( "first" ) )
127  fields |= SearchFieldFirst;
128  if( q->hasChild( "last" ) )
129  fields |= SearchFieldLast;
130  if( q->hasChild( "nick" ) )
131  fields |= SearchFieldNick;
132  if( q->hasChild( "email" ) )
133  fields |= SearchFieldEmail;
134  if( q->hasChild( "instructions" ) )
135  instructions = q->findChild( "instructions" )->cdata();
136 
137  (*it).second->handleSearchFields( stanza->from(), fields, instructions );
138  }
139  }
140  break;
141  }
142  case DoSearch:
143  {
144  Tag *q = stanza->findChild( "query" );
145  if( q && q->hasAttribute( "xmlns", XMLNS_SEARCH ) )
146  {
147  Tag *x = q->findChild( "x", "xmlns", XMLNS_X_DATA );
148  if( x )
149  {
150  DataForm *df = new DataForm( x );
151  (*it).second->handleSearchResult( stanza->from(), df );
152  }
153  else
154  {
157  const Tag::TagList &l = q->children();
158  Tag::TagList::const_iterator itl = l.begin();
159  for( ; itl != l.end(); ++itl )
160  {
161  if( (*itl)->name() == "item" )
162  {
163  s.jid.setJID( (*itl)->findAttribute( "jid" ) );
164  Tag *t = 0;
165  if( ( t = (*itl)->findChild( "first" ) ) != 0 )
166  s.first = t->cdata();
167  if( ( t = (*itl)->findChild( "last" ) ) != 0 )
168  s.last = t->cdata();
169  if( ( t = (*itl)->findChild( "nick" ) ) != 0 )
170  s.nick = t->cdata();
171  if( ( t = (*itl)->findChild( "email" ) ) != 0 )
172  s.email = t->cdata();
173  e.push_back( s );
174  }
175  }
176 
177  (*it).second->handleSearchResult( stanza->from(), e );
178  }
179  }
180  break;
181  }
182  }
183  break;
184  case StanzaIqError:
185  (*it).second->handleSearchError( stanza->from(), stanza );
186  break;
187 
188  default:
189  break;
190  }
191 
192  m_track.erase( it );
193  }
194 
195  return false;
196  }
197 
198 }