1 /* 2 * libjingle 3 * Copyright 2004--2005, Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #ifndef _rostermoduleimpl_h_ 29 #define _rostermoduleimpl_h_ 30 31 #include "talk/xmpp/moduleimpl.h" 32 #include "talk/xmpp/rostermodule.h" 33 34 namespace buzz { 35 36 //! Presence Information 37 //! This class stores both presence information for outgoing presence and is 38 //! returned by methods in XmppRosterModule to represent recieved incoming 39 //! presence information. When this class is writeable (non-const) then each 40 //! update to any property will set the inner xml. Setting the raw_xml will 41 //! rederive all of the other properties. 42 class XmppPresenceImpl : public XmppPresence { 43 public: ~XmppPresenceImpl()44 virtual ~XmppPresenceImpl() {} 45 46 //! The from Jid of for the presence information. 47 //! Typically this will be a full Jid with resource specified. For outgoing 48 //! presence this should remain JID_NULL and will be scrubbed from the 49 //! stanza when being sent. 50 virtual const Jid jid() const; 51 52 //! Is the contact available? 53 virtual XmppPresenceAvailable available() const; 54 55 //! Sets if the user is available or not 56 virtual XmppReturnStatus set_available(XmppPresenceAvailable available); 57 58 //! The show value of the presence info 59 virtual XmppPresenceShow presence_show() const; 60 61 //! Set the presence show value 62 virtual XmppReturnStatus set_presence_show(XmppPresenceShow show); 63 64 //! The Priority of the presence info 65 virtual int priority() const; 66 67 //! Set the priority of the presence 68 virtual XmppReturnStatus set_priority(int priority); 69 70 //! The plain text status of the presence info. 71 //! If there are multiple status because of language, this will either be a 72 //! status that is not tagged for language or the first available 73 virtual const std::string& status() const; 74 75 //! Sets the status for the presence info. 76 //! If there is more than one status present already then this will remove 77 //! them all and replace it with one status element we no specified language 78 virtual XmppReturnStatus set_status(const std::string& status); 79 80 //! The raw xml of the presence update 81 virtual const XmlElement* raw_xml() const; 82 83 //! Sets the raw presence stanza for the presence update 84 //! This will cause all other data items in this structure to be rederived 85 virtual XmppReturnStatus set_raw_xml(const XmlElement * xml); 86 87 private: 88 XmppPresenceImpl(); 89 90 friend class XmppPresence; 91 friend class XmppRosterModuleImpl; 92 93 void CreateRawXmlSkeleton(); 94 95 // Store everything in the XML element. If this becomes a perf issue we can 96 // cache the data. 97 talk_base::scoped_ptr<XmlElement> raw_xml_; 98 }; 99 100 //! A contact as given by the server 101 class XmppRosterContactImpl : public XmppRosterContact { 102 public: ~XmppRosterContactImpl()103 virtual ~XmppRosterContactImpl() {} 104 105 //! The jid for the contact. 106 //! Typically this will be a bare Jid. 107 virtual const Jid jid() const; 108 109 //! Sets the jid for the roster contact update 110 virtual XmppReturnStatus set_jid(const Jid& jid); 111 112 //! The name (nickname) stored for this contact 113 virtual const std::string& name() const; 114 115 //! Sets the name 116 virtual XmppReturnStatus set_name(const std::string& name); 117 118 //! The Presence subscription state stored on the server for this contact 119 //! This is never settable and will be ignored when generating a roster 120 //! add/update request 121 virtual XmppSubscriptionState subscription_state() const; 122 123 //! The number of Groups applied to this contact 124 virtual size_t GetGroupCount() const; 125 126 //! Gets a Group applied to the contact based on index. 127 virtual const std::string& GetGroup(size_t index) const; 128 129 //! Adds a group to this contact. 130 //! This will return a no error if the group is already present. 131 virtual XmppReturnStatus AddGroup(const std::string& group); 132 133 //! Removes a group from the contact. 134 //! This will return no error if the group isn't there 135 virtual XmppReturnStatus RemoveGroup(const std::string& group); 136 137 //! The raw xml for this roster contact 138 virtual const XmlElement* raw_xml() const; 139 140 //! Sets the raw presence stanza for the presence update 141 //! This will cause all other data items in this structure to be rederived 142 virtual XmppReturnStatus set_raw_xml(const XmlElement * xml); 143 144 private: 145 XmppRosterContactImpl(); 146 147 void CreateRawXmlSkeleton(); 148 void SetXmlFromWire(const XmlElement * xml); 149 void ResetGroupCache(); 150 151 bool FindGroup(const std::string& group, 152 XmlElement** element, 153 XmlChild** child_before); 154 155 friend class XmppRosterContact; 156 friend class XmppRosterModuleImpl; 157 158 int group_count_; 159 int group_index_returned_; 160 XmlElement * group_returned_; 161 talk_base::scoped_ptr<XmlElement> raw_xml_; 162 }; 163 164 //! An XmppModule for handle roster and presence functionality 165 class XmppRosterModuleImpl : public XmppModuleImpl, 166 public XmppRosterModule, public XmppIqHandler { 167 public: 168 virtual ~XmppRosterModuleImpl(); 169 170 IMPLEMENT_XMPPMODULE 171 172 //! Sets the roster handler (callbacks) for the module 173 virtual XmppReturnStatus set_roster_handler(XmppRosterHandler * handler); 174 175 //! Gets the roster handler for the module 176 virtual XmppRosterHandler* roster_handler(); 177 178 // USER PRESENCE STATE ------------------------------------------------------- 179 180 //! Gets the aggregate outgoing presence 181 //! This object is non-const and be edited directly. No update is sent 182 //! to the server until a Broadcast is sent 183 virtual XmppPresence* outgoing_presence(); 184 185 //! Broadcasts that the user is available. 186 //! Nothing with respect to presence is sent until this is called. 187 virtual XmppReturnStatus BroadcastPresence(); 188 189 //! Sends a directed presence to a Jid 190 //! Note that the client doesn't store where directed presence notifications 191 //! have been sent. The server can keep the appropriate state 192 virtual XmppReturnStatus SendDirectedPresence(const XmppPresence* presence, 193 const Jid& to_jid); 194 195 // INCOMING PRESENCE STATUS -------------------------------------------------- 196 197 //! Returns the number of incoming presence data recorded 198 virtual size_t GetIncomingPresenceCount(); 199 200 //! Returns an incoming presence datum based on index 201 virtual const XmppPresence* GetIncomingPresence(size_t index); 202 203 //! Gets the number of presence data for a bare Jid 204 //! There may be a datum per resource 205 virtual size_t GetIncomingPresenceForJidCount(const Jid& jid); 206 207 //! Returns a single presence data for a Jid based on index 208 virtual const XmppPresence* GetIncomingPresenceForJid(const Jid& jid, 209 size_t index); 210 211 // ROSTER MANAGEMENT --------------------------------------------------------- 212 213 //! Requests an update of the roster from the server 214 //! This must be called to initialize the client side cache of the roster 215 //! After this is sent the server should keep this module apprised of any 216 //! changes. 217 virtual XmppReturnStatus RequestRosterUpdate(); 218 219 //! Returns the number of contacts in the roster 220 virtual size_t GetRosterContactCount(); 221 222 //! Returns a contact by index 223 virtual const XmppRosterContact* GetRosterContact(size_t index); 224 225 //! Finds a contact by Jid 226 virtual const XmppRosterContact* FindRosterContact(const Jid& jid); 227 228 //! Send a request to the server to add a contact 229 //! Note that the contact won't show up in the roster until the server can 230 //! respond. This happens async when the socket is being serviced 231 virtual XmppReturnStatus RequestRosterChange( 232 const XmppRosterContact* contact); 233 234 //! Request that the server remove a contact 235 //! The jabber protocol specifies that the server should also cancel any 236 //! subscriptions when this is done. Like adding, this contact won't be 237 //! removed until the server responds. 238 virtual XmppReturnStatus RequestRosterRemove(const Jid& jid); 239 240 // SUBSCRIPTION MANAGEMENT --------------------------------------------------- 241 242 //! Request a subscription to presence notifications form a Jid 243 virtual XmppReturnStatus RequestSubscription(const Jid& jid); 244 245 //! Cancel a subscription to presence notifications from a Jid 246 virtual XmppReturnStatus CancelSubscription(const Jid& jid); 247 248 //! Approve a request to deliver presence notifications to a jid 249 virtual XmppReturnStatus ApproveSubscriber(const Jid& jid); 250 251 //! Deny or cancel presence notification deliver to a jid 252 virtual XmppReturnStatus CancelSubscriber(const Jid& jid); 253 254 // XmppIqHandler IMPLEMENTATION ---------------------------------------------- 255 virtual void IqResponse(XmppIqCookie cookie, const XmlElement * stanza); 256 257 protected: 258 // XmppModuleImpl OVERRIDES -------------------------------------------------- 259 virtual bool HandleStanza(const XmlElement *); 260 261 // PRIVATE DATA -------------------------------------------------------------- 262 private: 263 friend class XmppRosterModule; 264 XmppRosterModuleImpl(); 265 266 // Helper functions 267 void DeleteIncomingPresence(); 268 void DeleteContacts(); 269 XmppReturnStatus SendSubscriptionRequest(const Jid& jid, 270 const std::string& type); 271 void InternalSubscriptionRequest(const Jid& jid, const XmlElement* stanza, 272 XmppSubscriptionRequestType request_type); 273 void InternalIncomingPresence(const Jid& jid, const XmlElement* stanza); 274 void InternalIncomingPresenceError(const Jid& jid, const XmlElement* stanza); 275 void InternalRosterItems(const XmlElement* stanza); 276 277 // Member data 278 XmppPresenceImpl outgoing_presence_; 279 XmppRosterHandler* roster_handler_; 280 281 typedef std::vector<XmppPresenceImpl*> PresenceVector; 282 typedef std::map<Jid, PresenceVector*> JidPresenceVectorMap; 283 talk_base::scoped_ptr<JidPresenceVectorMap> incoming_presence_map_; 284 talk_base::scoped_ptr<PresenceVector> incoming_presence_vector_; 285 286 typedef std::vector<XmppRosterContactImpl*> ContactVector; 287 talk_base::scoped_ptr<ContactVector> contacts_; 288 }; 289 290 } 291 292 #endif 293