gloox  0.9.9.12
flexoff.cpp
1 /*
2  Copyright (c) 2005-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 #include "flexoff.h"
15 #include "dataform.h"
16 #include "disco.h"
17 
18 #include <cstdlib>
19 
20 namespace gloox
21 {
22 
24  : m_parent( parent ), m_flexibleOfflineHandler( 0 )
25  {
26  }
27 
29  {
30  m_parent->removeIDHandler( this );
31  }
32 
34  {
35  m_parent->disco()->getDiscoInfo( m_parent->jid().server(), "", this, FOCheckSupport );
36  }
37 
39  {
40  m_parent->disco()->getDiscoInfo( m_parent->jid().server(), XMLNS_OFFLINE, this, FORequestNum );
41  }
42 
44  {
45  m_parent->disco()->getDiscoItems( m_parent->jid().server(), XMLNS_OFFLINE, this, FORequestHeaders );
46  }
47 
49  {
50  const std::string& id = m_parent->getID();
51  Tag *iq = new Tag( "iq" );
52  iq->addAttribute( "type", "get" );
53  iq->addAttribute( "id", id );
54  Tag *o = new Tag( iq, "offline" );
55  o->addAttribute( "xmlns", XMLNS_OFFLINE );
56 
57  if( msgs.size() == 0 )
58  new Tag( o, "fetch" );
59  else
60  {
61  StringList::const_iterator it = msgs.begin();
62  for( ; it != msgs.end(); ++it )
63  {
64  Tag *i = new Tag( o, "item" );
65  i->addAttribute( "action", "view" );
66  i->addAttribute( "node", (*it) );
67  }
68  }
69 
70  m_parent->trackID( this, id, FORequestMsgs );
71  m_parent->send( iq );
72  }
73 
75  {
76  const std::string& id = m_parent->getID();
77  Tag *iq = new Tag( "iq" );
78  iq->addAttribute( "type", "get" );
79  iq->addAttribute( "id", id );
80  Tag *o = new Tag( iq, "offline" );
81  o->addAttribute( "xmlns", XMLNS_OFFLINE );
82 
83  if( msgs.size() == 0 )
84  new Tag( o, "purge" );
85  else
86  {
87  StringList::const_iterator it = msgs.begin();
88  for( ; it != msgs.end(); ++it )
89  {
90  Tag *i = new Tag( o, "item" );
91  i->addAttribute( "action", "remove" );
92  i->addAttribute( "node", (*it) );
93  }
94  }
95 
96  m_parent->trackID( this, id, FORemoveMsgs );
97  m_parent->send( iq );
98  }
99 
101  {
102  m_flexibleOfflineHandler = foh;
103  }
104 
106  {
107  m_flexibleOfflineHandler = 0;
108  }
109 
110  void FlexibleOffline::handleDiscoInfoResult( Stanza *stanza, int context )
111  {
112  if( !m_flexibleOfflineHandler )
113  return;
114 
115  switch( context )
116  {
117  case FOCheckSupport:
118  m_flexibleOfflineHandler->handleFlexibleOfflineSupport(
119  stanza->findChild( "query" )->hasChild( "feature", "var", XMLNS_OFFLINE ) );
120  break;
121 
122  case FORequestNum:
123  int num = -1;
124  DataForm f( stanza->findChild( "query" )->findChild( "x" ) );
125  if( f.hasField( "number_of_messages" ) )
126  num = atoi( f.field( "number_of_messages" )->value().c_str() );
127 
128  m_flexibleOfflineHandler->handleFlexibleOfflineMsgNum( num );
129  break;
130  }
131  }
132 
133  void FlexibleOffline::handleDiscoItemsResult( Stanza *stanza, int context )
134  {
135  if( context == FORequestHeaders && m_flexibleOfflineHandler )
136  {
137  Tag *q = stanza->findChild( "query" );
138  if( q && q->hasAttribute( "xmlns", XMLNS_DISCO_ITEMS ) && q->hasAttribute( "node", XMLNS_OFFLINE ) )
139  {
140  StringMap m;
141  const Tag::TagList& l = q->children();
142  Tag::TagList::const_iterator it = l.begin();
143  for( ; it != l.end(); ++it )
144  {
145  m[(*it)->findAttribute( "node" )] = (*it)->findAttribute( "name" );
146  }
147  m_flexibleOfflineHandler->handleFlexibleOfflineMessageHeaders( m );
148  }
149  }
150  }
151 
152  void FlexibleOffline::handleDiscoError( Stanza * /*stanza*/, int /*context*/ )
153  {
154  }
155 
156  bool FlexibleOffline::handleIqID( Stanza *stanza, int context )
157  {
158  if( !m_flexibleOfflineHandler )
159  return false;
160 
161  switch( context )
162  {
163  case FORequestMsgs:
164  switch( stanza->subtype() )
165  {
166  case StanzaIqResult:
167  m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrRequestSuccess );
168  break;
169  case StanzaIqError:
170  switch( stanza->error() )
171  {
173  m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrForbidden );
174  break;
176  m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrItemNotFound );
177  break;
178  default:
179  m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrUnknownError );
180  break;
181  }
182  break;
183  default:
184  break;
185  }
186  break;
187  case FORemoveMsgs:
188  switch( stanza->subtype() )
189  {
190  case StanzaIqResult:
191  m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrRemoveSuccess );
192  break;
193  case StanzaIqError:
194  switch( stanza->error() )
195  {
197  m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrForbidden );
198  break;
200  m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrItemNotFound );
201  break;
202  default:
203  m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrUnknownError );
204  break;
205  }
206  break;
207  default:
208  break;
209  }
210  break;
211  }
212 
213  return false;
214  }
215 
216  bool FlexibleOffline::handleIq( Stanza * /*stanza*/ )
217  {
218  return false;
219  }
220 
221 }