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