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

jabberoo-presencedb.cc

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 "jabberoo.hh"
00031 using namespace jabberoo;
00032 
00033 // Helpful predicates
00034 class pred_presence_jid
00035 {
00036 string _jid;
00037 public:
00038      pred_presence_jid(const Presence& p)
00039           : _jid(p.getFrom()) {}
00040      pred_presence_jid(const string& s) : _jid(s) {}
00041      // is there a string function to do a case insensitive compare?
00042      bool operator()(const Presence& p) const
00043           { return (JID::compare(_jid, p.getFrom()) == 0); }
00044 };
00045 
00046 class pred_presence_priority
00047 {
00048 int _priority;
00049 public:
00050      pred_presence_priority(const Presence& p)
00051           : _priority(p.getPriority()){}
00052      bool operator()(const Presence& p) const
00053           { return p.getPriority() <= _priority; }
00054 };
00055 
00056 PresenceDB::PresenceDB(Session& s)
00057      : _Owner(s)
00058 {}
00059 
00060 PresenceDB::db::const_iterator PresenceDB::find_or_throw(const string& jid) const
00061 {
00062      db::const_iterator it = _DB.find(JID::getUserHost(jid));
00063      if (it != _DB.end())
00064           return it;
00065      else
00066           throw XCP_InvalidJID();
00067 }
00068 
00069 void display(const Presence& p)
00070 {
00071      cerr << "\tItem: " << p.toString() << endl;
00072 }
00073 
00074 
00075 void PresenceDB::insert(const Presence& p)
00076 {
00077      // Get a reference to the list (create one if necessary)
00078      list<Presence>& l = _DB[JID::getUserHost(p.getFrom())];
00079      
00080      // If this presence is ptUnavailable, remove it from the cache
00081      if (p.getType() == Presence::ptUnavailable ||
00082          p.getType() == Presence::ptError)
00083      {
00084           // Empty list? Then exit..
00085           if (l.empty())
00086           {
00087                _DB.erase(JID::getUserHost(p.getFrom()));
00088                return;
00089           }
00090           else
00091           {
00092                // Attempt to find the presence packet and erase
00093                iterator it = find_if(l.begin(), l.end(), pred_presence_jid(p));
00094                if (it != l.end())
00095                     l.erase(it);
00096                // If the list is now empty, remove this entry from the _DB map
00097                if (l.empty())
00098                     _DB.erase(JID::getUserHost(p.getFrom()));
00099         }
00100     }
00101     // Otherwise, insert/update 
00102     else 
00103     {
00104         // If this list is empty, insert this presence and be done with it
00105         if (l.empty())
00106           {
00107                l.push_back(p);
00108           }
00109           // Otherwise insert into the list
00110           else
00111           {
00112                // Identify any existing items w/ this JID 
00113                iterator it = find_if(l.begin(), l.end(), pred_presence_jid(p));
00114                if (it != l.end())
00115                {
00116                     // If the item found has the same priority, simply update
00117                     if (it->getPriority() == p.getPriority())
00118                     {
00119                          // Replace and exit
00120                          *it = p;
00121                          return;
00122                     }
00123                     // Otherwise erase the element 
00124                     else
00125                          l.erase(it);
00126                }
00127                // Now identify the insertion point for this element
00128                it = find_if(l.begin(), l.end(), pred_presence_priority(p));
00129                l.insert(it, p);
00130           }
00131      }
00132 }
00133 
00134 void PresenceDB::remove(const string& jid)
00135 {
00136      list<Presence>& l = _DB[JID::getUserHost(jid)];
00137      
00138      // Empty list? Then exit..
00139      if (l.empty())
00140      {
00141           _DB.erase(JID::getUserHost(jid));
00142           return;
00143      }
00144      else
00145      {
00146           // Attempt to find the presence packet and erase
00147           iterator it = find_if(l.begin(), l.end(), pred_presence_jid(jid));
00148           if (it != l.end())
00149                l.erase(it);
00150           // If the list is now empty, remove this entry from the _DB map
00151           if (l.empty())
00152                _DB.erase(JID::getUserHost(jid));
00153      }
00154 }
00155 
00156 
00157 PresenceDB::range PresenceDB::equal_range(const string& jid) const
00158 {
00159     db::const_iterator it = find_or_throw(jid);
00160     return make_pair(it->second.begin(), it->second.end());
00161 }
00162 
00163 Presence PresenceDB::findExact(const string& jid) const
00164 {
00165      PresenceDB::db::const_iterator it = find_or_throw(jid);
00166 
00167      // If the list is empty, throw an exception
00168      if (it->second.begin() == it->second.end())
00169           throw XCP_InvalidJID();
00170 
00171      // otherwise check for a resource
00172      string::size_type i = jid.find("/");
00173      if (i != string::npos)
00174      {
00175           list<Presence> l= it->second;
00176 
00177           //return matching resource
00178           // Identify any existing items w/ this JID 
00179           iterator it2 = find_if(l.begin(), l.end(), pred_presence_jid(jid));
00180 
00181           // if we didn't find an entry, throw an exception
00182           if (it2 == l.end())
00183                throw XCP_InvalidJID();
00184 
00185           // return presence matching the full JID
00186           return *it2;
00187      }
00188      else
00189      {
00190           //return the first item in the list
00191           return *find_or_throw(jid)->second.begin();
00192      }
00193 }
00194 
00195 PresenceDB::const_iterator PresenceDB::find(const string& jid) const
00196 {
00197      PresenceDB::db::const_iterator it = find_or_throw(jid);
00198      // If the list is empty, throw an exception, otherwise return the first
00199      // item in the list
00200      if (it->second.begin() != it->second.end())
00201           return find_or_throw(jid)->second.begin();
00202      else
00203           throw XCP_InvalidJID();
00204 }
00205 
00206 bool PresenceDB::contains(const string& jid) const
00207 {
00208      return (_DB.find(JID::getUserHost(jid)) != _DB.end());
00209 }
00210 
00211 bool PresenceDB::available(const string& jid) const
00212 {
00213      db::const_iterator it = _DB.find(JID::getUserHost(jid));
00214      // it->second is a list that could be empty so we need to check
00215      // if there is actually an item in the list before we call getType
00216      // on the first iitem
00217      if (it != _DB.end() && it->second.begin() != it->second.end())
00218           return (it->second.begin()->getType() == Presence::ptAvailable);
00219      else
00220           return false;
00221 }
00222 
00223 void PresenceDB::clear()
00224 {
00225      // Erase all entries from the DB
00226      _DB.clear();
00227 }

Generated at Tue Apr 16 17:09:06 2002 for jabberoo by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001