Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members  

jabberoo-presencedb.cpp

00001 /* jabberoo-presencedb.cc
00002  * Jabber Presence Database
00003  *
00004  * Original Code Copyright (C) 1999-2001 Dave Smith (dave@jabber.org)
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  * 
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  * 
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  * Contributor(s): Julian Missig
00021  *
00022  * This Original Code has been modified by IBM Corporation. Modifications 
00023  * made by IBM described herein are Copyright (c) International Business 
00024  * Machines Corporation, 2002.
00025  *
00026  * Date             Modified by     Description of modification
00027  * 01/20/2002       IBM Corp.       Updated to libjudo 1.1.1
00028  */
00029 
00030 #include "presence.hh"
00031 #include "presenceDB.hh"
00032 #include "JID.hh"
00033 #include <iostream>
00034 using namespace std;
00035 namespace jabberoo {
00036 
00037 // Helpful predicates
00038 class pred_presence_jid
00039 {
00040 std::string _jid;
00041 public:
00042      pred_presence_jid(const Presence& p)
00043           : _jid(p.getFrom()) {}
00044      pred_presence_jid(const std::string& s) : _jid(s) {}
00045      // is there a std::string function to do a case insensitive compare?
00046      bool operator()(const Presence& p) const
00047           { return (JID::compare(_jid, p.getFrom()) == 0); }
00048 };
00049 
00050 class pred_presence_priority
00051 {
00052 int _priority;
00053 public:
00054      pred_presence_priority(const Presence& p)
00055           : _priority(p.getPriority()){}
00056      bool operator()(const Presence& p) const
00057           { return p.getPriority() <= _priority; }
00058 };
00059 
00060 PresenceDB::PresenceDB(Session& s)
00061      : _Owner(s)
00062 {}
00063 
00064 PresenceDB::db::const_iterator PresenceDB::find_or_throw(const std::string& jid) const
00065 {
00066      db::const_iterator it = _DB.find(JID::getUserHost(jid));
00067      if (it != _DB.end())
00068           return it;
00069      else
00070           throw XCP_InvalidJID();
00071 }
00072 
00073 void display(const Presence& p)
00074 {
00075     std::cerr << "\tItem: " << p.toString() << std::endl;
00076 }
00077 
00078 
00079 void PresenceDB::insert(const Presence& p)
00080 {
00081      // Get a reference to the list (create one if necessary)
00082         std::list<Presence>& l = _DB[JID::getUserHost(p.getFrom())];
00083      
00084      // If this presence is ptUnavailable, remove it from the cache
00085      if (p.getType() == Presence::ptUnavailable ||
00086          p.getType() == Presence::ptError)
00087      {
00088           // Empty list? Then exit..
00089           if (l.empty())
00090           {
00091                _DB.erase(JID::getUserHost(p.getFrom()));
00092                return;
00093           }
00094           else
00095           {
00096                // Attempt to find the presence packet and erase
00097                iterator it = find_if(l.begin(), l.end(), pred_presence_jid(p));
00098                if (it != l.end())
00099                     l.erase(it);
00100                // If the list is now empty, remove this entry from the _DB map
00101                if (l.empty())
00102                     _DB.erase(JID::getUserHost(p.getFrom()));
00103         }
00104     }
00105     // Otherwise, insert/update 
00106     else 
00107     {
00108         // If this list is empty, insert this presence and be done with it
00109         if (l.empty())
00110           {
00111                l.push_back(p);
00112           }
00113           // Otherwise insert into the list
00114           else
00115           {
00116                // Identify any existing items w/ this JID 
00117                iterator it = find_if(l.begin(), l.end(), pred_presence_jid(p));
00118                if (it != l.end())
00119                {
00120                     // If the item found has the same priority, simply update
00121                     if (it->getPriority() == p.getPriority())
00122                     {
00123                          // Replace and exit
00124                          *it = p;
00125                          return;
00126                     }
00127                     // Otherwise erase the element 
00128                     else
00129                          l.erase(it);
00130                }
00131                // Now identify the insertion point for this element
00132                it = find_if(l.begin(), l.end(), pred_presence_priority(p));
00133                l.insert(it, p);
00134           }
00135      }
00136 }
00137 
00138 void PresenceDB::remove(const std::string& jid)
00139 {
00140         std::list<jabberoo::Presence>& l = _DB[JID::getUserHost(jid)];
00141      
00142      // Empty list? Then exit..
00143      if (l.empty())
00144      {
00145           _DB.erase(JID::getUserHost(jid));
00146           return;
00147      }
00148      else
00149      {
00150           // Attempt to find the presence packet and erase
00151           iterator it = find_if(l.begin(), l.end(), pred_presence_jid(jid));
00152           if (it != l.end())
00153                l.erase(it);
00154           // If the list is now empty, remove this entry from the _DB map
00155           if (l.empty())
00156                _DB.erase(JID::getUserHost(jid));
00157      }
00158 }
00159 
00160 
00161 PresenceDB::range PresenceDB::equal_range(const std::string& jid) const
00162 {
00163     db::const_iterator it = find_or_throw(jid);
00164     return make_pair(it->second.begin(), it->second.end());
00165 }
00166 
00167 Presence PresenceDB::findExact(const std::string& jid) const
00168 {
00169      PresenceDB::db::const_iterator it = find_or_throw(jid);
00170 
00171      // If the list is empty, throw an exception
00172      if (it->second.begin() == it->second.end())
00173           throw XCP_InvalidJID();
00174 
00175      // otherwise check for a resource
00176      std::string::size_type i = jid.find("/");
00177      if (i != std::string::npos)
00178      {
00179                  std::list<jabberoo::Presence> l= it->second;
00180 
00181           //return matching resource
00182           // Identify any existing items w/ this JID 
00183           iterator it2 = find_if(l.begin(), l.end(), pred_presence_jid(jid));
00184 
00185           // if we didn't find an entry, throw an exception
00186           if (it2 == l.end())
00187                throw XCP_InvalidJID();
00188 
00189           // return presence matching the full JID
00190           return *it2;
00191      }
00192      else
00193      {
00194           //return the first item in the list
00195           return *find_or_throw(jid)->second.begin();
00196      }
00197 }
00198 
00199 PresenceDB::const_iterator PresenceDB::find(const std::string& jid) const
00200 {
00201      PresenceDB::db::const_iterator it = find_or_throw(jid);
00202      // If the list is empty, throw an exception, otherwise return the first
00203      // item in the list
00204      if (it->second.begin() != it->second.end())
00205           return find_or_throw(jid)->second.begin();
00206      else
00207           throw XCP_InvalidJID();
00208 }
00209 
00210 bool PresenceDB::contains(const std::string& jid) const
00211 {
00212      return (_DB.find(JID::getUserHost(jid)) != _DB.end());
00213 }
00214 
00215 bool PresenceDB::available(const std::string& jid) const
00216 {
00217      db::const_iterator it = _DB.find(JID::getUserHost(jid));
00218      // it->second is a list that could be empty so we need to check
00219      // if there is actually an item in the list before we call getType
00220      // on the first iitem
00221      if (it != _DB.end() && it->second.begin() != it->second.end())
00222           return (it->second.begin()->getType() == Presence::ptAvailable);
00223      else
00224           return false;
00225 }
00226 
00227 void PresenceDB::clear()
00228 {
00229      // Erase all entries from the DB
00230      _DB.clear();
00231 }
00232 } //  namespace jabberoo

Generated on Thu Jul 24 13:31:50 2003 for jabberoo by doxygen1.3-rc3