org.jivesoftware.smackx.muc.package-info Maven / Gradle / Ivy
/**
*
* Copyright 2015-2023 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Smack API for Multi-User Chat (MUC, XEP-0045). This API allows configuration of, participation in, and administration
* of individual text-based conference rooms. The two key API classes are {@link MultiUserChatManager} and
* {@link MultiUserChat}.
* Create a new Room
* 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.
*
* Usage
*
* In order to create a room you will need to first create an instance of _* *MultiUserChat**_. In order to do so, get a
* instance of `MultiUserChatManager` and call `getMultiUserChat(String)` to retrieve a `MultiUserChat` instance. 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 use `MucCreateConfigFormHandle.makeInstant()`. 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.
*
* Examples
*
* In this example we can see how to create an instant room:
*
*
* {@code
* // Get the MultiUserChatManager
* MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(connection);
* // Get a MultiUserChat using MultiUserChatManager
* MultiUserChat muc = manager.getMultiUserChat(mucJid);
* // Create the room and send an empty configuration form to make this an instant room
* muc.create(nickname).makeInstant();
* }
*
* In this example we can see how to create a reserved room. The form is completed with default values:
*
*
* {@code
* // Get the MultiUserChatManager
* MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(connection);
* // Create a MultiUserChat using an XMPPConnection for a room
* MultiUserChat muc = manager.getMultiUserChat(mucJid);
* // Prepare a list of owners of the new room
* Set owners = JidUtil.jidSetFrom(new String[] { "[email protected]", "[email protected]" });
* // Create the room
* muc.create(nickname).getConfigFormManger().setRoomOwners(owners).submitConfigurationForm();
* }
*
* Join a 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.
*
* Usage
*
* In order to join a room you will need to first get an instance of _**MultiUserChat**_. In order to do so, get a
* instance of `MultiUserChatManager` and call `getMultiUserChat(String)` to retrieve a `MultiUserChat` instance. 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, String password, DiscussionHistory history, long
* timeout)** where nickname is your nickname in the room, , password is your password to join the room, history is an
* object that specifies the amount of history to receive and timeout is the milliseconds to wait for a response from
* the server.
*
* Examples
*
* In this example we can see how to join a room with a given nickname:
*
*
* {@code
* // Get the MultiUserChatManager
* MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(connection);
* // Create a MultiUserChat using an XMPPConnection for a room
* MultiUserChat muc2 = manager.getMultiUserChat(mucJid);
* // User2 joins the new room
* // The room service will decide the amount of history to send
* muc2.join(nickname);
* }
*
* In this example we can see how to join a room with a given nickname and password:
*
*
* {@code
* // Get the MultiUserChatManager
* MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(connection);
* // Create a MultiUserChat using an XMPPConnection for a room
* MultiUserChat muc2 = manager.getMultiUserChat(mucJid);
* // User2 joins the new room using a password
* // The room service will decide the amount of history to send
* muc2.join(nickname, "password");
* }
*
* In this example we can see how to join a room with a given nickname specifying the amount of history to receive:
*
*
* {@code
* // Get the MultiUserChatManager
* MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(connection);
*
* // Create a MultiUserChat using an XMPPConnection for a room
* MultiUserChat muc2 = manager.getMultiUserChat(mucJid);
*
* // User2 joins the new room using a password and specifying
* // the amount of history to receive. In this example we are requesting the last 5 messages.
* DiscussionHistory history = new DiscussionHistory();
* history.setMaxStanzas(5);
* muc2.join(nickname, "password", history, conn1.getPacketReplyTimeout());
* }
*
* Manage room invitations
* 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.
*
* Usage
*
* 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. [email protected]) 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 _**MultiUserChatManager**_ 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.
*
* Examples
*
* In this example we can see how to invite another user to the room and lister for possible rejections:
*
*
* {@code
* // Get the MultiUserChatManager
* MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(connection);
*
* // Create a MultiUserChat using an XMPPConnection for a room
* MultiUserChat muc2 = manager.getMultiUserChat(mucJid);
*
* muc2.join(nickname);
* // 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(otherJid, "Meet me in this excellent room");
* }
*
* In this example we can see how to listen for room invitations and decline invitations:
*
*
* {@code
* // User3 listens for MUC invitations
* MultiUserChatManager.getInstanceFor(connection).addInvitationListener(new InvitationListener() {
* public void invitationReceived(XMPPConnection conn, String room, EntityFullJid inviter, String reason,
* String password) {
* // Reject the invitation
* MultiUserChat.decline(conn, room, inviter.asBareJid(), "I'm busy right now");
* }
* });
* }
*
* Discover MUC support
* Description
*
* A user may want to discover if one of the user's contacts supports the Multi-User Chat protocol.
*
* Usage
*
* In order to discover if one of the user's contacts supports MUC just send isServiceEnabled(String user)** to the
* _**MultiUserChatManager**_ class where user is a fully qualified XMPP ID, e.g. [email protected]. You will receive a
* boolean indicating whether the user supports MUC or not.
*
* Examples
*
* In this example we can see how to discover support of MUC:
*
*
* {@code
* // Discover whether [email protected] supports MUC or not
* boolean supportsMuc = MultiUserChatManager.getInstanceFor(connection).isServiceEnabled(otherJid);
* }
*
* Discover joined rooms
* Description
*
* A user may also want to query a contact regarding which rooms the contact is in.
*
* Usage
*
* In order to get the rooms where a user is in just send getJoinedRooms(String user)** to the
* _**MultiUserChatManager**_ class where user is a fully qualified XMPP ID, e.g. [email protected]. You will get an
* Iterator of Strings as an answer where each String represents a room name.
*
* Examples
*
* In this example we can see how to get the rooms where a user is in:
*
*
* {@code
* // Get the MultiUserChatManager
* MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(connection);
*
* // Get the rooms where [email protected] has joined
* List joinedRooms = manager.getJoinedRooms("[email protected]/Smack");
* }
*
* Discover room information
* Description
*
* A user may need to discover information about a room without having to actually join the room. The server will
* provide information only for public rooms.
*
* Usage
*
* In order to discover information about a room just send getRoomInfo(String room)** to the _**MultiUserChatManager**_
* class where room is the XMPP ID of the room, e.g. [email protected]. You will get a RoomInfo object that
* contains the discovered room information.
*
* Examples
*
* In this example we can see how to discover information about a room:
*
*
* {@code
* // Get the MultiUserChatManager
* MultiUserChatManager manager = MultiUserChatManager.getInstanceFor(connection);
*
* // Discover information about the room [email protected]
* RoomInfo info = manager.getRoomInfo("[email protected]");
* System.out.println("Number of occupants:" + info.getOccupantsCount());
* System.out.println("Room Subject:" + info.getSubject());
* }
*
* Start a private chat
* 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 address (e.g. [email protected]) of each other.
*
* Usage
*
* 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.
* '[email protected]/Paul'). You will receive a regular _**Chat**_ object that you can use to chat with
* the other room occupant.
*
* Examples
*
* In this example we can see how to start a private chat with another room occupant:
*
*
* {@code
* // Start a private chat with another participant
* Chat chat = muc2.createPrivateChat("[email protected]/johndoe");
* chat.sendMessage("Hello there");
* }
*
* Manage changes on room subject
* 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.
*
* Usage
*
* 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_.
*
* Examples
*
* In this example we can see how to change the room's subject and react whenever the room's subject is modified:
*
*
* {@code
* // 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");
* }
*
*
* Description
*
* There are four defined roles that an occupant can have:
*
*
* - Moderator
* - Participant
* - Visitor
* - None (the absence of a role)
*
*
* 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.
*
* Usage
*
* 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:
*
*
* Role Upgrade paths
*
* Old
* New
* Events
*
*
* None
* Visitor
* --
*
*
* Visitor
* Participant
* voiceGranted
*
*
* Participant
* Moderator
* moderatorGranted
*
*
* None
* Participant
* voiceGranted
*
*
* None
* Moderator
* voiceGranted + moderatorGranted
*
*
* Visitor
* Moderator
* voiceGranted + moderatorGranted
*
*
*
* These are the triggered events when the role has been downgraded:
*
*
* Role Downgrade paths
*
* Old
* New
* Events
*
*
* Moderator
* Participant
* moderatorRevoked
*
*
* Participant
* Vistor
* voiceRevoked
*
*
* Visitor
* None
* kicked
*
*
* Moderator
* Visitor
* voiceRevoked + moderatorRevoked
*
*
* Moderator
* None
* kicked
*
*
* Participant
* None
* kicked
*
*
* Examples
*
* In this example we can see how to grant voice to a visitor and listen for the notification events:
*
*
* {@code
* // User1 creates a room
* muc = manager.getMultiUserChat("[email protected]");
* muc.create("testbot");
* // User1 (which is the room owner) configures the room as a moderated room
* Form form = muc.getConfigurationForm();
* FillableForm answerForm = configForm.getFillableForm();
* answerForm.setAnswer("muc#roomconfig_moderatedroom", "1");
* muc.sendConfigurationForm(answerForm);
*
* // User2 joins the new room (as a visitor)
* MultiUserChat muc2 = manager2.getMultiUserChat("[email protected]");
* 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 = manager3.getMultiUserChat("[email protected]");
* 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");
* }
*
* Manage affiliation modifications
* Description
*
* There are five defined affiliations that a user can have in relation to a room:
*
*
* - Owner
* - Admin
* - Member
* - Outcast
* - None (the absence of an affiliation)
*
*
* 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 privileges 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:
*
*
* Affiliation Upgrade paths
*
* 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:
*
*
* Affiliation Downgrade paths
*
* Owner
* Admin
* ownershipRevoked + adminGranted
*
*
* Admin
* Member
* adminRevoked + membershipGranted
*
*
* Member
* None
* membershipRevoked
*
*
* Owner
* Member
* ownershipRevoked + membershipGranted
*
*
* Owner
* None
* ownershipRevoked
*
*
* Admin
* None
* adminRevoked
*
*
* Anyone
* Outcast
* banned
*
*
* Examples
*
* In this example we can see how to grant admin privileges to a user and listen for the notification events:
*
*
* {@code
* // User1 creates a room
* muc = manager.getMultiUserChat("[email protected]");
* muc.create("testbot");
* // User1 (which is the room owner) configures the room as a moderated room
* Form form = muc.getConfigurationForm();
* FillableForm answerForm = configForm.getFillableForm();
* answerForm.setAnswer("muc#roomconfig_moderatedroom", "1");
* muc.sendConfigurationForm(answerForm);
*
* // User2 joins the new room (as a visitor)
* MultiUserChat muc2 = manager2.getMultiUserChat("[email protected]");
* 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 = manager3.getMultiUserChat("[email protected]");
* 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("[email protected]");
* }
*
* @see XEP-0045: Multi-User Chat
*/
package org.jivesoftware.smackx.muc;