mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-11-22 12:02:05 +01:00
Introduce XMPPConnection.add(Message|Presence)Interceptor
add deprecate addStanzaInterceptor().
This commit is contained in:
parent
5db6191110
commit
e2d206e741
24 changed files with 419 additions and 102 deletions
|
@ -100,8 +100,12 @@ import org.jivesoftware.smack.packet.FullyQualifiedElement;
|
|||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.Mechanisms;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.MessageBuilder;
|
||||
import org.jivesoftware.smack.packet.MessageOrPresence;
|
||||
import org.jivesoftware.smack.packet.MessageOrPresenceBuilder;
|
||||
import org.jivesoftware.smack.packet.Nonza;
|
||||
import org.jivesoftware.smack.packet.Presence;
|
||||
import org.jivesoftware.smack.packet.PresenceBuilder;
|
||||
import org.jivesoftware.smack.packet.Session;
|
||||
import org.jivesoftware.smack.packet.Stanza;
|
||||
import org.jivesoftware.smack.packet.StanzaError;
|
||||
|
@ -123,11 +127,13 @@ import org.jivesoftware.smack.sasl.core.SASLAnonymous;
|
|||
import org.jivesoftware.smack.sasl.packet.SaslNonza;
|
||||
import org.jivesoftware.smack.util.Async;
|
||||
import org.jivesoftware.smack.util.CollectionUtil;
|
||||
import org.jivesoftware.smack.util.Consumer;
|
||||
import org.jivesoftware.smack.util.DNSUtil;
|
||||
import org.jivesoftware.smack.util.MultiMap;
|
||||
import org.jivesoftware.smack.util.Objects;
|
||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||
import org.jivesoftware.smack.util.ParserUtils;
|
||||
import org.jivesoftware.smack.util.Predicate;
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
import org.jivesoftware.smack.util.dns.HostAddress;
|
||||
import org.jivesoftware.smack.util.dns.SmackDaneProvider;
|
||||
|
@ -243,6 +249,10 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
|||
private final Map<StanzaListener, InterceptorWrapper> interceptors =
|
||||
new HashMap<>();
|
||||
|
||||
private final Map<Consumer<MessageBuilder>, GenericInterceptorWrapper<MessageBuilder, Message>> messageInterceptors = new HashMap<>();
|
||||
|
||||
private final Map<Consumer<PresenceBuilder>, GenericInterceptorWrapper<PresenceBuilder, Presence>> presenceInterceptors = new HashMap<>();
|
||||
|
||||
private XmlEnvironment incomingStreamXmlEnvironment;
|
||||
|
||||
protected XmlEnvironment outgoingStreamXmlEnvironment;
|
||||
|
@ -849,8 +859,8 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
|||
}
|
||||
// Invoke interceptors for the new stanza that is about to be sent. Interceptors may modify
|
||||
// the content of the stanza.
|
||||
firePacketInterceptors(stanza);
|
||||
sendStanzaInternal(stanza);
|
||||
Stanza stanzaAfterInterceptors = firePacketInterceptors(stanza);
|
||||
sendStanzaInternal(stanzaAfterInterceptors);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1204,6 +1214,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
|||
});
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public void addStanzaInterceptor(StanzaListener packetInterceptor,
|
||||
StanzaFilter packetFilter) {
|
||||
|
@ -1216,6 +1227,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
|||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public void removeStanzaInterceptor(StanzaListener packetInterceptor) {
|
||||
synchronized (interceptors) {
|
||||
|
@ -1223,15 +1235,83 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
|||
}
|
||||
}
|
||||
|
||||
private static <MPB extends MessageOrPresenceBuilder<MP, MPB>, MP extends MessageOrPresence<MPB>> void addInterceptor(
|
||||
Map<Consumer<MPB>, GenericInterceptorWrapper<MPB, MP>> interceptors, Consumer<MPB> interceptor,
|
||||
Predicate<MP> filter) {
|
||||
Objects.requireNonNull(interceptor, "Interceptor must not be null");
|
||||
|
||||
GenericInterceptorWrapper<MPB, MP> interceptorWrapper = new GenericInterceptorWrapper<>(interceptor, filter);
|
||||
|
||||
synchronized (interceptors) {
|
||||
interceptors.put(interceptor, interceptorWrapper);
|
||||
}
|
||||
}
|
||||
|
||||
private static <MPB extends MessageOrPresenceBuilder<MP, MPB>, MP extends MessageOrPresence<MPB>> void removeInterceptor(
|
||||
Map<Consumer<MPB>, GenericInterceptorWrapper<MPB, MP>> interceptors, Consumer<MPB> interceptor) {
|
||||
synchronized (interceptors) {
|
||||
interceptors.remove(interceptor);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addMessageInterceptor(Consumer<MessageBuilder> messageInterceptor, Predicate<Message> messageFilter) {
|
||||
addInterceptor(messageInterceptors, messageInterceptor, messageFilter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeMessageInterceptor(Consumer<MessageBuilder> messageInterceptor) {
|
||||
removeInterceptor(messageInterceptors, messageInterceptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPresenceInterceptor(Consumer<PresenceBuilder> presenceInterceptor,
|
||||
Predicate<Presence> presenceFilter) {
|
||||
addInterceptor(presenceInterceptors, presenceInterceptor, presenceFilter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePresenceInterceptor(Consumer<PresenceBuilder> presenceInterceptor) {
|
||||
removeInterceptor(presenceInterceptors, presenceInterceptor);
|
||||
}
|
||||
|
||||
private static <MPB extends MessageOrPresenceBuilder<MP, MPB>, MP extends MessageOrPresence<MPB>> MP fireMessageOrPresenceInterceptors(
|
||||
MP messageOrPresence, Map<Consumer<MPB>, GenericInterceptorWrapper<MPB, MP>> interceptors) {
|
||||
List<Consumer<MPB>> interceptorsToInvoke = new LinkedList<>();
|
||||
synchronized (interceptors) {
|
||||
for (GenericInterceptorWrapper<MPB, MP> interceptorWrapper : interceptors.values()) {
|
||||
if (interceptorWrapper.filterMatches(messageOrPresence)) {
|
||||
Consumer<MPB> interceptor = interceptorWrapper.getInterceptor();
|
||||
interceptorsToInvoke.add(interceptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Avoid transforming the stanza to a builder if there is no interceptor.
|
||||
if (interceptorsToInvoke.isEmpty()) {
|
||||
return messageOrPresence;
|
||||
}
|
||||
|
||||
MPB builder = messageOrPresence.asBuilder();
|
||||
for (Consumer<MPB> interceptor : interceptorsToInvoke) {
|
||||
interceptor.accept(builder);
|
||||
}
|
||||
|
||||
// Now that the interceptors have (probably) modified the stanza in its builder form, we need to re-assemble it.
|
||||
messageOrPresence = builder.build();
|
||||
return messageOrPresence;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process interceptors. Interceptors may modify the stanza that is about to be sent.
|
||||
* Since the thread that requested to send the stanza will invoke all interceptors, it
|
||||
* is important that interceptors perform their work as soon as possible so that the
|
||||
* thread does not remain blocked for a long period.
|
||||
*
|
||||
* @param packet the stanza that is going to be sent to the server
|
||||
* @param packet the stanza that is going to be sent to the server.
|
||||
* @return the, potentially modified stanza, after the interceptors are run.
|
||||
*/
|
||||
private void firePacketInterceptors(Stanza packet) {
|
||||
private Stanza firePacketInterceptors(Stanza packet) {
|
||||
List<StanzaListener> interceptorsToInvoke = new LinkedList<>();
|
||||
synchronized (interceptors) {
|
||||
for (InterceptorWrapper interceptorWrapper : interceptors.values()) {
|
||||
|
@ -1247,6 +1327,22 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
|||
LOGGER.log(Level.SEVERE, "Packet interceptor threw exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
final Stanza stanzaAfterInterceptors;
|
||||
if (packet instanceof Message) {
|
||||
Message message = (Message) packet;
|
||||
stanzaAfterInterceptors = fireMessageOrPresenceInterceptors(message, messageInterceptors);
|
||||
}
|
||||
else if (packet instanceof Presence) {
|
||||
Presence presence = (Presence) packet;
|
||||
stanzaAfterInterceptors = fireMessageOrPresenceInterceptors(presence, presenceInterceptors);
|
||||
} else {
|
||||
// We do not (yet) support interceptors for IQ stanzas.
|
||||
assert packet instanceof IQ;
|
||||
stanzaAfterInterceptors = packet;
|
||||
}
|
||||
|
||||
return stanzaAfterInterceptors;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1674,6 +1770,8 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
|||
/**
|
||||
* A wrapper class to associate a stanza filter with an interceptor.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove once addStanzaInterceptor is gone.
|
||||
protected static class InterceptorWrapper {
|
||||
|
||||
private final StanzaListener packetInterceptor;
|
||||
|
@ -1699,6 +1797,24 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
|||
}
|
||||
}
|
||||
|
||||
private static final class GenericInterceptorWrapper<MPB extends MessageOrPresenceBuilder<MP, MPB>, MP extends MessageOrPresence<MPB>> {
|
||||
private final Consumer<MPB> stanzaInterceptor;
|
||||
private final Predicate<MP> stanzaFilter;
|
||||
|
||||
private GenericInterceptorWrapper(Consumer<MPB> stanzaInterceptor, Predicate<MP> stanzaFilter) {
|
||||
this.stanzaInterceptor = stanzaInterceptor;
|
||||
this.stanzaFilter = stanzaFilter;
|
||||
}
|
||||
|
||||
private boolean filterMatches(MP stanza) {
|
||||
return stanzaFilter == null || stanzaFilter.test(stanza);
|
||||
}
|
||||
|
||||
public Consumer<MPB> getInterceptor() {
|
||||
return stanzaInterceptor;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getConnectionCounter() {
|
||||
return connectionCounterValue;
|
||||
|
|
|
@ -27,9 +27,15 @@ import org.jivesoftware.smack.iqrequest.IQRequestHandler;
|
|||
import org.jivesoftware.smack.packet.ExtensionElement;
|
||||
import org.jivesoftware.smack.packet.FullyQualifiedElement;
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.MessageBuilder;
|
||||
import org.jivesoftware.smack.packet.Nonza;
|
||||
import org.jivesoftware.smack.packet.Presence;
|
||||
import org.jivesoftware.smack.packet.PresenceBuilder;
|
||||
import org.jivesoftware.smack.packet.Stanza;
|
||||
import org.jivesoftware.smack.packet.StanzaFactory;
|
||||
import org.jivesoftware.smack.util.Consumer;
|
||||
import org.jivesoftware.smack.util.Predicate;
|
||||
|
||||
import org.jxmpp.jid.DomainBareJid;
|
||||
import org.jxmpp.jid.EntityFullJid;
|
||||
|
@ -446,16 +452,65 @@ public interface XMPPConnection {
|
|||
*
|
||||
* @param stanzaInterceptor the stanza interceptor to notify of stanzas about to be sent.
|
||||
* @param stanzaFilter the stanza filter to use.
|
||||
* @deprecated use {@link #addMessageInterceptor(Consumer, Predicate)} or {@link #addPresenceInterceptor(Consumer, Predicate)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove in Smack 4.5.
|
||||
void addStanzaInterceptor(StanzaListener stanzaInterceptor, StanzaFilter stanzaFilter);
|
||||
|
||||
/**
|
||||
* Removes a stanza interceptor.
|
||||
*
|
||||
* @param stanzaInterceptor the stanza interceptor to remove.
|
||||
* @deprecated use {@link #removeMessageInterceptor(Consumer)} or {@link #removePresenceInterceptor(Consumer)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove in Smack 4.5.
|
||||
void removeStanzaInterceptor(StanzaListener stanzaInterceptor);
|
||||
|
||||
/**
|
||||
* Registers a stanza interceptor with this connection. The interceptor will be
|
||||
* invoked every time a stanza is about to be sent by this connection. Interceptors
|
||||
* may modify the stanza to be sent. A stanza filter determines which stanzas
|
||||
* will be delivered to the interceptor.
|
||||
*
|
||||
* <p>
|
||||
* NOTE: For a similar functionality on incoming stanzas, see {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)}.
|
||||
* </p>
|
||||
*
|
||||
* @param messageInterceptor the stanza interceptor to notify of stanzas about to be sent.
|
||||
* @param messageFilter the stanza filter to use.
|
||||
*/
|
||||
void addMessageInterceptor(Consumer<MessageBuilder> messageInterceptor, Predicate<Message> messageFilter);
|
||||
|
||||
/**
|
||||
* Removes a message interceptor.
|
||||
*
|
||||
* @param messageInterceptor the message interceptor to remove.
|
||||
*/
|
||||
void removeMessageInterceptor(Consumer<MessageBuilder> messageInterceptor);
|
||||
|
||||
/**
|
||||
* Registers a stanza interceptor with this connection. The interceptor will be
|
||||
* invoked every time a stanza is about to be sent by this connection. Interceptors
|
||||
* may modify the stanza to be sent. A stanza filter determines which stanzas
|
||||
* will be delivered to the interceptor.
|
||||
*
|
||||
* <p>
|
||||
* NOTE: For a similar functionality on incoming stanzas, see {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)}.
|
||||
* </p>
|
||||
*
|
||||
* @param presenceInterceptor the stanza interceptor to notify of stanzas about to be sent.
|
||||
* @param presenceFilter the stanza filter to use.
|
||||
*/
|
||||
void addPresenceInterceptor(Consumer<PresenceBuilder> presenceInterceptor, Predicate<Presence> presenceFilter);
|
||||
|
||||
/**
|
||||
* Removes a presence interceptor.
|
||||
*
|
||||
* @param presenceInterceptor the stanza interceptor to remove.
|
||||
*/
|
||||
void removePresenceInterceptor(Consumer<PresenceBuilder> presenceInterceptor);
|
||||
/**
|
||||
* Returns the current value of the reply timeout in milliseconds for request for this
|
||||
* XMPPConnection instance.
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
package org.jivesoftware.smack.filter;
|
||||
|
||||
import org.jivesoftware.smack.packet.Stanza;
|
||||
import org.jivesoftware.smack.util.Predicate;
|
||||
|
||||
/**
|
||||
* Defines a way to filter stanzas for particular attributes. Stanza filters are used when
|
||||
|
@ -51,7 +52,7 @@ import org.jivesoftware.smack.packet.Stanza;
|
|||
* @see org.jivesoftware.smack.StanzaListener
|
||||
* @author Matt Tucker
|
||||
*/
|
||||
public interface StanzaFilter {
|
||||
public interface StanzaFilter extends Predicate<Stanza> {
|
||||
|
||||
/**
|
||||
* Tests whether or not the specified stanza should pass the filter.
|
||||
|
@ -60,4 +61,9 @@ public interface StanzaFilter {
|
|||
* @return true if and only if <code>stanza</code> passes the filter.
|
||||
*/
|
||||
boolean accept(Stanza stanza);
|
||||
|
||||
@Override
|
||||
default boolean test(Stanza stanza) {
|
||||
return accept(stanza);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,7 +60,8 @@ import org.jxmpp.stringprep.XmppStringprepException;
|
|||
*
|
||||
* @author Matt Tucker
|
||||
*/
|
||||
public final class Message extends Stanza implements MessageView, TypedCloneable<Message> {
|
||||
public final class Message extends MessageOrPresence<MessageBuilder>
|
||||
implements MessageView, TypedCloneable<Message> {
|
||||
|
||||
public static final String ELEMENT = "message";
|
||||
public static final String BODY = "body";
|
||||
|
@ -534,6 +535,7 @@ public final class Message extends Stanza implements MessageView, TypedCloneable
|
|||
return ELEMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageBuilder asBuilder() {
|
||||
return StanzaBuilder.buildMessageFrom(this, getStanzaId());
|
||||
}
|
||||
|
@ -664,6 +666,7 @@ public final class Message extends Stanza implements MessageView, TypedCloneable
|
|||
|
||||
public static final String ELEMENT = "body";
|
||||
public static final String NAMESPACE = StreamOpen.CLIENT_NAMESPACE;
|
||||
public static final QName QNAME = new QName(NAMESPACE, ELEMENT);
|
||||
|
||||
enum BodyElementNamespace {
|
||||
client(StreamOpen.CLIENT_NAMESPACE),
|
||||
|
|
|
@ -22,7 +22,7 @@ import org.jivesoftware.smack.packet.id.StanzaIdSource;
|
|||
import org.jivesoftware.smack.util.StringUtils;
|
||||
import org.jivesoftware.smack.util.ToStringUtil;
|
||||
|
||||
public final class MessageBuilder extends StanzaBuilder<MessageBuilder> implements MessageView {
|
||||
public final class MessageBuilder extends MessageOrPresenceBuilder<Message, MessageBuilder> implements MessageView {
|
||||
static final MessageBuilder EMPTY = new MessageBuilder(() -> {
|
||||
return null;
|
||||
});
|
||||
|
@ -153,6 +153,7 @@ public final class MessageBuilder extends StanzaBuilder<MessageBuilder> implemen
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Message build() {
|
||||
return new Message(this);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2019 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.smack.packet;
|
||||
|
||||
public abstract class MessageOrPresence<MPB extends MessageOrPresenceBuilder<?, ?>> extends Stanza {
|
||||
|
||||
@Deprecated
|
||||
// TODO: Remove in Smack 4.5.
|
||||
protected MessageOrPresence() {
|
||||
}
|
||||
|
||||
protected MessageOrPresence(StanzaBuilder<?> stanzaBuilder) {
|
||||
super(stanzaBuilder);
|
||||
}
|
||||
|
||||
protected MessageOrPresence(Stanza other) {
|
||||
super(other);
|
||||
}
|
||||
|
||||
public abstract MPB asBuilder();
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2019 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.smack.packet;
|
||||
|
||||
import org.jivesoftware.smack.packet.id.StanzaIdSource;
|
||||
|
||||
public abstract class MessageOrPresenceBuilder<MP extends MessageOrPresence<? extends MessageOrPresenceBuilder<MP, SB>>, SB extends StanzaBuilder<SB>>
|
||||
extends StanzaBuilder<SB> {
|
||||
|
||||
protected MessageOrPresenceBuilder(Stanza stanza, StanzaIdSource stanzaIdSource) {
|
||||
super(stanza, stanzaIdSource);
|
||||
}
|
||||
|
||||
protected MessageOrPresenceBuilder(Stanza stanza, String stanzaId) {
|
||||
super(stanza, stanzaId);
|
||||
}
|
||||
|
||||
protected MessageOrPresenceBuilder(StanzaIdSource stanzaIdSource) {
|
||||
super(stanzaIdSource);
|
||||
}
|
||||
|
||||
protected MessageOrPresenceBuilder(String stanzaId) {
|
||||
super(stanzaId);
|
||||
}
|
||||
|
||||
public abstract MP build();
|
||||
|
||||
}
|
|
@ -61,7 +61,8 @@ import org.jxmpp.jid.Jid;
|
|||
*
|
||||
* @author Matt Tucker
|
||||
*/
|
||||
public final class Presence extends Stanza implements PresenceView, TypedCloneable<Presence> {
|
||||
public final class Presence extends MessageOrPresence<PresenceBuilder>
|
||||
implements PresenceView, TypedCloneable<Presence> {
|
||||
|
||||
public static final String ELEMENT = "presence";
|
||||
|
||||
|
@ -277,6 +278,7 @@ public final class Presence extends Stanza implements PresenceView, TypedCloneab
|
|||
return ELEMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PresenceBuilder asBuilder() {
|
||||
return StanzaBuilder.buildPresenceFrom(this, getStanzaId());
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ import org.jivesoftware.smack.packet.id.StanzaIdSource;
|
|||
import org.jivesoftware.smack.util.Objects;
|
||||
import org.jivesoftware.smack.util.ToStringUtil;
|
||||
|
||||
public final class PresenceBuilder extends StanzaBuilder<PresenceBuilder> implements PresenceView {
|
||||
public final class PresenceBuilder extends MessageOrPresenceBuilder<Presence, PresenceBuilder> implements PresenceView {
|
||||
static final PresenceBuilder EMPTY = new PresenceBuilder(() -> {
|
||||
return null;
|
||||
});
|
||||
|
@ -102,6 +102,7 @@ public final class PresenceBuilder extends StanzaBuilder<PresenceBuilder> implem
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Presence build() {
|
||||
return new Presence(this);
|
||||
}
|
||||
|
|
|
@ -456,12 +456,8 @@ public abstract class Stanza implements StanzaView, TopLevelStreamElement {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a stanza extension with the given namespace exists.
|
||||
*
|
||||
* @param namespace TODO javadoc me please
|
||||
* @return true if a stanza extension exists, false otherwise.
|
||||
*/
|
||||
// Overridden in order to avoid an extra copy.
|
||||
@Override
|
||||
public boolean hasExtension(String namespace) {
|
||||
synchronized (extensionElements) {
|
||||
for (ExtensionElement packetExtension : extensionElements.values()) {
|
||||
|
|
|
@ -63,6 +63,26 @@ public interface StanzaView extends XmlLangElement {
|
|||
|
||||
<E extends ExtensionElement> E getExtension(QName qname);
|
||||
|
||||
default boolean hasExtension(QName qname) {
|
||||
return getExtension(qname) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a extension element with the given namespace exists.
|
||||
*
|
||||
* @param namespace the namespace of the extension element to check for.
|
||||
* @return true if a stanza extension exists, false otherwise.
|
||||
*/
|
||||
default boolean hasExtension(String namespace) {
|
||||
for (ExtensionElement packetExtension : getExtensions()) {
|
||||
if (packetExtension.getNamespace().equals(namespace)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
default <E extends ExtensionElement> E getExtension(Class<E> extensionElementClass) {
|
||||
QName qname = XmppElementUtil.getQNameFor(extensionElementClass);
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2019 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.smack.util;
|
||||
|
||||
// TODO: Replace with java.util.function.Predicate once Smack's minimum Android SDK level is 24 or higher.
|
||||
public interface Predicate<T> {
|
||||
|
||||
boolean test(T t);
|
||||
|
||||
}
|
|
@ -120,18 +120,10 @@ public final class ChatMarkersManager extends Manager {
|
|||
|
||||
chatManager = ChatManager.getInstanceFor(connection);
|
||||
|
||||
connection.addStanzaInterceptor(new StanzaListener() {
|
||||
@Override
|
||||
public void processStanza(Stanza packet)
|
||||
throws
|
||||
NotConnectedException,
|
||||
InterruptedException,
|
||||
SmackException.NotLoggedInException {
|
||||
Message message = (Message) packet;
|
||||
// add a markable extension
|
||||
message.addExtension(ChatMarkersElements.MarkableExtension.INSTANCE);
|
||||
}
|
||||
}, OUTGOING_MESSAGE_FILTER);
|
||||
connection.addMessageInterceptor(mb -> mb.addExtension(ChatMarkersElements.MarkableExtension.INSTANCE),
|
||||
m -> {
|
||||
return OUTGOING_MESSAGE_FILTER.accept(m);
|
||||
});
|
||||
|
||||
connection.addSyncStanzaListener(new StanzaListener() {
|
||||
@Override
|
||||
|
|
|
@ -21,7 +21,6 @@ import java.util.WeakHashMap;
|
|||
|
||||
import org.jivesoftware.smack.ConnectionCreationListener;
|
||||
import org.jivesoftware.smack.Manager;
|
||||
import org.jivesoftware.smack.StanzaListener;
|
||||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smack.XMPPConnectionRegistry;
|
||||
import org.jivesoftware.smack.filter.AndFilter;
|
||||
|
@ -31,8 +30,9 @@ import org.jivesoftware.smack.filter.StanzaExtensionFilter;
|
|||
import org.jivesoftware.smack.filter.StanzaFilter;
|
||||
import org.jivesoftware.smack.filter.ToTypeFilter;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.Stanza;
|
||||
|
||||
import org.jivesoftware.smack.packet.MessageBuilder;
|
||||
import org.jivesoftware.smack.util.Consumer;
|
||||
import org.jivesoftware.smack.util.Predicate;
|
||||
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
||||
import org.jivesoftware.smackx.sid.element.OriginIdElement;
|
||||
|
||||
|
@ -62,12 +62,12 @@ public final class StableUniqueStanzaIdManager extends Manager {
|
|||
private static final StanzaFilter ORIGIN_ID_FILTER = new StanzaExtensionFilter(OriginIdElement.ELEMENT, NAMESPACE);
|
||||
|
||||
// Listener for outgoing stanzas that adds origin-ids to outgoing stanzas.
|
||||
private static final StanzaListener ADD_ORIGIN_ID_INTERCEPTOR = new StanzaListener() {
|
||||
@Override
|
||||
public void processStanza(Stanza stanza) {
|
||||
Message message = (Message) stanza;
|
||||
OriginIdElement.addOriginId(message);
|
||||
}
|
||||
private static final Consumer<MessageBuilder> ADD_ORIGIN_ID_INTERCEPTOR = mb -> OriginIdElement.addOriginId(mb);
|
||||
|
||||
// We need a filter for outgoing messages that do not carry an origin-id already.
|
||||
private static final StanzaFilter ADD_ORIGIN_ID_FILTER = new AndFilter(OUTGOING_FILTER, new NotFilter(ORIGIN_ID_FILTER));
|
||||
private static final Predicate<Message> ADD_ORIGIN_ID_PREDICATE = m -> {
|
||||
return ADD_ORIGIN_ID_FILTER.accept(m);
|
||||
};
|
||||
|
||||
static {
|
||||
|
@ -112,10 +112,8 @@ public final class StableUniqueStanzaIdManager extends Manager {
|
|||
* Start appending origin-id elements to outgoing stanzas and add the feature to disco.
|
||||
*/
|
||||
public synchronized void enable() {
|
||||
connection().addMessageInterceptor(ADD_ORIGIN_ID_INTERCEPTOR, ADD_ORIGIN_ID_PREDICATE);
|
||||
ServiceDiscoveryManager.getInstanceFor(connection()).addFeature(NAMESPACE);
|
||||
// We need a filter for outgoing messages that do not carry an origin-id already
|
||||
StanzaFilter filter = new AndFilter(OUTGOING_FILTER, new NotFilter(ORIGIN_ID_FILTER));
|
||||
connection().addStanzaInterceptor(ADD_ORIGIN_ID_INTERCEPTOR, filter);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -123,7 +121,7 @@ public final class StableUniqueStanzaIdManager extends Manager {
|
|||
*/
|
||||
public synchronized void disable() {
|
||||
ServiceDiscoveryManager.getInstanceFor(connection()).removeFeature(NAMESPACE);
|
||||
connection().removeStanzaInterceptor(ADD_ORIGIN_ID_INTERCEPTOR);
|
||||
connection().removeMessageInterceptor(ADD_ORIGIN_ID_INTERCEPTOR);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package org.jivesoftware.smackx.sid.element;
|
||||
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.MessageBuilder;
|
||||
import org.jivesoftware.smack.util.XmlStringBuilder;
|
||||
|
||||
import org.jivesoftware.smackx.sid.StableUniqueStanzaIdManager;
|
||||
|
@ -38,7 +39,10 @@ public class OriginIdElement extends StableAndUniqueIdElement {
|
|||
*
|
||||
* @param message message.
|
||||
* @return the added origin-id element.
|
||||
* @deprecated use {@link #addOriginId(MessageBuilder)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove in Smack 4.5.
|
||||
public static OriginIdElement addOriginId(Message message) {
|
||||
OriginIdElement originId = new OriginIdElement();
|
||||
message.addExtension(originId);
|
||||
|
@ -47,6 +51,20 @@ public class OriginIdElement extends StableAndUniqueIdElement {
|
|||
return originId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an origin-id element to a message and set the stanzas id to the same id as in the origin-id element.
|
||||
*
|
||||
* @param messageBuilder the message builder to add an origin ID to.
|
||||
* @return the added origin-id element.
|
||||
*/
|
||||
public static OriginIdElement addOriginId(MessageBuilder messageBuilder) {
|
||||
OriginIdElement 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());
|
||||
return originId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true, if the message contains a origin-id element.
|
||||
*
|
||||
|
|
|
@ -23,6 +23,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
|
|||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.MessageBuilder;
|
||||
import org.jivesoftware.smack.packet.StanzaBuilder;
|
||||
import org.jivesoftware.smack.test.util.SmackTestSuite;
|
||||
import org.jivesoftware.smack.test.util.TestUtils;
|
||||
|
@ -71,12 +72,15 @@ public class StableUniqueStanzaIdTest extends SmackTestSuite {
|
|||
|
||||
@Test
|
||||
public void fromMessageTest() {
|
||||
Message message = StanzaBuilder.buildMessage().build();
|
||||
MessageBuilder messageBuilder = StanzaBuilder.buildMessage();
|
||||
|
||||
Message message = messageBuilder.build();
|
||||
assertFalse(OriginIdElement.hasOriginId(message));
|
||||
assertFalse(StanzaIdElement.hasStanzaId(message));
|
||||
|
||||
OriginIdElement.addOriginId(message);
|
||||
OriginIdElement.addOriginId(messageBuilder);
|
||||
|
||||
message = messageBuilder.build();
|
||||
assertTrue(OriginIdElement.hasOriginId(message));
|
||||
|
||||
StanzaIdElement stanzaId = new StanzaIdElement("alice@wonderland.lit");
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2017-2018 Florian Schmaus.
|
||||
* Copyright 2017-2019 Florian Schmaus.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -24,7 +24,6 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||
|
||||
import org.jivesoftware.smack.AsyncButOrdered;
|
||||
import org.jivesoftware.smack.Manager;
|
||||
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
||||
import org.jivesoftware.smack.StanzaListener;
|
||||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smack.filter.AndFilter;
|
||||
|
@ -36,6 +35,7 @@ import org.jivesoftware.smack.filter.StanzaExtensionFilter;
|
|||
import org.jivesoftware.smack.filter.StanzaFilter;
|
||||
import org.jivesoftware.smack.filter.ToTypeFilter;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.MessageView;
|
||||
import org.jivesoftware.smack.packet.Presence;
|
||||
import org.jivesoftware.smack.packet.Stanza;
|
||||
import org.jivesoftware.smack.roster.AbstractRosterListener;
|
||||
|
@ -124,22 +124,20 @@ public final class ChatManager extends Manager {
|
|||
}
|
||||
}, INCOMING_MESSAGE_FILTER);
|
||||
|
||||
connection.addStanzaInterceptor(new StanzaListener() {
|
||||
@Override
|
||||
public void processStanza(Stanza stanza) throws NotConnectedException, InterruptedException {
|
||||
Message message = (Message) stanza;
|
||||
if (!shouldAcceptMessage(message)) {
|
||||
connection.addMessageInterceptor(messageBuilder -> {
|
||||
if (!shouldAcceptMessage(messageBuilder)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final EntityBareJid to = message.getTo().asEntityBareJidOrThrow();
|
||||
final EntityBareJid to = messageBuilder.getTo().asEntityBareJidOrThrow();
|
||||
final Chat chat = chatWith(to);
|
||||
|
||||
for (OutgoingChatMessageListener listener : outgoingListeners) {
|
||||
listener.newOutgoingMessage(to, message, chat);
|
||||
listener.newOutgoingMessage(to, messageBuilder, chat);
|
||||
}
|
||||
}
|
||||
}, OUTGOING_MESSAGE_FILTER);
|
||||
}, m -> {
|
||||
return OUTGOING_MESSAGE_FILTER.accept(m);
|
||||
});
|
||||
|
||||
Roster roster = Roster.getInstanceFor(connection);
|
||||
roster.addRosterListener(new AbstractRosterListener() {
|
||||
|
@ -181,8 +179,8 @@ public final class ChatManager extends Manager {
|
|||
});
|
||||
}
|
||||
|
||||
private boolean shouldAcceptMessage(Message message) {
|
||||
if (!message.getBodies().isEmpty()) {
|
||||
private boolean shouldAcceptMessage(MessageView message) {
|
||||
if (message.hasExtension(Message.Body.QNAME)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2017 Florian Schmaus.
|
||||
* Copyright 2017-2019 Florian Schmaus.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -16,12 +16,12 @@
|
|||
*/
|
||||
package org.jivesoftware.smack.chat2;
|
||||
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.MessageBuilder;
|
||||
|
||||
import org.jxmpp.jid.EntityBareJid;
|
||||
|
||||
public interface OutgoingChatMessageListener {
|
||||
|
||||
void newOutgoingMessage(EntityBareJid to, Message message, Chat chat);
|
||||
void newOutgoingMessage(EntityBareJid to, MessageBuilder messageBuilder, Chat chat);
|
||||
|
||||
}
|
||||
|
|
|
@ -51,9 +51,11 @@ import org.jivesoftware.smack.filter.StanzaTypeFilter;
|
|||
import org.jivesoftware.smack.packet.ExtensionElement;
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.Presence;
|
||||
import org.jivesoftware.smack.packet.PresenceBuilder;
|
||||
import org.jivesoftware.smack.packet.Stanza;
|
||||
import org.jivesoftware.smack.roster.AbstractPresenceEventListener;
|
||||
import org.jivesoftware.smack.roster.Roster;
|
||||
import org.jivesoftware.smack.util.Consumer;
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
import org.jivesoftware.smack.util.stringencoder.Base64;
|
||||
|
||||
|
@ -308,6 +310,15 @@ public final class EntityCapsManager extends Manager {
|
|||
*/
|
||||
private String entityNode = DEFAULT_ENTITY_NODE;
|
||||
|
||||
// Intercept presence packages and add caps data when intended.
|
||||
// XEP-0115 specifies that a client SHOULD include entity capabilities
|
||||
// with every presence notification it sends.
|
||||
private final Consumer<PresenceBuilder> presenceInterceptor = presenceBuilder -> {
|
||||
CapsVersionAndHash capsVersionAndHash = getCapsVersionAndHash();
|
||||
CapsExtension caps = new CapsExtension(entityNode, capsVersionAndHash.version, capsVersionAndHash.hash);
|
||||
presenceBuilder.overrideExtension(caps);
|
||||
};
|
||||
|
||||
private EntityCapsManager(XMPPConnection connection) {
|
||||
super(connection);
|
||||
this.sdm = ServiceDiscoveryManager.getInstanceFor(connection);
|
||||
|
@ -379,23 +390,9 @@ public final class EntityCapsManager extends Manager {
|
|||
}
|
||||
}, PresenceTypeFilter.OUTGOING_PRESENCE_BROADCAST);
|
||||
|
||||
// Intercept presence packages and add caps data when intended.
|
||||
// XEP-0115 specifies that a client SHOULD include entity capabilities
|
||||
// with every presence notification it sends.
|
||||
StanzaListener packetInterceptor = new StanzaListener() {
|
||||
@Override
|
||||
public void processStanza(Stanza packet) {
|
||||
if (!entityCapsEnabled) {
|
||||
// Be sure to not send stanzas with the caps extension if it's not enabled
|
||||
packet.removeExtension(CapsExtension.ELEMENT, CapsExtension.NAMESPACE);
|
||||
return;
|
||||
}
|
||||
CapsVersionAndHash capsVersionAndHash = getCapsVersionAndHash();
|
||||
CapsExtension caps = new CapsExtension(entityNode, capsVersionAndHash.version, capsVersionAndHash.hash);
|
||||
packet.overrideExtension(caps);
|
||||
}
|
||||
};
|
||||
connection.addStanzaInterceptor(packetInterceptor, PresenceTypeFilter.AVAILABLE);
|
||||
|
||||
enableEntityCaps();
|
||||
|
||||
// It's important to do this as last action. Since it changes the
|
||||
// behavior of the SDM in some ways
|
||||
sdm.addEntityCapabilitiesChangedListener(new EntityCapabilitiesChangedListener() {
|
||||
|
@ -424,6 +421,10 @@ public final class EntityCapsManager extends Manager {
|
|||
}
|
||||
|
||||
public synchronized void enableEntityCaps() {
|
||||
connection().addPresenceInterceptor(presenceInterceptor, p -> {
|
||||
return PresenceTypeFilter.AVAILABLE.accept(p);
|
||||
});
|
||||
|
||||
// Add Entity Capabilities (XEP-0115) feature node.
|
||||
sdm.addFeature(NAMESPACE);
|
||||
updateLocalEntityCaps();
|
||||
|
@ -433,6 +434,8 @@ public final class EntityCapsManager extends Manager {
|
|||
public synchronized void disableEntityCaps() {
|
||||
entityCapsEnabled = false;
|
||||
sdm.removeFeature(NAMESPACE);
|
||||
|
||||
connection().removePresenceInterceptor(presenceInterceptor);
|
||||
}
|
||||
|
||||
public boolean entityCapsEnabled() {
|
||||
|
|
|
@ -37,11 +37,11 @@ import org.jivesoftware.smack.chat2.OutgoingChatMessageListener;
|
|||
import org.jivesoftware.smack.filter.AndFilter;
|
||||
import org.jivesoftware.smack.filter.FromTypeFilter;
|
||||
import org.jivesoftware.smack.filter.MessageTypeFilter;
|
||||
import org.jivesoftware.smack.filter.NotFilter;
|
||||
import org.jivesoftware.smack.filter.StanzaExtensionFilter;
|
||||
import org.jivesoftware.smack.filter.StanzaFilter;
|
||||
import org.jivesoftware.smack.packet.ExtensionElement;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.MessageBuilder;
|
||||
import org.jivesoftware.smack.packet.Stanza;
|
||||
import org.jivesoftware.smack.packet.StanzaBuilder;
|
||||
|
||||
|
@ -73,7 +73,6 @@ public final class ChatStateManager extends Manager {
|
|||
|
||||
private static final Map<XMPPConnection, ChatStateManager> INSTANCES = new WeakHashMap<>();
|
||||
|
||||
private static final StanzaFilter filter = new NotFilter(new StanzaExtensionFilter(NAMESPACE));
|
||||
private static final StanzaFilter INCOMING_MESSAGE_FILTER =
|
||||
new AndFilter(MessageTypeFilter.NORMAL_OR_CHAT, FromTypeFilter.ENTITY_FULL_JID);
|
||||
private static final StanzaFilter INCOMING_CHAT_STATE_FILTER = new AndFilter(INCOMING_MESSAGE_FILTER, new StanzaExtensionFilter(NAMESPACE));
|
||||
|
@ -117,13 +116,13 @@ public final class ChatStateManager extends Manager {
|
|||
ChatManager chatManager = ChatManager.getInstanceFor(connection);
|
||||
chatManager.addOutgoingListener(new OutgoingChatMessageListener() {
|
||||
@Override
|
||||
public void newOutgoingMessage(EntityBareJid to, Message message, Chat chat) {
|
||||
public void newOutgoingMessage(EntityBareJid to, MessageBuilder message, Chat chat) {
|
||||
if (chat == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// if message already has a chatStateExtension, then do nothing,
|
||||
if (!filter.accept(message)) {
|
||||
if (message.hasExtension(ChatStateExtension.NAMESPACE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -358,7 +358,7 @@ public class MultiUserChat {
|
|||
);
|
||||
// @formatter:on
|
||||
connection.addSyncStanzaListener(declinesListener, new AndFilter(fromRoomFilter, DECLINE_FILTER));
|
||||
connection.addStanzaInterceptor(presenceInterceptor, new AndFilter(ToMatchesFilter.create(room),
|
||||
connection.addStanzaSendingListener(presenceInterceptor, new AndFilter(ToMatchesFilter.create(room),
|
||||
StanzaTypeFilter.PRESENCE));
|
||||
messageCollector = connection.createStanzaCollector(fromRoomGroupchatFilter);
|
||||
|
||||
|
@ -2122,7 +2122,7 @@ public class MultiUserChat {
|
|||
connection.removeSyncStanzaListener(presenceListener);
|
||||
connection.removeSyncStanzaListener(subjectListener);
|
||||
connection.removeSyncStanzaListener(declinesListener);
|
||||
connection.removeStanzaInterceptor(presenceInterceptor);
|
||||
connection.removeStanzaSendingListener(presenceInterceptor);
|
||||
if (messageCollector != null) {
|
||||
messageCollector.cancel();
|
||||
messageCollector = null;
|
||||
|
|
|
@ -38,9 +38,11 @@ import org.jivesoftware.smack.filter.StanzaExtensionFilter;
|
|||
import org.jivesoftware.smack.filter.StanzaFilter;
|
||||
import org.jivesoftware.smack.filter.StanzaTypeFilter;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.MessageBuilder;
|
||||
import org.jivesoftware.smack.packet.Stanza;
|
||||
import org.jivesoftware.smack.packet.StanzaBuilder;
|
||||
import org.jivesoftware.smack.roster.Roster;
|
||||
import org.jivesoftware.smack.util.Consumer;
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
|
||||
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
||||
|
@ -271,13 +273,7 @@ public final class DeliveryReceiptManager extends Manager {
|
|||
);
|
||||
// @formatter:on
|
||||
|
||||
private static final StanzaListener AUTO_ADD_DELIVERY_RECEIPT_REQUESTS_LISTENER = new StanzaListener() {
|
||||
@Override
|
||||
public void processStanza(Stanza packet) throws NotConnectedException {
|
||||
Message message = (Message) packet;
|
||||
DeliveryReceiptRequest.addTo(message);
|
||||
}
|
||||
};
|
||||
private static final Consumer<MessageBuilder> AUTO_ADD_DELIVERY_RECEIPT_REQUESTS_LISTENER = mb -> DeliveryReceiptRequest.addTo(mb);
|
||||
|
||||
/**
|
||||
* Enables automatic requests of delivery receipts for outgoing messages of
|
||||
|
@ -288,8 +284,9 @@ public final class DeliveryReceiptManager extends Manager {
|
|||
* @see #dontAutoAddDeliveryReceiptRequests()
|
||||
*/
|
||||
public void autoAddDeliveryReceiptRequests() {
|
||||
connection().addStanzaInterceptor(AUTO_ADD_DELIVERY_RECEIPT_REQUESTS_LISTENER,
|
||||
MESSAGES_TO_REQUEST_RECEIPTS_FOR);
|
||||
connection().addMessageInterceptor(AUTO_ADD_DELIVERY_RECEIPT_REQUESTS_LISTENER, m -> {
|
||||
return MESSAGES_TO_REQUEST_RECEIPTS_FOR.accept(m);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -299,7 +296,7 @@ public final class DeliveryReceiptManager extends Manager {
|
|||
* @see #autoAddDeliveryReceiptRequests()
|
||||
*/
|
||||
public void dontAutoAddDeliveryReceiptRequests() {
|
||||
connection().removeStanzaInterceptor(AUTO_ADD_DELIVERY_RECEIPT_REQUESTS_LISTENER);
|
||||
connection().removeMessageInterceptor(AUTO_ADD_DELIVERY_RECEIPT_REQUESTS_LISTENER);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -21,8 +21,10 @@ import java.util.ArrayList;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import org.jivesoftware.smack.packet.ExtensionElement;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.MessageView;
|
||||
import org.jivesoftware.smack.util.XmlStringBuilder;
|
||||
|
||||
/**
|
||||
|
@ -40,6 +42,8 @@ public class XHTMLExtension implements ExtensionElement {
|
|||
public static final String ELEMENT = "html";
|
||||
public static final String NAMESPACE = "http://jabber.org/protocol/xhtml-im";
|
||||
|
||||
public static final QName QNAME = new QName(NAMESPACE, ELEMENT);
|
||||
|
||||
private final List<CharSequence> bodies = new ArrayList<>();
|
||||
|
||||
/**
|
||||
|
@ -125,7 +129,7 @@ public class XHTMLExtension implements ExtensionElement {
|
|||
}
|
||||
}
|
||||
|
||||
public static XHTMLExtension from(Message message) {
|
||||
return message.getExtension(ELEMENT, NAMESPACE);
|
||||
public static XHTMLExtension from(MessageView message) {
|
||||
return message.getExtension(QNAME);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package org.jivesoftware.smack.chat2;
|
||||
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.MessageBuilder;
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
|
||||
import org.igniterealtime.smack.inttest.SmackIntegrationTest;
|
||||
|
@ -36,7 +37,8 @@ public class OutgoingMessageListenerIntegrationTest extends AbstractChatIntegrat
|
|||
final SimpleResultSyncPoint syncPoint = new SimpleResultSyncPoint();
|
||||
final OutgoingChatMessageListener listener = new OutgoingChatMessageListener() {
|
||||
@Override
|
||||
public void newOutgoingMessage(EntityBareJid to, Message message, Chat chat) {
|
||||
public void newOutgoingMessage(EntityBareJid to, MessageBuilder messageBuilder, Chat chat) {
|
||||
Message message = messageBuilder.build();
|
||||
if (message.getBody().equals(body)) {
|
||||
syncPoint.signal();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue