4 * Extensible Messaging and Presence Protocol (XMPP)
5 * JEP-0045 Multi-User Chat
7 * Portable Windows Library
9 * Copyright (c) 2004 Reitek S.p.A.
11 * The contents of this file are subject to the Mozilla Public License
12 * Version 1.0 (the "License"); you may not use this file except in
13 * compliance with the License. You may obtain a copy of the License at
14 * http://www.mozilla.org/MPL/
16 * Software distributed under the License is distributed on an "AS IS"
17 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
18 * the License for the specific language governing rights and limitations
21 * The Original Code is Portable Windows Library.
23 * The Initial Developer of the Original Code is Post Increment
25 * Contributor(s): ______________________________________.
28 * Revision 1.1 2004/05/09 07:23:50 rjongbloed
29 * More work on XMPP, thanks Federico Pinna and Reitek S.p.A.
35 #pragma implementation "xmpp_muc.h"
39 #include <ptclib/xmpp_muc.h>
44 PObject::Comparison
XMPP::MUC::User::Compare(const PObject
& obj
) const
46 if (PIsDescendant(&obj
, XMPP::MUC::User
))
47 return m_Nick
.Compare(((const XMPP::MUC::User
&)obj
).m_Nick
);
48 else if (PIsDescendant(&obj
, PString
))
49 return m_Nick
.Compare((const PString
&)obj
);
51 PAssertAlways(PInvalidCast
);
52 return PObject::LessThan
;
55 ///////////////////////////////////////////////////////
57 PString
XMPP::MUC::Namespace("http://jabber.org/protocol/muc");
58 PString
XMPP::MUC::User::Namespace("http://jabber.org/protocol/muc#user");
60 XMPP::MUC::Room::Room(C2S::StreamHandler
* handler
, const JID
& jid
, const PString
& nick
)
61 : m_Handler(handler
), m_RoomJID(jid
)
63 PCREATE_SMART_NOTIFIEE
;
65 if (PAssertNULL(m_Handler
) == NULL
)
69 m_User
.m_Role
= XMPP::MUC::User::None
;
70 m_User
.m_Affiliation
= XMPP::MUC::User::None_a
;
72 m_RoomJID
.SetResource(PString::Empty());
73 m_Handler
->SessionReleasedHandlers().Add(new PCREATE_SMART_NOTIFIER(OnSessionReleased
));
74 m_Handler
->PresenceHandlers().Add(new PCREATE_SMART_NOTIFIER(OnPresence
));
75 m_Handler
->MessageSenderHandlers(m_RoomJID
).Add(new PCREATE_SMART_NOTIFIER(OnMessage
));
79 BOOL
XMPP::MUC::Room::Enter()
81 if (PAssertNULL(m_Handler
) == NULL
)
84 JID
ourUser(m_RoomJID
);
85 ourUser
.SetResource(m_User
.m_Nick
);
89 pre
.SetStatus("Available");
92 PXMLElement
* x
= new PXMLElement(NULL
, "x");
93 x
->SetAttribute(XMPP::Namespace
, XMPP::MUC::Namespace
);
97 return m_Handler
->Write(pre
);
101 BOOL
XMPP::MUC::Room::Leave()
103 if (PAssertNULL(m_Handler
) == NULL
)
107 pre
.SetTo(m_RoomJID
);
108 pre
.SetType(XMPP::Presence::Unavailable
);
110 return m_Handler
->Write(pre
);
114 BOOL
XMPP::MUC::Room::SendMessage(const PString
& msg
)
119 return SendMessage(_msg
);
123 BOOL
XMPP::MUC::Room::SendMessage(Message
& msg
)
125 if (PAssertNULL(m_Handler
) == NULL
)
128 msg
.SetTo(m_RoomJID
);
129 msg
.SetType(XMPP::Message::GroupChat
);
131 return m_Handler
->Write(msg
);
135 void XMPP::MUC::Room::OnMessage(Message
& msg
)
136 { m_MessageHandlers
.Fire(msg
); }
138 void XMPP::MUC::Room::OnRoomJoined()
139 { m_RoomJoinedHandlers
.Fire(*this); }
142 void XMPP::MUC::Room::OnRoomLeft()
143 { m_RoomLeftHandlers
.Fire(*this); }
146 void XMPP::MUC::Room::OnUserAdded(User
& user
)
147 { m_UserAddedHandlers
.Fire(user
); }
150 void XMPP::MUC::Room::OnUserRemoved(User
& user
)
151 { m_UserRemovedHandlers
.Fire(user
); }
154 void XMPP::MUC::Room::OnUserChanged(User
& user
)
155 { m_UserChangedHandlers
.Fire(user
); }
158 void XMPP::MUC::Room::OnSessionReleased(C2S::StreamHandler
&, INT
)
160 m_User
.m_Role
= XMPP::MUC::User::None
;
161 m_User
.m_Affiliation
= XMPP::MUC::User::None_a
;
166 void XMPP::MUC::Room::OnMessage(XMPP::Message
& msg
, INT
)
172 void XMPP::MUC::Room::OnPresence(XMPP::Presence
& msg
, INT
)
174 JID from
= msg
.GetFrom();
175 PString res
= from
.GetResource();
177 if (m_RoomJID
!= from
) // It's not about this room
180 XMPP::MUC::User::Role role
= XMPP::MUC::User::Role::Unknown
;
181 XMPP::MUC::User::Affiliation affiliation
= XMPP::MUC::User::Affiliation::Unknown_a
;
183 PXMLElement
* x
= msg
.GetElement("x");
185 if (x
!= NULL
&& x
->GetAttribute(XMPP::Namespace
) == XMPP::MUC::User::Namespace
) {
186 PXMLElement
* item
= x
->GetElement("item");
189 PString attr
= item
->GetAttribute("role");
191 role
= XMPP::MUC::User::None
;
192 else if (attr
*= "moderator")
193 role
= XMPP::MUC::User::Moderator
;
194 else if (attr
*= "participant")
195 role
= XMPP::MUC::User::Participant
;
196 else if (attr
*= "visitor")
197 role
= XMPP::MUC::User::Visitor
;
199 attr
= item
->GetAttribute("affiliation");
201 affiliation
= XMPP::MUC::User::None_a
;
202 else if (attr
*= "owner")
203 affiliation
= XMPP::MUC::User::Owner
;
204 else if (attr
*= "admin")
205 affiliation
= XMPP::MUC::User::Admin
;
206 else if (attr
*= "member")
207 affiliation
= XMPP::MUC::User::Member
;
208 else if (attr
*= "outcast")
209 affiliation
= XMPP::MUC::User::Outcast
;
213 if (res
== m_User
.m_Nick
) { // is this about us?
214 if (msg
.GetType() == XMPP::Presence::Unavailable
) {
216 m_User
.m_Role
= XMPP::MUC::User::None
;
217 m_User
.m_Affiliation
= XMPP::MUC::User::None_a
;
219 else if (m_User
.m_Role
== XMPP::MUC::User::None
) {
220 m_User
.m_Role
= role
;
221 m_User
.m_Affiliation
= affiliation
;
225 m_User
.m_Role
= role
;
226 m_User
.m_Affiliation
= affiliation
;
227 // TODO: raise a "LocalUserChanged" event...
231 XMPP::MUC::User user
;
234 user
.m_Affiliation
= affiliation
;
236 XMPP::MUC::User
* puser
;
238 PINDEX i
= m_OtherUsers
.GetValuesIndex(user
);
240 if (i
!= P_MAX_INDEX
) { // known user?
241 if (msg
.GetType() == XMPP::Presence::Unavailable
) {
243 m_OtherUsers
.RemoveAt(i
);
246 puser
= (XMPP::MUC::User
*)m_OtherUsers
.GetAt(i
);
247 puser
->m_Role
= role
;
248 puser
->m_Affiliation
= affiliation
;
253 puser
= new XMPP::MUC::User
;
254 puser
->m_Role
= role
;
255 puser
->m_Affiliation
= affiliation
;
256 m_OtherUsers
.Append(puser
);
264 // End of File ///////////////////////////////////////////////////////////////