mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-12-22 10:37:59 +01:00
Merge branch '4.4'
This commit is contained in:
commit
ed807d5954
5 changed files with 91 additions and 6 deletions
|
@ -31,6 +31,7 @@ import org.jivesoftware.smack.filter.StanzaFilter;
|
||||||
import org.jivesoftware.smack.filter.ToTypeFilter;
|
import org.jivesoftware.smack.filter.ToTypeFilter;
|
||||||
|
|
||||||
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
||||||
|
import org.jivesoftware.smackx.muc.MultiUserChatManager;
|
||||||
import org.jivesoftware.smackx.sid.element.OriginIdElement;
|
import org.jivesoftware.smackx.sid.element.OriginIdElement;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -48,7 +49,7 @@ public final class StableUniqueStanzaIdManager extends Manager {
|
||||||
|
|
||||||
private static final Map<XMPPConnection, StableUniqueStanzaIdManager> INSTANCES = new WeakHashMap<>();
|
private static final Map<XMPPConnection, StableUniqueStanzaIdManager> INSTANCES = new WeakHashMap<>();
|
||||||
|
|
||||||
private static boolean enabledByDefault = true;
|
private static boolean enabledByDefault = false;
|
||||||
|
|
||||||
// Filter for outgoing stanzas.
|
// Filter for outgoing stanzas.
|
||||||
private static final StanzaFilter OUTGOING_FILTER = new AndFilter(
|
private static final StanzaFilter OUTGOING_FILTER = new AndFilter(
|
||||||
|
@ -68,6 +69,14 @@ public final class StableUniqueStanzaIdManager extends Manager {
|
||||||
if (enabledByDefault) {
|
if (enabledByDefault) {
|
||||||
getInstanceFor(connection).enable();
|
getInstanceFor(connection).enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MultiUserChatManager.addDefaultMessageInterceptor((mb, muc) -> {
|
||||||
|
// No need to add an <origin-id/> if the MUC service supports stable IDs.
|
||||||
|
if (muc.serviceSupportsStableIds()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
OriginIdElement.addTo(mb);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -48,7 +48,12 @@ public class OriginIdElement extends StableAndUniqueIdElement {
|
||||||
@Deprecated
|
@Deprecated
|
||||||
// TODO: Remove in Smack 4.5.
|
// TODO: Remove in Smack 4.5.
|
||||||
public static OriginIdElement addOriginId(Message message) {
|
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);
|
message.addExtension(originId);
|
||||||
// TODO: Find solution to have both the originIds stanzaId and a nice to look at incremental stanzaID.
|
// TODO: Find solution to have both the originIds stanzaId and a nice to look at incremental stanzaID.
|
||||||
// message.setStanzaId(originId.getId());
|
// message.setStanzaId(originId.getId());
|
||||||
|
@ -62,7 +67,12 @@ public class OriginIdElement extends StableAndUniqueIdElement {
|
||||||
* @return the added origin-id element.
|
* @return the added origin-id element.
|
||||||
*/
|
*/
|
||||||
public static OriginIdElement addTo(MessageBuilder messageBuilder) {
|
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);
|
messageBuilder.addExtension(originId);
|
||||||
// TODO: Find solution to have both the originIds stanzaId and a nice to look at incremental stanzaID.
|
// TODO: Find solution to have both the originIds stanzaId and a nice to look at incremental stanzaID.
|
||||||
// message.setStanzaId(originId.getId());
|
// message.setStanzaId(originId.getId());
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
}
|
|
@ -23,6 +23,7 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.concurrent.CopyOnWriteArraySet;
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
@ -156,10 +157,13 @@ public class MultiUserChat {
|
||||||
*/
|
*/
|
||||||
private volatile boolean processedReflectedSelfPresence;
|
private volatile boolean processedReflectedSelfPresence;
|
||||||
|
|
||||||
|
private CopyOnWriteArrayList<MucMessageInterceptor> messageInterceptors;
|
||||||
|
|
||||||
MultiUserChat(XMPPConnection connection, EntityBareJid room, MultiUserChatManager multiUserChatManager) {
|
MultiUserChat(XMPPConnection connection, EntityBareJid room, MultiUserChatManager multiUserChatManager) {
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
this.room = room;
|
this.room = room;
|
||||||
this.multiUserChatManager = multiUserChatManager;
|
this.multiUserChatManager = multiUserChatManager;
|
||||||
|
this.messageInterceptors = MultiUserChatManager.getMessageInterceptors();
|
||||||
|
|
||||||
fromRoomFilter = FromMatchesFilter.create(room);
|
fromRoomFilter = FromMatchesFilter.create(room);
|
||||||
fromRoomGroupchatFilter = new AndFilter(fromRoomFilter, MessageTypeFilter.GROUPCHAT);
|
fromRoomGroupchatFilter = new AndFilter(fromRoomFilter, MessageTypeFilter.GROUPCHAT);
|
||||||
|
@ -778,8 +782,7 @@ public class MultiUserChat {
|
||||||
MUCUserStatusCodeFilter.STATUS_110_PRESENCE_TO_SELF),
|
MUCUserStatusCodeFilter.STATUS_110_PRESENCE_TO_SELF),
|
||||||
new AndFilter(fromRoomFilter, PresenceTypeFilter.ERROR)));
|
new AndFilter(fromRoomFilter, PresenceTypeFilter.ERROR)));
|
||||||
|
|
||||||
boolean supportsStableId = mucServiceDiscoInfo.containsFeature(MultiUserChatConstants.STABLE_ID_FEATURE);
|
if (serviceSupportsStableIds()) {
|
||||||
if (supportsStableId) {
|
|
||||||
reflectedLeavePresenceFilters.add(new StanzaIdFilter(leavePresence));
|
reflectedLeavePresenceFilters.add(new StanzaIdFilter(leavePresence));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2035,6 +2038,10 @@ public class MultiUserChat {
|
||||||
* @throws InterruptedException if the calling thread was interrupted.
|
* @throws InterruptedException if the calling thread was interrupted.
|
||||||
*/
|
*/
|
||||||
public void sendMessage(MessageBuilder messageBuilder) throws NotConnectedException, InterruptedException {
|
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();
|
Message message = messageBuilder.to(room).ofType(Message.Type.groupchat).build();
|
||||||
connection.sendStanza(message);
|
connection.sendStanza(message);
|
||||||
}
|
}
|
||||||
|
@ -2118,6 +2125,14 @@ public class MultiUserChat {
|
||||||
return messageListeners.remove(listener);
|
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"
|
* 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
|
* 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;
|
return connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean serviceSupportsStableIds() {
|
||||||
|
return mucServiceDiscoInfo.containsFeature(MultiUserChatConstants.STABLE_ID_FEATURE);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "MUC: " + room + "(" + connection.getUser() + ")";
|
return "MUC: " + room + "(" + connection.getUser() + ")";
|
||||||
|
|
|
@ -20,10 +20,12 @@ import java.lang.ref.WeakReference;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.concurrent.CopyOnWriteArraySet;
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
@ -140,6 +142,8 @@ public final class MultiUserChatManager extends Manager {
|
||||||
private static final ExpirationCache<DomainBareJid, DiscoverInfo> KNOWN_MUC_SERVICES = new ExpirationCache<>(
|
private static final ExpirationCache<DomainBareJid, DiscoverInfo> KNOWN_MUC_SERVICES = new ExpirationCache<>(
|
||||||
100, 1000 * 60 * 60 * 24);
|
100, 1000 * 60 * 60 * 24);
|
||||||
|
|
||||||
|
private static final Set<MucMessageInterceptor> DEFAULT_MESSAGE_INTERCEPTORS = new HashSet<>();
|
||||||
|
|
||||||
private final Set<InvitationListener> invitationsListeners = new CopyOnWriteArraySet<InvitationListener>();
|
private final Set<InvitationListener> invitationsListeners = new CopyOnWriteArraySet<InvitationListener>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -275,6 +279,18 @@ public final class MultiUserChatManager extends Manager {
|
||||||
return multiUserChat;
|
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) {
|
private MultiUserChat createNewMucAndAddToMap(EntityBareJid jid) {
|
||||||
MultiUserChat multiUserChat = new MultiUserChat(connection(), jid, this);
|
MultiUserChat multiUserChat = new MultiUserChat(connection(), jid, this);
|
||||||
multiUserChats.put(jid, new WeakReference<MultiUserChat>(multiUserChat));
|
multiUserChats.put(jid, new WeakReference<MultiUserChat>(multiUserChat));
|
||||||
|
@ -535,4 +551,10 @@ public final class MultiUserChatManager extends Manager {
|
||||||
void removeJoinedRoom(EntityBareJid room) {
|
void removeJoinedRoom(EntityBareJid room) {
|
||||||
joinedRooms.remove(room);
|
joinedRooms.remove(room);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CopyOnWriteArrayList<MucMessageInterceptor> getMessageInterceptors() {
|
||||||
|
synchronized (DEFAULT_MESSAGE_INTERCEPTORS) {
|
||||||
|
return new CopyOnWriteArrayList<>(DEFAULT_MESSAGE_INTERCEPTORS);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue