• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 received 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 connection status
81   virtual XmppPresenceConnectionStatus connection_status() const;
82 
83   //! The focus obfuscated GAIA id
84   virtual const std::string google_user_id() const;
85 
86   //! The nickname in the presence
87   virtual const std::string nickname() const;
88 
89   //! The raw xml of the presence update
90   virtual const XmlElement* raw_xml() const;
91 
92   //! Sets the raw presence stanza for the presence update
93   //! This will cause all other data items in this structure to be rederived
94   virtual XmppReturnStatus set_raw_xml(const XmlElement * xml);
95 
96 private:
97   XmppPresenceImpl();
98 
99   friend class XmppPresence;
100   friend class XmppRosterModuleImpl;
101 
102   void CreateRawXmlSkeleton();
103 
104   // Store everything in the XML element. If this becomes a perf issue we can
105   // cache the data.
106   talk_base::scoped_ptr<XmlElement> raw_xml_;
107 };
108 
109 //! A contact as given by the server
110 class XmppRosterContactImpl : public XmppRosterContact {
111 public:
~XmppRosterContactImpl()112   virtual ~XmppRosterContactImpl() {}
113 
114   //! The jid for the contact.
115   //! Typically this will be a bare Jid.
116   virtual const Jid jid() const;
117 
118   //! Sets the jid for the roster contact update
119   virtual XmppReturnStatus set_jid(const Jid& jid);
120 
121   //! The name (nickname) stored for this contact
122   virtual const std::string name() const;
123 
124   //! Sets the name
125   virtual XmppReturnStatus set_name(const std::string& name);
126 
127   //! The Presence subscription state stored on the server for this contact
128   //! This is never settable and will be ignored when generating a roster
129   //! add/update request
130   virtual XmppSubscriptionState subscription_state() const;
131 
132   //! The number of Groups applied to this contact
133   virtual size_t GetGroupCount() const;
134 
135   //! Gets a Group applied to the contact based on index.
136   virtual const std::string GetGroup(size_t index) const;
137 
138   //! Adds a group to this contact.
139   //! This will return a no error if the group is already present.
140   virtual XmppReturnStatus AddGroup(const std::string& group);
141 
142   //! Removes a group from the contact.
143   //! This will return no error if the group isn't there
144   virtual XmppReturnStatus RemoveGroup(const std::string& group);
145 
146   //! The raw xml for this roster contact
147   virtual const XmlElement* raw_xml() const;
148 
149   //! Sets the raw presence stanza for the presence update
150   //! This will cause all other data items in this structure to be rederived
151   virtual XmppReturnStatus set_raw_xml(const XmlElement * xml);
152 
153 private:
154   XmppRosterContactImpl();
155 
156   void CreateRawXmlSkeleton();
157   void SetXmlFromWire(const XmlElement * xml);
158   void ResetGroupCache();
159 
160   bool FindGroup(const std::string& group,
161                  XmlElement** element,
162                  XmlChild** child_before);
163 
164 
165   friend class XmppRosterContact;
166   friend class XmppRosterModuleImpl;
167 
168   int group_count_;
169   int group_index_returned_;
170   XmlElement * group_returned_;
171   talk_base::scoped_ptr<XmlElement> raw_xml_;
172 };
173 
174 //! An XmppModule for handle roster and presence functionality
175 class XmppRosterModuleImpl : public XmppModuleImpl,
176   public XmppRosterModule, public XmppIqHandler {
177 public:
178   virtual ~XmppRosterModuleImpl();
179 
180   IMPLEMENT_XMPPMODULE
181 
182   //! Sets the roster handler (callbacks) for the module
183   virtual XmppReturnStatus set_roster_handler(XmppRosterHandler * handler);
184 
185   //! Gets the roster handler for the module
186   virtual XmppRosterHandler* roster_handler();
187 
188   // USER PRESENCE STATE -------------------------------------------------------
189 
190   //! Gets the aggregate outgoing presence
191   //! This object is non-const and be edited directly.  No update is sent
192   //! to the server until a Broadcast is sent
193   virtual XmppPresence* outgoing_presence();
194 
195   //! Broadcasts that the user is available.
196   //! Nothing with respect to presence is sent until this is called.
197   virtual XmppReturnStatus BroadcastPresence();
198 
199   //! Sends a directed presence to a Jid
200   //! Note that the client doesn't store where directed presence notifications
201   //! have been sent.  The server can keep the appropriate state
202   virtual XmppReturnStatus SendDirectedPresence(const XmppPresence* presence,
203                                                 const Jid& to_jid);
204 
205   // INCOMING PRESENCE STATUS --------------------------------------------------
206 
207   //! Returns the number of incoming presence data recorded
208   virtual size_t GetIncomingPresenceCount();
209 
210   //! Returns an incoming presence datum based on index
211   virtual const XmppPresence* GetIncomingPresence(size_t index);
212 
213   //! Gets the number of presence data for a bare Jid
214   //! There may be a datum per resource
215   virtual size_t GetIncomingPresenceForJidCount(const Jid& jid);
216 
217   //! Returns a single presence data for a Jid based on index
218   virtual const XmppPresence* GetIncomingPresenceForJid(const Jid& jid,
219                                                         size_t index);
220 
221   // ROSTER MANAGEMENT ---------------------------------------------------------
222 
223   //! Requests an update of the roster from the server
224   //! This must be called to initialize the client side cache of the roster
225   //! After this is sent the server should keep this module apprised of any
226   //! changes.
227   virtual XmppReturnStatus RequestRosterUpdate();
228 
229   //! Returns the number of contacts in the roster
230   virtual size_t GetRosterContactCount();
231 
232   //! Returns a contact by index
233   virtual const XmppRosterContact* GetRosterContact(size_t index);
234 
235   //! Finds a contact by Jid
236   virtual const XmppRosterContact* FindRosterContact(const Jid& jid);
237 
238   //! Send a request to the server to add a contact
239   //! Note that the contact won't show up in the roster until the server can
240   //! respond.  This happens async when the socket is being serviced
241   virtual XmppReturnStatus RequestRosterChange(
242     const XmppRosterContact* contact);
243 
244   //! Request that the server remove a contact
245   //! The jabber protocol specifies that the server should also cancel any
246   //! subscriptions when this is done.  Like adding, this contact won't be
247   //! removed until the server responds.
248   virtual XmppReturnStatus RequestRosterRemove(const Jid& jid);
249 
250   // SUBSCRIPTION MANAGEMENT ---------------------------------------------------
251 
252   //! Request a subscription to presence notifications form a Jid
253   virtual XmppReturnStatus RequestSubscription(const Jid& jid);
254 
255   //! Cancel a subscription to presence notifications from a Jid
256   virtual XmppReturnStatus CancelSubscription(const Jid& jid);
257 
258   //! Approve a request to deliver presence notifications to a jid
259   virtual XmppReturnStatus ApproveSubscriber(const Jid& jid);
260 
261   //! Deny or cancel presence notification deliver to a jid
262   virtual XmppReturnStatus CancelSubscriber(const Jid& jid);
263 
264   // XmppIqHandler IMPLEMENTATION ----------------------------------------------
265   virtual void IqResponse(XmppIqCookie cookie, const XmlElement * stanza);
266 
267 protected:
268   // XmppModuleImpl OVERRIDES --------------------------------------------------
269   virtual bool HandleStanza(const XmlElement *);
270 
271   // PRIVATE DATA --------------------------------------------------------------
272 private:
273   friend class XmppRosterModule;
274   XmppRosterModuleImpl();
275 
276   // Helper functions
277   void DeleteIncomingPresence();
278   void DeleteContacts();
279   XmppReturnStatus SendSubscriptionRequest(const Jid& jid,
280                                            const std::string& type);
281   void InternalSubscriptionRequest(const Jid& jid, const XmlElement* stanza,
282                                    XmppSubscriptionRequestType request_type);
283   void InternalIncomingPresence(const Jid& jid, const XmlElement* stanza);
284   void InternalIncomingPresenceError(const Jid& jid, const XmlElement* stanza);
285   void InternalRosterItems(const XmlElement* stanza);
286 
287   // Member data
288   XmppPresenceImpl outgoing_presence_;
289   XmppRosterHandler* roster_handler_;
290 
291   typedef std::vector<XmppPresenceImpl*> PresenceVector;
292   typedef std::map<Jid, PresenceVector*> JidPresenceVectorMap;
293   talk_base::scoped_ptr<JidPresenceVectorMap> incoming_presence_map_;
294   talk_base::scoped_ptr<PresenceVector> incoming_presence_vector_;
295 
296   typedef std::vector<XmppRosterContactImpl*> ContactVector;
297   talk_base::scoped_ptr<ContactVector> contacts_;
298 };
299 
300 }
301 
302 #endif
303