gloox 1.0
flexoff.cpp
00001 /*
00002   Copyright (c) 2005-2009 by Jakob Schroeter <js@camaya.net>
00003   This file is part of the gloox library. http://camaya.net/gloox
00004 
00005   This software is distributed under a license. The full license
00006   agreement can be found in the file LICENSE in this distribution.
00007   This software may not be copied, modified, sold or distributed
00008   other than expressed in the named license agreement.
00009 
00010   This software is distributed without any warranty.
00011 */
00012 
00013 
00014 #include "flexoff.h"
00015 #include "dataform.h"
00016 #include "disco.h"
00017 #include "error.h"
00018 
00019 #include <cstdlib>
00020 
00021 namespace gloox
00022 {
00023 
00024   // ---- FlexibleOffline::Offline ----
00025   FlexibleOffline::Offline::Offline( const Tag* /*tag*/ )
00026     : StanzaExtension( ExtFlexOffline )
00027   {
00028     // FIXME what to do here?
00029   }
00030 
00031   FlexibleOffline::Offline::Offline( int context, const StringList& msgs )
00032     : StanzaExtension( ExtFlexOffline ), m_context( context ), m_msgs( msgs )
00033   {
00034   }
00035 
00036   FlexibleOffline::Offline::~Offline()
00037   {
00038   }
00039 
00040   const std::string& FlexibleOffline::Offline::filterString() const
00041   {
00042     static const std::string filter = "/iq/offline[@xmlns='" + XMLNS_OFFLINE + "']";
00043     return filter;
00044   }
00045 
00046   Tag* FlexibleOffline::Offline::tag() const
00047   {
00048     Tag* t = new Tag( "offline" );
00049     t->setXmlns( XMLNS_OFFLINE );
00050 
00051     if( m_msgs.empty() )
00052       new Tag( t, m_context == FORequestMsgs ? "fetch" : "purge" );
00053     else
00054     {
00055       const std::string action = m_context == FORequestMsgs ? "view" : "remove";
00056       StringList::const_iterator it = m_msgs.begin();
00057       for( ; it != m_msgs.end(); ++it )
00058       {
00059         Tag* i = new Tag( t, "item", "action", action );
00060         i->addAttribute( "node", (*it) );
00061       }
00062     }
00063     return t;
00064   }
00065   // ---- ~FlexibleOffline::Offline ----
00066 
00067   // ---- FlexibleOffline ----
00068   FlexibleOffline::FlexibleOffline( ClientBase* parent )
00069     : m_parent( parent ), m_flexibleOfflineHandler( 0 )
00070   {
00071     if( m_parent )
00072       m_parent->registerStanzaExtension( new Offline() );
00073   }
00074 
00075   FlexibleOffline::~FlexibleOffline()
00076   {
00077     if( m_parent )
00078       m_parent->removeIDHandler( this );
00079   }
00080 
00081   void FlexibleOffline::checkSupport()
00082   {
00083     m_parent->disco()->getDiscoInfo( m_parent->jid().server(), EmptyString, this, FOCheckSupport );
00084   }
00085 
00086   void FlexibleOffline::getMsgCount()
00087   {
00088     m_parent->disco()->getDiscoInfo( m_parent->jid().server(), XMLNS_OFFLINE, this, FORequestNum );
00089   }
00090 
00091   void FlexibleOffline::fetchHeaders()
00092   {
00093     m_parent->disco()->getDiscoItems( m_parent->jid().server(), XMLNS_OFFLINE, this, FORequestHeaders );
00094   }
00095 
00096   void FlexibleOffline::messageOperation( int context, const StringList& msgs )
00097   {
00098     const std::string& id = m_parent->getID();
00099     IQ::IqType iqType = context == FORequestMsgs ? IQ::Get : IQ::Set;
00100     IQ iq( iqType, JID(), id );
00101     iq.addExtension( new Offline( context, msgs ) );
00102     m_parent->send( iq, this, context );
00103   }
00104 
00105   void FlexibleOffline::registerFlexibleOfflineHandler( FlexibleOfflineHandler* foh )
00106   {
00107     m_flexibleOfflineHandler = foh;
00108   }
00109 
00110   void FlexibleOffline::removeFlexibleOfflineHandler()
00111   {
00112     m_flexibleOfflineHandler = 0;
00113   }
00114 
00115   void FlexibleOffline::handleDiscoInfo( const JID& /*from*/, const Disco::Info& info, int context )
00116   {
00117     if( !m_flexibleOfflineHandler )
00118       return;
00119 
00120     switch( context )
00121     {
00122       case FOCheckSupport:
00123         m_flexibleOfflineHandler->handleFlexibleOfflineSupport( info.hasFeature( XMLNS_OFFLINE ) );
00124         break;
00125 
00126       case FORequestNum:
00127         int num = -1;
00128         if( info.form() && info.form()->hasField( "number_of_messages" ) )
00129           num = atoi( info.form()->field( "number_of_messages" )->value().c_str() );
00130 
00131         m_flexibleOfflineHandler->handleFlexibleOfflineMsgNum( num );
00132         break;
00133     }
00134   }
00135 
00136   void FlexibleOffline::handleDiscoItems( const JID& /*from*/, const Disco::Items& items, int context )
00137   {
00138     if( context == FORequestHeaders && m_flexibleOfflineHandler )
00139     {
00140       if( items.node() == XMLNS_OFFLINE )
00141         m_flexibleOfflineHandler->handleFlexibleOfflineMessageHeaders( items.items() );
00142     }
00143   }
00144 
00145   void FlexibleOffline::handleDiscoError( const JID& /*from*/, const Error* /*error*/, int /*context*/ )
00146   {
00147   }
00148 
00149   void FlexibleOffline::handleIqID( const IQ& iq, int context )
00150   {
00151     if( !m_flexibleOfflineHandler )
00152       return;
00153 
00154     switch( context )
00155     {
00156       case FORequestMsgs:
00157         switch( iq.subtype() )
00158         {
00159           case IQ::Result:
00160             m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrRequestSuccess );
00161             break;
00162           case IQ::Error:
00163             switch( iq.error()->error() )
00164             {
00165               case StanzaErrorForbidden:
00166                 m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrForbidden );
00167                 break;
00168               case StanzaErrorItemNotFound:
00169                 m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrItemNotFound );
00170                 break;
00171               default:
00172                 m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrUnknownError );
00173                 break;
00174             }
00175             break;
00176           default:
00177             break;
00178         }
00179         break;
00180       case FORemoveMsgs:
00181         switch( iq.subtype() )
00182         {
00183           case IQ::Result:
00184             m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrRemoveSuccess );
00185             break;
00186           case IQ::Error:
00187             switch( iq.error()->error() )
00188             {
00189               case StanzaErrorForbidden:
00190                 m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrForbidden );
00191                 break;
00192               case StanzaErrorItemNotFound:
00193                 m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrItemNotFound );
00194                 break;
00195               default:
00196                 m_flexibleOfflineHandler->handleFlexibleOfflineResult( FomrUnknownError );
00197                 break;
00198             }
00199             break;
00200           default:
00201             break;
00202         }
00203         break;
00204     }
00205   }
00206 
00207 }