From 800c771700515b6a12a0e4eea0637f3da62199b2 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Tue, 23 Mar 2021 21:19:33 +0100 Subject: [PATCH 1/4] [sid] Check if there is already a in addOriginId() --- .../smackx/sid/element/OriginIdElement.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/sid/element/OriginIdElement.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/sid/element/OriginIdElement.java index d5f6935da..a50fd99e2 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/sid/element/OriginIdElement.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/sid/element/OriginIdElement.java @@ -1,6 +1,6 @@ /** * - * Copyright 2018 Paul Schaub + * Copyright 2018 Paul Schaub, 2021 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,7 +48,12 @@ public class OriginIdElement extends StableAndUniqueIdElement { @Deprecated // TODO: Remove in Smack 4.5. public static OriginIdElement addOriginId(Message message) { - OriginIdElement originId = new OriginIdElement(); + OriginIdElement originId = message.getExtension(OriginIdElement.class); + if (originId != null) { + return originId; + } + + originId = new OriginIdElement(); message.addExtension(originId); // TODO: Find solution to have both the originIds stanzaId and a nice to look at incremental stanzaID. // message.setStanzaId(originId.getId()); @@ -62,7 +67,12 @@ public class OriginIdElement extends StableAndUniqueIdElement { * @return the added origin-id element. */ public static OriginIdElement addTo(MessageBuilder messageBuilder) { - OriginIdElement originId = new OriginIdElement(); + OriginIdElement originId = messageBuilder.getExtension(OriginIdElement.class); + if (originId != null) { + return originId; + } + + originId = new OriginIdElement(); messageBuilder.addExtension(originId); // TODO: Find solution to have both the originIds stanzaId and a nice to look at incremental stanzaID. // message.setStanzaId(originId.getId()); From b8f23eb371974c7dd7b246c38014986989076883 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Tue, 23 Mar 2021 21:20:13 +0100 Subject: [PATCH 2/4] [sid] Do not enable StableUniqueStanzaIdManager per default --- .../jivesoftware/smackx/sid/StableUniqueStanzaIdManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/sid/StableUniqueStanzaIdManager.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/sid/StableUniqueStanzaIdManager.java index 35242eba9..ec492b006 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/sid/StableUniqueStanzaIdManager.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/sid/StableUniqueStanzaIdManager.java @@ -48,7 +48,7 @@ public final class StableUniqueStanzaIdManager extends Manager { private static final Map INSTANCES = new WeakHashMap<>(); - private static boolean enabledByDefault = true; + private static boolean enabledByDefault = false; // Filter for outgoing stanzas. private static final StanzaFilter OUTGOING_FILTER = new AndFilter( From 4381d04831ffe09c0144f72db5195920bcd59ce9 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Tue, 23 Mar 2021 21:21:19 +0100 Subject: [PATCH 3/4] [muc] Introduce MucMessageInterceptor --- .../smackx/muc/MucMessageInterceptor.java | 25 +++++++++++++++++++ .../smackx/muc/MultiUserChat.java | 23 +++++++++++++++-- .../smackx/muc/MultiUserChatManager.java | 22 ++++++++++++++++ 3 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucMessageInterceptor.java diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucMessageInterceptor.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucMessageInterceptor.java new file mode 100644 index 000000000..19cf3a6a2 --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucMessageInterceptor.java @@ -0,0 +1,25 @@ +/** + * + * Copyright 2021 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. + */ +package org.jivesoftware.smackx.muc; + +import org.jivesoftware.smack.packet.MessageBuilder; + +public interface MucMessageInterceptor { + + void intercept(MessageBuilder messageBuilder, MultiUserChat multiUserChat); + +} diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java index f7480becd..aac039264 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java @@ -23,6 +23,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArraySet; import java.util.logging.Level; import java.util.logging.Logger; @@ -156,10 +157,13 @@ public class MultiUserChat { */ private volatile boolean processedReflectedSelfPresence; + private CopyOnWriteArrayList messageInterceptors; + MultiUserChat(XMPPConnection connection, EntityBareJid room, MultiUserChatManager multiUserChatManager) { this.connection = connection; this.room = room; this.multiUserChatManager = multiUserChatManager; + this.messageInterceptors = MultiUserChatManager.getMessageInterceptors(); fromRoomFilter = FromMatchesFilter.create(room); fromRoomGroupchatFilter = new AndFilter(fromRoomFilter, MessageTypeFilter.GROUPCHAT); @@ -778,8 +782,7 @@ public class MultiUserChat { MUCUserStatusCodeFilter.STATUS_110_PRESENCE_TO_SELF), new AndFilter(fromRoomFilter, PresenceTypeFilter.ERROR))); - boolean supportsStableId = mucServiceDiscoInfo.containsFeature(MultiUserChatConstants.STABLE_ID_FEATURE); - if (supportsStableId) { + if (serviceSupportsStableIds()) { reflectedLeavePresenceFilters.add(new StanzaIdFilter(leavePresence)); } @@ -2035,6 +2038,10 @@ public class MultiUserChat { * @throws InterruptedException if the calling thread was interrupted. */ public void sendMessage(MessageBuilder messageBuilder) throws NotConnectedException, InterruptedException { + for (MucMessageInterceptor interceptor : messageInterceptors) { + interceptor.intercept(messageBuilder, this); + } + Message message = messageBuilder.to(room).ofType(Message.Type.groupchat).build(); connection.sendStanza(message); } @@ -2118,6 +2125,14 @@ public class MultiUserChat { return messageListeners.remove(listener); } + public boolean addMessageInterceptor(MucMessageInterceptor interceptor) { + return messageInterceptors.add(interceptor); + } + + public boolean removeMessageInterceptor(MucMessageInterceptor interceptor) { + return messageInterceptors.remove(interceptor); + } + /** * Changes 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 @@ -2539,6 +2554,10 @@ public class MultiUserChat { return connection; } + public boolean serviceSupportsStableIds() { + return mucServiceDiscoInfo.containsFeature(MultiUserChatConstants.STABLE_ID_FEATURE); + } + @Override public String toString() { return "MUC: " + room + "(" + connection.getUser() + ")"; diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatManager.java index 2cf5778ff..55a791faf 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatManager.java @@ -20,10 +20,12 @@ import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.WeakHashMap; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArraySet; import java.util.logging.Level; import java.util.logging.Logger; @@ -140,6 +142,8 @@ public final class MultiUserChatManager extends Manager { private static final ExpirationCache KNOWN_MUC_SERVICES = new ExpirationCache<>( 100, 1000 * 60 * 60 * 24); + private static final Set DEFAULT_MESSAGE_INTERCEPTORS = new HashSet<>(); + private final Set invitationsListeners = new CopyOnWriteArraySet(); /** @@ -275,6 +279,18 @@ public final class MultiUserChatManager extends Manager { return multiUserChat; } + public static boolean addDefaultMessageInterceptor(MucMessageInterceptor messageInterceptor) { + synchronized (DEFAULT_MESSAGE_INTERCEPTORS) { + return DEFAULT_MESSAGE_INTERCEPTORS.add(messageInterceptor); + } + } + + public static boolean removeDefaultMessageInterceptor(MucMessageInterceptor messageInterceptor) { + synchronized (DEFAULT_MESSAGE_INTERCEPTORS) { + return DEFAULT_MESSAGE_INTERCEPTORS.remove(messageInterceptor); + } + } + private MultiUserChat createNewMucAndAddToMap(EntityBareJid jid) { MultiUserChat multiUserChat = new MultiUserChat(connection(), jid, this); multiUserChats.put(jid, new WeakReference(multiUserChat)); @@ -535,4 +551,10 @@ public final class MultiUserChatManager extends Manager { void removeJoinedRoom(EntityBareJid room) { joinedRooms.remove(room); } + + static CopyOnWriteArrayList getMessageInterceptors() { + synchronized (DEFAULT_MESSAGE_INTERCEPTORS) { + return new CopyOnWriteArrayList<>(DEFAULT_MESSAGE_INTERCEPTORS); + } + } } From 64a2db3f193002bbd557b76b07c90241a78defb6 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Tue, 23 Mar 2021 21:21:31 +0100 Subject: [PATCH 4/4] [sid] Add to MUC messages if not muc#stable_id --- .../smackx/sid/StableUniqueStanzaIdManager.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/sid/StableUniqueStanzaIdManager.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/sid/StableUniqueStanzaIdManager.java index ec492b006..3f016cde2 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/sid/StableUniqueStanzaIdManager.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/sid/StableUniqueStanzaIdManager.java @@ -31,6 +31,7 @@ import org.jivesoftware.smack.filter.StanzaFilter; import org.jivesoftware.smack.filter.ToTypeFilter; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; +import org.jivesoftware.smackx.muc.MultiUserChatManager; import org.jivesoftware.smackx.sid.element.OriginIdElement; /** @@ -68,6 +69,14 @@ public final class StableUniqueStanzaIdManager extends Manager { if (enabledByDefault) { getInstanceFor(connection).enable(); } + + MultiUserChatManager.addDefaultMessageInterceptor((mb, muc) -> { + // No need to add an if the MUC service supports stable IDs. + if (muc.serviceSupportsStableIds()) { + return; + } + OriginIdElement.addTo(mb); + }); } }); }