mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-27 00:32:07 +01:00
7bb63a5d8d
git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@2404 b35dd754-fafc-0310-a699-88a17e54d16e
591 lines
No EOL
28 KiB
HTML
591 lines
No EOL
28 KiB
HTML
<html>
|
|
<head>
|
|
<title>Multi User Chat</title>
|
|
<link rel="stylesheet" type="text/css" href="style.css" />
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<div class="header">Multi User Chat</div><p>
|
|
|
|
Allows configuration of, participation in, and administration of individual text-based conference rooms.<p>
|
|
|
|
<ul>
|
|
<li><a href="#create">Create a new Room</a></li>
|
|
<li><a href="#join">Join a room</a></li>
|
|
<li><a href="#invite">Manage room invitations</a></li>
|
|
<li><a href="#discomuc">Discover MUC support</a></li>
|
|
<li><a href="#discojoin">Discover joined rooms</a></li>
|
|
<li><a href="#privchat">Start a private chat</a></li>
|
|
<li><a href="#subject">Manage changes on room subject</a></li>
|
|
<li><a href="#role">Manage role modifications</a></li>
|
|
<li><a href="#afiliation">Manage affiliation modifications</a></li>
|
|
</ul>
|
|
<b>JEP related:</b> <a href="http://www.jabber.org/jeps/jep-0045.html">JEP-45</a>
|
|
|
|
<hr>
|
|
|
|
<div class="subheader"><a name="create">Create a new Room</a></div><p>
|
|
|
|
<b>Description</b><p>
|
|
|
|
Allowed users may create new rooms. There are two types of rooms that you can create. <b>Instant rooms</b>
|
|
which are available for immediate access and are automatically created based on some default
|
|
configuration and <b>Reserved rooms</b> which are manually configured by the room creator before
|
|
anyone is allowed to enter.</p>
|
|
|
|
<b>Usage</b><p>
|
|
|
|
In order to create a room you will need to first create an instance of <i><b>MultiUserChat</b></i>. The
|
|
room name passed to the constructor will be the name of the room to create. The next step is to send
|
|
<b>create(String nickname)</b> to the <i><b>MultiUserChat</b></i> instance where nickname is the nickname
|
|
to use when joining the room.</p><p>
|
|
|
|
Depending on the type of room that you want to create you will have to use different configuration forms. In
|
|
order to create an Instant room just send <b>sendConfigurationForm(Form form)</b> where form is an empty form.
|
|
But if you want to create a Reserved room then you should first get the room's configuration form, complete
|
|
the form and finally send it back to the server.</p>
|
|
|
|
<b>Examples</b><p>
|
|
|
|
In this example we can see how to create an instant room: <br>
|
|
<blockquote>
|
|
<pre> <font color="#3f7f5f">// Create a MultiUserChat using an XMPPConnection for a room</font>
|
|
MultiUserChat muc = new MultiUserChat(conn1, <font color="#0000FF">"myroom@conference.jabber.org"</font>);
|
|
|
|
<font color="#3f7f5f">// Create the room</font>
|
|
muc.create(<font color="#0000FF">"testbot"</font>);
|
|
|
|
<font color="#3f7f5f">// Send an empty room configuration form which indicates that we want</font>
|
|
<font color="#3f7f5f">// an instant room</font>
|
|
muc.sendConfigurationForm(new Form(Form.TYPE_SUBMIT));
|
|
</pre>
|
|
</blockquote>
|
|
|
|
In this example we can see how to create a reserved room. The form is completed with default values: <br>
|
|
<blockquote>
|
|
<pre> <font color="#3f7f5f">// Create a MultiUserChat using an XMPPConnection for a room</font>
|
|
MultiUserChat muc = new MultiUserChat(conn1, <font color="#0000FF">"myroom@conference.jabber.org"</font>);
|
|
|
|
<font color="#3f7f5f">// Create the room</font>
|
|
muc.create(<font color="#0000FF">"testbot"</font>);
|
|
|
|
<font color="#3f7f5f">// Get the the room's configuration form</font>
|
|
Form form = muc.getConfigurationForm();
|
|
<font color="#3f7f5f">// Create a new form to submit based on the original form</font>
|
|
Form submitForm = form.createAnswerForm();
|
|
<font color="#3f7f5f">// Add default answers to the form to submit</font>
|
|
for (Iterator fields = form.getFields(); fields.hasNext();) {
|
|
FormField field = (FormField) fields.next();
|
|
if (!FormField.TYPE_HIDDEN.equals(field.getType()) && field.getVariable() != null) {
|
|
<font color="#3f7f5f">// Sets the default value as the answer</font>
|
|
submitForm.setDefaultAnswer(field.getVariable());
|
|
}
|
|
}
|
|
<font color="#3f7f5f">// Sets the new owner of the room</font>
|
|
List owners = new ArrayList();
|
|
owners.add(<font color="#0000FF">"johndoe@jabber.org"</font>);
|
|
submitForm.setAnswer(<font color="#0000FF">"muc#roomconfig_roomowners"</font>, owners);
|
|
<font color="#3f7f5f">// Send the completed form (with default values) to the server to configure the room</font>
|
|
muc.sendConfigurationForm(submitForm);
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<hr>
|
|
|
|
<div class="subheader"><a name="join">Join a room</a></div><p>
|
|
|
|
<b>Description</b><p>
|
|
|
|
Your usual first step in order to send messages to a room is to join the room. Multi User Chat allows
|
|
to specify several parameter while joining a room. Basically you can control the amount of history to
|
|
receive after joining the room as well as provide your nickname within the room and a password if the
|
|
room is password protected.</p>
|
|
|
|
<b>Usage</b><p>
|
|
|
|
In order to join a room you will need to first create an instance of <i><b>MultiUserChat</b></i>. The
|
|
room name passed to the constructor will be the name of the room to join. The next step is to send
|
|
<b>join(...)</b> to the <i><b>MultiUserChat</b></i> instance. But first you will have to decide which
|
|
join message to send. If you want to just join the room without a password and without specifying the amount
|
|
of history to receive then you could use <b>join(String nickname)</b> where nickname if your nickname in
|
|
the room. In case the room requires a password in order to join you could then use
|
|
<b>join(String nickname, String password)</b>. And finally, the most complete way to join a room is to send
|
|
<b>join(String nickname, long timeout, String password, int maxchars, int maxstanzas, int seconds, Date since)</b>
|
|
where nickname is your nickname in the room, timeout is the amount of time to wait for a reply from the MUC
|
|
service(in milleseconds), password is your password to join the room, maxchars is the total number of characters
|
|
to receive in the history, maxstanzas is the total number of messages to receive in the history, seconds indicates
|
|
to the service to send only the messages received in the last "X" seconds and since indicates to the service
|
|
to send only the messages received since the Date specified.</p>
|
|
|
|
<b>Examples</b><p>
|
|
|
|
In this example we can see how to join a room with a given nickname: <br>
|
|
<blockquote>
|
|
<pre> <font color="#3f7f5f">// Create a MultiUserChat using an XMPPConnection for a room</font>
|
|
MultiUserChat muc2 = new MultiUserChat(conn1, <font color="#0000FF">"myroom@conference.jabber.org"</font>);
|
|
|
|
<font color="#3f7f5f">// User2 joins the new room</font>
|
|
<font color="#3f7f5f">// The room service will decide the amount of history to send</font>
|
|
muc2.join(<font color="#0000FF">"testbot2"</font>);
|
|
</pre>
|
|
</blockquote>
|
|
|
|
In this example we can see how to join a room with a given nickname and password: <br>
|
|
<blockquote>
|
|
<pre> <font color="#3f7f5f">// Create a MultiUserChat using an XMPPConnection for a room</font>
|
|
MultiUserChat muc2 = new MultiUserChat(conn1, <font color="#0000FF">"myroom@conference.jabber.org"</font>);
|
|
|
|
<font color="#3f7f5f">// User2 joins the new room using a password</font>
|
|
<font color="#3f7f5f">// The room service will decide the amount of history to send</font>
|
|
muc2.join(<font color="#0000FF">"testbot2"</font>, <font color="#0000FF">"password"</font>);
|
|
</pre>
|
|
</blockquote>
|
|
|
|
In this example we can see how to join a room with a given nickname specifying the amount of history
|
|
to receive: <br>
|
|
<blockquote>
|
|
<pre> <font color="#3f7f5f">// Create a MultiUserChat using an XMPPConnection for a room</font>
|
|
MultiUserChat muc2 = new MultiUserChat(conn1, <font color="#0000FF">"myroom@conference.jabber.org"</font>);
|
|
|
|
<font color="#3f7f5f">// User2 joins the new room using a password and specifying</font>
|
|
<font color="#3f7f5f">// the amount of history to receive</font>
|
|
muc2.join(<font color="#0000FF">"testbot2"</font>,SmackConfiguration.getPacketReplyTimeout(), <font color="#0000FF">"password"</font>, 0, -1, -1, null);
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<hr>
|
|
|
|
<div class="subheader"><a name="invite">Manage room invitations</a></div><p>
|
|
|
|
<b>Description</b><p>
|
|
|
|
It can be useful to invite another user to a room in which one is an occupant. Depending on the
|
|
room's type the invitee could receive a password to use to join the room and/or be added to the
|
|
member list if the room is of type members-only. Smack allows to send room invitations and let
|
|
potential invitees to listening for room invitations and inviters to listen for invitees'
|
|
rejections.</p>
|
|
|
|
<b>Usage</b><p>
|
|
|
|
In order to invite another user to a room you must be already joined to the room. Once you are
|
|
joined just send <b>invite(String participant, String reason)</b> to the <i><b>MultiUserChat</b></i>
|
|
where participant is the user to invite to the room (e.g. hecate@shakespeare.lit) and reason is
|
|
the reason why the user is being invited.</p><p>
|
|
|
|
If potential invitees want to listen for room invitations then the invitee must add an <i><b>InvitationListener</b></i>
|
|
to the <i><b>MultiUserChat</b></i> class. Since the <i><b>InvitationListener</b></i> is an <i>interface</i>,
|
|
it is necessary to create a class that implements this <i>interface</i>. If an inviter wants to
|
|
listen for room invitation rejections, just add an <i><b>InvitationRejectionListener</b></i>
|
|
to the <i><b>MultiUserChat</b></i>. <i><b>InvitationRejectionListener</b></i> is also an
|
|
interface so you will need to create a class that implements this interface.</p>
|
|
|
|
<b>Examples</b><p>
|
|
|
|
In this example we can see how to invite another user to the room and lister for possible rejections: <br>
|
|
<blockquote>
|
|
<pre> <font color="#3f7f5f">// User2 joins the room</font>
|
|
MultiUserChat muc2 = new MultiUserChat(conn2, room);
|
|
muc2.join(<font color="#0000FF">"testbot2"</font>);
|
|
|
|
<font color="#3f7f5f">// User2 listens for invitation rejections</font>
|
|
muc2.addInvitationRejectionListener(new InvitationRejectionListener() {
|
|
public void invitationDeclined(String invitee, String reason) {
|
|
<font color="#3f7f5f">// Do whatever you need here...</font>
|
|
}
|
|
});
|
|
|
|
<font color="#3f7f5f">// User2 invites user3 to join to the room</font>
|
|
muc2.invite(<font color="#0000FF">"user3@host.org/Smack"</font>, <font color="#0000FF">"Meet me in this excellent room"</font>);
|
|
</pre>
|
|
</blockquote>
|
|
|
|
In this example we can see how to listen for room invitations and decline invitations: <br>
|
|
<blockquote>
|
|
<pre> <font color="#3f7f5f">// User3 listens for MUC invitations</font>
|
|
MultiUserChat.addInvitationListener(conn3, new InvitationListener() {
|
|
public void invitationReceived(XMPPConnection conn, String room, String inviter, String reason, String password) {
|
|
<font color="#3f7f5f">// Reject the invitation</font>
|
|
MultiUserChat.decline(conn, room, inviter, <font color="#0000FF">"I'm busy right now"</font>);
|
|
}
|
|
});
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<hr>
|
|
|
|
<div class="subheader"><a name="discomuc">Discover MUC support</a></div><p>
|
|
|
|
<b>Description</b><p>
|
|
|
|
A user may want to discover if one of the user's contacts supports the Multi-User Chat protocol.</p>
|
|
|
|
<b>Usage</b><p>
|
|
|
|
In order to discover if one of the user's contacts supports MUC just send
|
|
<b>isServiceEnabled(XMPPConnection connection, String user)</b> to the <i><b>MultiUserChat</b></i>
|
|
class where user is a fully qualified XMPP ID, e.g. jdoe@example.com. You will receive
|
|
a boolean indicating whether the user supports MUC or not.</p>
|
|
|
|
<b>Examples</b><p>
|
|
|
|
In this example we can see how to discover support of MUC: <br>
|
|
<blockquote>
|
|
<pre> <font color="#3f7f5f">// Discover whether user3@host.org supports MUC or not</font>
|
|
boolean supports = MultiUserChat.isServiceEnabled(conn, <font color="#0000FF">"user3@host.org/Smack"</font>);
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<hr>
|
|
|
|
<div class="subheader"><a name="discojoin">Discover joined rooms</a></div><p>
|
|
|
|
<b>Description</b><p>
|
|
|
|
A user may also want to query a contact regarding which rooms the contact is in.</p>
|
|
|
|
<b>Usage</b><p>
|
|
|
|
In order to get the rooms where a user is in just send
|
|
<b>getJoinedRooms(XMPPConnection connection, String user)</b> to the <i><b>MultiUserChat</b></i>
|
|
class where user is a fully qualified XMPP ID, e.g. jdoe@example.com. You will get an Iterator
|
|
of Strings as an answer where each String represents a room name.</p>
|
|
|
|
<b>Examples</b><p>
|
|
|
|
In this example we can see how to get the rooms where a user is in: <br>
|
|
<blockquote>
|
|
<pre> <font color="#3f7f5f">// Get the rooms where user3@host.org has joined</font>
|
|
Iterator joinedRooms = MultiUserChat.getJoinedRooms(conn, <font color="#0000FF">"user3@host.org/Smack"</font>);
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<hr>
|
|
|
|
<div class="subheader"><a name="privchat">Start a private chat</a></div><p>
|
|
|
|
<b>Description</b><p>
|
|
|
|
A room occupant may want to start a private chat with another room occupant even though they
|
|
don't know the fully qualified XMPP ID (e.g. jdoe@example.com) of each other.</p>
|
|
|
|
<b>Usage</b><p>
|
|
|
|
To create a private chat with another room occupant just send <b>createPrivateChat(String participant)</b>
|
|
to the <i><b>MultiUserChat</b></i> that you used to join the room. The parameter participant is the
|
|
occupant unique room JID (e.g. 'darkcave@macbeth.shakespeare.lit/Paul'). You will receive
|
|
a regular <i><b>Chat</b></i> object that you can use to chat with the other room occupant.</p>
|
|
|
|
<b>Examples</b><p>
|
|
|
|
In this example we can see how to start a private chat with another room occupant: <br>
|
|
<blockquote>
|
|
<pre> <font color="#3f7f5f">// Start a private chat with another participant</font>
|
|
Chat chat = muc2.createPrivateChat(<font color="#0000FF">"myroom@conference.jabber.org/johndoe"</font>);
|
|
chat.sendMessage(<font color="#0000FF">"Hello there"</font>);
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<hr>
|
|
|
|
<div class="subheader"><a name="subject">Manage changes on room subject</a></div><p>
|
|
|
|
<b>Description</b><p>
|
|
|
|
A common feature of multi-user chat rooms is the ability to change the subject within the room. As a
|
|
default, only users with a role of "moderator" are allowed to change the subject in a room. Although
|
|
some rooms may be configured to allow a mere participant or even a visitor to change the subject.</p><p>
|
|
|
|
Every time the room's subject is changed you may want to be notified of the modification. The new subject
|
|
could be used to display an in-room message.</p>
|
|
|
|
<b>Usage</b><p>
|
|
|
|
In order to modify the room's subject just send <b>changeSubject(String subject)</b> to the
|
|
<i><b>MultiUserChat</b></i> that you used to join the room where subject is the new room's subject. On
|
|
the other hand, if you want to be notified whenever the room's subject is modified you should add a
|
|
<i><b>SubjectUpdatedListener</b></i> to the <i><b>MultiUserChat</b></i> by sending
|
|
<b>addSubjectUpdatedListener(SubjectUpdatedListener listener)</b> to the <i><b>MultiUserChat</b></i>.
|
|
Since the <i><b>SubjectUpdatedListener</b></i> is an <i>interface</i>, it is necessary to create a class
|
|
that implements this <i>interface</i>.</p>
|
|
|
|
<b>Examples</b><p>
|
|
|
|
In this example we can see how to change the room's subject and react whenever the room's subject is
|
|
modified: <br>
|
|
<blockquote>
|
|
<pre> <font color="#3f7f5f">// An occupant wants to be notified every time the room's subject is changed</font>
|
|
muc3.addSubjectUpdatedListener(new SubjectUpdatedListener() {
|
|
public void subjectUpdated(String subject, String from) {
|
|
....
|
|
}
|
|
});
|
|
|
|
<font color="#3f7f5f">// A room's owner changes the room's subject</font>
|
|
muc2.changeSubject(<font color="#0000FF">"New Subject"</font>);
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<hr>
|
|
|
|
<div class="subheader"><a name="role">Manage role modifications</a></div><p>
|
|
|
|
<b>Description</b><p>
|
|
|
|
There are four defined roles that an occupant can have:</p>
|
|
<ol start="" type="">
|
|
<li>Moderator</li>
|
|
<li>Participant</li>
|
|
<li>Visitor</li>
|
|
<li>None (the absence of a role)</li>
|
|
</ol><p>
|
|
|
|
These roles are temporary in that they do not persist across a user's visits to the room
|
|
and can change during the course of an occupant's visit to the room.</p><p>
|
|
|
|
A moderator is the most powerful occupant within the context of the room, and can to some
|
|
extent manage other occupants' roles in the room. A participant has fewer privileges than a
|
|
moderator, although he or she always has the right to speak. A visitor is a more restricted
|
|
role within the context of a moderated room, since visitors are not allowed to send messages
|
|
to all occupants.</p><p>
|
|
|
|
Roles are granted, revoked, and maintained based on the occupant's room nickname or full
|
|
JID. Whenever an occupant's role is changed Smack will trigger specific events.</p>
|
|
|
|
<b>Usage</b><p>
|
|
|
|
In order to grant voice (i.e. make someone a <i>participant</i>) just send the message
|
|
<b>grantVoice(String nickname)</b> to <i><b>MultiUserChat</b></i>. Use <b>revokeVoice(String nickname)</b>
|
|
to revoke the occupant's voice (i.e. make the occupant a <i>visitor</i>).</p><p>
|
|
|
|
In order to grant moderator privileges to a participant or visitor just send the message
|
|
<b>grantModerator(String nickname)</b> to <i><b>MultiUserChat</b></i>. Use <b>revokeModerator(String nickname)</b>
|
|
to revoke the moderator privilege from the occupant thus making the occupant a participant.</p><p>
|
|
|
|
Smack allows you to listen for role modification events. If you are interested in listening role modification
|
|
events of any occupant then use the listener <b><i>ParticipantStatusListener</i></b>. But if you are interested
|
|
in listening for your own role modification events, use the listener <b><i>UserStatusListener</i></b>. Both listeners
|
|
should be added to the <i><b>MultiUserChat</b></i> by using
|
|
<b>addParticipantStatusListener(ParticipantStatusListener listener)</b> or
|
|
<b>addUserStatusListener(UserStatusListener listener)</b> respectively. These listeners include several notification
|
|
events but you may be interested in just a few of them. Smack provides default implementations for these listeners
|
|
avoiding you to implement all the interfaces' methods. The default implementations are <b><i>DefaultUserStatusListener</i></b>
|
|
and <b><i>DefaultParticipantStatusListener</i></b>. Below you will find the sent messages to the listeners whenever
|
|
an occupant's role has changed.</p><p>
|
|
|
|
These are the triggered events when the role has been upgraded:
|
|
</p>
|
|
<table border="1">
|
|
<tr><td><b>Old</b></td><td><b>New</b></td><td><b>Events</b></td></tr>
|
|
|
|
<tr><td>None</td><td>Visitor</td><td>--</td></tr>
|
|
<tr><td>Visitor</td><td>Participant</td><td>voiceGranted</td></tr>
|
|
<tr><td>Participant</td><td>Moderator</td><td>moderatorGranted</td></tr>
|
|
|
|
<tr><td>None</td><td>Participant</td><td>voiceGranted</td></tr>
|
|
<tr><td>None</td><td>Moderator</td><td>voiceGranted + moderatorGranted</td></tr>
|
|
<tr><td>Visitor</td><td>Moderator</td><td>voiceGranted + moderatorGranted</td></tr>
|
|
</table><p>
|
|
|
|
These are the triggered events when the role has been downgraded:
|
|
</p>
|
|
<table border="1">
|
|
<tr><td><b>Old</b></td><td><b>New</b></td><td><b>Events</b></td></tr>
|
|
|
|
<tr><td>Moderator</td><td>Participant</td><td>moderatorRevoked</td></tr>
|
|
<tr><td>Participant</td><td>Visitor</td><td>voiceRevoked</td></tr>
|
|
<tr><td>Visitor</td><td>None</td><td>kicked</td></tr>
|
|
|
|
<tr><td>Moderator</td><td>Visitor</td><td>voiceRevoked + moderatorRevoked</td></tr>
|
|
<tr><td>Moderator</td><td>None</td><td>kicked</td></tr>
|
|
<tr><td>Participant</td><td>None</td><td>kicked</td></tr>
|
|
</table></p>
|
|
|
|
<b>Examples</b><p>
|
|
|
|
In this example we can see how to grant voice to a visitor and listen for the notification events: <br>
|
|
<blockquote>
|
|
<pre> <font color="#3f7f5f">// User1 creates a room</font>
|
|
muc = new MultiUserChat(conn1, <font color="#0000FF">"myroom@conference.jabber.org"</font>);
|
|
muc.create(<font color="#0000FF">"testbot"</font>);
|
|
|
|
<font color="#3f7f5f">// User1 (which is the room owner) configures the room as a moderated room</font>
|
|
Form form = muc.getConfigurationForm();
|
|
Form answerForm = form.createAnswerForm();
|
|
answerForm.setAnswer(<font color="#0000FF">"muc#roomconfig_moderatedroom"</font>, <font color="#0000FF">"1"</font>);
|
|
muc.sendConfigurationForm(answerForm);
|
|
|
|
<font color="#3f7f5f">// User2 joins the new room (as a visitor)</font>
|
|
MultiUserChat muc2 = new MultiUserChat(conn2, <font color="#0000FF">"myroom@conference.jabber.org"</font>);
|
|
muc2.join(<font color="#0000FF">"testbot2"</font>);
|
|
<font color="#3f7f5f">// User2 will listen for his own "voice" notification events</font>
|
|
muc2.addUserStatusListener(new DefaultUserStatusListener() {
|
|
public void voiceGranted() {
|
|
super.voiceGranted();
|
|
...
|
|
}
|
|
public void voiceRevoked() {
|
|
super.voiceRevoked();
|
|
...
|
|
}
|
|
});
|
|
|
|
<font color="#3f7f5f">// User3 joins the new room (as a visitor)</font>
|
|
MultiUserChat muc3 = new MultiUserChat(conn3, <font color="#0000FF">"myroom@conference.jabber.org"</font>);
|
|
muc3.join(<font color="#0000FF">"testbot3"</font>);
|
|
<font color="#3f7f5f">// User3 will lister for other occupants "voice" notification events</font>
|
|
muc3.addParticipantStatusListener(new DefaultParticipantStatusListener() {
|
|
public void voiceGranted(String participant) {
|
|
super.voiceGranted(participant);
|
|
...
|
|
}
|
|
|
|
public void voiceRevoked(String participant) {
|
|
super.voiceRevoked(participant);
|
|
...
|
|
}
|
|
});
|
|
|
|
<font color="#3f7f5f">// The room's owner grants voice to user2</font>
|
|
muc.grantVoice(<font color="#0000FF">"testbot2"</font>);
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<hr>
|
|
|
|
<div class="subheader"><a name="afiliation">Manage affiliation modifications</a></div><p>
|
|
|
|
<b>Description</b><p>
|
|
|
|
There are five defined affiliations that a user can have in relation to a room:</p>
|
|
<ol start="" type="">
|
|
<li>Owner</li>
|
|
<li>Admin</li>
|
|
<li>Member</li>
|
|
<li>Outcast</li>
|
|
<li>None (the absence of an affiliation)</li>
|
|
</ol><p>
|
|
|
|
These affiliations are semi-permanent in that they persist across a user's visits to the room and
|
|
are not affected by happenings in the room. Affiliations are granted, revoked, and maintained
|
|
based on the user's bare JID.</p><p>
|
|
|
|
If a user without a defined affiliation enters a room, the user's affiliation is defined as "none";
|
|
however, this affiliation does not persist across visits.</p><p>
|
|
|
|
Owners and admins are by definition immune from certain actions. Specifically, an owner or admin cannot
|
|
be kicked from a room and cannot be banned from a room. An admin must first lose his or her affiliation
|
|
(i.e., have an affiliation of "none" or "member") before such actions could be performed
|
|
on them.</p><p>
|
|
|
|
The member affiliation provides a way for a room owner or admin to specify a "whitelist" of users
|
|
who are allowed to enter a members-only room. When a member enters a members-only room, his or her affiliation
|
|
does not change, no matter what his or her role is. The member affiliation also provides a way for users to
|
|
effectively register with an open room and thus be permanently associated with that room in some way (one
|
|
result may be that the user's nickname is reserved in the room).</p><p>
|
|
|
|
An outcast is a user who has been banned from a room and who is not allowed to enter the room. Whenever a
|
|
user's affiliation is changed Smack will trigger specific events.</p>
|
|
|
|
<b>Usage</b><p>
|
|
|
|
In order to grant membership to a room, administrator privileges or owner priveliges just send
|
|
<b>grantMembership(String jid)</b>, <b>grantAdmin(String jid)</b> or <b>grantOwnership(String jid)</b>
|
|
to <i><b>MultiUserChat</b></i> respectively. Use <b>revokeMembership(String jid)</b>, <b>revokeAdmin(String jid)</b>
|
|
or <b>revokeOwnership(String jid)</b> to revoke the membership to a room, administrator privileges or
|
|
owner priveliges respectively.</p><p>
|
|
|
|
In order to ban a user from the room just send the message <b>banUser(String jid, String reason)</b> to
|
|
<i><b>MultiUserChat</b></i>.</p><p>
|
|
|
|
Smack allows you to listen for affiliation modification events. If you are interested in listening affiliation modification
|
|
events of any user then use the listener <b><i>ParticipantStatusListener</i></b>. But if you are interested
|
|
in listening for your own affiliation modification events, use the listener <b><i>UserStatusListener</i></b>. Both listeners
|
|
should be added to the <i><b>MultiUserChat</b></i> by using
|
|
<b>addParticipantStatusListener(ParticipantStatusListener listener)</b> or
|
|
<b>addUserStatusListener(UserStatusListener listener)</b> respectively. These listeners include several notification
|
|
events but you may be interested in just a few of them. Smack provides default implementations for these listeners
|
|
avoiding you to implement all the interfaces' methods. The default implementations are <b><i>DefaultUserStatusListener</i></b>
|
|
and <b><i>DefaultParticipantStatusListener</i></b>. Below you will find the sent messages to the listeners whenever
|
|
a user's affiliation has changed.</p><p>
|
|
|
|
These are the triggered events when the affiliation has been upgraded:
|
|
</p>
|
|
<table border="1">
|
|
<tr><td><b>Old</b></td><td><b>New</b></td><td><b>Events</b></td></tr>
|
|
|
|
<tr><td>None</td><td>Member</td><td>membershipGranted</td></tr>
|
|
<tr><td>Member</td><td>Admin</td><td>membershipRevoked + adminGranted</td></tr>
|
|
<tr><td>Admin</td><td>Owner</td><td>adminRevoked + ownershipGranted</td></tr>
|
|
|
|
<tr><td>None</td><td>Admin</td><td>adminGranted</td></tr>
|
|
<tr><td>None</td><td>Owner</td><td>ownershipGranted</td></tr>
|
|
<tr><td>Member</td><td>Owner</td><td>membershipRevoked + ownershipGranted</td></tr>
|
|
</table><p>
|
|
|
|
These are the triggered events when the affiliation has been downgraded:
|
|
</p>
|
|
<table border="1">
|
|
<tr><td><b>Old</b></td><td><b>New</b></td><td><b>Events</b></td></tr>
|
|
|
|
<tr><td>Owner</td><td>Admin</td><td>ownershipRevoked + adminGranted</td></tr>
|
|
<tr><td>Admin</td><td>Member</td><td>adminRevoked + membershipGranted</td></tr>
|
|
<tr><td>Member</td><td>None</td><td>membershipRevoked</td></tr>
|
|
|
|
<tr><td>Owner</td><td>Member</td><td>ownershipRevoked + membershipGranted</td></tr>
|
|
<tr><td>Owner</td><td>None</td><td>ownershipRevoked</td></tr>
|
|
<tr><td>Admin</td><td>None</td><td>adminRevoked</td></tr>
|
|
<tr><td><i>Anyone</i></td><td>Outcast</td><td>banned</td></tr>
|
|
</table></p>
|
|
|
|
<b>Examples</b><p>
|
|
|
|
In this example we can see how to grant admin privileges to a user and listen for the notification events: <br>
|
|
<blockquote>
|
|
<pre> <font color="#3f7f5f">// User1 creates a room</font>
|
|
muc = new MultiUserChat(conn1, <font color="#0000FF">"myroom@conference.jabber.org"</font>);
|
|
muc.create(<font color="#0000FF">"testbot"</font>);
|
|
|
|
<font color="#3f7f5f">// User1 (which is the room owner) configures the room as a moderated room</font>
|
|
Form form = muc.getConfigurationForm();
|
|
Form answerForm = form.createAnswerForm();
|
|
answerForm.setAnswer(<font color="#0000FF">"muc#roomconfig_moderatedroom"</font>, <font color="#0000FF">"1"</font>);
|
|
muc.sendConfigurationForm(answerForm);
|
|
|
|
<font color="#3f7f5f">// User2 joins the new room (as a visitor)</font>
|
|
MultiUserChat muc2 = new MultiUserChat(conn2, <font color="#0000FF">"myroom@conference.jabber.org"</font>);
|
|
muc2.join(<font color="#0000FF">"testbot2"</font>);
|
|
<font color="#3f7f5f">// User2 will listen for his own admin privileges</font>
|
|
muc2.addUserStatusListener(new DefaultUserStatusListener() {
|
|
public void membershipRevoked() {
|
|
super.membershipRevoked();
|
|
...
|
|
}
|
|
public void adminGranted() {
|
|
super.adminGranted();
|
|
...
|
|
}
|
|
});
|
|
|
|
<font color="#3f7f5f">// User3 joins the new room (as a visitor)</font>
|
|
MultiUserChat muc3 = new MultiUserChat(conn3, <font color="#0000FF">"myroom@conference.jabber.org"</font>);
|
|
muc3.join(<font color="#0000FF">"testbot3"</font>);
|
|
<font color="#3f7f5f">// User3 will lister for other users admin privileges</font>
|
|
muc3.addParticipantStatusListener(new DefaultParticipantStatusListener() {
|
|
public void membershipRevoked(String participant) {
|
|
super.membershipRevoked(participant);
|
|
...
|
|
}
|
|
public void adminGranted(String participant) {
|
|
super.adminGranted(participant);
|
|
...
|
|
}
|
|
});
|
|
|
|
<font color="#3f7f5f">// The room's owner grants admin privileges to user2</font>
|
|
muc.grantAdmin(<font color="#0000FF">"user2@jabber.org"</font>);
|
|
</pre>
|
|
</blockquote>
|
|
</body>
|
|
|
|
</html> |