mirror of
https://github.com/vanitasvitae/Smack.git
synced 2025-12-13 22:41:08 +01:00
Add partial support for XEP-0249 Direct MUC Invitations.
Exposes a method for a MUC to invite a user to the room, and adds a listener to the MultiUserChat listener to inform users of direct invitations they have received. Fixes SMACK-932.
This commit is contained in:
parent
f6c85d9fb3
commit
9e9c233468
5 changed files with 481 additions and 0 deletions
|
|
@ -74,6 +74,7 @@ import org.jivesoftware.smackx.muc.MultiUserChatException.MucNotJoinedException;
|
|||
import org.jivesoftware.smackx.muc.MultiUserChatException.NotAMucServiceException;
|
||||
import org.jivesoftware.smackx.muc.filter.MUCUserStatusCodeFilter;
|
||||
import org.jivesoftware.smackx.muc.packet.Destroy;
|
||||
import org.jivesoftware.smackx.muc.packet.GroupChatInvitation;
|
||||
import org.jivesoftware.smackx.muc.packet.MUCAdmin;
|
||||
import org.jivesoftware.smackx.muc.packet.MUCInitialPresence;
|
||||
import org.jivesoftware.smackx.muc.packet.MUCItem;
|
||||
|
|
@ -1063,6 +1064,51 @@ public class MultiUserChat {
|
|||
connection.sendStanza(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invites another user to the room in which one is an occupant. In contrast
|
||||
* to the method "invite", the invitation is sent directly to the user rather
|
||||
* than via the chat room. This is useful when the user being invited is
|
||||
* offline, as otherwise the invitation would be dropped.
|
||||
*
|
||||
* @param address the user to send the invitation to
|
||||
* @throws NotConnectedException if the XMPP connection is not connected.
|
||||
* @throws InterruptedException if the calling thread was interrupted.
|
||||
*/
|
||||
public void inviteDirectly(EntityBareJid address) throws NotConnectedException, InterruptedException {
|
||||
inviteDirectly(address, null, null, false, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invites another user to the room in which one is an occupant. In contrast
|
||||
* to the method "invite", the invitation is sent directly to the user rather
|
||||
* than via the chat room. This is useful when the user being invited is
|
||||
* offline, as otherwise the invitation would be dropped.
|
||||
*
|
||||
* @param address the user to send the invitation to
|
||||
* @param reason the purpose for the invitation
|
||||
* @param password specifies a password needed for entry
|
||||
* @param continueAsOneToOneChat specifies if the groupchat room continues a one-to-one chat having the designated thread
|
||||
* @param thread the thread to continue
|
||||
* @throws NotConnectedException if the XMPP connection is not connected.
|
||||
* @throws InterruptedException if the calling thread was interrupted.
|
||||
*/
|
||||
public void inviteDirectly(EntityBareJid address, String reason, String password, boolean continueAsOneToOneChat, String thread)
|
||||
throws NotConnectedException, InterruptedException {
|
||||
// Add the extension for direct invitation
|
||||
GroupChatInvitation invitationExt = new GroupChatInvitation(room,
|
||||
reason,
|
||||
password,
|
||||
continueAsOneToOneChat,
|
||||
thread);
|
||||
|
||||
Message message = connection.getStanzaFactory().buildMessageStanza()
|
||||
.to(address)
|
||||
.addExtension(invitationExt)
|
||||
.build();
|
||||
|
||||
connection.sendStanza(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a listener to invitation rejections notifications. The listener will be fired anytime
|
||||
* an invitation is declined.
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ import org.jivesoftware.smack.XMPPConnection;
|
|||
import org.jivesoftware.smack.XMPPConnectionRegistry;
|
||||
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
|
||||
import org.jivesoftware.smack.filter.AndFilter;
|
||||
import org.jivesoftware.smack.filter.ExtensionElementFilter;
|
||||
import org.jivesoftware.smack.filter.MessageTypeFilter;
|
||||
import org.jivesoftware.smack.filter.NotFilter;
|
||||
import org.jivesoftware.smack.filter.StanzaExtensionFilter;
|
||||
|
|
@ -57,6 +58,7 @@ import org.jivesoftware.smackx.disco.packet.DiscoverInfo;
|
|||
import org.jivesoftware.smackx.disco.packet.DiscoverItems;
|
||||
import org.jivesoftware.smackx.muc.MultiUserChatException.MucNotJoinedException;
|
||||
import org.jivesoftware.smackx.muc.MultiUserChatException.NotAMucServiceException;
|
||||
import org.jivesoftware.smackx.muc.packet.GroupChatInvitation;
|
||||
import org.jivesoftware.smackx.muc.packet.MUCInitialPresence;
|
||||
import org.jivesoftware.smackx.muc.packet.MUCUser;
|
||||
|
||||
|
|
@ -139,6 +141,11 @@ public final class MultiUserChatManager extends Manager {
|
|||
private static final StanzaFilter INVITATION_FILTER = new AndFilter(StanzaTypeFilter.MESSAGE, new StanzaExtensionFilter(new MUCUser()),
|
||||
new NotFilter(MessageTypeFilter.ERROR));
|
||||
|
||||
private static final StanzaFilter DIRECT_INVITATION_FILTER =
|
||||
new AndFilter(StanzaTypeFilter.MESSAGE,
|
||||
new ExtensionElementFilter<GroupChatInvitation>(GroupChatInvitation.class),
|
||||
new NotFilter(MessageTypeFilter.ERROR));
|
||||
|
||||
private static final ExpirationCache<DomainBareJid, DiscoverInfo> KNOWN_MUC_SERVICES = new ExpirationCache<>(
|
||||
100, 1000 * 60 * 60 * 24);
|
||||
|
||||
|
|
@ -199,6 +206,33 @@ public final class MultiUserChatManager extends Manager {
|
|||
};
|
||||
connection.addAsyncStanzaListener(invitationPacketListener, INVITATION_FILTER);
|
||||
|
||||
// Listens for all messages that include an XEP-0249 GroupChatInvitation extension and fire the invitation
|
||||
// listeners
|
||||
StanzaListener directInvitationStanzaListener = new StanzaListener() {
|
||||
@Override
|
||||
public void processStanza(Stanza stanza) {
|
||||
final Message message = (Message) stanza;
|
||||
GroupChatInvitation invite =
|
||||
stanza.getExtension(GroupChatInvitation.class);
|
||||
|
||||
// Fire event for invitation listeners
|
||||
final MultiUserChat muc = getMultiUserChat(invite.getRoomAddress());
|
||||
final XMPPConnection connection = connection();
|
||||
final EntityJid from = message.getFrom().asEntityJidIfPossible();
|
||||
if (from == null) {
|
||||
LOGGER.warning("Group Chat Invitation from non entity JID in '" + message + "'");
|
||||
return;
|
||||
}
|
||||
final String reason = invite.getReason();
|
||||
final String password = invite.getPassword();
|
||||
final MUCUser.Invite mucInvite = new MUCUser.Invite(reason, from, connection.getUser().asEntityBareJid());
|
||||
for (final InvitationListener listener : invitationsListeners) {
|
||||
listener.invitationReceived(connection, muc, from, reason, password, message, mucInvite);
|
||||
}
|
||||
}
|
||||
};
|
||||
connection.addAsyncStanzaListener(directInvitationStanzaListener, DIRECT_INVITATION_FILTER);
|
||||
|
||||
connection.addConnectionListener(new ConnectionListener() {
|
||||
@Override
|
||||
public void authenticated(XMPPConnection connection, boolean resumed) {
|
||||
|
|
|
|||
|
|
@ -69,6 +69,10 @@ public class GroupChatInvitation implements ExtensionElement {
|
|||
public static final QName QNAME = new QName(NAMESPACE, ELEMENT);
|
||||
|
||||
private final EntityBareJid roomAddress;
|
||||
private final String reason;
|
||||
private final String password;
|
||||
private final String thread;
|
||||
private final boolean continueAsOneToOneChat;
|
||||
|
||||
/**
|
||||
* Creates a new group chat invitation to the specified room address.
|
||||
|
|
@ -79,7 +83,67 @@ public class GroupChatInvitation implements ExtensionElement {
|
|||
* @param roomAddress the address of the group chat room.
|
||||
*/
|
||||
public GroupChatInvitation(EntityBareJid roomAddress) {
|
||||
this(roomAddress, null, null, false, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new group chat invitation to the specified room address.
|
||||
* GroupChat room addresses are in the form <code>room@service</code>,
|
||||
* where <code>service</code> is the name of group chat server, such as
|
||||
* <code>chat.example.com</code>.
|
||||
*
|
||||
* @param roomAddress the address of the group chat room.
|
||||
* @param reason the purpose for the invitation
|
||||
* @param password specifies a password needed for entry
|
||||
* @param continueAsOneToOneChat specifies if the groupchat room continues a one-to-one chat having the designated thread
|
||||
* @param thread the thread to continue
|
||||
*/
|
||||
public GroupChatInvitation(EntityBareJid roomAddress,
|
||||
String reason,
|
||||
String password,
|
||||
boolean continueAsOneToOneChat,
|
||||
String thread) {
|
||||
this.roomAddress = Objects.requireNonNull(roomAddress);
|
||||
this.reason = reason;
|
||||
this.password = password;
|
||||
this.continueAsOneToOneChat = continueAsOneToOneChat;
|
||||
this.thread = thread;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the purpose for the invitation.
|
||||
*
|
||||
* @return the address of the group chat room.
|
||||
*/
|
||||
public String getReason() {
|
||||
return reason;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the password needed for entry.
|
||||
*
|
||||
* @return the password needed for entry
|
||||
*/
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the thread to continue.
|
||||
*
|
||||
* @return the thread to continue.
|
||||
*/
|
||||
public String getThread() {
|
||||
return thread;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the groupchat room continues a one-to-one chat.
|
||||
*
|
||||
* @return whether the groupchat room continues a one-to-one chat.
|
||||
*/
|
||||
public boolean continueAsOneToOneChat() {
|
||||
return continueAsOneToOneChat;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -107,6 +171,13 @@ public class GroupChatInvitation implements ExtensionElement {
|
|||
public XmlStringBuilder toXML(org.jivesoftware.smack.packet.XmlEnvironment enclosingNamespace) {
|
||||
XmlStringBuilder xml = new XmlStringBuilder(this);
|
||||
xml.attribute("jid", getRoomAddress());
|
||||
xml.optAttribute("reason", getReason());
|
||||
xml.optAttribute("password", getPassword());
|
||||
xml.optAttribute("thread", getThread());
|
||||
|
||||
if (continueAsOneToOneChat())
|
||||
xml.optBooleanAttribute("continue", true);
|
||||
|
||||
xml.closeEmptyElement();
|
||||
return xml;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue