mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-25 15:52: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.MucNotJoinedException;
|
||||
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.packet.Destroy;
|
||||
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.packet.DataForm;
|
||||
import org.jxmpp.jid.BareJid;
|
||||
import org.jxmpp.jid.DomainBareJid;
|
||||
import org.jxmpp.jid.FullJid;
|
||||
import org.jxmpp.jid.Jid;
|
||||
import org.jxmpp.jid.JidWithLocalpart;
|
||||
import org.jxmpp.jid.impl.JidCreate;
|
||||
import org.jxmpp.jid.parts.Resourcepart;
|
||||
import org.jxmpp.util.cache.ExpirationCache;
|
||||
|
||||
/**
|
||||
* A MultiUserChat room (XEP-45), created with {@link MultiUserChatManager#getMultiUserChat(BareJid)}.
|
||||
|
@ -98,6 +101,9 @@ import org.jxmpp.jid.parts.Resourcepart;
|
|||
public class MultiUserChat {
|
||||
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 BareJid room;
|
||||
private final MultiUserChatManager multiUserChatManager;
|
||||
|
@ -287,12 +293,21 @@ public class MultiUserChat {
|
|||
* @throws NoResponseException
|
||||
* @throws XMPPErrorException
|
||||
* @throws InterruptedException
|
||||
* @throws NotAMucServiceException
|
||||
* @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,
|
||||
long timeout) throws NotConnectedException, NoResponseException,
|
||||
XMPPErrorException, InterruptedException {
|
||||
XMPPErrorException, InterruptedException, NotAMucServiceException {
|
||||
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"
|
||||
// field is in the form "roomName@service/nickname"
|
||||
Presence joinPresence = new Presence(Presence.Type.available);
|
||||
|
@ -369,10 +384,11 @@ public class MultiUserChat {
|
|||
* @throws NotConnectedException
|
||||
* @throws MucAlreadyJoinedException
|
||||
* @throws MissingMucCreationAcknowledgeException
|
||||
* @throws NotAMucServiceException
|
||||
*/
|
||||
public synchronized MucCreateConfigFormHandle create(Resourcepart nickname) throws NoResponseException,
|
||||
XMPPErrorException, InterruptedException, MucAlreadyJoinedException,
|
||||
NotConnectedException, MissingMucCreationAcknowledgeException {
|
||||
NotConnectedException, MissingMucCreationAcknowledgeException, NotAMucServiceException {
|
||||
if (joined) {
|
||||
throw new MucAlreadyJoinedException();
|
||||
}
|
||||
|
@ -398,10 +414,11 @@ public class MultiUserChat {
|
|||
* @throws InterruptedException
|
||||
* @throws NotConnectedException
|
||||
* @throws MucAlreadyJoinedException
|
||||
* @throws NotAMucServiceException
|
||||
* @see #createOrJoin(Resourcepart, String, DiscussionHistory, long)
|
||||
*/
|
||||
public synchronized MucCreateConfigFormHandle createOrJoin(Resourcepart nickname) throws NoResponseException, XMPPErrorException,
|
||||
InterruptedException, MucAlreadyJoinedException, NotConnectedException {
|
||||
InterruptedException, MucAlreadyJoinedException, NotConnectedException, NotAMucServiceException {
|
||||
return createOrJoin(nickname, null, null, connection.getPacketReplyTimeout());
|
||||
}
|
||||
|
||||
|
@ -422,9 +439,10 @@ public class MultiUserChat {
|
|||
* @throws InterruptedException
|
||||
* @throws MucAlreadyJoinedException if the MUC is already joined
|
||||
* @throws NotConnectedException
|
||||
* @throws NotAMucServiceException
|
||||
*/
|
||||
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) {
|
||||
throw new MucAlreadyJoinedException();
|
||||
}
|
||||
|
@ -495,9 +513,10 @@ public class MultiUserChat {
|
|||
* @throws XMPPErrorException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
* @throws NotAMucServiceException
|
||||
*/
|
||||
public MucCreateConfigFormHandle createOrJoinIfNecessary(Resourcepart nickname, String password) throws NoResponseException,
|
||||
XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
XMPPErrorException, NotConnectedException, InterruptedException, NotAMucServiceException {
|
||||
if (isJoined()) {
|
||||
return null;
|
||||
}
|
||||
|
@ -527,8 +546,9 @@ public class MultiUserChat {
|
|||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @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());
|
||||
}
|
||||
|
||||
|
@ -553,8 +573,9 @@ public class MultiUserChat {
|
|||
* @throws InterruptedException
|
||||
* @throws NotConnectedException
|
||||
* @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());
|
||||
}
|
||||
|
||||
|
@ -585,13 +606,14 @@ public class MultiUserChat {
|
|||
* @throws NoResponseException if there was no response from the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
* @throws NotAMucServiceException
|
||||
*/
|
||||
public synchronized void join(
|
||||
Resourcepart nickname,
|
||||
String password,
|
||||
DiscussionHistory history,
|
||||
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
|
||||
// nickname.
|
||||
if (joined) {
|
||||
|
|
|
@ -83,4 +83,23 @@ public abstract class MultiUserChatException extends SmackException {
|
|||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* 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.muc.MultiUserChat;
|
||||
import org.jivesoftware.smackx.muc.MultiUserChat.MucCreateConfigFormHandle;
|
||||
import org.jivesoftware.smackx.muc.MultiUserChatException.NotAMucServiceException;
|
||||
import org.jivesoftware.smackx.muc.MultiUserChatManager;
|
||||
import org.jxmpp.jid.parts.Resourcepart;
|
||||
|
||||
|
@ -136,7 +137,7 @@ public final class MucBookmarkAutojoinManager extends Manager {
|
|||
// abort here
|
||||
break;
|
||||
}
|
||||
catch (NoResponseException | XMPPErrorException e) {
|
||||
catch (NotAMucServiceException | NoResponseException | XMPPErrorException e) {
|
||||
// Do no abort, just log,
|
||||
LOGGER.log(Level.WARNING, "Could not autojoin bookmarked MUC", e);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue