gloox  1.0
flexoff.cpp
1 /*
2  Copyright (c) 2005-2009 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 #include "error.h"
18 
19 #include <cstdlib>
20 
21 namespace gloox
22 {
23 
24  // ---- FlexibleOffline::Offline ----
25  FlexibleOffline::Offline::Offline( const Tag* /*tag*/ )
26  : StanzaExtension( ExtFlexOffline )
27  {
28  // FIXME what to do here?
29  }
30 
31  FlexibleOffline::Offline::Offline( int context, const StringList& msgs )
32  : StanzaExtension( ExtFlexOffline ), m_context( context ), m_msgs( msgs )
33  {
34  }
35 
36  FlexibleOffline::Offline::~Offline()
37  {
38  }
39 
40  const std::string& FlexibleOffline::Offline::filterString() const
41  {
42  static const std::string filter = "/iq/offline[@xmlns='" + XMLNS_OFFLINE + "']";
43  return filter;
44  }
45 
46  Tag* FlexibleOffline::Offline::tag() const
47  {
48  Tag* t = new Tag( "offline" );
49  t->setXmlns( XMLNS_OFFLINE );
50 
51  if( m_msgs.empty() )
52  new Tag( t, m_context == FORequestMsgs ? "fetch" : "purge" );
53  else
54  {
55  const std::string action = m_context == FORequestMsgs ? "view" : "remove";
56  StringList::const_iterator it = m_msgs.begin();
57  for( ; it != m_msgs.end(); ++it )
58  {
59  Tag* i = new Tag( t, "item", "action", action );
60  i->addAttribute( "node", (*it) );
61  }
62  }
63  return t;
64  }
65  // ---- ~FlexibleOffline::Offline ----
66 
67  // ---- FlexibleOffline ----
69  : m_parent( parent ), m_flexibleOfflineHandler( 0 )
70  {
71  if( m_parent )
72  m_parent->registerStanzaExtension( new Offline() );
73  }
74 
76  {
77  if( m_parent )
78  m_parent->removeIDHandler( this );
79  }
80 
82  {
83  m_parent->disco()->getDiscoInfo( m_parent->jid().server(), EmptyString, this, FOCheckSupport );
84  }
85 
87  {
88  m_parent->disco()->getDiscoInfo( m_parent->jid().server(), XMLNS_OFFLINE, this, FORequestNum );
89  }
90 
92  {
93  m_parent->disco()->getDiscoItems( m_parent->jid().server(), XMLNS_OFFLINE, this, FORequestHeaders );
94  }
95 
96  void FlexibleOffline::messageOperation( int context, const StringList& msgs )
97  {
98  const std::string& id = m_parent->getID();
99  IQ::IqType iqType = context == FORequestMsgs ? IQ::Get : IQ::Set;
100  IQ iq( iqType, JID(), id );
101  iq.addExtension( new Offline( context, msgs ) );
102  m_parent->send( iq, this, context );
103  }
104 
106  {
107  m_flexibleOfflineHandler = foh;
108  }
109 
111  {
112  m_flexibleOfflineHandler = 0;
113  }
114 
115  void FlexibleOffline::handleDiscoInfo( const JID& /*from*/, const Disco::Info& info, int context )
116  {
117  if( !m_flexibleOfflineHandler )
118  return;
119 
120  switch( context )
121  {
122  case FOCheckSupport:
123  m_flexibleOfflineHandler->handleFlexibleOfflineSupport( info.hasFeature( XMLNS_OFFLINE ) );
124  break;
125 
126  case FORequestNum:
127  int num = -1;
128  if( info.form() && info.form()->hasField( "number_of_messages" ) )
129  num = atoi( info.form()->field( "number_of_messages" )->value().c_str() );
130 
131  m_flexibleOfflineHandler->handleFlexibleOfflineMsgNum( num );
132  break;
133  }
134  }
135 
136  void FlexibleOffline::handleDiscoItems( const JID& /*from*/, const Disco::Items& items, int context )
137  {
138  if( context == FORequestHeaders && m_flexibleOfflineHandler )
139  {
140  if( items.node() == XMLNS_OFFLINE )
141  m_flexibleOfflineHandler->handleFlexibleOfflineMessageHeaders( items.items() );
142  }
143  }
144 
145  void FlexibleOffline::handleDiscoError( const JID& /*from*/, const Error* /*error*/, int /*context*/ )
146  {
147  }
148 
149  void FlexibleOffline::handleIqID( const IQ& iq, int context )
150  {
151  if( !m_flexibleOfflineHandler )
152  return;
153 
154  switch( context )
155  {
156  case FORequestMsgs:
157  switch( iq.subtype() )
158  {
159  case IQ::Result:
160  m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrRequestSuccess );
161  break;
162  case IQ::Error:
163  switch( iq.error()->error() )
164  {
166  m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrForbidden );
167  break;
169  m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrItemNotFound );
170  break;
171  default:
172  m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrUnknownError );
173  break;
174  }
175  break;
176  default:
177  break;
178  }
179  break;
180  case FORemoveMsgs:
181  switch( iq.subtype() )
182  {
183  case IQ::Result:
184  m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrRemoveSuccess );
185  break;
186  case IQ::Error:
187  switch( iq.error()->error() )
188  {
190  m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrForbidden );
191  break;
193  m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrItemNotFound );
194  break;
195  default:
196  m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrUnknownError );
197  break;
198  }
199  break;
200  default:
201  break;
202  }
203  break;
204  }
205  }
206 
207 }