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