1
0
Fork 0
mirror of https://github.com/vanitasvitae/Smack.git synced 2024-12-22 10:37:59 +01:00

Merge pull request #528 from Flowdalic/fix-mux-presence-interceptor

[muc] Fix Presence interceptors
This commit is contained in:
Florian Schmaus 2022-05-23 12:30:58 +02:00 committed by GitHub
commit f402a9d12d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1,6 +1,6 @@
/**
*
* Copyright 2003-2007 Jive Software. 2020-2021 Florian Schmaus
* Copyright 2003-2007 Jive Software. 2020-2022 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -25,6 +25,7 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -59,7 +60,9 @@ import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.MessageBuilder;
import org.jivesoftware.smack.packet.MessageView;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.PresenceBuilder;
import org.jivesoftware.smack.packet.Stanza;
import org.jivesoftware.smack.util.Consumer;
import org.jivesoftware.smack.util.Objects;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
@ -124,7 +127,7 @@ public class MultiUserChat {
private final Set<ParticipantStatusListener> participantStatusListeners = new CopyOnWriteArraySet<ParticipantStatusListener>();
private final Set<MessageListener> messageListeners = new CopyOnWriteArraySet<MessageListener>();
private final Set<PresenceListener> presenceListeners = new CopyOnWriteArraySet<PresenceListener>();
private final Set<PresenceListener> presenceInterceptors = new CopyOnWriteArraySet<PresenceListener>();
private final Set<Consumer<PresenceBuilder>> presenceInterceptors = new CopyOnWriteArraySet<>();
/**
* This filter will match all stanzas send from the groupchat or from one if
@ -138,7 +141,16 @@ public class MultiUserChat {
*/
private final StanzaFilter fromRoomGroupchatFilter;
private final StanzaListener presenceInterceptor;
private final AtomicInteger presenceInterceptorCount = new AtomicInteger();
// We want to save the presence interceptor in a variable, using a lambda, (and not use a method reference) to be
// able to dynamically add and remove it from the connection.
@SuppressWarnings("UnnecessaryLambda")
private final Consumer<PresenceBuilder> presenceInterceptor = presenceBuilder -> {
for (Consumer<PresenceBuilder> interceptor : presenceInterceptors) {
interceptor.accept(presenceBuilder);
}
};
private final StanzaListener messageListener;
private final StanzaListener presenceListener;
private final StanzaListener subjectListener;
@ -316,16 +328,6 @@ public class MultiUserChat {
fireInvitationRejectionListeners(message, rejection);
}
};
presenceInterceptor = new StanzaListener() {
@Override
public void processStanza(Stanza packet) {
Presence presence = (Presence) packet;
for (PresenceListener interceptor : presenceInterceptors) {
interceptor.processPresence(presence);
}
}
};
}
@ -379,8 +381,6 @@ public class MultiUserChat {
);
// @formatter:on
connection.addStanzaListener(declinesListener, new AndFilter(fromRoomFilter, DECLINE_FILTER));
connection.addStanzaSendingListener(presenceInterceptor, new AndFilter(ToMatchesFilter.create(room),
StanzaTypeFilter.PRESENCE));
messageCollector = connection.createStanzaCollector(fromRoomGroupchatFilter);
// Wait for a presence packet back from the server.
@ -1112,8 +1112,13 @@ public class MultiUserChat {
*
* @param presenceInterceptor the new stanza interceptor that will intercept presence packets.
*/
public void addPresenceInterceptor(PresenceListener presenceInterceptor) {
presenceInterceptors.add(presenceInterceptor);
public void addPresenceInterceptor(Consumer<PresenceBuilder> presenceInterceptor) {
boolean added = presenceInterceptors.add(presenceInterceptor);
if (!added) return;
int currentCount = presenceInterceptorCount.incrementAndGet();
if (currentCount == 1) {
connection.addPresenceInterceptor(this.presenceInterceptor, ToMatchesFilter.create(room).asPredicate(Presence.class));
}
}
/**
@ -1123,8 +1128,13 @@ public class MultiUserChat {
*
* @param presenceInterceptor the stanza interceptor to remove.
*/
public void removePresenceInterceptor(PresenceListener presenceInterceptor) {
presenceInterceptors.remove(presenceInterceptor);
public void removePresenceInterceptor(Consumer<PresenceBuilder> presenceInterceptor) {
boolean removed = presenceInterceptors.remove(presenceInterceptor);
if (!removed) return;
int currentCount = presenceInterceptorCount.decrementAndGet();
if (currentCount == 0) {
connection.removePresenceInterceptor(presenceInterceptor);
}
}
/**
@ -2180,7 +2190,7 @@ public class MultiUserChat {
connection.removeStanzaListener(presenceListener);
connection.removeStanzaListener(subjectListener);
connection.removeStanzaListener(declinesListener);
connection.removeStanzaSendingListener(presenceInterceptor);
connection.removePresenceInterceptor(presenceInterceptor);
if (messageCollector != null) {
messageCollector.cancel();
messageCollector = null;