mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-29 09:42:06 +01:00
Check if MUC room is hosted on a MUC service
when trying to enter a room.
This commit is contained in:
parent
bbc7aaae77
commit
ff72ea320c
4 changed files with 69 additions and 9 deletions
|
@ -60,6 +60,7 @@ import org.jivesoftware.smackx.iqregister.packet.Registration;
|
||||||
import org.jivesoftware.smackx.muc.MultiUserChatException.MucAlreadyJoinedException;
|
import org.jivesoftware.smackx.muc.MultiUserChatException.MucAlreadyJoinedException;
|
||||||
import org.jivesoftware.smackx.muc.MultiUserChatException.MucNotJoinedException;
|
import org.jivesoftware.smackx.muc.MultiUserChatException.MucNotJoinedException;
|
||||||
import org.jivesoftware.smackx.muc.MultiUserChatException.MissingMucCreationAcknowledgeException;
|
import org.jivesoftware.smackx.muc.MultiUserChatException.MissingMucCreationAcknowledgeException;
|
||||||
|
import org.jivesoftware.smackx.muc.MultiUserChatException.NotAMucServiceException;
|
||||||
import org.jivesoftware.smackx.muc.filter.MUCUserStatusCodeFilter;
|
import org.jivesoftware.smackx.muc.filter.MUCUserStatusCodeFilter;
|
||||||
import org.jivesoftware.smackx.muc.packet.Destroy;
|
import org.jivesoftware.smackx.muc.packet.Destroy;
|
||||||
import org.jivesoftware.smackx.muc.packet.MUCAdmin;
|
import org.jivesoftware.smackx.muc.packet.MUCAdmin;
|
||||||
|
@ -72,11 +73,13 @@ import org.jivesoftware.smackx.xdata.Form;
|
||||||
import org.jivesoftware.smackx.xdata.FormField;
|
import org.jivesoftware.smackx.xdata.FormField;
|
||||||
import org.jivesoftware.smackx.xdata.packet.DataForm;
|
import org.jivesoftware.smackx.xdata.packet.DataForm;
|
||||||
import org.jxmpp.jid.BareJid;
|
import org.jxmpp.jid.BareJid;
|
||||||
|
import org.jxmpp.jid.DomainBareJid;
|
||||||
import org.jxmpp.jid.FullJid;
|
import org.jxmpp.jid.FullJid;
|
||||||
import org.jxmpp.jid.Jid;
|
import org.jxmpp.jid.Jid;
|
||||||
import org.jxmpp.jid.JidWithLocalpart;
|
import org.jxmpp.jid.JidWithLocalpart;
|
||||||
import org.jxmpp.jid.impl.JidCreate;
|
import org.jxmpp.jid.impl.JidCreate;
|
||||||
import org.jxmpp.jid.parts.Resourcepart;
|
import org.jxmpp.jid.parts.Resourcepart;
|
||||||
|
import org.jxmpp.util.cache.ExpirationCache;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A MultiUserChat room (XEP-45), created with {@link MultiUserChatManager#getMultiUserChat(BareJid)}.
|
* A MultiUserChat room (XEP-45), created with {@link MultiUserChatManager#getMultiUserChat(BareJid)}.
|
||||||
|
@ -98,6 +101,9 @@ import org.jxmpp.jid.parts.Resourcepart;
|
||||||
public class MultiUserChat {
|
public class MultiUserChat {
|
||||||
private static final Logger LOGGER = Logger.getLogger(MultiUserChat.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(MultiUserChat.class.getName());
|
||||||
|
|
||||||
|
private static final ExpirationCache<DomainBareJid, Void> KNOWN_MUC_SERVICES = new ExpirationCache<>(
|
||||||
|
100, 1000 * 60 * 60 * 24);
|
||||||
|
|
||||||
private final XMPPConnection connection;
|
private final XMPPConnection connection;
|
||||||
private final BareJid room;
|
private final BareJid room;
|
||||||
private final MultiUserChatManager multiUserChatManager;
|
private final MultiUserChatManager multiUserChatManager;
|
||||||
|
@ -287,12 +293,21 @@ public class MultiUserChat {
|
||||||
* @throws NoResponseException
|
* @throws NoResponseException
|
||||||
* @throws XMPPErrorException
|
* @throws XMPPErrorException
|
||||||
* @throws InterruptedException
|
* @throws InterruptedException
|
||||||
|
* @throws NotAMucServiceException
|
||||||
* @see <a href="http://xmpp.org/extensions/xep-0045.html#enter">XEP-45 7.2 Entering a Room</a>
|
* @see <a href="http://xmpp.org/extensions/xep-0045.html#enter">XEP-45 7.2 Entering a Room</a>
|
||||||
*/
|
*/
|
||||||
private Presence enter(Resourcepart nickname, String password, DiscussionHistory history,
|
private Presence enter(Resourcepart nickname, String password, DiscussionHistory history,
|
||||||
long timeout) throws NotConnectedException, NoResponseException,
|
long timeout) throws NotConnectedException, NoResponseException,
|
||||||
XMPPErrorException, InterruptedException {
|
XMPPErrorException, InterruptedException, NotAMucServiceException {
|
||||||
StringUtils.requireNotNullOrEmpty(nickname, "Nickname must not be null or blank.");
|
StringUtils.requireNotNullOrEmpty(nickname, "Nickname must not be null or blank.");
|
||||||
|
final DomainBareJid mucService = room.asDomainBareJid();
|
||||||
|
if (!KNOWN_MUC_SERVICES.containsKey(mucService)) {
|
||||||
|
if (multiUserChatManager.providesMucService(mucService)) {
|
||||||
|
KNOWN_MUC_SERVICES.put(mucService, null);
|
||||||
|
} else {
|
||||||
|
throw new NotAMucServiceException(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
// We enter a room by sending a presence packet where the "to"
|
// We enter a room by sending a presence packet where the "to"
|
||||||
// field is in the form "roomName@service/nickname"
|
// field is in the form "roomName@service/nickname"
|
||||||
Presence joinPresence = new Presence(Presence.Type.available);
|
Presence joinPresence = new Presence(Presence.Type.available);
|
||||||
|
@ -369,10 +384,11 @@ public class MultiUserChat {
|
||||||
* @throws NotConnectedException
|
* @throws NotConnectedException
|
||||||
* @throws MucAlreadyJoinedException
|
* @throws MucAlreadyJoinedException
|
||||||
* @throws MissingMucCreationAcknowledgeException
|
* @throws MissingMucCreationAcknowledgeException
|
||||||
|
* @throws NotAMucServiceException
|
||||||
*/
|
*/
|
||||||
public synchronized MucCreateConfigFormHandle create(Resourcepart nickname) throws NoResponseException,
|
public synchronized MucCreateConfigFormHandle create(Resourcepart nickname) throws NoResponseException,
|
||||||
XMPPErrorException, InterruptedException, MucAlreadyJoinedException,
|
XMPPErrorException, InterruptedException, MucAlreadyJoinedException,
|
||||||
NotConnectedException, MissingMucCreationAcknowledgeException {
|
NotConnectedException, MissingMucCreationAcknowledgeException, NotAMucServiceException {
|
||||||
if (joined) {
|
if (joined) {
|
||||||
throw new MucAlreadyJoinedException();
|
throw new MucAlreadyJoinedException();
|
||||||
}
|
}
|
||||||
|
@ -398,10 +414,11 @@ public class MultiUserChat {
|
||||||
* @throws InterruptedException
|
* @throws InterruptedException
|
||||||
* @throws NotConnectedException
|
* @throws NotConnectedException
|
||||||
* @throws MucAlreadyJoinedException
|
* @throws MucAlreadyJoinedException
|
||||||
|
* @throws NotAMucServiceException
|
||||||
* @see #createOrJoin(Resourcepart, String, DiscussionHistory, long)
|
* @see #createOrJoin(Resourcepart, String, DiscussionHistory, long)
|
||||||
*/
|
*/
|
||||||
public synchronized MucCreateConfigFormHandle createOrJoin(Resourcepart nickname) throws NoResponseException, XMPPErrorException,
|
public synchronized MucCreateConfigFormHandle createOrJoin(Resourcepart nickname) throws NoResponseException, XMPPErrorException,
|
||||||
InterruptedException, MucAlreadyJoinedException, NotConnectedException {
|
InterruptedException, MucAlreadyJoinedException, NotConnectedException, NotAMucServiceException {
|
||||||
return createOrJoin(nickname, null, null, connection.getPacketReplyTimeout());
|
return createOrJoin(nickname, null, null, connection.getPacketReplyTimeout());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -422,9 +439,10 @@ public class MultiUserChat {
|
||||||
* @throws InterruptedException
|
* @throws InterruptedException
|
||||||
* @throws MucAlreadyJoinedException if the MUC is already joined
|
* @throws MucAlreadyJoinedException if the MUC is already joined
|
||||||
* @throws NotConnectedException
|
* @throws NotConnectedException
|
||||||
|
* @throws NotAMucServiceException
|
||||||
*/
|
*/
|
||||||
public synchronized MucCreateConfigFormHandle createOrJoin(Resourcepart nickname, String password, DiscussionHistory history, long timeout)
|
public synchronized MucCreateConfigFormHandle createOrJoin(Resourcepart nickname, String password, DiscussionHistory history, long timeout)
|
||||||
throws NoResponseException, XMPPErrorException, InterruptedException, MucAlreadyJoinedException, NotConnectedException {
|
throws NoResponseException, XMPPErrorException, InterruptedException, MucAlreadyJoinedException, NotConnectedException, NotAMucServiceException {
|
||||||
if (joined) {
|
if (joined) {
|
||||||
throw new MucAlreadyJoinedException();
|
throw new MucAlreadyJoinedException();
|
||||||
}
|
}
|
||||||
|
@ -495,9 +513,10 @@ public class MultiUserChat {
|
||||||
* @throws XMPPErrorException
|
* @throws XMPPErrorException
|
||||||
* @throws NotConnectedException
|
* @throws NotConnectedException
|
||||||
* @throws InterruptedException
|
* @throws InterruptedException
|
||||||
|
* @throws NotAMucServiceException
|
||||||
*/
|
*/
|
||||||
public MucCreateConfigFormHandle createOrJoinIfNecessary(Resourcepart nickname, String password) throws NoResponseException,
|
public MucCreateConfigFormHandle createOrJoinIfNecessary(Resourcepart nickname, String password) throws NoResponseException,
|
||||||
XMPPErrorException, NotConnectedException, InterruptedException {
|
XMPPErrorException, NotConnectedException, InterruptedException, NotAMucServiceException {
|
||||||
if (isJoined()) {
|
if (isJoined()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -527,8 +546,9 @@ public class MultiUserChat {
|
||||||
* @throws NoResponseException if there was no response from the server.
|
* @throws NoResponseException if there was no response from the server.
|
||||||
* @throws NotConnectedException
|
* @throws NotConnectedException
|
||||||
* @throws InterruptedException
|
* @throws InterruptedException
|
||||||
|
* @throws NotAMucServiceException
|
||||||
*/
|
*/
|
||||||
public void join(Resourcepart nickname) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
public void join(Resourcepart nickname) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException, NotAMucServiceException {
|
||||||
join(nickname, null, null, connection.getPacketReplyTimeout());
|
join(nickname, null, null, connection.getPacketReplyTimeout());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -553,8 +573,9 @@ public class MultiUserChat {
|
||||||
* @throws InterruptedException
|
* @throws InterruptedException
|
||||||
* @throws NotConnectedException
|
* @throws NotConnectedException
|
||||||
* @throws NoResponseException if there was no response from the server.
|
* @throws NoResponseException if there was no response from the server.
|
||||||
|
* @throws NotAMucServiceException
|
||||||
*/
|
*/
|
||||||
public void join(Resourcepart nickname, String password) throws XMPPErrorException, InterruptedException, NoResponseException, NotConnectedException {
|
public void join(Resourcepart nickname, String password) throws XMPPErrorException, InterruptedException, NoResponseException, NotConnectedException, NotAMucServiceException {
|
||||||
join(nickname, password, null, connection.getPacketReplyTimeout());
|
join(nickname, password, null, connection.getPacketReplyTimeout());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -585,13 +606,14 @@ public class MultiUserChat {
|
||||||
* @throws NoResponseException if there was no response from the server.
|
* @throws NoResponseException if there was no response from the server.
|
||||||
* @throws NotConnectedException
|
* @throws NotConnectedException
|
||||||
* @throws InterruptedException
|
* @throws InterruptedException
|
||||||
|
* @throws NotAMucServiceException
|
||||||
*/
|
*/
|
||||||
public synchronized void join(
|
public synchronized void join(
|
||||||
Resourcepart nickname,
|
Resourcepart nickname,
|
||||||
String password,
|
String password,
|
||||||
DiscussionHistory history,
|
DiscussionHistory history,
|
||||||
long timeout)
|
long timeout)
|
||||||
throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException {
|
throws XMPPErrorException, NoResponseException, NotConnectedException, InterruptedException, NotAMucServiceException {
|
||||||
// If we've already joined the room, leave it before joining under a new
|
// If we've already joined the room, leave it before joining under a new
|
||||||
// nickname.
|
// nickname.
|
||||||
if (joined) {
|
if (joined) {
|
||||||
|
|
|
@ -83,4 +83,23 @@ public abstract class MultiUserChatException extends SmackException {
|
||||||
super("The MUC configuration '" + configString + "' is not supported by the MUC service");
|
super("The MUC configuration '" + configString + "' is not supported by the MUC service");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thrown when trying to enter a MUC room that is not hosted a domain providing a MUC service.
|
||||||
|
* Try {@link MultiUserChatManager#getServiceNames()} for a list of client-local domains
|
||||||
|
* providing a MUC service.
|
||||||
|
*/
|
||||||
|
public static class NotAMucServiceException extends MultiUserChatException {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public NotAMucServiceException(MultiUserChat multiUserChat) {
|
||||||
|
super("Can not join '" + multiUserChat.getRoom() + "', because '"
|
||||||
|
+ multiUserChat.getRoom().asDomainBareJid()
|
||||||
|
+ "' does not provide a MUC (XEP-45) service.");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -261,6 +261,24 @@ public final class MultiUserChatManager extends Manager {
|
||||||
return sdm.findServices(MUCInitialPresence.NAMESPACE, false, false);
|
return sdm.findServices(MUCInitialPresence.NAMESPACE, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the provided domain bare JID provides a MUC service.
|
||||||
|
*
|
||||||
|
* @param domainBareJid the domain bare JID to check.
|
||||||
|
* @return <code>true</code> if the provided JID provides a MUC service, <code>false</code> otherwise.
|
||||||
|
* @throws NoResponseException
|
||||||
|
* @throws XMPPErrorException
|
||||||
|
* @throws NotConnectedException
|
||||||
|
* @throws InterruptedException
|
||||||
|
* @see <a href="http://xmpp.org/extensions/xep-0045.html#disco-service-features">XEP-45 § 6.2 Discovering the Features Supported by a MUC Service</a>
|
||||||
|
* @since 4.2
|
||||||
|
*/
|
||||||
|
public boolean providesMucService(DomainBareJid domainBareJid) throws NoResponseException,
|
||||||
|
XMPPErrorException, NotConnectedException, InterruptedException {
|
||||||
|
return ServiceDiscoveryManager.getInstanceFor(connection()).supportsFeature(domainBareJid,
|
||||||
|
MUCInitialPresence.NAMESPACE);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a List of HostedRooms where each HostedRoom has the XMPP address of the room and the room's name.
|
* Returns a List of HostedRooms where each HostedRoom has the XMPP address of the room and the room's name.
|
||||||
* Once discovered the rooms hosted by a chat service it is possible to discover more detailed room information or
|
* Once discovered the rooms hosted by a chat service it is possible to discover more detailed room information or
|
||||||
|
|
|
@ -34,6 +34,7 @@ import org.jivesoftware.smackx.bookmarks.BookmarkManager;
|
||||||
import org.jivesoftware.smackx.bookmarks.BookmarkedConference;
|
import org.jivesoftware.smackx.bookmarks.BookmarkedConference;
|
||||||
import org.jivesoftware.smackx.muc.MultiUserChat;
|
import org.jivesoftware.smackx.muc.MultiUserChat;
|
||||||
import org.jivesoftware.smackx.muc.MultiUserChat.MucCreateConfigFormHandle;
|
import org.jivesoftware.smackx.muc.MultiUserChat.MucCreateConfigFormHandle;
|
||||||
|
import org.jivesoftware.smackx.muc.MultiUserChatException.NotAMucServiceException;
|
||||||
import org.jivesoftware.smackx.muc.MultiUserChatManager;
|
import org.jivesoftware.smackx.muc.MultiUserChatManager;
|
||||||
import org.jxmpp.jid.parts.Resourcepart;
|
import org.jxmpp.jid.parts.Resourcepart;
|
||||||
|
|
||||||
|
@ -136,7 +137,7 @@ public final class MucBookmarkAutojoinManager extends Manager {
|
||||||
// abort here
|
// abort here
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
catch (NoResponseException | XMPPErrorException e) {
|
catch (NotAMucServiceException | NoResponseException | XMPPErrorException e) {
|
||||||
// Do no abort, just log,
|
// Do no abort, just log,
|
||||||
LOGGER.log(Level.WARNING, "Could not autojoin bookmarked MUC", e);
|
LOGGER.log(Level.WARNING, "Could not autojoin bookmarked MUC", e);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue