From 4381d04831ffe09c0144f72db5195920bcd59ce9 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Tue, 23 Mar 2021 21:21:19 +0100 Subject: [PATCH] [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); + } + } }