From a4c49d5e04394a257cc27f008a461f7914f32bda Mon Sep 17 00:00:00 2001
From: Gaston Dombiak
+
+Description
+
+Allowed users may create new rooms. There are two types of rooms that you can create. Instant rooms
+which are available for immediate access and are automatically created based on some default
+configuration and Reserved rooms which are manually configured by the room creator before
+anyone is allowed to enter.
+
+In order to create a room you will need to first create an instance of MultiUserChat. The
+room name passed to the constructor will be the name of the room to create. The next step is to send
+create(String nickname) to the MultiUserChat instance where nickname is the nickname
+to use when joining the room.
+
+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 sendConfigurationForm(Form form) 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.
+
+In this example we can see how to create an instant room:
+
+Description
+
+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.
+
+In order to join a room you will need to first create an instance of MultiUserChat. The
+room name passed to the constructor will be the name of the room to join. The next step is to send
+join(...) to the MultiUserChat 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 join(String nickname) where nickname if your nickname in
+the room. In case the room requires a password in order to join you could then use
+join(String nickname, String password). And finally, the most complete way to join a room is to send
+join(String nickname, long timeout, String password, int maxchars, int maxstanzas, int seconds, Date since)
+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.
+
+In this example we can see how to join a room with a given nickname:
+
+Description
+
+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.
+
+In order to invite another user to a room you must be already joined to the room. Once you are
+joined just send invite(String participant, String reason) to the MultiUserChat
+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.
+
+If potential invitees want to listen for room invitations then the invitee must add an InvitationListener
+to the MultiUserChat class. Since the InvitationListener is an interface,
+it is necessary to create a class that implements this interface. If an inviter wants to
+listen for room invitation rejections, just add an InvitationRejectionListener
+to the MultiUserChat. InvitationRejectionListener is also an
+interface so you will need to create a class that implements this interface.
+
+In this example we can see how to invite another user to the room and lister for possible rejections:
+
+Description
+
+A user may want to discover if one of the user's contacts supports the Multi-User Chat protocol.
+
+In order to discover if one of the user's contacts supports MUC just send
+isServiceEnabled(XMPPConnection connection, String user) to the MultiUserChat
+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.
+
+In this example we can see how to discover support of MUC:
+
+Description
+
+A user may also want to query a contact regarding which rooms the contact is in.
+
+In order to get the rooms where a user is in just send
+getJoinedRooms(XMPPConnection connection, String user) to the MultiUserChat
+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.
+
+In this example we can see how to get the rooms where a user is in:
+
+Description
+
+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.
+
+To create a private chat with another room occupant just send createPrivateChat(String participant)
+to the MultiUserChat 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 Chat object that you can use to chat with the other room occupant.
+
+In this example we can see how to start a private chat with another room occupant:
+
+Description
+
+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.
+
+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.
+
+In order to modify the room's subject just send changeSubject(String subject) to the
+MultiUserChat 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
+SubjectUpdatedListener to the MultiUserChat by sending
+addSubjectUpdatedListener(SubjectUpdatedListener listener) to the MultiUserChat.
+Since the SubjectUpdatedListener is an interface, it is necessary to create a class
+that implements this interface.
+
+In this example we can see how to change the room's subject and react whenever the room's subject is
+modified:
+
+Description
+
+There are four defined roles that an occupant can have:
+
+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.
+
+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.
+
+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.
+
+In order to grant voice (i.e. make someone a participant) just send the message
+grantVoice(String nickname) to MultiUserChat. Use revokeVoice(String nickname)
+to revoke the occupant's voice (i.e. make the occupant a visitor).
+
+In order to grant moderator privileges to a participant or visitor just send the message
+grantModerator(String nickname) to MultiUserChat. Use revokeModerator(String nickname)
+to revoke the moderator privilege from the occupant thus making the occupant a participant.
+
+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 ParticipantStatusListener. But if you are interested
+in listening for your own role modification events, use the listener UserStatusListener. Both listeners
+should be added to the MultiUserChat by using
+addParticipantStatusListener(ParticipantStatusListener listener) or
+addUserStatusListener(UserStatusListener listener) 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 DefaultUserStatusListener
+and DefaultParticipantStatusListener. Below you will find the sent messages to the listeners whenever
+an occupant's role has changed.
+
+These are the triggered events when the role has been upgraded:
+
+
+These are the triggered events when the role has been downgraded:
+
+
JEP related: JEP-45
-More coming soon.
+
+
+
+
+In this example we can see how to create a reserved room: // Create a MultiUserChat using an XMPPConnection for a room
+ MultiUserChat muc = new MultiUserChat(conn1, "myroom@conference.jabber.org");
+
+ // Create the room
+ muc.create("testbot");
+
+ // Send an empty room configuration form which indicates that we want
+ // an instant room
+ muc.sendConfigurationForm(new Form(Form.TYPE_SUBMIT));
+
+
+
+
+
+ // Create a MultiUserChat using an XMPPConnection for a room
+ MultiUserChat muc = new MultiUserChat(conn1, "myroom@conference.jabber.org");
+
+ // Create the room
+ muc.create("testbot");
+
+ // Get the the room's configuration form
+ Form form = muc.getConfigurationForm();
+ // Create a new form to submit based on the original form
+ Form submitForm = form.createAnswerForm();
+ // Add default answers to the form to submit
+ for (Iterator fields = form.getFields(); fields.hasNext();) {
+ FormField field = (FormField) fields.next();
+ if (!FormField.TYPE_HIDDEN.equals(field.getType()) && field.getVariable() != null) {
+ // Add the field values to a List
+ List values = new ArrayList();
+ for (Iterator it = field.getValues(); it.hasNext();) {
+ values.add((String) it.next());
+ }
+ // Sets the new answer to the form to submit
+ submitForm.setAnswer(field.getVariable(), values);
+ }
+ }
+ // Send the completed form (with default values) to the server to configure the room
+ muc.sendConfigurationForm(submitForm);
+
+
+
+
+
+
+
+In this example we can see how to join a room with a given nickname and password: // Create a MultiUserChat using an XMPPConnection for a room
+ MultiUserChat muc2 = new MultiUserChat(conn1, "myroom@conference.jabber.org");
+
+ // User2 joins the new room
+ // The room service will decide the amount of history to send
+ muc2.join("testbot2");
+
+
+
+
+
+In this example we can see how to join a room with a given nickname specifying the amount of history
+to receive: // Create a MultiUserChat using an XMPPConnection for a room
+ MultiUserChat muc2 = new MultiUserChat(conn1, "myroom@conference.jabber.org");
+
+ // User2 joins the new room using a password
+ // The room service will decide the amount of history to send
+ muc2.join("testbot2", "password");
+
+
+
+
+
+ // Create a MultiUserChat using an XMPPConnection for a room
+ MultiUserChat muc2 = new MultiUserChat(conn1, "myroom@conference.jabber.org");
+
+ // User2 joins the new room using a password and specifying
+ // the amount of history to receive
+ muc2.join("testbot2",SmackConfiguration.getPacketReplyTimeout(), "password", 0, -1, -1, null);
+
+
+
+
+
+
+
+In this example we can see how to listen for room invitations and decline invitations: // User2 joins the room
+ MultiUserChat muc2 = new MultiUserChat(conn2, room);
+ muc2.join("testbot2");
+
+ // User2 listens for invitation rejections
+ muc2.addInvitationRejectionListener(new InvitationRejectionListener() {
+ public void invitationDeclined(String invitee, String reason) {
+ // Do whatever you need here...
+ }
+ });
+
+ // User2 invites user3 to join to the room
+ muc2.invite("user3@host.org/Smack", "Meet me in this excellent room");
+
+
+
+
+
+ // User3 listens for MUC invitations
+ MultiUserChat.addInvitationListener(conn3, new InvitationListener() {
+ public void invitationReceived(XMPPConnection conn, String room, String inviter, String reason, String password) {
+ // Reject the invitation
+ MultiUserChat.decline(conn, room, inviter, "I'm busy right now");
+ }
+ });
+
+
+
+
+
+
+
+ // Discover whether user3@host.org supports MUC or not
+ boolean supports = MultiUserChat.isServiceEnabled(conn, "user3@host.org/Smack");
+
+
+
+
+
+
+
+ // Get the rooms where user3@host.org has joined
+ Iterator joinedRooms = MultiUserChat.getJoinedRooms(conn, "user3@host.org/Smack");
+
+
+
+
+
+
+
+ // Start a private chat with another participant
+ Chat chat = muc2.createPrivateChat("myroom@conference.jabber.org/johndoe");
+ chat.sendMessage("Hello there");
+
+
+
+
+
+
+
+ // An occupant wants to be notified every time the room's subject is changed
+ muc3.addSubjectUpdatedListener(new SubjectUpdatedListener() {
+ public void subjectUpdated(String subject, String from) {
+ ....
+ }
+ });
+
+ // A room's owner changes the room's subject
+ muc2.changeSubject("New Subject");
+
+
+
+
+
+
+
+Old New Events
+None Visitor --
+Visitor Participant voiceGranted
+
+Participant Moderator moderatorGranted
+None Participant voiceGranted
+None Moderator voiceGranted + moderatorGranted
+Visitor Moderator voiceGranted + moderatorGranted
+
+
+Old New Events
+Moderator Participant moderatorRevoked
+Participant Visitor voiceRevoked
+
+Visitor None kicked
+Moderator Visitor voiceRevoked + moderatorRevoked
+Moderator None kicked
+Participant None kicked
+
+In this example we can see how to grant voice to a visitor and listen for the notification events:
+
++ +// User1 creates a room + muc = new MultiUserChat(conn1, "myroom@conference.jabber.org"); + muc.create("testbot"); + + // User1 (which is the room owner) configures the room as a moderated room + Form form = muc.getConfigurationForm(); + Form answerForm = form.createAnswerForm(); + answerForm.setAnswer("muc#owner_moderatedroom", "1"); + muc.sendConfigurationForm(answerForm); + + // User2 joins the new room (as a visitor) + MultiUserChat muc2 = new MultiUserChat(conn2, "myroom@conference.jabber.org"); + muc2.join("testbot2"); + // User2 will listen for his own "voice" notification events + muc2.addUserStatusListener(new DefaultUserStatusListener() { + public void voiceGranted() { + super.voiceGranted(); + ... + } + public void voiceRevoked() { + super.voiceRevoked(); + ... + } + }); + + // User3 joins the new room (as a visitor) + MultiUserChat muc3 = new MultiUserChat(conn3, "myroom@conference.jabber.org"); + muc3.join("testbot3"); + // User3 will lister for other occupants "voice" notification events + muc3.addParticipantStatusListener(new DefaultParticipantStatusListener() { + public void voiceGranted(String participant) { + super.voiceGranted(participant); + ... + } + + public void voiceRevoked(String participant) { + super.voiceRevoked(participant); + ... + } + }); + + // The room's owner grants voice to user2 + muc.grantVoice("testbot2"); ++
+ +Description
+ +There are five defined affiliations that a user can have in relation to a room:
++ +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.
+ +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.
+ +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.
+ +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).
+ +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.
+ +Usage+ +In order to grant membership to a room, administrator privileges or owner priveliges just send +grantMembership(String jid), grantAdmin(String jid) or grantOwnership(String jid) +to MultiUserChat respectively. Use revokeMembership(String jid), revokeAdmin(String jid) +or revokeOwnership(String jid) to revoke the membership to a room, administrator privileges or +owner priveliges respectively.
+ +In order to ban a user from the room just send the message banUser(String jid, String reason) to +MultiUserChat.
+ +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 ParticipantStatusListener. But if you are interested +in listening for your own affiliation modification events, use the listener UserStatusListener. Both listeners +should be added to the MultiUserChat by using +addParticipantStatusListener(ParticipantStatusListener listener) or +addUserStatusListener(UserStatusListener listener) 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 DefaultUserStatusListener +and DefaultParticipantStatusListener. Below you will find the sent messages to the listeners whenever +a user's affiliation has changed.
+ +These are the triggered events when the affiliation has been upgraded: +
+Old | New | Events |
None | Member | membershipGranted |
Member | Admin | membershipRevoked + adminGranted |
Admin | Owner | adminRevoked + ownershipGranted |
None | Admin | adminGranted |
None | Owner | ownershipGranted |
Member | Owner | membershipRevoked + ownershipGranted |
+ +These are the triggered events when the affiliation has been downgraded: +
+Old | New | Events |
Owner | Admin | ownershipRevoked + adminGranted |
Admin | Member | adminRevoked + membershipGranted |
Member | None | membershipRevoked |
Owner | Member | ownershipRevoked + membershipGranted |
Owner | None | ownershipRevoked |
Admin | None | adminRevoked |
Anyone | Outcast | banned |
+
+In this example we can see how to grant admin privileges to a user and listen for the notification events:
+
+// User1 creates a room + muc = new MultiUserChat(conn1, "myroom@conference.jabber.org"); + muc.create("testbot"); + + // User1 (which is the room owner) configures the room as a moderated room + Form form = muc.getConfigurationForm(); + Form answerForm = form.createAnswerForm(); + answerForm.setAnswer("muc#owner_moderatedroom", "1"); + muc.sendConfigurationForm(answerForm); + + // User2 joins the new room (as a visitor) + MultiUserChat muc2 = new MultiUserChat(conn2, "myroom@conference.jabber.org"); + muc2.join("testbot2"); + // User2 will listen for his own admin privileges + muc2.addUserStatusListener(new DefaultUserStatusListener() { + public void membershipRevoked() { + super.membershipRevoked(); + ... + } + public void adminGranted() { + super.adminGranted(); + ... + } + }); + + // User3 joins the new room (as a visitor) + MultiUserChat muc3 = new MultiUserChat(conn3, "myroom@conference.jabber.org"); + muc3.join("testbot3"); + // User3 will lister for other users admin privileges + muc3.addParticipantStatusListener(new DefaultParticipantStatusListener() { + public void membershipRevoked(String participant) { + super.membershipRevoked(participant); + ... + } + public void adminGranted(String participant) { + super.adminGranted(participant); + ... + } + }); + + // The room's owner grants admin privileges to user2 + muc.grantAdmin("user2@jabber.org"); ++