00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "flexoff.h"
00015 #include "dataform.h"
00016 #include "disco.h"
00017
00018 #include <cstdlib>
00019
00020 namespace gloox
00021 {
00022
00023 FlexibleOffline::FlexibleOffline( ClientBase *parent )
00024 : m_parent( parent ), m_flexibleOfflineHandler( 0 )
00025 {
00026 }
00027
00028 FlexibleOffline::~FlexibleOffline()
00029 {
00030 m_parent->removeIDHandler( this );
00031 }
00032
00033 void FlexibleOffline::checkSupport()
00034 {
00035 m_parent->disco()->getDiscoInfo( m_parent->jid().server(), "", this, FOCheckSupport );
00036 }
00037
00038 void FlexibleOffline::getMsgCount()
00039 {
00040 m_parent->disco()->getDiscoInfo( m_parent->jid().server(), XMLNS_OFFLINE, this, FORequestNum );
00041 }
00042
00043 void FlexibleOffline::fetchHeaders()
00044 {
00045 m_parent->disco()->getDiscoItems( m_parent->jid().server(), XMLNS_OFFLINE, this, FORequestHeaders );
00046 }
00047
00048 void FlexibleOffline::fetchMessages( const StringList& msgs )
00049 {
00050 const std::string& id = m_parent->getID();
00051 Tag *iq = new Tag( "iq" );
00052 iq->addAttribute( "type", "get" );
00053 iq->addAttribute( "id", id );
00054 Tag *o = new Tag( iq, "offline" );
00055 o->addAttribute( "xmlns", XMLNS_OFFLINE );
00056
00057 if( msgs.size() == 0 )
00058 new Tag( o, "fetch" );
00059 else
00060 {
00061 StringList::const_iterator it = msgs.begin();
00062 for( ; it != msgs.end(); ++it )
00063 {
00064 Tag *i = new Tag( o, "item" );
00065 i->addAttribute( "action", "view" );
00066 i->addAttribute( "node", (*it) );
00067 }
00068 }
00069
00070 m_parent->trackID( this, id, FORequestMsgs );
00071 m_parent->send( iq );
00072 }
00073
00074 void FlexibleOffline::removeMessages( const StringList& msgs )
00075 {
00076 const std::string& id = m_parent->getID();
00077 Tag *iq = new Tag( "iq" );
00078 iq->addAttribute( "type", "get" );
00079 iq->addAttribute( "id", id );
00080 Tag *o = new Tag( iq, "offline" );
00081 o->addAttribute( "xmlns", XMLNS_OFFLINE );
00082
00083 if( msgs.size() == 0 )
00084 new Tag( o, "purge" );
00085 else
00086 {
00087 StringList::const_iterator it = msgs.begin();
00088 for( ; it != msgs.end(); ++it )
00089 {
00090 Tag *i = new Tag( o, "item" );
00091 i->addAttribute( "action", "remove" );
00092 i->addAttribute( "node", (*it) );
00093 }
00094 }
00095
00096 m_parent->trackID( this, id, FORemoveMsgs );
00097 m_parent->send( iq );
00098 }
00099
00100 void FlexibleOffline::registerFlexibleOfflineHandler( FlexibleOfflineHandler *foh )
00101 {
00102 m_flexibleOfflineHandler = foh;
00103 }
00104
00105 void FlexibleOffline::removeFlexibleOfflineHandler()
00106 {
00107 m_flexibleOfflineHandler = 0;
00108 }
00109
00110 void FlexibleOffline::handleDiscoInfoResult( Stanza *stanza, int context )
00111 {
00112 if( !m_flexibleOfflineHandler )
00113 return;
00114
00115 switch( context )
00116 {
00117 case FOCheckSupport:
00118 m_flexibleOfflineHandler->handleFlexibleOfflineSupport(
00119 stanza->findChild( "query" )->hasChild( "feature", "var", XMLNS_OFFLINE ) );
00120 break;
00121
00122 case FORequestNum:
00123 int num = -1;
00124 DataForm f( stanza->findChild( "query" )->findChild( "x" ) );
00125 if( f.hasField( "number_of_messages" ) )
00126 num = atoi( f.field( "number_of_messages" )->value().c_str() );
00127
00128 m_flexibleOfflineHandler->handleFlexibleOfflineMsgNum( num );
00129 break;
00130 }
00131 }
00132
00133 void FlexibleOffline::handleDiscoItemsResult( Stanza *stanza, int context )
00134 {
00135 if( context == FORequestHeaders && m_flexibleOfflineHandler )
00136 {
00137 Tag *q = stanza->findChild( "query" );
00138 if( q && q->hasAttribute( "xmlns", XMLNS_DISCO_ITEMS ) && q->hasAttribute( "node", XMLNS_OFFLINE ) )
00139 {
00140 StringMap m;
00141 const Tag::TagList& l = q->children();
00142 Tag::TagList::const_iterator it = l.begin();
00143 for( ; it != l.end(); ++it )
00144 {
00145 m[(*it)->findAttribute( "node" )] = (*it)->findAttribute( "name" );
00146 }
00147 m_flexibleOfflineHandler->handleFlexibleOfflineMessageHeaders( m );
00148 }
00149 }
00150 }
00151
00152 void FlexibleOffline::handleDiscoError( Stanza * , int )
00153 {
00154 }
00155
00156 bool FlexibleOffline::handleIqID( Stanza *stanza, int context )
00157 {
00158 if( !m_flexibleOfflineHandler )
00159 return false;
00160
00161 switch( context )
00162 {
00163 case FORequestMsgs:
00164 switch( stanza->subtype() )
00165 {
00166 case StanzaIqResult:
00167 m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrRequestSuccess );
00168 break;
00169 case StanzaIqError:
00170 switch( stanza->error() )
00171 {
00172 case StanzaErrorForbidden:
00173 m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrForbidden );
00174 break;
00175 case StanzaErrorItemNotFound:
00176 m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrItemNotFound );
00177 break;
00178 default:
00179 m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrUnknownError );
00180 break;
00181 }
00182 break;
00183 default:
00184 break;
00185 }
00186 break;
00187 case FORemoveMsgs:
00188 switch( stanza->subtype() )
00189 {
00190 case StanzaIqResult:
00191 m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrRemoveSuccess );
00192 break;
00193 case StanzaIqError:
00194 switch( stanza->error() )
00195 {
00196 case StanzaErrorForbidden:
00197 m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrForbidden );
00198 break;
00199 case StanzaErrorItemNotFound:
00200 m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrItemNotFound );
00201 break;
00202 default:
00203 m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrUnknownError );
00204 break;
00205 }
00206 break;
00207 default:
00208 break;
00209 }
00210 break;
00211 }
00212
00213 return false;
00214 }
00215
00216 bool FlexibleOffline::handleIq( Stanza * )
00217 {
00218 return false;
00219 }
00220
00221 }