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