mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-11-24 13:02:06 +01:00
Introduce StanzaBuilder
As first step to immutable Stanza types.
This commit is contained in:
parent
926c5892ad
commit
5db6191110
134 changed files with 2576 additions and 764 deletions
|
@ -15,7 +15,11 @@ Smack Key Advantages
|
|||
AbstractXMPPConnection connection = new XMPPTCPConnection("mtucker", "password", "jabber.org");
|
||||
connection.connect().login();
|
||||
|
||||
Message message = new Message("jsmith@jivesoftware.com", "Howdy! How are you?");
|
||||
Message message = connection.getStanzaFactory()
|
||||
.buildMessageStanza()
|
||||
.to("jsmith@jivesoftware.com")
|
||||
.setBody("Howdy! How are you?")
|
||||
.build();
|
||||
connection.sendStanza(message);
|
||||
```
|
||||
|
||||
|
|
|
@ -517,8 +517,8 @@ public class XMPPBOSHConnection extends AbstractXMPPConnection {
|
|||
if ("urn:ietf:params:xml:ns:xmpp-streams".equals(parser.getNamespace(null))) {
|
||||
throw new StreamErrorException(PacketParserUtils.parseStreamError(parser));
|
||||
} else {
|
||||
StanzaError.Builder builder = PacketParserUtils.parseError(parser);
|
||||
throw new XMPPException.XMPPErrorException(null, builder.build());
|
||||
StanzaError stanzaError = PacketParserUtils.parseError(parser);
|
||||
throw new XMPPException.XMPPErrorException(null, stanzaError);
|
||||
}
|
||||
default:
|
||||
parseAndProcessNonza(parser);
|
||||
|
|
|
@ -105,11 +105,13 @@ import org.jivesoftware.smack.packet.Presence;
|
|||
import org.jivesoftware.smack.packet.Session;
|
||||
import org.jivesoftware.smack.packet.Stanza;
|
||||
import org.jivesoftware.smack.packet.StanzaError;
|
||||
import org.jivesoftware.smack.packet.StanzaFactory;
|
||||
import org.jivesoftware.smack.packet.StartTls;
|
||||
import org.jivesoftware.smack.packet.StreamError;
|
||||
import org.jivesoftware.smack.packet.StreamOpen;
|
||||
import org.jivesoftware.smack.packet.TopLevelStreamElement;
|
||||
import org.jivesoftware.smack.packet.XmlEnvironment;
|
||||
import org.jivesoftware.smack.packet.id.StanzaIdSource;
|
||||
import org.jivesoftware.smack.parsing.ParsingExceptionCallback;
|
||||
import org.jivesoftware.smack.parsing.SmackParsingException;
|
||||
import org.jivesoftware.smack.provider.ExtensionElementProvider;
|
||||
|
@ -402,6 +404,8 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
|||
private final Map<QName, IQRequestHandler> setIqRequestHandler = new HashMap<>();
|
||||
private final Map<QName, IQRequestHandler> getIqRequestHandler = new HashMap<>();
|
||||
|
||||
private final StanzaFactory stanzaFactory;
|
||||
|
||||
/**
|
||||
* Create a new XMPPConnection to an XMPP server.
|
||||
*
|
||||
|
@ -440,6 +444,9 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
|||
for (ConnectionCreationListener listener : XMPPConnectionRegistry.getConnectionCreationListeners()) {
|
||||
listener.connectionCreated(this);
|
||||
}
|
||||
|
||||
StanzaIdSource stanzaIdSource = configuration.constructStanzaIdSource();
|
||||
stanzaFactory = new StanzaFactory(stanzaIdSource);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -733,7 +740,11 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
|||
// eventually load the roster. And we should load the roster before we
|
||||
// send the initial presence.
|
||||
if (config.isSendPresence() && !resumed) {
|
||||
sendStanza(new Presence(Presence.Type.available));
|
||||
Presence availablePresence = getStanzaFactory()
|
||||
.buildPresenceStanza()
|
||||
.ofType(Presence.Type.available)
|
||||
.build();
|
||||
sendStanza(availablePresence);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -814,6 +825,11 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final StanzaFactory getStanzaFactory() {
|
||||
return stanzaFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void sendStanza(Stanza stanza) throws NotConnectedException, InterruptedException {
|
||||
Objects.requireNonNull(stanza, "Stanza must not be null");
|
||||
|
@ -893,7 +909,9 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
|||
public void disconnect() {
|
||||
Presence unavailablePresence = null;
|
||||
if (isAuthenticated()) {
|
||||
unavailablePresence = new Presence(Presence.Type.unavailable);
|
||||
unavailablePresence = getStanzaFactory().buildPresenceStanza()
|
||||
.ofType(Presence.Type.unavailable)
|
||||
.build();
|
||||
}
|
||||
try {
|
||||
disconnect(unavailablePresence);
|
||||
|
@ -1416,7 +1434,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection {
|
|||
// If the IQ stanza is of type "get" or "set" with no registered IQ request handler, then answer an
|
||||
// IQ of type 'error' with condition 'service-unavailable'.
|
||||
final ErrorIQ errorIQ = IQ.createErrorResponse(iq, StanzaError.getBuilder(
|
||||
replyCondition));
|
||||
replyCondition).build());
|
||||
// Use async sendStanza() here, since if sendStanza() would block, then some connections, e.g.
|
||||
// XmppNioTcpConnection, would deadlock, as this operation is performed in the same thread that is
|
||||
asyncGo(() -> {
|
||||
|
|
|
@ -36,6 +36,9 @@ import javax.net.ssl.X509TrustManager;
|
|||
import javax.security.auth.callback.CallbackHandler;
|
||||
|
||||
import org.jivesoftware.smack.debugger.SmackDebuggerFactory;
|
||||
import org.jivesoftware.smack.packet.id.StandardStanzaIdSource;
|
||||
import org.jivesoftware.smack.packet.id.StanzaIdSource;
|
||||
import org.jivesoftware.smack.packet.id.StanzaIdSourceFactory;
|
||||
import org.jivesoftware.smack.proxy.ProxyInfo;
|
||||
import org.jivesoftware.smack.sasl.SASLMechanism;
|
||||
import org.jivesoftware.smack.sasl.core.SASLAnonymous;
|
||||
|
@ -159,6 +162,8 @@ public abstract class ConnectionConfiguration {
|
|||
|
||||
private final boolean compressionEnabled;
|
||||
|
||||
private final StanzaIdSourceFactory stanzaIdSourceFactory;
|
||||
|
||||
protected ConnectionConfiguration(Builder<?, ?> builder) {
|
||||
authzid = builder.authzid;
|
||||
username = builder.username;
|
||||
|
@ -213,6 +218,8 @@ public abstract class ConnectionConfiguration {
|
|||
|
||||
compressionEnabled = builder.compressionEnabled;
|
||||
|
||||
stanzaIdSourceFactory = builder.stanzaIdSourceFactory;
|
||||
|
||||
// If the enabledSaslmechanisms are set, then they must not be empty
|
||||
assert enabledSaslMechanisms == null || !enabledSaslMechanisms.isEmpty();
|
||||
|
||||
|
@ -568,6 +575,10 @@ public abstract class ConnectionConfiguration {
|
|||
return Collections.unmodifiableSet(enabledSaslMechanisms);
|
||||
}
|
||||
|
||||
StanzaIdSource constructStanzaIdSource() {
|
||||
return stanzaIdSourceFactory.constructStanzaIdSource();
|
||||
}
|
||||
|
||||
/**
|
||||
* A builder for XMPP connection configurations.
|
||||
* <p>
|
||||
|
@ -612,6 +623,7 @@ public abstract class ConnectionConfiguration {
|
|||
private Set<String> enabledSaslMechanisms;
|
||||
private X509TrustManager customX509TrustManager;
|
||||
private boolean compressionEnabled = false;
|
||||
private StanzaIdSourceFactory stanzaIdSourceFactory = new StandardStanzaIdSource.Factory();
|
||||
|
||||
protected Builder() {
|
||||
if (SmackConfiguration.DEBUG) {
|
||||
|
@ -1134,6 +1146,17 @@ public abstract class ConnectionConfiguration {
|
|||
return getThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the factory for stanza ID sources to use.
|
||||
*
|
||||
* @param stanzaIdSourceFactory the factory for stanza ID sources to use.
|
||||
* @return a reference to this builder.
|
||||
* @since 4.4
|
||||
*/
|
||||
public B setStanzaIdSourceFactory(StanzaIdSourceFactory stanzaIdSourceFactory) {
|
||||
this.stanzaIdSourceFactory = Objects.requireNonNull(stanzaIdSourceFactory);
|
||||
return getThis();
|
||||
}
|
||||
|
||||
public abstract C build();
|
||||
|
||||
|
|
|
@ -49,7 +49,6 @@ import org.jivesoftware.smack.sasl.core.ScramSha1PlusMechanism;
|
|||
import org.jivesoftware.smack.util.CloseableUtil;
|
||||
import org.jivesoftware.smack.util.FileUtils;
|
||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||
|
||||
import org.jivesoftware.smack.xml.XmlPullParser;
|
||||
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ import org.jivesoftware.smack.packet.FullyQualifiedElement;
|
|||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.Nonza;
|
||||
import org.jivesoftware.smack.packet.Stanza;
|
||||
import org.jivesoftware.smack.packet.StanzaFactory;
|
||||
|
||||
import org.jxmpp.jid.DomainBareJid;
|
||||
import org.jxmpp.jid.EntityFullJid;
|
||||
|
@ -178,6 +179,8 @@ public interface XMPPConnection {
|
|||
*/
|
||||
boolean isUsingCompression();
|
||||
|
||||
StanzaFactory getStanzaFactory();
|
||||
|
||||
/**
|
||||
* Sends the specified stanza to the server.
|
||||
*
|
||||
|
|
|
@ -26,7 +26,6 @@ import org.jivesoftware.smack.packet.XmlEnvironment;
|
|||
import org.jivesoftware.smack.parsing.SmackParsingException;
|
||||
import org.jivesoftware.smack.provider.NonzaProvider;
|
||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||
|
||||
import org.jivesoftware.smack.xml.XmlPullParser;
|
||||
import org.jivesoftware.smack.xml.XmlPullParserException;
|
||||
|
||||
|
@ -62,8 +61,7 @@ public final class FailureProvider extends NonzaProvider<Failure> {
|
|||
case StreamOpen.SERVER_NAMESPACE:
|
||||
switch (name) {
|
||||
case StanzaError.ERROR:
|
||||
StanzaError.Builder stanzaErrorBuilder = PacketParserUtils.parseError(parser, failureXmlEnvironment);
|
||||
stanzaError = stanzaErrorBuilder.build();
|
||||
stanzaError = PacketParserUtils.parseError(parser, failureXmlEnvironment);
|
||||
break;
|
||||
default:
|
||||
LOGGER.warning("Unknown element in " + namespace + ": " + name);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright © 2014 Florian Schmaus
|
||||
* Copyright © 2014-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.
|
||||
|
@ -18,14 +18,18 @@ package org.jivesoftware.smack.packet;
|
|||
|
||||
public class EmptyResultIQ extends IQ {
|
||||
|
||||
EmptyResultIQ(IqBuilder iqBuilder) {
|
||||
super(iqBuilder, null, null);
|
||||
}
|
||||
|
||||
// TODO: Deprecate when stanza builder and parsing logic is ready.
|
||||
public EmptyResultIQ() {
|
||||
super(null, null);
|
||||
setType(IQ.Type.result);
|
||||
}
|
||||
|
||||
public EmptyResultIQ(IQ request) {
|
||||
this();
|
||||
initializeAsResultFor(request);
|
||||
this(StanzaBuilder.buildIqResultFor(request));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -27,13 +27,13 @@ public class ErrorIQ extends SimpleIQ {
|
|||
* <p>
|
||||
* According to RFC 6120 § 8.3.1 "4. An error stanza MUST contain an <error/> child element.", so the xmppError argument is mandatory.
|
||||
* </p>
|
||||
* @param xmppErrorBuilder the XMPPError builder (required).
|
||||
* @param stanzaError the stanzaError (required).
|
||||
*/
|
||||
public ErrorIQ(StanzaError.Builder xmppErrorBuilder) {
|
||||
public ErrorIQ(StanzaError stanzaError) {
|
||||
super(ELEMENT, null);
|
||||
Objects.requireNonNull(xmppErrorBuilder, "xmppErrorBuilder must not be null");
|
||||
Objects.requireNonNull(stanzaError, "stanzaError must not be null");
|
||||
setType(IQ.Type.error);
|
||||
setError(xmppErrorBuilder);
|
||||
setError(stanzaError);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ package org.jivesoftware.smack.packet;
|
|||
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
public interface FullyQualifiedElement extends NamedElement {
|
||||
public interface FullyQualifiedElement extends NamedElement, XmlLangElement {
|
||||
|
||||
/**
|
||||
* Returns the root element XML namespace.
|
||||
|
@ -33,11 +33,7 @@ public interface FullyQualifiedElement extends NamedElement {
|
|||
return new QName(namespaceURI, localPart);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the xml:lang of this XML element, or null if one has not been set.
|
||||
*
|
||||
* @return the xml:lang of this XML element, or null.
|
||||
*/
|
||||
@Override
|
||||
default String getLanguage() {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ import org.jivesoftware.smack.util.XmlStringBuilder;
|
|||
*
|
||||
* @author Matt Tucker
|
||||
*/
|
||||
public abstract class IQ extends Stanza {
|
||||
public abstract class IQ extends Stanza implements IqView {
|
||||
|
||||
// Don't name this field 'ELEMENT'. When it comes to IQ, ELEMENT is the child element!
|
||||
public static final String IQ_ELEMENT = "iq";
|
||||
|
@ -54,6 +54,7 @@ public abstract class IQ extends Stanza {
|
|||
|
||||
private Type type = Type.get;
|
||||
|
||||
// TODO: This method should be protected!
|
||||
public IQ(IQ iq) {
|
||||
super(iq);
|
||||
type = iq.getType();
|
||||
|
@ -62,7 +63,16 @@ public abstract class IQ extends Stanza {
|
|||
this.childElementQName = iq.childElementQName;
|
||||
}
|
||||
|
||||
// TODO: Deprecate when stanza builder is ready.
|
||||
protected IQ(String childElementName, String childElementNamespace) {
|
||||
this(IqBuilder.EMPTY, childElementName, childElementNamespace);
|
||||
}
|
||||
|
||||
protected IQ(IqBuilder iqBuilder, String childElementName, String childElementNamespace) {
|
||||
super(iqBuilder);
|
||||
|
||||
type = iqBuilder.type;
|
||||
|
||||
this.childElementName = childElementName;
|
||||
this.childElementNamespace = childElementNamespace;
|
||||
if (childElementName == null) {
|
||||
|
@ -72,11 +82,7 @@ public abstract class IQ extends Stanza {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of the IQ packet.
|
||||
*
|
||||
* @return the type of the IQ packet.
|
||||
*/
|
||||
@Override
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
@ -90,6 +96,7 @@ public abstract class IQ extends Stanza {
|
|||
*
|
||||
* @param type the type of the IQ packet.
|
||||
*/
|
||||
// TODO: Mark this as deprecated once StanzaBuilder is ready and all call sites are gone.
|
||||
public void setType(Type type) {
|
||||
this.type = Objects.requireNonNull(type, "type must not be null");
|
||||
}
|
||||
|
@ -260,19 +267,6 @@ public abstract class IQ extends Stanza {
|
|||
*/
|
||||
protected abstract IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml);
|
||||
|
||||
protected final void initializeAsResultFor(IQ request) {
|
||||
assert this != request;
|
||||
|
||||
if (!(request.getType() == Type.get || request.getType() == Type.set)) {
|
||||
throw new IllegalArgumentException(
|
||||
"IQ must be of type 'set' or 'get'. Original IQ: " + request.toXML());
|
||||
}
|
||||
setStanzaId(request.getStanzaId());
|
||||
setFrom(request.getTo());
|
||||
setTo(request.getFrom());
|
||||
setType(Type.result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to create a new empty {@link Type#result IQ.Type.result}
|
||||
* IQ based on a {@link Type#get IQ.Type.get} or {@link Type#set IQ.Type.set}
|
||||
|
@ -311,7 +305,7 @@ public abstract class IQ extends Stanza {
|
|||
* {@link Type#get IQ.Type.get} or {@link Type#set IQ.Type.set}.
|
||||
* @return a new {@link Type#error IQ.Type.error} IQ based on the originating IQ.
|
||||
*/
|
||||
public static ErrorIQ createErrorResponse(final IQ request, final StanzaError.Builder error) {
|
||||
public static ErrorIQ createErrorResponse(final IQ request, final StanzaError error) {
|
||||
if (!request.isRequestIQ()) {
|
||||
throw new IllegalArgumentException(
|
||||
"IQ must be of type 'set' or 'get'. Original IQ: " + request.toXML());
|
||||
|
@ -321,35 +315,25 @@ public abstract class IQ extends Stanza {
|
|||
result.setFrom(request.getTo());
|
||||
result.setTo(request.getFrom());
|
||||
|
||||
error.setStanza(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static ErrorIQ createErrorResponse(final IQ request, final StanzaError.Condition condition) {
|
||||
return createErrorResponse(request, StanzaError.getBuilder(condition));
|
||||
/**
|
||||
* Deprecated.
|
||||
*
|
||||
* @param request the request.
|
||||
* @param error the error.
|
||||
* @return an error IQ.
|
||||
* @deprecated use {@link #createErrorResponse(IQ, StanzaError)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove in Smack 4.5.
|
||||
public static ErrorIQ createErrorResponse(final IQ request, final StanzaError.Builder error) {
|
||||
return createErrorResponse(request, error.build());
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to create a new {@link Type#error IQ.Type.error} IQ
|
||||
* based on a {@link Type#get IQ.Type.get} or {@link Type#set IQ.Type.set}
|
||||
* IQ. The new stanza will be initialized with:<ul>
|
||||
* <li>The sender set to the recipient of the originating IQ.
|
||||
* <li>The recipient set to the sender of the originating IQ.
|
||||
* <li>The type set to {@link Type#error IQ.Type.error}.
|
||||
* <li>The id set to the id of the originating IQ.
|
||||
* <li>The child element contained in the associated originating IQ.
|
||||
* <li>The provided {@link StanzaError XMPPError}.
|
||||
* </ul>
|
||||
*
|
||||
* @param request the {@link Type#get IQ.Type.get} or {@link Type#set IQ.Type.set} IQ packet.
|
||||
* @param error the error to associate with the created IQ packet.
|
||||
* @throws IllegalArgumentException if the IQ stanza does not have a type of
|
||||
* {@link Type#get IQ.Type.get} or {@link Type#set IQ.Type.set}.
|
||||
* @return a new {@link Type#error IQ.Type.error} IQ based on the originating IQ.
|
||||
*/
|
||||
public static ErrorIQ createErrorResponse(final IQ request, final StanzaError error) {
|
||||
return createErrorResponse(request, StanzaError.getBuilder(error));
|
||||
public static ErrorIQ createErrorResponse(final IQ request, final StanzaError.Condition condition) {
|
||||
return createErrorResponse(request, StanzaError.getBuilder(condition).build());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/**
|
||||
*
|
||||
* 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.IQ.Type;
|
||||
import org.jivesoftware.smack.packet.id.StandardStanzaIdSource;
|
||||
import org.jivesoftware.smack.packet.id.StanzaIdSource;
|
||||
import org.jivesoftware.smack.util.Objects;
|
||||
import org.jivesoftware.smack.util.ToStringUtil;
|
||||
|
||||
public final class IqBuilder extends StanzaBuilder<IqBuilder> implements IqView {
|
||||
static final IqBuilder EMPTY = new IqBuilder(StandardStanzaIdSource.DEFAULT);
|
||||
|
||||
IQ.Type type = Type.get;
|
||||
|
||||
IqBuilder(StanzaIdSource stanzaIdSource) {
|
||||
super(stanzaIdSource);
|
||||
}
|
||||
|
||||
IqBuilder(String stanzaId) {
|
||||
super(stanzaId);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addStanzaSpecificAttributes(ToStringUtil.Builder builder) {
|
||||
builder.addValue("type", type);
|
||||
}
|
||||
|
||||
public IqBuilder ofType(IQ.Type type) {
|
||||
this.type = Objects.requireNonNull(type);
|
||||
return getThis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IqBuilder getThis() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IQ.Type getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/**
|
||||
*
|
||||
* 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 interface IqView extends StanzaView {
|
||||
|
||||
/**
|
||||
* Returns the type of the IQ packet.
|
||||
*
|
||||
* @return the type of the IQ packet.
|
||||
*/
|
||||
IQ.Type getType();
|
||||
|
||||
}
|
|
@ -24,6 +24,8 @@ import java.util.List;
|
|||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import org.jivesoftware.smack.util.EqualsUtil;
|
||||
import org.jivesoftware.smack.util.HashCode;
|
||||
import org.jivesoftware.smack.util.Objects;
|
||||
|
@ -58,7 +60,7 @@ import org.jxmpp.stringprep.XmppStringprepException;
|
|||
*
|
||||
* @author Matt Tucker
|
||||
*/
|
||||
public final class Message extends Stanza implements TypedCloneable<Message> {
|
||||
public final class Message extends Stanza implements MessageView, TypedCloneable<Message> {
|
||||
|
||||
public static final String ELEMENT = "message";
|
||||
public static final String BODY = "body";
|
||||
|
@ -66,11 +68,12 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
|
|||
private Type type;
|
||||
private String thread = null;
|
||||
|
||||
private final Set<Subject> subjects = new HashSet<Subject>();
|
||||
|
||||
/**
|
||||
* Creates a new, "normal" message.
|
||||
* @deprecated use {@link StanzaBuilder}, preferable via {@link StanzaFactory}, instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove in Smack 4.5.
|
||||
public Message() {
|
||||
}
|
||||
|
||||
|
@ -78,7 +81,10 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
|
|||
* Creates a new "normal" message to the specified recipient.
|
||||
*
|
||||
* @param to the recipient of the message.
|
||||
* @deprecated use {@link StanzaBuilder}, preferable via {@link StanzaFactory}, instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove in Smack 4.5.
|
||||
public Message(Jid to) {
|
||||
setTo(to);
|
||||
}
|
||||
|
@ -88,7 +94,10 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
|
|||
*
|
||||
* @param to the user to send the message to.
|
||||
* @param type the message type.
|
||||
* @deprecated use {@link StanzaBuilder}, preferable via {@link StanzaFactory}, instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove in Smack 4.5.
|
||||
public Message(Jid to, Type type) {
|
||||
this(to);
|
||||
setType(type);
|
||||
|
@ -99,7 +108,10 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
|
|||
*
|
||||
* @param to the user to send the message to.
|
||||
* @param body the body of the message.
|
||||
* @deprecated use {@link StanzaBuilder}, preferable via {@link StanzaFactory}, instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove in Smack 4.5.
|
||||
public Message(Jid to, String body) {
|
||||
this(to);
|
||||
setBody(body);
|
||||
|
@ -111,7 +123,10 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
|
|||
* @param to the user to send the message to.
|
||||
* @param body the body of the message.
|
||||
* @throws XmppStringprepException if 'to' is not a valid XMPP address.
|
||||
* @deprecated use {@link StanzaBuilder}, preferable via {@link StanzaFactory}, instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove in Smack 4.5.
|
||||
public Message(String to, String body) throws XmppStringprepException {
|
||||
this(JidCreate.from(to), body);
|
||||
}
|
||||
|
@ -122,12 +137,21 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
|
|||
* @param to TODO javadoc me please
|
||||
* @param extensionElement TODO javadoc me please
|
||||
* @since 4.2
|
||||
* @deprecated use {@link StanzaBuilder}, preferable via {@link StanzaFactory}, instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove in Smack 4.5.
|
||||
public Message(Jid to, ExtensionElement extensionElement) {
|
||||
this(to);
|
||||
addExtension(extensionElement);
|
||||
}
|
||||
|
||||
Message(MessageBuilder messageBuilder) {
|
||||
super(messageBuilder);
|
||||
type = messageBuilder.type;
|
||||
thread = messageBuilder.thread;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor.
|
||||
* <p>
|
||||
|
@ -141,15 +165,9 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
|
|||
super(other);
|
||||
this.type = other.type;
|
||||
this.thread = other.thread;
|
||||
this.subjects.addAll(other.subjects);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of the message. If no type has been set this method will return {@link
|
||||
* org.jivesoftware.smack.packet.Message.Type#normal}.
|
||||
*
|
||||
* @return the type of the message.
|
||||
*/
|
||||
@Override
|
||||
public Type getType() {
|
||||
if (type == null) {
|
||||
return Type.normal;
|
||||
|
@ -161,7 +179,10 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
|
|||
* Sets the type of the message.
|
||||
*
|
||||
* @param type the type of the message.
|
||||
* @deprecated use {@link StanzaBuilder} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove in Smack 4.5.
|
||||
public void setType(Type type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
@ -195,8 +216,9 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
|
|||
|
||||
private Subject getMessageSubject(String language) {
|
||||
language = determineLanguage(language);
|
||||
for (Subject subject : subjects) {
|
||||
if (Objects.equals(language, subject.language)) {
|
||||
for (Subject subject : getSubjects()) {
|
||||
if (Objects.equals(language, subject.language)
|
||||
|| (subject.language == null && Objects.equals(this.language, language))) {
|
||||
return subject;
|
||||
}
|
||||
}
|
||||
|
@ -210,7 +232,12 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
|
|||
* @return a collection of all subjects in this message.
|
||||
*/
|
||||
public Set<Subject> getSubjects() {
|
||||
return Collections.unmodifiableSet(subjects);
|
||||
List<Subject> subjectList = getExtensions(Subject.class);
|
||||
|
||||
Set<Subject> subjects = new HashSet<>(subjectList.size());
|
||||
subjects.addAll(subjectList);
|
||||
|
||||
return subjects;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -218,7 +245,10 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
|
|||
* message contents.
|
||||
*
|
||||
* @param subject the subject of the message.
|
||||
* @deprecated use {@link StanzaBuilder} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove when stanza builder is ready.
|
||||
public void setSubject(String subject) {
|
||||
if (subject == null) {
|
||||
removeSubject(""); // use empty string because #removeSubject(null) is ambiguous
|
||||
|
@ -235,10 +265,20 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
|
|||
* @return the new {@link org.jivesoftware.smack.packet.Message.Subject}
|
||||
* @throws NullPointerException if the subject is null, a null pointer exception is thrown
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove when stanza builder is ready.
|
||||
public Subject addSubject(String language, String subject) {
|
||||
language = determineLanguage(language);
|
||||
|
||||
List<Subject> currentSubjects = getExtensions(Subject.class);
|
||||
for (Subject currentSubject : currentSubjects) {
|
||||
if (language.equals(currentSubject.getLanguage())) {
|
||||
throw new IllegalArgumentException("Subject with the language " + language + " already exists");
|
||||
}
|
||||
}
|
||||
|
||||
Subject messageSubject = new Subject(language, subject);
|
||||
subjects.add(messageSubject);
|
||||
addExtension(messageSubject);
|
||||
return messageSubject;
|
||||
}
|
||||
|
||||
|
@ -248,11 +288,13 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
|
|||
* @param language the language of the subject which is to be removed
|
||||
* @return true if a subject was removed and false if it was not.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove when stanza builder is ready.
|
||||
public boolean removeSubject(String language) {
|
||||
language = determineLanguage(language);
|
||||
for (Subject subject : subjects) {
|
||||
for (Subject subject : getExtensions(Subject.class)) {
|
||||
if (language.equals(subject.language)) {
|
||||
return subjects.remove(subject);
|
||||
return removeSubject(subject);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -264,8 +306,10 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
|
|||
* @param subject the subject being removed from the message.
|
||||
* @return true if the subject was successfully removed and false if it was not.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove when stanza builder is ready.
|
||||
public boolean removeSubject(Subject subject) {
|
||||
return subjects.remove(subject);
|
||||
return removeExtension(subject) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -276,7 +320,7 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
|
|||
public List<String> getSubjectLanguages() {
|
||||
Subject defaultSubject = getMessageSubject(null);
|
||||
List<String> languages = new ArrayList<String>();
|
||||
for (Subject subject : subjects) {
|
||||
for (Subject subject : getExtensions(Subject.class)) {
|
||||
if (!subject.equals(defaultSubject)) {
|
||||
languages.add(subject.language);
|
||||
}
|
||||
|
@ -345,7 +389,10 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
|
|||
* @param body the body of the message.
|
||||
* @see #setBody(String)
|
||||
* @since 4.2
|
||||
* @deprecated use {@link StanzaBuilder} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove when stanza builder is ready.
|
||||
public void setBody(CharSequence body) {
|
||||
String bodyString;
|
||||
if (body != null) {
|
||||
|
@ -360,7 +407,10 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
|
|||
* Sets the body of the message. The body is the main message contents.
|
||||
*
|
||||
* @param body the body of the message.
|
||||
* @deprecated use {@link StanzaBuilder} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove when stanza builder is ready.
|
||||
public void setBody(String body) {
|
||||
if (body == null) {
|
||||
removeBody(""); // use empty string because #removeBody(null) is ambiguous
|
||||
|
@ -377,7 +427,10 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
|
|||
* @return the new {@link org.jivesoftware.smack.packet.Message.Body}
|
||||
* @throws NullPointerException if the body is null, a null pointer exception is thrown
|
||||
* @since 3.0.2
|
||||
* @deprecated use {@link StanzaBuilder} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove when stanza builder is ready.
|
||||
public Body addBody(String language, String body) {
|
||||
language = determineLanguage(language);
|
||||
|
||||
|
@ -393,7 +446,10 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
|
|||
*
|
||||
* @param language the language of the body which is to be removed
|
||||
* @return true if a body was removed and false if it was not.
|
||||
* @deprecated use {@link StanzaBuilder} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove when stanza builder is ready.
|
||||
public boolean removeBody(String language) {
|
||||
language = determineLanguage(language);
|
||||
for (Body body : getBodies()) {
|
||||
|
@ -412,7 +468,10 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
|
|||
* @param body the body being removed from the message.
|
||||
* @return true if the body was successfully removed and false if it was not.
|
||||
* @since 3.0.2
|
||||
* @deprecated use {@link StanzaBuilder} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove when stanza builder is ready.
|
||||
public boolean removeBody(Body body) {
|
||||
ExtensionElement removedElement = removeExtension(body);
|
||||
return removedElement != null;
|
||||
|
@ -450,7 +509,10 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
|
|||
* of "chat" messages.
|
||||
*
|
||||
* @param thread the thread id of the message.
|
||||
* @deprecated use {@link StanzaBuilder} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove when stanza builder is ready.
|
||||
public void setThread(String thread) {
|
||||
this.thread = thread;
|
||||
}
|
||||
|
@ -472,6 +534,10 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
|
|||
return ELEMENT;
|
||||
}
|
||||
|
||||
public MessageBuilder asBuilder() {
|
||||
return StanzaBuilder.buildMessageFrom(this, getStanzaId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
@ -491,18 +557,6 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
|
|||
buf.optAttribute("type", type);
|
||||
buf.rightAngleBracket();
|
||||
|
||||
// Add the subject in the default language
|
||||
Subject defaultSubject = getMessageSubject(null);
|
||||
if (defaultSubject != null) {
|
||||
buf.element("subject", defaultSubject.subject);
|
||||
}
|
||||
// Add the subject in other languages
|
||||
for (Subject subject : getSubjects()) {
|
||||
// Skip the default language
|
||||
if (subject.equals(defaultSubject))
|
||||
continue;
|
||||
buf.append(subject);
|
||||
}
|
||||
buf.optElement("thread", thread);
|
||||
// Append the error subpacket if the message type is an error.
|
||||
if (type == Type.error) {
|
||||
|
@ -537,10 +591,12 @@ public final class Message extends Stanza implements TypedCloneable<Message> {
|
|||
public static final String ELEMENT = "subject";
|
||||
public static final String NAMESPACE = StreamOpen.CLIENT_NAMESPACE;
|
||||
|
||||
public static final QName QNAME = new QName(NAMESPACE, ELEMENT);
|
||||
|
||||
private final String subject;
|
||||
private final String language;
|
||||
|
||||
private Subject(String language, String subject) {
|
||||
public Subject(String language, String subject) {
|
||||
if (subject == null) {
|
||||
throw new NullPointerException("Subject cannot be null.");
|
||||
}
|
||||
|
|
|
@ -0,0 +1,164 @@
|
|||
/**
|
||||
*
|
||||
* 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.Message.Body;
|
||||
import org.jivesoftware.smack.packet.Message.Subject;
|
||||
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 {
|
||||
static final MessageBuilder EMPTY = new MessageBuilder(() -> {
|
||||
return null;
|
||||
});
|
||||
|
||||
Message.Type type;
|
||||
|
||||
String thread;
|
||||
|
||||
MessageBuilder(Message message, String stanzaId) {
|
||||
super(message, stanzaId);
|
||||
copyFromMessage(message);
|
||||
}
|
||||
|
||||
MessageBuilder(Message message, StanzaIdSource stanzaIdSource) {
|
||||
super(message, stanzaIdSource);
|
||||
copyFromMessage(message);
|
||||
}
|
||||
|
||||
MessageBuilder(StanzaIdSource stanzaIdSource) {
|
||||
super(stanzaIdSource);
|
||||
}
|
||||
|
||||
MessageBuilder(String stanzaId) {
|
||||
super(stanzaId);
|
||||
}
|
||||
|
||||
private void copyFromMessage(Message message) {
|
||||
type = message.getType();
|
||||
thread = message.getThread();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addStanzaSpecificAttributes(ToStringUtil.Builder builder) {
|
||||
builder.addValue("type", type)
|
||||
.addValue("thread", thread)
|
||||
;
|
||||
}
|
||||
|
||||
public MessageBuilder ofType(Message.Type type) {
|
||||
this.type = type;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
public MessageBuilder setThread(String thread) {
|
||||
this.thread = thread;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the subject of the message. The subject is a short description of
|
||||
* message contents.
|
||||
*
|
||||
* @param subject the subject of the message.
|
||||
* @return a reference to this builder.
|
||||
*/
|
||||
public MessageBuilder setSubject(String subject) {
|
||||
return addSubject(null, subject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a subject with a corresponding language.
|
||||
*
|
||||
* @param language the language of the subject being added.
|
||||
* @param subject the subject being added to the message.
|
||||
* @return a reference to this builder.
|
||||
* @throws NullPointerException if the subject is null.
|
||||
*/
|
||||
public MessageBuilder addSubject(String language, String subject) {
|
||||
language = StringUtils.requireNullOrNotEmpty(language, "language must be null or not empty");
|
||||
|
||||
for (Subject currentSubject : getExtensions(Subject.class)) {
|
||||
if (StringUtils.nullSafeCharSequenceEquals(language, currentSubject.getLanguage())) {
|
||||
throw new IllegalArgumentException("Subject with the language " + language + " already exists");
|
||||
}
|
||||
}
|
||||
|
||||
Subject messageSubject = new Subject(language, subject);
|
||||
addExtension(messageSubject);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the body of the message.
|
||||
*
|
||||
* @param body the body of the message.
|
||||
* @return a reference to this builder.
|
||||
* @see #setBody(String)
|
||||
*/
|
||||
public MessageBuilder setBody(CharSequence body) {
|
||||
return setBody(body.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the body of the message. The body is the main message contents.
|
||||
*
|
||||
* @param body the body of the message.
|
||||
* @return a reference to this builder.
|
||||
*/
|
||||
public MessageBuilder setBody(String body) {
|
||||
return addBody(null, body);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a body with a corresponding language.
|
||||
*
|
||||
* @param language the language of the body being added.
|
||||
* @param body the body being added to the message.
|
||||
* @return a reference to this builder.
|
||||
*/
|
||||
public MessageBuilder addBody(String language, String body) {
|
||||
language = StringUtils.requireNullOrNotEmpty(language, "language must be null or not empty");
|
||||
|
||||
for (Body currentBody : getExtensions(Body.class)) {
|
||||
if (StringUtils.nullSafeCharSequenceEquals(language, currentBody.getLanguage())) {
|
||||
throw new IllegalArgumentException("Bodyt with the language " + language + " already exists");
|
||||
}
|
||||
}
|
||||
|
||||
Body messageBody = new Body(language, body);
|
||||
addExtension(messageBody);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageBuilder getThis() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Message build() {
|
||||
return new Message(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Message.Type getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/**
|
||||
*
|
||||
* 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 interface MessageView extends StanzaView {
|
||||
|
||||
/**
|
||||
* Returns the type of the message. If no type has been set this method will return {@link
|
||||
* org.jivesoftware.smack.packet.Message.Type#normal}.
|
||||
*
|
||||
* @return the type of the message.
|
||||
*/
|
||||
Message.Type getType();
|
||||
|
||||
}
|
|
@ -19,7 +19,8 @@ package org.jivesoftware.smack.packet;
|
|||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.jivesoftware.smack.packet.id.StanzaIdUtil;
|
||||
import javax.net.SocketFactory;
|
||||
|
||||
import org.jivesoftware.smack.util.Objects;
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
import org.jivesoftware.smack.util.TypedCloneable;
|
||||
|
@ -60,7 +61,7 @@ import org.jxmpp.jid.Jid;
|
|||
*
|
||||
* @author Matt Tucker
|
||||
*/
|
||||
public final class Presence extends Stanza implements TypedCloneable<Presence> {
|
||||
public final class Presence extends Stanza implements PresenceView, TypedCloneable<Presence> {
|
||||
|
||||
public static final String ELEMENT = "presence";
|
||||
|
||||
|
@ -81,7 +82,10 @@ public final class Presence extends Stanza implements TypedCloneable<Presence> {
|
|||
* Creates a new presence update. Status, priority, and mode are left un-set.
|
||||
*
|
||||
* @param type the type.
|
||||
* @deprecated use {@link StanzaBuilder} or {@link SocketFactory} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove in Smack 4.5.
|
||||
public Presence(Type type) {
|
||||
// Ensure that the stanza ID is set by calling super().
|
||||
super();
|
||||
|
@ -94,7 +98,10 @@ public final class Presence extends Stanza implements TypedCloneable<Presence> {
|
|||
* @param to the recipient.
|
||||
* @param type the type.
|
||||
* @since 4.2
|
||||
* @deprecated use {@link StanzaBuilder} or {@link SocketFactory} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove in Smack 4.5.
|
||||
public Presence(Jid to, Type type) {
|
||||
this(type);
|
||||
setTo(to);
|
||||
|
@ -107,7 +114,10 @@ public final class Presence extends Stanza implements TypedCloneable<Presence> {
|
|||
* @param status a text message describing the presence update.
|
||||
* @param priority the priority of this presence update.
|
||||
* @param mode the mode type for this presence update.
|
||||
* @deprecated use {@link StanzaBuilder} or {@link SocketFactory} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove in Smack 4.5.
|
||||
public Presence(Type type, String status, int priority, Mode mode) {
|
||||
// Ensure that the stanza ID is set by calling super().
|
||||
super();
|
||||
|
@ -117,6 +127,14 @@ public final class Presence extends Stanza implements TypedCloneable<Presence> {
|
|||
setMode(mode);
|
||||
}
|
||||
|
||||
Presence(PresenceBuilder presenceBuilder) {
|
||||
super(presenceBuilder);
|
||||
type = presenceBuilder.type;
|
||||
status = presenceBuilder.status;
|
||||
priority = presenceBuilder.priority;
|
||||
mode = presenceBuilder.mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor.
|
||||
* <p>
|
||||
|
@ -163,11 +181,7 @@ public final class Presence extends Stanza implements TypedCloneable<Presence> {
|
|||
return type == Type.available && (mode == Mode.away || mode == Mode.xa || mode == Mode.dnd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of this presence packet.
|
||||
*
|
||||
* @return the type of the presence packet.
|
||||
*/
|
||||
@Override
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
@ -176,18 +190,15 @@ public final class Presence extends Stanza implements TypedCloneable<Presence> {
|
|||
* Sets the type of the presence packet.
|
||||
*
|
||||
* @param type the type of the presence packet.
|
||||
* @deprecated use {@link StanzaBuilder} or {@link SocketFactory} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove in Smack 4.5.
|
||||
public void setType(Type type) {
|
||||
this.type = Objects.requireNonNull(type, "Type cannot be null");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the status message of the presence update, or <code>null</code> if there
|
||||
* is not a status. The status is free-form text describing a user's presence
|
||||
* (i.e., "gone to lunch").
|
||||
*
|
||||
* @return the status message.
|
||||
*/
|
||||
@Override
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
@ -197,18 +208,21 @@ public final class Presence extends Stanza implements TypedCloneable<Presence> {
|
|||
* describing a user's presence (i.e., "gone to lunch").
|
||||
*
|
||||
* @param status the status message.
|
||||
* @deprecated use {@link StanzaBuilder} or {@link SocketFactory} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove in Smack 4.5.
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the priority of the presence.
|
||||
*
|
||||
* @return the priority.
|
||||
* @see <a href="https://tools.ietf.org/html/rfc6121#section-4.7.2.3">RFC 6121 § 4.7.2.3. Priority Element</a>
|
||||
*/
|
||||
@Override
|
||||
public int getPriority() {
|
||||
return getPriorityByte();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getPriorityByte() {
|
||||
if (priority == null) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -221,7 +235,10 @@ public final class Presence extends Stanza implements TypedCloneable<Presence> {
|
|||
* @param priority the priority of the presence.
|
||||
* @throws IllegalArgumentException if the priority is outside the valid range.
|
||||
* @see <a href="https://tools.ietf.org/html/rfc6121#section-4.7.2.3">RFC 6121 § 4.7.2.3. Priority Element</a>
|
||||
* @deprecated use {@link StanzaBuilder} or {@link SocketFactory} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove in Smack 4.5.
|
||||
public void setPriority(int priority) {
|
||||
if (priority < -128 || priority > 127) {
|
||||
throw new IllegalArgumentException("Priority value " + priority +
|
||||
|
@ -234,11 +251,7 @@ public final class Presence extends Stanza implements TypedCloneable<Presence> {
|
|||
this.priority = priority;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the mode of the presence update.
|
||||
*
|
||||
* @return the mode.
|
||||
*/
|
||||
@Override
|
||||
public Mode getMode() {
|
||||
if (mode == null) {
|
||||
return Mode.available;
|
||||
|
@ -251,7 +264,10 @@ public final class Presence extends Stanza implements TypedCloneable<Presence> {
|
|||
* to be the same thing as {@link Presence.Mode#available}.
|
||||
*
|
||||
* @param mode the mode.
|
||||
* @deprecated use {@link StanzaBuilder} or {@link SocketFactory} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove in Smack 4.5.
|
||||
public void setMode(Mode mode) {
|
||||
this.mode = mode;
|
||||
}
|
||||
|
@ -261,6 +277,10 @@ public final class Presence extends Stanza implements TypedCloneable<Presence> {
|
|||
return ELEMENT;
|
||||
}
|
||||
|
||||
public PresenceBuilder asBuilder() {
|
||||
return StanzaBuilder.buildPresenceFrom(this, getStanzaId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
@ -326,7 +346,7 @@ public final class Presence extends Stanza implements TypedCloneable<Presence> {
|
|||
*/
|
||||
public Presence cloneWithNewId() {
|
||||
Presence clone = clone();
|
||||
clone.setStanzaId(StanzaIdUtil.newStanzaId());
|
||||
clone.setNewStanzaId();
|
||||
return clone;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
/**
|
||||
*
|
||||
* 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.Presence.Mode;
|
||||
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 {
|
||||
static final PresenceBuilder EMPTY = new PresenceBuilder(() -> {
|
||||
return null;
|
||||
});
|
||||
|
||||
Presence.Type type = Presence.Type.available;
|
||||
|
||||
String status;
|
||||
|
||||
Byte priority;
|
||||
|
||||
Presence.Mode mode;
|
||||
|
||||
PresenceBuilder(Presence presence, String stanzaId) {
|
||||
super(presence, stanzaId);
|
||||
copyFromPresence(presence);
|
||||
}
|
||||
|
||||
PresenceBuilder(Presence presence, StanzaIdSource stanzaIdSource) {
|
||||
super(presence, stanzaIdSource);
|
||||
copyFromPresence(presence);
|
||||
}
|
||||
|
||||
PresenceBuilder(StanzaIdSource stanzaIdSource) {
|
||||
super(stanzaIdSource);
|
||||
}
|
||||
|
||||
PresenceBuilder(String stanzaId) {
|
||||
super(stanzaId);
|
||||
}
|
||||
|
||||
private void copyFromPresence(Presence presence) {
|
||||
type = presence.getType();
|
||||
status = presence.getStatus();
|
||||
priority = presence.getPriorityByte();
|
||||
mode = presence.getMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addStanzaSpecificAttributes(ToStringUtil.Builder builder) {
|
||||
builder.addValue("type", type)
|
||||
.addValue("mode", mode)
|
||||
.addValue("priority", priority)
|
||||
.addValue("status", status)
|
||||
;
|
||||
}
|
||||
|
||||
public PresenceBuilder ofType(Presence.Type type) {
|
||||
this.type = Objects.requireNonNull(type, "Type cannot be null");
|
||||
return getThis();
|
||||
}
|
||||
|
||||
public PresenceBuilder setStatus(String status) {
|
||||
this.status = status;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
public PresenceBuilder setPriority(int priority) {
|
||||
if (priority < -128 || priority > 127) {
|
||||
throw new IllegalArgumentException("Priority value " + priority +
|
||||
" is not valid. Valid range is -128 through 127.");
|
||||
}
|
||||
Byte priorityByte = (byte) priority;
|
||||
return setPriority(priorityByte);
|
||||
}
|
||||
|
||||
public PresenceBuilder setPriority(Byte priority) {
|
||||
this.priority = priority;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
public PresenceBuilder setMode(Presence.Mode mode) {
|
||||
this.mode = mode;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PresenceBuilder getThis() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Presence build() {
|
||||
return new Presence(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Presence.Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPriority() {
|
||||
return getPriorityByte();
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte getPriorityByte() {
|
||||
if (priority == null) {
|
||||
return 0;
|
||||
}
|
||||
return priority;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Presence.Mode getMode() {
|
||||
if (mode == null) {
|
||||
return Mode.available;
|
||||
}
|
||||
return mode;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/**
|
||||
*
|
||||
* 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 interface PresenceView extends StanzaView {
|
||||
|
||||
/**
|
||||
* Returns the type of this presence stanza.
|
||||
*
|
||||
* @return the type of the presence stanza.
|
||||
*/
|
||||
Presence.Type getType();
|
||||
|
||||
/**
|
||||
* Returns the status message of the presence update, or <code>null</code> if there
|
||||
* is not a status. The status is free-form text describing a user's presence
|
||||
* (i.e., "gone to lunch").
|
||||
*
|
||||
* @return the status message.
|
||||
*/
|
||||
String getStatus();
|
||||
|
||||
/**
|
||||
* Returns the priority of the presence.
|
||||
*
|
||||
* @return the priority.
|
||||
* @see <a href="https://tools.ietf.org/html/rfc6121#section-4.7.2.3">RFC 6121 § 4.7.2.3. Priority Element</a>
|
||||
*/
|
||||
int getPriority();
|
||||
|
||||
/**
|
||||
* Returns the priority of the presence.
|
||||
*
|
||||
* @return the priority.
|
||||
* @see <a href="https://tools.ietf.org/html/rfc6121#section-4.7.2.3">RFC 6121 § 4.7.2.3. Priority Element</a>
|
||||
*/
|
||||
byte getPriorityByte();
|
||||
|
||||
/**
|
||||
* Returns the mode of the presence update.
|
||||
*
|
||||
* @return the mode.
|
||||
*/
|
||||
Presence.Mode getMode();
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright © 2014 Florian Schmaus
|
||||
* Copyright © 2014-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.
|
||||
|
@ -29,6 +29,10 @@ public abstract class SimpleIQ extends IQ {
|
|||
super(childElementName, childElementNamespace);
|
||||
}
|
||||
|
||||
protected SimpleIQ(IqBuilder iqBuilder, String childElementName, String childElementNamespace) {
|
||||
super(iqBuilder, childElementName, childElementNamespace);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) {
|
||||
xml.setEmptyElement();
|
||||
|
|
|
@ -20,15 +20,19 @@ package org.jivesoftware.smack.packet;
|
|||
import static org.jivesoftware.smack.util.StringUtils.requireNotNullNorEmpty;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import org.jivesoftware.smack.packet.id.StanzaIdUtil;
|
||||
import org.jivesoftware.smack.packet.id.StandardStanzaIdSource;
|
||||
import org.jivesoftware.smack.packet.id.StanzaIdSource;
|
||||
import org.jivesoftware.smack.util.MultiMap;
|
||||
import org.jivesoftware.smack.util.PacketUtil;
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
import org.jivesoftware.smack.util.XmlStringBuilder;
|
||||
import org.jivesoftware.smack.util.XmppElementUtil;
|
||||
|
||||
import org.jxmpp.jid.Jid;
|
||||
|
||||
|
@ -43,12 +47,16 @@ import org.jxmpp.jid.Jid;
|
|||
* XMPP Stanzas are {@link Message}, {@link IQ} and {@link Presence}. Which therefore subclass this
|
||||
* class. <b>If you think you need to subclass this class, then you are doing something wrong.</b>
|
||||
* </p>
|
||||
* <p>
|
||||
* Use {@link StanzaBuilder} to construct a stanza instance. All instance mutating methods of this
|
||||
* class are deprecated, although not all of them are currently marked as such, and must not be used.
|
||||
* </p>
|
||||
*
|
||||
* @author Matt Tucker
|
||||
* @author Florian Schmaus
|
||||
* @see <a href="http://xmpp.org/rfcs/rfc6120.html#stanzas">RFC 6120 § 8. XML Stanzas</a>
|
||||
*/
|
||||
public abstract class Stanza implements TopLevelStreamElement {
|
||||
public abstract class Stanza implements StanzaView, TopLevelStreamElement {
|
||||
|
||||
public static final String TEXT = "text";
|
||||
public static final String ITEM = "item";
|
||||
|
@ -56,12 +64,14 @@ public abstract class Stanza implements TopLevelStreamElement {
|
|||
protected static final String DEFAULT_LANGUAGE =
|
||||
java.util.Locale.getDefault().getLanguage().toLowerCase(Locale.US);
|
||||
|
||||
private final MultiMap<QName, ExtensionElement> extensionElements = new MultiMap<>();
|
||||
private final MultiMap<QName, ExtensionElement> extensionElements;
|
||||
|
||||
// Assume that all stanzas Smack handles are in the client namespace, since Smack is an XMPP client library. We can
|
||||
// change this behavior later if it is required.
|
||||
private final String namespace = StreamOpen.CLIENT_NAMESPACE;
|
||||
|
||||
private final StanzaIdSource usedStanzaIdSource;
|
||||
|
||||
private String id = null;
|
||||
private Jid to;
|
||||
private Jid from;
|
||||
|
@ -80,30 +90,46 @@ public abstract class Stanza implements TopLevelStreamElement {
|
|||
protected String language;
|
||||
|
||||
protected Stanza() {
|
||||
this(StanzaIdUtil.newStanzaId());
|
||||
extensionElements = new MultiMap<>();
|
||||
usedStanzaIdSource = null;
|
||||
id = StandardStanzaIdSource.DEFAULT.getNewStanzaId();
|
||||
}
|
||||
|
||||
protected Stanza(String stanzaId) {
|
||||
setStanzaId(stanzaId);
|
||||
protected Stanza(StanzaBuilder<?> stanzaBuilder) {
|
||||
if (stanzaBuilder.stanzaIdSource != null) {
|
||||
id = stanzaBuilder.stanzaIdSource.getNewStanzaId();
|
||||
// Note that some stanza ID sources, e.g. StanzaBuilder.PresenceBuilder.EMPTY return null here. Hence we
|
||||
// only check that the returned string is not empty.
|
||||
assert StringUtils.isNullOrNotEmpty(id);
|
||||
usedStanzaIdSource = stanzaBuilder.stanzaIdSource;
|
||||
} else {
|
||||
// N.B. It is ok if stanzaId here is null.
|
||||
id = stanzaBuilder.stanzaId;
|
||||
usedStanzaIdSource = null;
|
||||
}
|
||||
|
||||
to = stanzaBuilder.to;
|
||||
from = stanzaBuilder.from;
|
||||
|
||||
error = stanzaBuilder.stanzaError;
|
||||
|
||||
language = stanzaBuilder.language;
|
||||
|
||||
extensionElements = stanzaBuilder.extensionElements.clone();
|
||||
}
|
||||
|
||||
protected Stanza(Stanza p) {
|
||||
usedStanzaIdSource = p.usedStanzaIdSource;
|
||||
|
||||
id = p.getStanzaId();
|
||||
to = p.getTo();
|
||||
from = p.getFrom();
|
||||
error = p.error;
|
||||
|
||||
// Copy extensions
|
||||
for (ExtensionElement pe : p.getExtensions()) {
|
||||
addExtension(pe);
|
||||
}
|
||||
extensionElements = p.extensionElements.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the unique ID of the stanza. The returned value could be <code>null</code>.
|
||||
*
|
||||
* @return the packet's unique ID or <code>null</code> if the id is not available.
|
||||
*/
|
||||
@Override
|
||||
public String getStanzaId() {
|
||||
return id;
|
||||
}
|
||||
|
@ -138,56 +164,50 @@ public abstract class Stanza implements TopLevelStreamElement {
|
|||
*
|
||||
* @return the stanza id.
|
||||
* @since 4.2
|
||||
* @deprecated use {@link #setNewStanzaId()} instead.
|
||||
* @deprecated use {@link StanzaBuilder} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove in Smack 4.5.
|
||||
public String setStanzaId() {
|
||||
return ensureStanzaIdSet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a new stanza ID even if there is already one set.
|
||||
*
|
||||
* @return the stanza id.
|
||||
* @since 4.4
|
||||
*/
|
||||
public String setNewStanzaId() {
|
||||
return ensureStanzaIdSet(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure a stanza id is set.
|
||||
*
|
||||
* @return the stanza id.
|
||||
* @since 4.4
|
||||
*/
|
||||
public String ensureStanzaIdSet() {
|
||||
return ensureStanzaIdSet(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that a stanza ID is set.
|
||||
*
|
||||
* @param forceNew force a new ID even if there is already one set.
|
||||
* @return the stanza ID.
|
||||
* @since 4.4
|
||||
*/
|
||||
private String ensureStanzaIdSet(boolean forceNew) {
|
||||
if (forceNew || !hasStanzaIdSet()) {
|
||||
setStanzaId(StanzaIdUtil.newStanzaId());
|
||||
if (!hasStanzaIdSet()) {
|
||||
setNewStanzaId();
|
||||
}
|
||||
return getStanzaId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns who the stanza is being sent "to", or <code>null</code> if
|
||||
* the value is not set. The XMPP protocol often makes the "to"
|
||||
* attribute optional, so it does not always need to be set.<p>
|
||||
* Throws an {@link IllegalArgumentException} if this stanza has no stanza ID set.
|
||||
*
|
||||
* @return who the stanza is being sent to, or <code>null</code> if the
|
||||
* value has not been set.
|
||||
* @throws IllegalArgumentException if this stanza has no stanza ID set.
|
||||
* @since 4.4.
|
||||
*/
|
||||
public final void throwIfNoStanzaId() {
|
||||
if (hasStanzaIdSet()) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("The stanza has no RFC stanza ID set, although one is required");
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that a stanza ID is set.
|
||||
*
|
||||
* @return the stanza ID.
|
||||
* @since 4.4
|
||||
*/
|
||||
// TODO: Remove this method once StanzaBuilder is ready.
|
||||
protected String setNewStanzaId() {
|
||||
if (usedStanzaIdSource != null) {
|
||||
id = usedStanzaIdSource.getNewStanzaId();
|
||||
}
|
||||
else {
|
||||
id = StandardStanzaIdSource.DEFAULT.getNewStanzaId();
|
||||
}
|
||||
|
||||
return getStanzaId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Jid getTo() {
|
||||
return to;
|
||||
}
|
||||
|
@ -198,18 +218,12 @@ public abstract class Stanza implements TopLevelStreamElement {
|
|||
*
|
||||
* @param to who the packet is being sent to.
|
||||
*/
|
||||
// TODO: Mark this as deprecated once StanzaBuilder is ready and all call sites are gone.
|
||||
public void setTo(Jid to) {
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns who the stanza is being sent "from" or <code>null</code> if
|
||||
* the value is not set. The XMPP protocol often makes the "from"
|
||||
* attribute optional, so it does not always need to be set.<p>
|
||||
*
|
||||
* @return who the stanza is being sent from, or <code>null</code> if the
|
||||
* value has not been set.
|
||||
*/
|
||||
@Override
|
||||
public Jid getFrom() {
|
||||
return from;
|
||||
}
|
||||
|
@ -221,16 +235,12 @@ public abstract class Stanza implements TopLevelStreamElement {
|
|||
*
|
||||
* @param from who the packet is being sent to.
|
||||
*/
|
||||
// TODO: Mark this as deprecated once StanzaBuilder is ready and all call sites are gone.
|
||||
public void setFrom(Jid from) {
|
||||
this.from = from;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the error associated with this packet, or <code>null</code> if there are
|
||||
* no errors.
|
||||
*
|
||||
* @return the error sub-packet or <code>null</code> if there isn't an error.
|
||||
*/
|
||||
@Override
|
||||
public StanzaError getError() {
|
||||
return error;
|
||||
}
|
||||
|
@ -238,14 +248,22 @@ public abstract class Stanza implements TopLevelStreamElement {
|
|||
/**
|
||||
* Sets the error for this stanza.
|
||||
*
|
||||
* @param xmppErrorBuilder the error to associate with this stanza.
|
||||
* @param stanzaError the error that this stanza carries and hence signals.
|
||||
*/
|
||||
public void setError(StanzaError.Builder xmppErrorBuilder) {
|
||||
if (xmppErrorBuilder == null) {
|
||||
return;
|
||||
}
|
||||
xmppErrorBuilder.setStanza(this);
|
||||
error = xmppErrorBuilder.build();
|
||||
// TODO: Mark this as deprecated once StanzaBuilder is ready and all call sites are gone.
|
||||
public void setError(StanzaError stanzaError) {
|
||||
error = stanzaError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated.
|
||||
* @param stanzaError the stanza error.
|
||||
* @deprecated use {@link StanzaBuilder} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove in Smack 4.5.
|
||||
public void setError(StanzaError.Builder stanzaError) {
|
||||
setError(stanzaError.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -257,16 +275,15 @@ public abstract class Stanza implements TopLevelStreamElement {
|
|||
* Sets the xml:lang of this Stanza.
|
||||
*
|
||||
* @param language the xml:lang of this Stanza.
|
||||
* @deprecated use {@link StanzaBuilder#setLanguage(String)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove in Smack 4.5.
|
||||
public void setLanguage(String language) {
|
||||
this.language = language;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all extension elements of this stanza.
|
||||
*
|
||||
* @return a list of all extension elements of this stanza.
|
||||
*/
|
||||
@Override
|
||||
public List<ExtensionElement> getExtensions() {
|
||||
synchronized (extensionElements) {
|
||||
// No need to create a new list, values() will already create a new one for us
|
||||
|
@ -274,6 +291,16 @@ public abstract class Stanza implements TopLevelStreamElement {
|
|||
}
|
||||
}
|
||||
|
||||
public final MultiMap<QName, ExtensionElement> getExtensionsMap() {
|
||||
return cloneExtensionsMap();
|
||||
}
|
||||
|
||||
final MultiMap<QName, ExtensionElement> cloneExtensionsMap() {
|
||||
synchronized (extensionElements) {
|
||||
return extensionElements.clone();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of all extensions with the given element name <em>and</em> namespace.
|
||||
* <p>
|
||||
|
@ -289,7 +316,23 @@ public abstract class Stanza implements TopLevelStreamElement {
|
|||
requireNotNullNorEmpty(elementName, "elementName must not be null nor empty");
|
||||
requireNotNullNorEmpty(namespace, "namespace must not be null nor empty");
|
||||
QName key = new QName(namespace, elementName);
|
||||
return extensionElements.getAll(key);
|
||||
return getExtensions(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ExtensionElement> getExtensions(QName qname) {
|
||||
List<ExtensionElement> res;
|
||||
synchronized (extensionElements) {
|
||||
res = extensionElements.getAll(qname);
|
||||
}
|
||||
return Collections.unmodifiableList(res);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <E extends ExtensionElement> List<E> getExtensions(Class<E> extensionElementClass) {
|
||||
synchronized (extensionElements) {
|
||||
return XmppElementUtil.getElementsFrom(extensionElements, extensionElementClass);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -322,21 +365,31 @@ public abstract class Stanza implements TopLevelStreamElement {
|
|||
return null;
|
||||
}
|
||||
QName key = new QName(namespace, elementName);
|
||||
ExtensionElement packetExtension;
|
||||
synchronized (extensionElements) {
|
||||
packetExtension = extensionElements.getFirst(key);
|
||||
}
|
||||
ExtensionElement packetExtension = getExtension(key);
|
||||
if (packetExtension == null) {
|
||||
return null;
|
||||
}
|
||||
return (PE) packetExtension;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public final <E extends ExtensionElement> E getExtension(QName qname) {
|
||||
synchronized (extensionElements) {
|
||||
return (E) extensionElements.getFirst(qname);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a stanza extension to the packet. Does nothing if extension is null.
|
||||
* <p>
|
||||
* Please note that although this method is not yet marked as deprecated, it is recommended to use
|
||||
* {@link StanzaBuilder#addExtension(ExtensionElement)} instead.
|
||||
* </p>
|
||||
*
|
||||
* @param extension a stanza extension.
|
||||
*/
|
||||
// TODO: Mark this as deprecated once StanzaBuilder is ready and all call sites are gone.
|
||||
public void addExtension(ExtensionElement extension) {
|
||||
if (extension == null) return;
|
||||
QName key = extension.getQName();
|
||||
|
@ -348,11 +401,16 @@ public abstract class Stanza implements TopLevelStreamElement {
|
|||
/**
|
||||
* Add the given extension and override eventually existing extensions with the same name and
|
||||
* namespace.
|
||||
* <p>
|
||||
* Please note that although this method is not yet marked as deprecated, it is recommended to use
|
||||
* {@link StanzaBuilder#overrideExtension(ExtensionElement)} instead.
|
||||
* </p>
|
||||
*
|
||||
* @param extension the extension element to add.
|
||||
* @return one of the removed extensions or <code>null</code> if there are none.
|
||||
* @since 4.1.2
|
||||
*/
|
||||
// TODO: Mark this as deprecated once StanzaBuilder is ready and all call sites are gone.
|
||||
public ExtensionElement overrideExtension(ExtensionElement extension) {
|
||||
if (extension == null) return null;
|
||||
synchronized (extensionElements) {
|
||||
|
@ -370,6 +428,7 @@ public abstract class Stanza implements TopLevelStreamElement {
|
|||
*
|
||||
* @param extensions a collection of stanza extensions
|
||||
*/
|
||||
// TODO: Mark this as deprecated once StanzaBuilder is ready and all call sites are gone.
|
||||
public void addExtensions(Collection<ExtensionElement> extensions) {
|
||||
if (extensions == null) return;
|
||||
for (ExtensionElement packetExtension : extensions) {
|
||||
|
@ -421,6 +480,7 @@ public abstract class Stanza implements TopLevelStreamElement {
|
|||
* @param namespace TODO javadoc me please
|
||||
* @return the removed stanza extension or null.
|
||||
*/
|
||||
// TODO: Mark this as deprecated once StanzaBuilder is ready and all call sites are gone.
|
||||
public ExtensionElement removeExtension(String elementName, String namespace) {
|
||||
QName key = new QName(namespace, elementName);
|
||||
synchronized (extensionElements) {
|
||||
|
@ -433,7 +493,10 @@ public abstract class Stanza implements TopLevelStreamElement {
|
|||
*
|
||||
* @param extension the stanza extension to remove.
|
||||
* @return the removed stanza extension or null.
|
||||
* @deprecated use {@link StanzaBuilder} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove in Smack 4.5.
|
||||
public ExtensionElement removeExtension(ExtensionElement extension) {
|
||||
QName key = extension.getQName();
|
||||
synchronized (extensionElements) {
|
||||
|
|
|
@ -0,0 +1,301 @@
|
|||
/**
|
||||
*
|
||||
* 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 java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ.Type;
|
||||
import org.jivesoftware.smack.packet.id.StanzaIdSource;
|
||||
import org.jivesoftware.smack.util.MultiMap;
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
import org.jivesoftware.smack.util.ToStringUtil;
|
||||
import org.jivesoftware.smack.util.XmppElementUtil;
|
||||
|
||||
import org.jxmpp.jid.Jid;
|
||||
import org.jxmpp.jid.impl.JidCreate;
|
||||
import org.jxmpp.stringprep.XmppStringprepException;
|
||||
|
||||
public abstract class StanzaBuilder<B extends StanzaBuilder<B>> implements StanzaView {
|
||||
|
||||
final StanzaIdSource stanzaIdSource;
|
||||
final String stanzaId;
|
||||
|
||||
Jid to;
|
||||
Jid from;
|
||||
|
||||
StanzaError stanzaError;
|
||||
|
||||
String language;
|
||||
|
||||
MultiMap<QName, ExtensionElement> extensionElements = new MultiMap<>();
|
||||
|
||||
protected StanzaBuilder(StanzaIdSource stanzaIdSource) {
|
||||
this.stanzaIdSource = stanzaIdSource;
|
||||
this.stanzaId = null;
|
||||
}
|
||||
|
||||
protected StanzaBuilder(String stanzaId) {
|
||||
this.stanzaIdSource = null;
|
||||
this.stanzaId = StringUtils.requireNullOrNotEmpty(stanzaId, "Stanza ID must not be the empty String");
|
||||
}
|
||||
|
||||
protected StanzaBuilder(Stanza message, String stanzaId) {
|
||||
this(stanzaId);
|
||||
copyFromStanza(message);
|
||||
}
|
||||
|
||||
protected StanzaBuilder(Stanza message, StanzaIdSource stanzaIdSource) {
|
||||
this(stanzaIdSource);
|
||||
copyFromStanza(message);
|
||||
}
|
||||
|
||||
private void copyFromStanza(Stanza stanza) {
|
||||
to = stanza.getTo();
|
||||
from = stanza.getFrom();
|
||||
stanzaError = stanza.getError();
|
||||
language = stanza.getLanguage();
|
||||
|
||||
extensionElements = stanza.cloneExtensionsMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the recipent address of the stanza.
|
||||
*
|
||||
* @param to whoe the stanza is being sent to.
|
||||
* @return a reference to this builder.
|
||||
* @throws XmppStringprepException if the provided character sequence is not a valid XMPP address.
|
||||
* @see #to(Jid)
|
||||
*/
|
||||
public final B to(CharSequence to) throws XmppStringprepException {
|
||||
return to(JidCreate.from(to));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets who the stanza is being sent "to". The XMPP protocol often makes the "to" attribute optional, so it does not
|
||||
* always need to be set.
|
||||
*
|
||||
* @param to who the stanza is being sent to.
|
||||
* @return a reference to this builder.
|
||||
*/
|
||||
public final B to(Jid to) {
|
||||
this.to = to;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets who the the stanza is being sent "from".
|
||||
*
|
||||
* @param from who the stanza is being sent from.
|
||||
* @return a reference to this builder.
|
||||
* @throws XmppStringprepException if the provided character sequence is not a valid XMPP address.
|
||||
* @see #from(Jid)
|
||||
*/
|
||||
public final B from(CharSequence from) throws XmppStringprepException {
|
||||
return from(JidCreate.from(from));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets who the stanza is being sent "from". The XMPP protocol often makes the "from" attribute optional, so it does
|
||||
* not always need to be set.
|
||||
*
|
||||
* @param from who the stanza is being sent from.
|
||||
* @return a reference to this builder.
|
||||
*/
|
||||
public final B from(Jid from) {
|
||||
this.from = from;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the error for this stanza.
|
||||
*
|
||||
* @param stanzaError the error to associate with this stanza.
|
||||
* @return a reference to this builder.
|
||||
*/
|
||||
public final B setError(StanzaError stanzaError) {
|
||||
this.stanzaError = stanzaError;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the xml:lang for this stanza.
|
||||
*
|
||||
* @param language the xml:lang of this stanza.
|
||||
* @return a reference to this builder.
|
||||
*/
|
||||
public final B setLanguage(String language) {
|
||||
this.language = language;
|
||||
return getThis();
|
||||
}
|
||||
|
||||
public final B addExtension(ExtensionElement extensionElement) {
|
||||
QName key = extensionElement.getQName();
|
||||
extensionElements.put(key, extensionElement);
|
||||
return getThis();
|
||||
}
|
||||
|
||||
public final B addExtensions(Collection<? extends ExtensionElement> extensionElements) {
|
||||
for (ExtensionElement extensionElement : extensionElements) {
|
||||
addExtension(extensionElement);
|
||||
}
|
||||
return getThis();
|
||||
}
|
||||
|
||||
public final B overrideExtension(ExtensionElement extensionElement) {
|
||||
QName key = extensionElement.getQName();
|
||||
extensionElements.remove(key);
|
||||
extensionElements.put(key, extensionElement);
|
||||
return getThis();
|
||||
}
|
||||
|
||||
public abstract B getThis();
|
||||
|
||||
@Override
|
||||
public final String getStanzaId() {
|
||||
return stanzaId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Jid getTo() {
|
||||
return to;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Jid getFrom() {
|
||||
return from;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getLanguage() {
|
||||
return language;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final StanzaError getError() {
|
||||
return stanzaError;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public final <E extends ExtensionElement> E getExtension(QName qname) {
|
||||
return (E) extensionElements.getFirst(qname);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<ExtensionElement> getExtensions() {
|
||||
return extensionElements.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<ExtensionElement> getExtensions(QName qname) {
|
||||
return extensionElements.getAll(qname);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <E extends ExtensionElement> List<E> getExtensions(Class<E> extensionElementClass) {
|
||||
return XmppElementUtil.getElementsFrom(extensionElements, extensionElementClass);
|
||||
}
|
||||
|
||||
public final boolean willBuildStanzaWithId() {
|
||||
return stanzaIdSource != null || StringUtils.isNotEmpty(stanzaId);
|
||||
}
|
||||
|
||||
public final void throwIfNoStanzaId() {
|
||||
if (willBuildStanzaWithId()) {
|
||||
return;
|
||||
}
|
||||
throw new IllegalArgumentException(
|
||||
"The builder will not build a stanza with an ID set, although it is required");
|
||||
}
|
||||
|
||||
protected abstract void addStanzaSpecificAttributes(ToStringUtil.Builder builder);
|
||||
|
||||
@Override
|
||||
public final String toString() {
|
||||
ToStringUtil.Builder builder = ToStringUtil.builderFor(getClass())
|
||||
.addValue("id", stanzaId)
|
||||
.addValue("from", from)
|
||||
.addValue("to", to)
|
||||
.addValue("language", language)
|
||||
.addValue("error", stanzaError)
|
||||
;
|
||||
|
||||
addStanzaSpecificAttributes(builder);
|
||||
|
||||
builder.add("Extension Elements", extensionElements.values(), e -> {
|
||||
return e.getQName();
|
||||
});
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public static MessageBuilder buildMessage() {
|
||||
return buildMessage(null);
|
||||
}
|
||||
|
||||
public static MessageBuilder buildMessage(String stanzaId) {
|
||||
return new MessageBuilder(stanzaId);
|
||||
}
|
||||
|
||||
public static MessageBuilder buildMessageFrom(Message message, String stanzaId) {
|
||||
return new MessageBuilder(message, stanzaId);
|
||||
}
|
||||
|
||||
public static MessageBuilder buildMessageFrom(Message message, StanzaIdSource stanzaIdSource) {
|
||||
return new MessageBuilder(message, stanzaIdSource);
|
||||
}
|
||||
|
||||
public static PresenceBuilder buildPresence() {
|
||||
return buildPresence(null);
|
||||
}
|
||||
|
||||
public static PresenceBuilder buildPresence(String stanzaId) {
|
||||
return new PresenceBuilder(stanzaId);
|
||||
}
|
||||
|
||||
public static PresenceBuilder buildPresenceFrom(Presence presence, String stanzaId) {
|
||||
return new PresenceBuilder(presence, stanzaId);
|
||||
}
|
||||
|
||||
public static PresenceBuilder buildPresenceFrom(Presence presence, StanzaIdSource stanzaIdSource) {
|
||||
return new PresenceBuilder(presence, stanzaIdSource);
|
||||
}
|
||||
|
||||
public static IqBuilder buildIq(String stanzaId) {
|
||||
return new IqBuilder(stanzaId);
|
||||
}
|
||||
|
||||
public static IqBuilder buildIqResultFor(IQ request) {
|
||||
if (!(request.getType() == Type.get || request.getType() == Type.set)) {
|
||||
throw new IllegalArgumentException(
|
||||
"IQ request must be of type 'set' or 'get'. Original IQ: " + request.toXML());
|
||||
}
|
||||
|
||||
return buildIq(request.getStanzaId())
|
||||
.to(request.getFrom())
|
||||
.from(request.getTo())
|
||||
.ofType(IQ.Type.result);
|
||||
}
|
||||
|
||||
public static EmptyResultIQ buildEmptyIqResultFor(IQ request) {
|
||||
IqBuilder iqBuilder = buildIqResultFor(request);
|
||||
return new EmptyResultIQ(iqBuilder);
|
||||
}
|
||||
}
|
|
@ -106,7 +106,6 @@ public class StanzaError extends AbstractError implements ExtensionElement {
|
|||
private final String conditionText;
|
||||
private final String errorGenerator;
|
||||
private final Type type;
|
||||
private final Stanza stanza;
|
||||
|
||||
/**
|
||||
* Creates a new error with the specified type, condition and message.
|
||||
|
@ -120,13 +119,11 @@ public class StanzaError extends AbstractError implements ExtensionElement {
|
|||
* @param errorGenerator TODO javadoc me please
|
||||
* @param descriptiveTexts TODO javadoc me please
|
||||
* @param extensions list of stanza extensions
|
||||
* @param stanza the stanza carrying this XMPP error.
|
||||
*/
|
||||
public StanzaError(Condition condition, String conditionText, String errorGenerator, Type type, Map<String, String> descriptiveTexts,
|
||||
List<ExtensionElement> extensions, Stanza stanza) {
|
||||
List<ExtensionElement> extensions) {
|
||||
super(descriptiveTexts, ERROR_CONDITION_AND_TEXT_NAMESPACE, extensions);
|
||||
this.condition = Objects.requireNonNull(condition, "condition must not be null");
|
||||
this.stanza = stanza;
|
||||
// Some implementations may send the condition as non-empty element containing the empty string, that is
|
||||
// <condition xmlns='foo'></condition>, in this case the parser may calls this constructor with the empty string
|
||||
// as conditionText, therefore reset it to null if it's the empty string
|
||||
|
@ -184,16 +181,6 @@ public class StanzaError extends AbstractError implements ExtensionElement {
|
|||
return conditionText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the stanza carrying the XMPP error.
|
||||
*
|
||||
* @return the stanza carrying the XMPP error.
|
||||
* @since 4.2
|
||||
*/
|
||||
public Stanza getStanza() {
|
||||
return stanza;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder("XMPPError: ");
|
||||
|
@ -271,7 +258,6 @@ public class StanzaError extends AbstractError implements ExtensionElement {
|
|||
private String conditionText;
|
||||
private String errorGenerator;
|
||||
private Type type;
|
||||
private Stanza stanza;
|
||||
|
||||
private Builder() {
|
||||
}
|
||||
|
@ -296,17 +282,11 @@ public class StanzaError extends AbstractError implements ExtensionElement {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder setStanza(Stanza stanza) {
|
||||
this.stanza = stanza;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder copyFrom(StanzaError xmppError) {
|
||||
setCondition(xmppError.getCondition());
|
||||
setType(xmppError.getType());
|
||||
setConditionText(xmppError.getConditionText());
|
||||
setErrorGenerator(xmppError.getErrorGenerator());
|
||||
setStanza(xmppError.getStanza());
|
||||
setDescriptiveTexts(xmppError.descriptiveTexts);
|
||||
setTextNamespace(xmppError.textNamespace);
|
||||
setExtensions(xmppError.extensions);
|
||||
|
@ -315,7 +295,7 @@ public class StanzaError extends AbstractError implements ExtensionElement {
|
|||
|
||||
public StanzaError build() {
|
||||
return new StanzaError(condition, conditionText, errorGenerator, type, descriptiveTexts,
|
||||
extensions, stanza);
|
||||
extensions);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
*
|
||||
* 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 final class StanzaFactory {
|
||||
|
||||
private final StanzaIdSource stanzaIdSource;
|
||||
|
||||
public StanzaFactory(StanzaIdSource stanzaIdSource) {
|
||||
this.stanzaIdSource = stanzaIdSource;
|
||||
}
|
||||
|
||||
public MessageBuilder buildMessageStanza() {
|
||||
return new MessageBuilder(stanzaIdSource);
|
||||
}
|
||||
|
||||
public MessageBuilder buildMessageStanzaFrom(Message message) {
|
||||
return new MessageBuilder(message, stanzaIdSource);
|
||||
}
|
||||
|
||||
public PresenceBuilder buildPresenceStanza() {
|
||||
return new PresenceBuilder(stanzaIdSource);
|
||||
}
|
||||
|
||||
public PresenceBuilder buildPresenceStanzaFrom(Presence presence) {
|
||||
return new PresenceBuilder(presence, stanzaIdSource);
|
||||
}
|
||||
|
||||
public IqBuilder buildIqStanza() {
|
||||
return new IqBuilder(stanzaIdSource);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
/**
|
||||
*
|
||||
* 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 java.util.List;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import org.jivesoftware.smack.util.XmppElementUtil;
|
||||
|
||||
import org.jxmpp.jid.Jid;
|
||||
|
||||
public interface StanzaView extends XmlLangElement {
|
||||
|
||||
/**
|
||||
* Returns the unique ID of the stanza. The returned value could be <code>null</code>.
|
||||
*
|
||||
* @return the packet's unique ID or <code>null</code> if the id is not available.
|
||||
*/
|
||||
String getStanzaId();
|
||||
|
||||
/**
|
||||
* Returns who the stanza is being sent "to", or <code>null</code> if
|
||||
* the value is not set. The XMPP protocol often makes the "to"
|
||||
* attribute optional, so it does not always need to be set.<p>
|
||||
*
|
||||
* @return who the stanza is being sent to, or <code>null</code> if the
|
||||
* value has not been set.
|
||||
*/
|
||||
Jid getTo();
|
||||
|
||||
/**
|
||||
* Returns who the stanza is being sent "from" or <code>null</code> if
|
||||
* the value is not set. The XMPP protocol often makes the "from"
|
||||
* attribute optional, so it does not always need to be set.<p>
|
||||
*
|
||||
* @return who the stanza is being sent from, or <code>null</code> if the
|
||||
* value has not been set.
|
||||
*/
|
||||
Jid getFrom();
|
||||
|
||||
/**
|
||||
* Returns the error associated with this packet, or <code>null</code> if there are
|
||||
* no errors.
|
||||
*
|
||||
* @return the error sub-packet or <code>null</code> if there isn't an error.
|
||||
*/
|
||||
StanzaError getError();
|
||||
|
||||
<E extends ExtensionElement> E getExtension(QName qname);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
default <E extends ExtensionElement> E getExtension(Class<E> extensionElementClass) {
|
||||
QName qname = XmppElementUtil.getQNameFor(extensionElementClass);
|
||||
return (E) getExtension(qname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all extension elements of this stanza.
|
||||
*
|
||||
* @return a list of all extension elements of this stanza.
|
||||
*/
|
||||
List<ExtensionElement> getExtensions();
|
||||
|
||||
List<ExtensionElement> getExtensions(QName qname);
|
||||
|
||||
<E extends ExtensionElement> List<E> getExtensions(Class<E> extensionElementClass);
|
||||
}
|
|
@ -18,7 +18,6 @@ package org.jivesoftware.smack.packet;
|
|||
|
||||
import org.jivesoftware.smack.util.ParserUtils;
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
|
||||
import org.jivesoftware.smack.xml.XmlPullParser;
|
||||
|
||||
public class XmlEnvironment {
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
/**
|
||||
*
|
||||
* 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 interface XmlLangElement {
|
||||
|
||||
/**
|
||||
* Returns the xml:lang of this XML element, or null if one has not been set.
|
||||
*
|
||||
* @return the xml:lang of this XML element, or null.
|
||||
*/
|
||||
String getLanguage();
|
||||
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/**
|
||||
*
|
||||
* 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.id;
|
||||
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
|
||||
public final class RandomStringStanzaIdSource {
|
||||
|
||||
public static class Factory implements StanzaIdSourceFactory {
|
||||
|
||||
private static final int REQUIRED_MIN_LENGTH = 10;
|
||||
|
||||
private final int length;
|
||||
private final boolean verySecure;
|
||||
|
||||
public static final Factory VERY_SECURE = new Factory(10, true);
|
||||
public static final Factory MEDIUM_SECURE = new Factory(10, false);
|
||||
|
||||
public Factory(int length, boolean verySecure) {
|
||||
if (length < REQUIRED_MIN_LENGTH) {
|
||||
throw new IllegalArgumentException(
|
||||
"Insufficient length " + length + ", must be at least " + REQUIRED_MIN_LENGTH);
|
||||
}
|
||||
this.length = length;
|
||||
this.verySecure = verySecure;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StanzaIdSource constructStanzaIdSource() {
|
||||
StanzaIdSource stanzaIdSource;
|
||||
if (verySecure) {
|
||||
stanzaIdSource = () -> StringUtils.randomString(length);
|
||||
} else {
|
||||
stanzaIdSource = () -> StringUtils.insecureRandomString(length);
|
||||
}
|
||||
return stanzaIdSource;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2003-2007 Jive Software, 2015 Florian Schmaus
|
||||
* 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.
|
||||
|
@ -20,20 +20,32 @@ import java.util.concurrent.atomic.AtomicLong;
|
|||
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
|
||||
public class StanzaIdUtil {
|
||||
public class StandardStanzaIdSource implements StanzaIdSource {
|
||||
|
||||
public static final StandardStanzaIdSource DEFAULT = new StandardStanzaIdSource();
|
||||
|
||||
/**
|
||||
* A prefix helps to make sure that ID's are unique across multiple instances.
|
||||
*/
|
||||
private static final String PREFIX = StringUtils.randomString(5) + "-";
|
||||
private final String prefix = StringUtils.randomString(5) + "-";
|
||||
|
||||
/**
|
||||
* Keeps track of the current increment, which is appended to the prefix to
|
||||
* forum a unique ID.
|
||||
*/
|
||||
private static final AtomicLong ID = new AtomicLong();
|
||||
private final AtomicLong id = new AtomicLong();
|
||||
|
||||
@Override
|
||||
public String getNewStanzaId() {
|
||||
return prefix + Long.toString(id.incrementAndGet());
|
||||
}
|
||||
|
||||
public static class Factory implements StanzaIdSourceFactory {
|
||||
|
||||
@Override
|
||||
public StandardStanzaIdSource constructStanzaIdSource() {
|
||||
return new StandardStanzaIdSource();
|
||||
}
|
||||
|
||||
public static String newStanzaId() {
|
||||
return PREFIX + Long.toString(ID.incrementAndGet());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
/**
|
||||
*
|
||||
* 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.id;
|
||||
|
||||
public interface StanzaIdSource {
|
||||
String getNewStanzaId();
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
/**
|
||||
*
|
||||
* 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.id;
|
||||
|
||||
public interface StanzaIdSourceFactory {
|
||||
StanzaIdSource constructStanzaIdSource();
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
*
|
||||
* 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.id;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public final class UuidStanzaIdSource implements StanzaIdSource {
|
||||
|
||||
public static final UuidStanzaIdSource INSTANCE = new UuidStanzaIdSource();
|
||||
|
||||
private UuidStanzaIdSource() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNewStanzaId() {
|
||||
return UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
public static class Factory implements StanzaIdSourceFactory {
|
||||
|
||||
@Override
|
||||
public UuidStanzaIdSource constructStanzaIdSource() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/**
|
||||
*
|
||||
* 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;
|
||||
|
||||
public interface Function<R, T> {
|
||||
|
||||
R apply(T t);
|
||||
|
||||
}
|
|
@ -34,7 +34,7 @@ import java.util.Set;
|
|||
* @param <K> the type of the keys the map uses.
|
||||
* @param <V> the type of the values the map uses.
|
||||
*/
|
||||
public class MultiMap<K, V> {
|
||||
public class MultiMap<K, V> implements TypedCloneable<MultiMap<K, V>> {
|
||||
|
||||
/**
|
||||
* The constant value {@value}.
|
||||
|
@ -252,6 +252,19 @@ public class MultiMap<K, V> {
|
|||
return new MultiMap<K, V>(Collections.unmodifiableMap(mapCopy));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiMap<K, V> clone() {
|
||||
Map<K, List<V>> clonedMap = new LinkedHashMap<>(map.size());
|
||||
|
||||
// TODO: Use Map.forEach() once Smack's minimum Android API is 24 or higher.
|
||||
for (Entry<K, List<V>> entry : map.entrySet()) {
|
||||
List<V> clonedList = CollectionUtil.newListWith(entry.getValue());
|
||||
clonedMap.put(entry.getKey(), clonedList);
|
||||
}
|
||||
|
||||
return new MultiMap<>(clonedMap);
|
||||
}
|
||||
|
||||
private static final class SimpleMapEntry<K, V> implements Map.Entry<K, V> {
|
||||
|
||||
private final K key;
|
||||
|
|
|
@ -28,6 +28,7 @@ import java.util.HashMap;
|
|||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.jivesoftware.smack.compress.packet.Compress;
|
||||
|
@ -36,9 +37,12 @@ import org.jivesoftware.smack.packet.ErrorIQ;
|
|||
import org.jivesoftware.smack.packet.ExtensionElement;
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.MessageBuilder;
|
||||
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.StanzaBuilder;
|
||||
import org.jivesoftware.smack.packet.StanzaError;
|
||||
import org.jivesoftware.smack.packet.StartTls;
|
||||
import org.jivesoftware.smack.packet.StreamError;
|
||||
|
@ -120,18 +124,25 @@ public class PacketParserUtils {
|
|||
}
|
||||
}
|
||||
|
||||
private static void parseCommonStanzaAttributes(Stanza stanza, XmlPullParser parser, XmlEnvironment xmlEnvironment) throws XmppStringprepException {
|
||||
private interface StanzaBuilderSupplier<SB extends StanzaBuilder<?>> {
|
||||
SB get(String stanzaId);
|
||||
}
|
||||
|
||||
private static <SB extends StanzaBuilder<?>> SB parseCommonStanzaAttributes(StanzaBuilderSupplier<SB> stanzaBuilderSupplier, XmlPullParser parser, XmlEnvironment xmlEnvironment) throws XmppStringprepException {
|
||||
String id = parser.getAttributeValue("id");
|
||||
stanza.setStanzaId(id);
|
||||
|
||||
SB stanzaBuilder = stanzaBuilderSupplier.get(id);
|
||||
|
||||
Jid to = ParserUtils.getJidAttribute(parser, "to");
|
||||
stanza.setTo(to);
|
||||
stanzaBuilder.to(to);
|
||||
|
||||
Jid from = ParserUtils.getJidAttribute(parser, "from");
|
||||
stanza.setFrom(from);
|
||||
stanzaBuilder.from(from);
|
||||
|
||||
String language = ParserUtils.getXmlLang(parser, xmlEnvironment);
|
||||
stanza.setLanguage(language);
|
||||
stanzaBuilder.setLanguage(language);
|
||||
|
||||
return stanzaBuilder;
|
||||
}
|
||||
|
||||
public static Message parseMessage(XmlPullParser parser) throws XmlPullParserException, IOException, SmackParsingException {
|
||||
|
@ -154,11 +165,14 @@ public class PacketParserUtils {
|
|||
|
||||
XmlEnvironment messageXmlEnvironment = XmlEnvironment.from(parser, outerXmlEnvironment);
|
||||
final int initialDepth = parser.getDepth();
|
||||
Message message = new Message();
|
||||
parseCommonStanzaAttributes(message, parser, outerXmlEnvironment);
|
||||
|
||||
MessageBuilder message = parseCommonStanzaAttributes(id -> {
|
||||
return StanzaBuilder.buildMessage(id);
|
||||
}, parser, outerXmlEnvironment);
|
||||
|
||||
String typeString = parser.getAttributeValue("", "type");
|
||||
if (typeString != null) {
|
||||
message.setType(Message.Type.fromString(typeString));
|
||||
message.ofType(Message.Type.fromString(typeString));
|
||||
}
|
||||
|
||||
// Parse sub-elements. We include extra logic to make sure the values
|
||||
|
@ -176,9 +190,8 @@ public class PacketParserUtils {
|
|||
String xmlLangSubject = ParserUtils.getXmlLang(parser);
|
||||
String subject = parseElementText(parser);
|
||||
|
||||
if (message.getSubject(xmlLangSubject) == null) {
|
||||
message.addSubject(xmlLangSubject, subject);
|
||||
}
|
||||
Message.Subject subjectExtensionElement = new Message.Subject(xmlLangSubject, subject);
|
||||
message.addExtension(subjectExtensionElement);
|
||||
break;
|
||||
case "thread":
|
||||
if (thread == null) {
|
||||
|
@ -189,7 +202,8 @@ public class PacketParserUtils {
|
|||
message.setError(parseError(parser, messageXmlEnvironment));
|
||||
break;
|
||||
default:
|
||||
PacketParserUtils.addExtensionElement(message, parser, elementName, namespace, messageXmlEnvironment);
|
||||
ExtensionElement extensionElement = parseExtensionElement(elementName, namespace, parser, messageXmlEnvironment);
|
||||
message.addExtension(extensionElement);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -208,7 +222,7 @@ public class PacketParserUtils {
|
|||
// situations where we have a body element with an explicit xml lang set and once where the value is inherited
|
||||
// and both values are equal.
|
||||
|
||||
return message;
|
||||
return message.build();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -436,13 +450,16 @@ public class PacketParserUtils {
|
|||
final int initialDepth = parser.getDepth();
|
||||
XmlEnvironment presenceXmlEnvironment = XmlEnvironment.from(parser, outerXmlEnvironment);
|
||||
|
||||
PresenceBuilder presence = parseCommonStanzaAttributes(
|
||||
stanzaId -> StanzaBuilder.buildPresence(stanzaId), parser, outerXmlEnvironment);
|
||||
|
||||
Presence.Type type = Presence.Type.available;
|
||||
String typeString = parser.getAttributeValue("", "type");
|
||||
if (typeString != null && !typeString.equals("")) {
|
||||
type = Presence.Type.fromString(typeString);
|
||||
}
|
||||
Presence presence = new Presence(type);
|
||||
parseCommonStanzaAttributes(presence, parser, outerXmlEnvironment);
|
||||
|
||||
presence.ofType(type);
|
||||
|
||||
// Parse sub-elements
|
||||
outerloop: while (true) {
|
||||
|
@ -468,9 +485,7 @@ public class PacketParserUtils {
|
|||
// '<show />' element, which is a invalid XMPP presence
|
||||
// stanza according to RFC 6121 4.7.2.1
|
||||
LOGGER.warning("Empty or null mode text in presence show element form "
|
||||
+ presence.getFrom()
|
||||
+ " with id '"
|
||||
+ presence.getStanzaId()
|
||||
+ presence
|
||||
+ "' which is invalid according to RFC6121 4.7.2.1");
|
||||
}
|
||||
break;
|
||||
|
@ -482,10 +497,10 @@ public class PacketParserUtils {
|
|||
// Be extra robust: Skip PacketExtensions that cause Exceptions, instead of
|
||||
// failing completely here. See SMACK-390 for more information.
|
||||
try {
|
||||
PacketParserUtils.addExtensionElement(presence, parser, elementName, namespace, presenceXmlEnvironment);
|
||||
ExtensionElement extensionElement = parseExtensionElement(elementName, namespace, parser, presenceXmlEnvironment);
|
||||
presence.addExtension(extensionElement);
|
||||
} catch (Exception e) {
|
||||
LOGGER.warning("Failed to parse extension element in Presence stanza: \"" + e + "\" from: '"
|
||||
+ presence.getFrom() + " id: '" + presence.getStanzaId() + "'");
|
||||
LOGGER.log(Level.WARNING, "Failed to parse extension element in Presence stanza: " + presence, e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -500,7 +515,8 @@ public class PacketParserUtils {
|
|||
break;
|
||||
}
|
||||
}
|
||||
return presence;
|
||||
|
||||
return presence.build();
|
||||
}
|
||||
|
||||
public static IQ parseIQ(XmlPullParser parser) throws Exception {
|
||||
|
@ -523,7 +539,7 @@ public class PacketParserUtils {
|
|||
final int initialDepth = parser.getDepth();
|
||||
XmlEnvironment iqXmlEnvironment = XmlEnvironment.from(parser, outerXmlEnvironment);
|
||||
IQ iqPacket = null;
|
||||
StanzaError.Builder error = null;
|
||||
StanzaError error = null;
|
||||
|
||||
final String id = parser.getAttributeValue("", "id");
|
||||
final Jid to = ParserUtils.getJidAttribute(parser, "to");
|
||||
|
@ -747,7 +763,7 @@ public class PacketParserUtils {
|
|||
return new StreamError(condition, conditionText, descriptiveTexts, extensions);
|
||||
}
|
||||
|
||||
public static StanzaError.Builder parseError(XmlPullParser parser) throws XmlPullParserException, IOException, SmackParsingException {
|
||||
public static StanzaError parseError(XmlPullParser parser) throws XmlPullParserException, IOException, SmackParsingException {
|
||||
return parseError(parser, null);
|
||||
}
|
||||
|
||||
|
@ -761,7 +777,7 @@ public class PacketParserUtils {
|
|||
* @throws XmlPullParserException if an error in the XML parser occured.
|
||||
* @throws SmackParsingException if the Smack parser (provider) encountered invalid input.
|
||||
*/
|
||||
public static StanzaError.Builder parseError(XmlPullParser parser, XmlEnvironment outerXmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException {
|
||||
public static StanzaError parseError(XmlPullParser parser, XmlEnvironment outerXmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException {
|
||||
final int initialDepth = parser.getDepth();
|
||||
Map<String, String> descriptiveTexts = null;
|
||||
XmlEnvironment stanzaErrorXmlEnvironment = XmlEnvironment.from(parser, outerXmlEnvironment);
|
||||
|
@ -808,7 +824,8 @@ public class PacketParserUtils {
|
|||
}
|
||||
}
|
||||
builder.setExtensions(extensions).setDescriptiveTexts(descriptiveTexts);
|
||||
return builder;
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -427,6 +427,13 @@ public class StringUtils {
|
|||
return true;
|
||||
}
|
||||
|
||||
public static boolean isNullOrNotEmpty(CharSequence cs) {
|
||||
if (cs == null) {
|
||||
return true;
|
||||
}
|
||||
return !cs.toString().isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given CharSequence is empty.
|
||||
*
|
||||
|
@ -456,6 +463,11 @@ public class StringUtils {
|
|||
*/
|
||||
public static StringBuilder toStringBuilder(Collection<? extends Object> collection, String delimiter) {
|
||||
StringBuilder sb = new StringBuilder(collection.size() * 20);
|
||||
appendTo(collection, delimiter, sb);
|
||||
return sb;
|
||||
}
|
||||
|
||||
public static void appendTo(Collection<? extends Object> collection, String delimiter, StringBuilder sb) {
|
||||
for (Iterator<? extends Object> it = collection.iterator(); it.hasNext();) {
|
||||
Object cs = it.next();
|
||||
sb.append(cs);
|
||||
|
@ -463,7 +475,6 @@ public class StringUtils {
|
|||
sb.append(delimiter);
|
||||
}
|
||||
}
|
||||
return sb;
|
||||
}
|
||||
|
||||
public static String returnIfNotEmptyTrimmed(String string) {
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
/**
|
||||
*
|
||||
* 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;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class ToStringUtil {
|
||||
|
||||
public static Builder builderFor(Class<?> clazz) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(clazz.getSimpleName()).append('(');
|
||||
return new Builder(sb);
|
||||
}
|
||||
|
||||
public static final class Builder {
|
||||
private final StringBuilder sb;
|
||||
|
||||
private Builder(StringBuilder sb) {
|
||||
this.sb = sb;
|
||||
}
|
||||
|
||||
public Builder addValue(String name, Object value) {
|
||||
if (value == null) {
|
||||
return this;
|
||||
}
|
||||
if (sb.charAt(sb.length() - 1) != '(') {
|
||||
sb.append(' ');
|
||||
}
|
||||
sb.append(name).append("='").append(value).append('\'');
|
||||
return this;
|
||||
}
|
||||
|
||||
public <V> Builder add(String name, Collection<? extends V> values, Function<?, V> toStringFunction) {
|
||||
if (values.isEmpty()) {
|
||||
return this;
|
||||
}
|
||||
|
||||
sb.append(' ').append(name).append('[');
|
||||
|
||||
List<String> stringValues = new ArrayList<>(values.size());
|
||||
for (V value : values) {
|
||||
String valueString = toStringFunction.apply(value).toString();
|
||||
stringValues.add(valueString);
|
||||
}
|
||||
|
||||
StringUtils.appendTo(stringValues, ", ", sb);
|
||||
|
||||
sb.append(']');
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public String build() {
|
||||
sb.append(')');
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,6 +16,9 @@
|
|||
*/
|
||||
package org.jivesoftware.smack.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
|
@ -52,4 +55,21 @@ public class XmppElementUtil {
|
|||
return new QName(namespace, element);
|
||||
}
|
||||
|
||||
public static <E extends FullyQualifiedElement, R extends FullyQualifiedElement> List<R> getElementsFrom(
|
||||
MultiMap<QName, E> elementMap, Class<R> extensionElementClass) {
|
||||
QName qname = XmppElementUtil.getQNameFor(extensionElementClass);
|
||||
|
||||
List<E> extensionElements = elementMap.getAll(qname);
|
||||
|
||||
if (extensionElements.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<R> res = new ArrayList<>(extensionElements.size());
|
||||
for (E extensionElement : extensionElements) {
|
||||
R e = extensionElementClass.cast(extensionElement);
|
||||
res.add(e);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,8 +19,8 @@ package org.jivesoftware.smack.filter;
|
|||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.Stanza;
|
||||
import org.jivesoftware.smack.packet.StanzaBuilder;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.jxmpp.jid.EntityFullJid;
|
||||
|
@ -47,7 +47,7 @@ public class FromMatchesFilterTest {
|
|||
@Test
|
||||
public void autoCompareMatchingEntityFullJid() {
|
||||
FromMatchesFilter filter = FromMatchesFilter.create(FULL_JID1_R1);
|
||||
Stanza packet = new Message();
|
||||
Stanza packet = StanzaBuilder.buildMessage().build();
|
||||
|
||||
packet.setFrom(FULL_JID1_R1);
|
||||
assertTrue(filter.accept(packet));
|
||||
|
@ -71,7 +71,7 @@ public class FromMatchesFilterTest {
|
|||
@Test
|
||||
public void autoCompareMatchingBaseJid() {
|
||||
FromMatchesFilter filter = FromMatchesFilter.create(BASE_JID1);
|
||||
Stanza packet = new Message();
|
||||
Stanza packet = StanzaBuilder.buildMessage().build();
|
||||
|
||||
packet.setFrom(BASE_JID1);
|
||||
assertTrue(filter.accept(packet));
|
||||
|
@ -95,7 +95,7 @@ public class FromMatchesFilterTest {
|
|||
@Test
|
||||
public void autoCompareMatchingServiceJid() {
|
||||
FromMatchesFilter filter = FromMatchesFilter.create(SERVICE_JID1);
|
||||
Stanza packet = new Message();
|
||||
Stanza packet = StanzaBuilder.buildMessage().build();
|
||||
|
||||
packet.setFrom(SERVICE_JID1);
|
||||
assertTrue(filter.accept(packet));
|
||||
|
@ -116,7 +116,7 @@ public class FromMatchesFilterTest {
|
|||
@Test
|
||||
public void bareCompareMatchingEntityFullJid() {
|
||||
FromMatchesFilter filter = FromMatchesFilter.createBare(FULL_JID1_R1);
|
||||
Stanza packet = new Message();
|
||||
Stanza packet = StanzaBuilder.buildMessage().build();
|
||||
|
||||
packet.setFrom(BASE_JID1);
|
||||
assertTrue(filter.accept(packet));
|
||||
|
@ -140,7 +140,7 @@ public class FromMatchesFilterTest {
|
|||
@Test
|
||||
public void bareCompareMatchingBaseJid() {
|
||||
FromMatchesFilter filter = FromMatchesFilter.createBare(BASE_JID1);
|
||||
Stanza packet = new Message();
|
||||
Stanza packet = StanzaBuilder.buildMessage().build();
|
||||
|
||||
packet.setFrom(BASE_JID1);
|
||||
assertTrue(filter.accept(packet));
|
||||
|
@ -164,7 +164,7 @@ public class FromMatchesFilterTest {
|
|||
@Test
|
||||
public void bareCompareMatchingServiceJid() {
|
||||
FromMatchesFilter filter = FromMatchesFilter.createBare(SERVICE_JID1);
|
||||
Stanza packet = new Message();
|
||||
Stanza packet = StanzaBuilder.buildMessage().build();
|
||||
|
||||
packet.setFrom(SERVICE_JID1);
|
||||
assertTrue(filter.accept(packet));
|
||||
|
@ -185,7 +185,7 @@ public class FromMatchesFilterTest {
|
|||
@Test
|
||||
public void fullCompareMatchingEntityFullJid() {
|
||||
FromMatchesFilter filter = FromMatchesFilter.createFull(FULL_JID1_R1);
|
||||
Stanza packet = new Message();
|
||||
Stanza packet = StanzaBuilder.buildMessage().build();
|
||||
|
||||
packet.setFrom(FULL_JID1_R1);
|
||||
assertTrue(filter.accept(packet));
|
||||
|
@ -209,7 +209,7 @@ public class FromMatchesFilterTest {
|
|||
@Test
|
||||
public void fullCompareMatchingBaseJid() {
|
||||
FromMatchesFilter filter = FromMatchesFilter.createFull(BASE_JID1);
|
||||
Stanza packet = new Message();
|
||||
Stanza packet = StanzaBuilder.buildMessage().build();
|
||||
|
||||
packet.setFrom(BASE_JID1);
|
||||
assertTrue(filter.accept(packet));
|
||||
|
@ -233,7 +233,7 @@ public class FromMatchesFilterTest {
|
|||
@Test
|
||||
public void fullCompareMatchingServiceJid() {
|
||||
FromMatchesFilter filter = FromMatchesFilter.createFull(SERVICE_JID1);
|
||||
Stanza packet = new Message();
|
||||
Stanza packet = StanzaBuilder.buildMessage().build();
|
||||
|
||||
packet.setFrom(SERVICE_JID1);
|
||||
assertTrue(filter.accept(packet));
|
||||
|
|
|
@ -62,7 +62,7 @@ public class IQResponseTest {
|
|||
*/
|
||||
@Test
|
||||
public void testGeneratingValidErrorResponse() throws XmppStringprepException {
|
||||
final StanzaError.Builder error = StanzaError.getBuilder(StanzaError.Condition.bad_request);
|
||||
final StanzaError error = StanzaError.getBuilder(StanzaError.Condition.bad_request).build();
|
||||
final IQ request = new TestIQ(ELEMENT, NAMESPACE);
|
||||
|
||||
request.setType(IQ.Type.set);
|
||||
|
@ -75,7 +75,7 @@ public class IQResponseTest {
|
|||
assertNotNull(result.getStanzaId());
|
||||
assertEquals(request.getStanzaId(), result.getStanzaId());
|
||||
assertEquals(request.getFrom(), result.getTo());
|
||||
assertEquals(error.build().toXML().toString(), result.getError().toXML().toString());
|
||||
assertEquals(error.toXML().toString(), result.getError().toXML().toString());
|
||||
// TODO this test was never valid
|
||||
// assertEquals(CHILD_ELEMENT, result.getChildElementXML());
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ public class IQResponseTest {
|
|||
*/
|
||||
@Test
|
||||
public void testGeneratingErrorBasedOnError() throws XmppStringprepException {
|
||||
final StanzaError.Builder error = StanzaError.getBuilder(StanzaError.Condition.bad_request);
|
||||
final StanzaError error = StanzaError.getBuilder(StanzaError.Condition.bad_request).build();
|
||||
final IQ request = new TestIQ(ELEMENT, NAMESPACE);
|
||||
|
||||
request.setType(IQ.Type.error);
|
||||
|
|
|
@ -18,7 +18,6 @@ package org.jivesoftware.smack.packet;
|
|||
|
||||
import static org.jivesoftware.smack.test.util.XmlUnitUtils.assertXmlSimilar;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.IOException;
|
||||
|
@ -44,10 +43,12 @@ public class MessageTest {
|
|||
.append("</message>");
|
||||
String control = controlBuilder.toString();
|
||||
|
||||
Message messageTypeInConstructor = new Message(null, Message.Type.chat);
|
||||
messageTypeInConstructor.setStanzaId(null);
|
||||
assertEquals(type, messageTypeInConstructor.getType());
|
||||
assertXmlSimilar(control, messageTypeInConstructor.toXML(StreamOpen.CLIENT_NAMESPACE).toString());
|
||||
Message messageBuildWithBuilder = StanzaBuilder.buildMessage()
|
||||
.ofType(Message.Type.chat)
|
||||
.build();
|
||||
|
||||
assertEquals(type, messageBuildWithBuilder.getType());
|
||||
assertXmlSimilar(control, messageBuildWithBuilder.toXML(StreamOpen.CLIENT_NAMESPACE).toString());
|
||||
|
||||
controlBuilder = new StringBuilder();
|
||||
controlBuilder.append("<message")
|
||||
|
@ -57,16 +58,18 @@ public class MessageTest {
|
|||
.append("</message>");
|
||||
control = controlBuilder.toString();
|
||||
|
||||
Message messageTypeSet = getNewMessage();
|
||||
messageTypeSet.setType(type2);
|
||||
Message messageTypeSet = StanzaBuilder.buildMessage()
|
||||
.ofType(type2)
|
||||
.build();
|
||||
assertEquals(type2, messageTypeSet.getType());
|
||||
assertXmlSimilar(control, messageTypeSet.toXML(StreamOpen.CLIENT_NAMESPACE).toString());
|
||||
}
|
||||
|
||||
@Test(expected = NullPointerException.class)
|
||||
public void setNullMessageBodyTest() {
|
||||
Message message = getNewMessage();
|
||||
message.addBody(null, null);
|
||||
StanzaBuilder.buildMessage()
|
||||
.addBody(null, null)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -81,9 +84,9 @@ public class MessageTest {
|
|||
.append("</message>");
|
||||
String control = controlBuilder.toString();
|
||||
|
||||
Message message = getNewMessage();
|
||||
message.setSubject(messageSubject);
|
||||
|
||||
Message message = StanzaBuilder.buildMessage()
|
||||
.setSubject(messageSubject)
|
||||
.build();
|
||||
assertEquals(messageSubject, message.getSubject());
|
||||
assertXmlSimilar(control, message.toXML(StreamOpen.CLIENT_NAMESPACE).toString());
|
||||
}
|
||||
|
@ -100,9 +103,9 @@ public class MessageTest {
|
|||
.append("</message>");
|
||||
String control = controlBuilder.toString();
|
||||
|
||||
Message message = getNewMessage();
|
||||
message.setBody(messageBody);
|
||||
|
||||
Message message = StanzaBuilder.buildMessage()
|
||||
.setBody(messageBody)
|
||||
.build();
|
||||
assertEquals(messageBody, message.getBody());
|
||||
assertXmlSimilar(control, message.toXML(StreamOpen.CLIENT_NAMESPACE).toString());
|
||||
}
|
||||
|
@ -133,10 +136,11 @@ public class MessageTest {
|
|||
.append("</message>");
|
||||
String control = controlBuilder.toString();
|
||||
|
||||
Message message = getNewMessage();
|
||||
message.addBody(null, messageBody1);
|
||||
message.addBody(lang2, messageBody2);
|
||||
message.addBody(lang3, messageBody3);
|
||||
Message message = StanzaBuilder.buildMessage()
|
||||
.addBody(null, messageBody1)
|
||||
.addBody(lang2, messageBody2)
|
||||
.addBody(lang3, messageBody3)
|
||||
.build();
|
||||
assertXmlSimilar(control, message.toXML(StreamOpen.CLIENT_NAMESPACE));
|
||||
|
||||
Collection<String> languages = message.getBodyLanguages();
|
||||
|
@ -148,21 +152,20 @@ public class MessageTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void removeMessageBodyTest() {
|
||||
Message message = getNewMessage();
|
||||
message.setBody("test");
|
||||
public void simpleMessageBodyTest() {
|
||||
Message message = StanzaBuilder.buildMessage()
|
||||
.setBody("test")
|
||||
.build();
|
||||
assertTrue(message.getBodies().size() == 1);
|
||||
|
||||
message.setBody(null);
|
||||
message = StanzaBuilder.buildMessage().build();
|
||||
assertTrue(message.getBodies().size() == 0);
|
||||
|
||||
assertFalse(message.removeBody("sp"));
|
||||
|
||||
Message.Body body = message.addBody("es", "test");
|
||||
message = StanzaBuilder.buildMessage()
|
||||
.addBody("es", "test")
|
||||
.build();
|
||||
assertTrue(message.getBodies().size() == 1);
|
||||
|
||||
message.removeBody(body);
|
||||
assertTrue(message.getBodies().size() == 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -177,8 +180,9 @@ public class MessageTest {
|
|||
.append("</message>");
|
||||
String control = controlBuilder.toString();
|
||||
|
||||
Message message = getNewMessage();
|
||||
message.setThread(messageThread);
|
||||
Message message = StanzaBuilder.buildMessage()
|
||||
.setThread(messageThread)
|
||||
.build();
|
||||
|
||||
assertEquals(messageThread, message.getThread());
|
||||
assertXmlSimilar(control, message.toXML(StreamOpen.CLIENT_NAMESPACE).toString());
|
||||
|
@ -196,15 +200,10 @@ public class MessageTest {
|
|||
.append("</message>");
|
||||
String control = controlBuilder.toString();
|
||||
|
||||
Message message = getNewMessage();
|
||||
message.setLanguage(lang);
|
||||
Message message = StanzaBuilder.buildMessage()
|
||||
.setLanguage(lang)
|
||||
.build();
|
||||
|
||||
assertXmlSimilar(control, message.toXML(StreamOpen.CLIENT_NAMESPACE).toString());
|
||||
}
|
||||
|
||||
private static Message getNewMessage() {
|
||||
Message message = new Message();
|
||||
message.setStanzaId(null);
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,8 +41,9 @@ public class PresenceTest {
|
|||
.append("</presence>");
|
||||
String control = controlBuilder.toString();
|
||||
|
||||
Presence presenceTypeInConstructor = new Presence(type);
|
||||
presenceTypeInConstructor.setStanzaId(null);
|
||||
Presence presenceTypeInConstructor = StanzaBuilder.buildPresence()
|
||||
.ofType(type)
|
||||
.build();
|
||||
assertEquals(type, presenceTypeInConstructor.getType());
|
||||
assertXmlSimilar(control, presenceTypeInConstructor.toXML(StreamOpen.CLIENT_NAMESPACE).toString());
|
||||
|
||||
|
@ -54,27 +55,27 @@ public class PresenceTest {
|
|||
.append("</presence>");
|
||||
control = controlBuilder.toString();
|
||||
|
||||
Presence presenceTypeSet = getNewPresence();
|
||||
presenceTypeSet.setType(type2);
|
||||
PresenceBuilder presenceTypeSet = getNewPresence();
|
||||
presenceTypeSet.ofType(type2);
|
||||
assertEquals(type2, presenceTypeSet.getType());
|
||||
assertXmlSimilar(control, presenceTypeSet.toXML(StreamOpen.CLIENT_NAMESPACE).toString());
|
||||
assertXmlSimilar(control, presenceTypeSet.build().toXML(StreamOpen.CLIENT_NAMESPACE).toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setNullPresenceTypeTest() {
|
||||
assertThrows(IllegalArgumentException.class, () ->
|
||||
getNewPresence().setType(null)
|
||||
getNewPresence().ofType(null)
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isPresenceAvailableTest() {
|
||||
Presence presence = getNewPresence();
|
||||
presence.setType(Presence.Type.available);
|
||||
assertTrue(presence.isAvailable());
|
||||
PresenceBuilder presence = getNewPresence();
|
||||
presence.ofType(Presence.Type.available);
|
||||
assertTrue(presence.build().isAvailable());
|
||||
|
||||
presence.setType(Presence.Type.unavailable);
|
||||
assertFalse(presence.isAvailable());
|
||||
presence.ofType(Presence.Type.unavailable);
|
||||
assertFalse(presence.build().isAvailable());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -89,11 +90,11 @@ public class PresenceTest {
|
|||
.append("</presence>");
|
||||
String control = controlBuilder.toString();
|
||||
|
||||
Presence presence = getNewPresence();
|
||||
PresenceBuilder presence = getNewPresence();
|
||||
presence.setStatus(status);
|
||||
|
||||
assertEquals(status, presence.getStatus());
|
||||
assertXmlSimilar(control, presence.toXML(StreamOpen.CLIENT_NAMESPACE).toString());
|
||||
assertXmlSimilar(control, presence.build().toXML(StreamOpen.CLIENT_NAMESPACE).toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -108,11 +109,11 @@ public class PresenceTest {
|
|||
.append("</presence>");
|
||||
String control = controlBuilder.toString();
|
||||
|
||||
Presence presence = getNewPresence();
|
||||
PresenceBuilder presence = getNewPresence();
|
||||
presence.setPriority(priority);
|
||||
|
||||
assertEquals(priority, presence.getPriority());
|
||||
assertXmlSimilar(control, presence.toXML(StreamOpen.CLIENT_NAMESPACE).toString());
|
||||
assertXmlSimilar(control, presence.build().toXML(StreamOpen.CLIENT_NAMESPACE).toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -143,11 +144,14 @@ public class PresenceTest {
|
|||
.append("</presence>");
|
||||
String control = controlBuilder.toString();
|
||||
|
||||
Presence presenceModeInConstructor = new Presence(Presence.Type.available, status, priority,
|
||||
mode1);
|
||||
presenceModeInConstructor.setStanzaId(null);
|
||||
assertEquals(mode1, presenceModeInConstructor.getMode());
|
||||
assertXmlSimilar(control, presenceModeInConstructor.toXML(StreamOpen.CLIENT_NAMESPACE).toString());
|
||||
Presence presenceBuildWithBuilder = StanzaBuilder.buildPresence()
|
||||
.ofType(Presence.Type.available)
|
||||
.setStatus(status)
|
||||
.setPriority(priority)
|
||||
.setMode(mode1)
|
||||
.build();
|
||||
assertEquals(mode1, presenceBuildWithBuilder.getMode());
|
||||
assertXmlSimilar(control, presenceBuildWithBuilder.toXML(StreamOpen.CLIENT_NAMESPACE).toString());
|
||||
|
||||
controlBuilder = new StringBuilder();
|
||||
controlBuilder.append("<presence>")
|
||||
|
@ -157,20 +161,20 @@ public class PresenceTest {
|
|||
.append("</presence>");
|
||||
control = controlBuilder.toString();
|
||||
|
||||
Presence presenceModeSet = getNewPresence();
|
||||
PresenceBuilder presenceModeSet = getNewPresence();
|
||||
presenceModeSet.setMode(mode2);
|
||||
assertEquals(mode2, presenceModeSet.getMode());
|
||||
assertXmlSimilar(control, presenceModeSet.toXML(StreamOpen.CLIENT_NAMESPACE).toString());
|
||||
assertXmlSimilar(control, presenceModeSet.build().toXML(StreamOpen.CLIENT_NAMESPACE).toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isModeAwayTest() {
|
||||
Presence presence = getNewPresence();
|
||||
PresenceBuilder presence = getNewPresence();
|
||||
presence.setMode(Presence.Mode.away);
|
||||
assertTrue(presence.isAway());
|
||||
assertTrue(presence.build().isAway());
|
||||
|
||||
presence.setMode(Presence.Mode.chat);
|
||||
assertFalse(presence.isAway());
|
||||
assertFalse(presence.build().isAway());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -185,15 +189,14 @@ public class PresenceTest {
|
|||
.append("</presence>");
|
||||
String control = controlBuilder.toString();
|
||||
|
||||
Presence presence = getNewPresence();
|
||||
PresenceBuilder presence = getNewPresence();
|
||||
presence.setLanguage(lang);
|
||||
|
||||
assertXmlSimilar(control, presence.toXML(StreamOpen.CLIENT_NAMESPACE).toString());
|
||||
assertXmlSimilar(control, presence.build().toXML(StreamOpen.CLIENT_NAMESPACE).toString());
|
||||
}
|
||||
|
||||
private static Presence getNewPresence() {
|
||||
Presence presence = new Presence(Presence.Type.available);
|
||||
presence.setStanzaId(null);
|
||||
private static PresenceBuilder getNewPresence() {
|
||||
PresenceBuilder presence = StanzaBuilder.buildPresence().ofType(Presence.Type.available);
|
||||
return presence;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright © 2016-2017 Florian Schmaus
|
||||
* Copyright © 2016-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.
|
||||
|
@ -18,8 +18,6 @@ package org.jivesoftware.smack.packet;
|
|||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.jivesoftware.smack.packet.Presence.Mode;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.jxmpp.jid.JidTestUtil;
|
||||
|
||||
|
@ -27,15 +25,21 @@ public class ToStringTest {
|
|||
|
||||
@Test
|
||||
public void messageTest() {
|
||||
Message message = new Message(JidTestUtil.BARE_JID_1, Message.Type.headline);
|
||||
message.setStanzaId("message-id");
|
||||
Message message = StanzaBuilder.buildMessage("message-id")
|
||||
.ofType(Message.Type.headline)
|
||||
.to(JidTestUtil.BARE_JID_1)
|
||||
.build();
|
||||
String string = message.toString();
|
||||
assertEquals("Message Stanza [to=one@exampleone.org,id=message-id,type=headline,]", string);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void presenceTest() {
|
||||
Presence presence = new Presence(Presence.Type.subscribe, null, 0, Mode.away);
|
||||
Presence presence = StanzaBuilder.buildPresence()
|
||||
.ofType(Presence.Type.subscribe)
|
||||
.setPriority(0)
|
||||
.setMode(Presence.Mode.away)
|
||||
.build();
|
||||
presence.setStanzaId("presence-id");
|
||||
String string = presence.toString();
|
||||
assertEquals("Presence Stanza [id=presence-id,type=subscribe,mode=away,prio=0,]", string);
|
||||
|
|
|
@ -16,12 +16,13 @@
|
|||
*/
|
||||
package org.jivesoftware.smack.packet;
|
||||
|
||||
import static org.jivesoftware.smack.packet.StanzaError.Condition;
|
||||
import static org.jivesoftware.smack.packet.StanzaError.Type;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.jivesoftware.smack.packet.StanzaError.Condition;
|
||||
import org.jivesoftware.smack.packet.StanzaError.Type;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class XMPPErrorTest {
|
||||
|
|
|
@ -45,7 +45,6 @@ import org.jivesoftware.smack.xml.XmlPullParser;
|
|||
import org.jivesoftware.smack.xml.XmlPullParserException;
|
||||
|
||||
import com.jamesmurty.utils.XMLBuilder;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
|
@ -547,30 +546,6 @@ public class PacketParserUtilsTest {
|
|||
assertTrue(message.getSubjectLanguages().contains(otherLanguage));
|
||||
assertXmlSimilar(control, message.toXML(StreamOpen.CLIENT_NAMESPACE).toString());
|
||||
|
||||
// message has default language, first subject no language, second subject default language
|
||||
control = XMLBuilder.create("message")
|
||||
.a("from", "romeo@montague.lit/orchard")
|
||||
.a("to", "juliet@capulet.lit/balcony")
|
||||
.a("id", "zid615d9")
|
||||
.a("type", "chat")
|
||||
.a("xml:lang", defaultLanguage)
|
||||
.e("subject")
|
||||
.t(defaultLanguage)
|
||||
.up()
|
||||
.e("subject")
|
||||
.a("xml:lang", defaultLanguage)
|
||||
.t(defaultLanguage + "2")
|
||||
.asString(outputProperties);
|
||||
|
||||
message = PacketParserUtils
|
||||
.parseMessage(PacketParserUtils.getParserFor(control));
|
||||
|
||||
assertEquals(defaultLanguage, message.getSubject());
|
||||
assertEquals(defaultLanguage, message.getSubject(defaultLanguage));
|
||||
assertEquals(1, message.getSubjects().size());
|
||||
assertEquals(0, message.getSubjectLanguages().size());
|
||||
assertXmlNotSimilar(control, message.toXML(StreamOpen.CLIENT_NAMESPACE).toString());
|
||||
|
||||
// message has non-default language, first subject no language, second subject default language
|
||||
control = XMLBuilder.create("message")
|
||||
.a("from", "romeo@montague.lit/orchard")
|
||||
|
@ -867,7 +842,7 @@ public class PacketParserUtilsTest {
|
|||
.element("text", StanzaError.ERROR_CONDITION_AND_TEXT_NAMESPACE).t(text).up()
|
||||
.asString();
|
||||
XmlPullParser parser = TestUtils.getParser(errorXml);
|
||||
StanzaError error = PacketParserUtils.parseError(parser).build();
|
||||
StanzaError error = PacketParserUtils.parseError(parser);
|
||||
assertEquals(text, error.getDescriptiveText());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,10 +88,11 @@ public final class DnsOverXmppManager extends Manager {
|
|||
try {
|
||||
response = resolver.resolve(query);
|
||||
} catch (IOException exception) {
|
||||
StanzaError.Builder errorBuilder = StanzaError.getBuilder()
|
||||
StanzaError errorBuilder = StanzaError.getBuilder()
|
||||
.setType(Type.CANCEL)
|
||||
.setCondition(Condition.internal_server_error)
|
||||
.setDescriptiveEnText("Exception while resolving your DNS query", exception)
|
||||
.build()
|
||||
;
|
||||
|
||||
IQ errorResponse = IQ.createErrorResponse(iqRequest, errorBuilder);
|
||||
|
|
|
@ -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.
|
||||
|
@ -20,8 +20,12 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import org.jivesoftware.smack.packet.ExtensionElement;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.MessageBuilder;
|
||||
import org.jivesoftware.smack.packet.MessageView;
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
import org.jivesoftware.smack.util.XmlStringBuilder;
|
||||
|
||||
|
@ -33,6 +37,8 @@ public class ExplicitMessageEncryptionElement implements ExtensionElement {
|
|||
|
||||
public static final String NAMESPACE = "urn:xmpp:eme:0";
|
||||
|
||||
public static final QName QNAME = new QName(NAMESPACE, ELEMENT);
|
||||
|
||||
public enum ExplicitMessageEncryptionProtocol {
|
||||
|
||||
/**
|
||||
|
@ -154,14 +160,12 @@ public class ExplicitMessageEncryptionElement implements ExtensionElement {
|
|||
* @param protocolNamespace namespace
|
||||
* @return true if message has EME element for that namespace, otherwise false
|
||||
*/
|
||||
public static boolean hasProtocol(Message message, String protocolNamespace) {
|
||||
List<ExtensionElement> extensionElements = message.getExtensions(
|
||||
ExplicitMessageEncryptionElement.ELEMENT,
|
||||
ExplicitMessageEncryptionElement.NAMESPACE);
|
||||
public static boolean hasProtocol(MessageView message, String protocolNamespace) {
|
||||
List<ExplicitMessageEncryptionElement> emeElements = message
|
||||
.getExtensions(ExplicitMessageEncryptionElement.class);
|
||||
|
||||
for (ExtensionElement extensionElement : extensionElements) {
|
||||
ExplicitMessageEncryptionElement e = (ExplicitMessageEncryptionElement) extensionElement;
|
||||
if (e.getEncryptionNamespace().equals(protocolNamespace)) {
|
||||
for (ExplicitMessageEncryptionElement emeElement : emeElements) {
|
||||
if (emeElement.getEncryptionNamespace().equals(protocolNamespace)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -176,7 +180,7 @@ public class ExplicitMessageEncryptionElement implements ExtensionElement {
|
|||
* @param protocol protocol
|
||||
* @return true if message has EME element for that namespace, otherwise false
|
||||
*/
|
||||
public static boolean hasProtocol(Message message, ExplicitMessageEncryptionProtocol protocol) {
|
||||
public static boolean hasProtocol(MessageView message, ExplicitMessageEncryptionProtocol protocol) {
|
||||
return hasProtocol(message, protocol.namespace);
|
||||
}
|
||||
|
||||
|
@ -184,10 +188,10 @@ public class ExplicitMessageEncryptionElement implements ExtensionElement {
|
|||
* Add an EME element containing the specified {@code protocol} namespace to the message.
|
||||
* In case there is already an element with that protocol, we do nothing.
|
||||
*
|
||||
* @param message message
|
||||
* @param message a message builder.
|
||||
* @param protocol encryption protocol
|
||||
*/
|
||||
public static void set(Message message, ExplicitMessageEncryptionProtocol protocol) {
|
||||
public static void set(MessageBuilder message, ExplicitMessageEncryptionProtocol protocol) {
|
||||
if (!hasProtocol(message, protocol.namespace)) {
|
||||
message.addExtension(new ExplicitMessageEncryptionElement(protocol));
|
||||
}
|
||||
|
|
|
@ -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,7 +16,10 @@
|
|||
*/
|
||||
package org.jivesoftware.smackx.hints.element;
|
||||
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import org.jivesoftware.smack.packet.MessageBuilder;
|
||||
import org.jivesoftware.smack.packet.MessageView;
|
||||
|
||||
/**
|
||||
* A "store" hint. Messages with this hint should be stored in permanent stores or archives.
|
||||
|
@ -29,6 +32,8 @@ public final class StoreHint extends MessageProcessingHint {
|
|||
|
||||
public static final String ELEMENT = "store";
|
||||
|
||||
public static final QName QNAME = new QName(NAMESPACE, ELEMENT);
|
||||
|
||||
private StoreHint() {
|
||||
}
|
||||
|
||||
|
@ -47,15 +52,15 @@ public final class StoreHint extends MessageProcessingHint {
|
|||
return MessageProcessingHintType.store;
|
||||
}
|
||||
|
||||
public static StoreHint from(Message message) {
|
||||
return message.getExtension(ELEMENT, NAMESPACE);
|
||||
public static StoreHint from(MessageView message) {
|
||||
return message.getExtension(QNAME);
|
||||
}
|
||||
|
||||
public static boolean hasHint(Message message) {
|
||||
public static boolean hasHint(MessageView message) {
|
||||
return from(message) != null;
|
||||
}
|
||||
|
||||
public static void set(Message message) {
|
||||
public static void set(MessageBuilder message) {
|
||||
message.overrideExtension(INSTANCE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright © 2016 Florian Schmaus
|
||||
* Copyright © 2016-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.
|
||||
|
@ -17,19 +17,25 @@
|
|||
package org.jivesoftware.smackx.iot.control.element;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.IqBuilder;
|
||||
import org.jivesoftware.smack.packet.StanzaBuilder;
|
||||
|
||||
public class IoTSetResponse extends IQ {
|
||||
|
||||
public static final String ELEMENT = "setResponse";
|
||||
public static final String NAMESPACE = Constants.IOT_CONTROL_NAMESPACE;
|
||||
|
||||
public IoTSetResponse(IqBuilder iqBuilder) {
|
||||
super(iqBuilder, ELEMENT, NAMESPACE);
|
||||
}
|
||||
|
||||
// TODO: Deprecate when stanza build is ready.
|
||||
public IoTSetResponse() {
|
||||
super(ELEMENT, NAMESPACE);
|
||||
}
|
||||
|
||||
public IoTSetResponse(IoTSetRequest iotSetRequest) {
|
||||
this();
|
||||
initializeAsResultFor(iotSetRequest);
|
||||
this(StanzaBuilder.buildIqResultFor(iotSetRequest));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -125,10 +125,14 @@ public final class IoTDataManager extends IoTManager {
|
|||
@Override
|
||||
public void momentaryReadOut(List<? extends IoTDataField> results) {
|
||||
IoTFieldsExtension iotFieldsExtension = IoTFieldsExtension.buildFor(dataRequest.getSequenceNr(), true, thing.getNodeInfo(), results);
|
||||
Message message = new Message(dataRequest.getFrom());
|
||||
message.addExtension(iotFieldsExtension);
|
||||
|
||||
XMPPConnection connection = connection();
|
||||
Message message = connection.getStanzaFactory().buildMessageStanza()
|
||||
.to(dataRequest.getFrom())
|
||||
.addExtension(iotFieldsExtension)
|
||||
.build();
|
||||
try {
|
||||
connection().sendStanza(message);
|
||||
connection.sendStanza(message);
|
||||
}
|
||||
catch (NotConnectedException | InterruptedException e) {
|
||||
LOGGER.log(Level.SEVERE, "Could not send read-out response " + message, e);
|
||||
|
|
|
@ -140,8 +140,10 @@ public final class IoTProvisioningManager extends Manager {
|
|||
+ " is already not subscribed to our presence.");
|
||||
return;
|
||||
}
|
||||
Presence unsubscribed = new Presence(Presence.Type.unsubscribed);
|
||||
unsubscribed.setTo(unfriendJid);
|
||||
Presence unsubscribed = connection.getStanzaFactory().buildPresenceStanza()
|
||||
.ofType(Presence.Type.unsubscribed)
|
||||
.to(unfriendJid)
|
||||
.build();
|
||||
connection.sendStanza(unsubscribed);
|
||||
}
|
||||
}, UNFRIEND_MESSAGE);
|
||||
|
@ -162,7 +164,10 @@ public final class IoTProvisioningManager extends Manager {
|
|||
// friendship requests.
|
||||
final XMPPConnection connection = connection();
|
||||
Friend friendNotification = new Friend(connection.getUser().asBareJid());
|
||||
Message notificationMessage = new Message(friendJid, friendNotification);
|
||||
Message notificationMessage = connection.getStanzaFactory().buildMessageStanza()
|
||||
.to(friendJid)
|
||||
.addExtension(friendNotification)
|
||||
.build();
|
||||
connection.sendStanza(notificationMessage);
|
||||
} else {
|
||||
// Check is the message was send from a thing we previously
|
||||
|
@ -359,8 +364,11 @@ public final class IoTProvisioningManager extends Manager {
|
|||
}
|
||||
|
||||
public void sendFriendshipRequest(BareJid bareJid) throws NotConnectedException, InterruptedException {
|
||||
Presence presence = new Presence(Presence.Type.subscribe);
|
||||
presence.setTo(bareJid);
|
||||
XMPPConnection connection = connection();
|
||||
Presence presence = connection.getStanzaFactory().buildPresenceStanza()
|
||||
.ofType(Presence.Type.subscribe)
|
||||
.to(bareJid)
|
||||
.build();
|
||||
|
||||
friendshipRequestedCache.put(bareJid, null);
|
||||
|
||||
|
@ -379,9 +387,12 @@ public final class IoTProvisioningManager extends Manager {
|
|||
|
||||
public void unfriend(Jid friend) throws NotConnectedException, InterruptedException {
|
||||
if (isMyFriend(friend)) {
|
||||
Presence presence = new Presence(Presence.Type.unsubscribed);
|
||||
presence.setTo(friend);
|
||||
connection().sendStanza(presence);
|
||||
XMPPConnection connection = connection();
|
||||
Presence presence = connection.getStanzaFactory().buildPresenceStanza()
|
||||
.ofType(Presence.Type.unsubscribed)
|
||||
.to(friend)
|
||||
.build();
|
||||
connection.sendStanza(presence);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,8 +35,8 @@ import org.jivesoftware.smack.filter.MessageTypeFilter;
|
|||
import org.jivesoftware.smack.filter.StanzaFilter;
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.MessageBuilder;
|
||||
import org.jivesoftware.smack.packet.Stanza;
|
||||
|
||||
import org.jivesoftware.smackx.muclight.element.MUCLightAffiliationsIQ;
|
||||
import org.jivesoftware.smackx.muclight.element.MUCLightChangeAffiliationsIQ;
|
||||
import org.jivesoftware.smackx.muclight.element.MUCLightConfigurationIQ;
|
||||
|
@ -126,9 +126,9 @@ public class MultiUserChatLight {
|
|||
* @throws InterruptedException if the calling thread was interrupted.
|
||||
*/
|
||||
public void sendMessage(String text) throws NotConnectedException, InterruptedException {
|
||||
Message message = createMessage();
|
||||
MessageBuilder message = buildMessage();
|
||||
message.setBody(text);
|
||||
connection.sendStanza(message);
|
||||
connection.sendStanza(message.build());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -157,9 +157,28 @@ public class MultiUserChatLight {
|
|||
* Creates a new Message to send to the chat room.
|
||||
*
|
||||
* @return a new Message addressed to the chat room.
|
||||
* @deprecated use {@link #buildMessage()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove when stanza builder is ready.
|
||||
public Message createMessage() {
|
||||
return new Message(room, Message.Type.groupchat);
|
||||
return connection.getStanzaFactory().buildMessageStanza()
|
||||
.ofType(Message.Type.groupchat)
|
||||
.to(room)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new message builder for messages send to this MUC room.
|
||||
*
|
||||
* @return a new message builder.
|
||||
*/
|
||||
public MessageBuilder buildMessage() {
|
||||
return connection.getStanzaFactory()
|
||||
.buildMessageStanza()
|
||||
.ofType(Message.Type.groupchat)
|
||||
.to(room)
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -169,10 +188,23 @@ public class MultiUserChatLight {
|
|||
* the message.
|
||||
* @throws NotConnectedException if the XMPP connection is not connected.
|
||||
* @throws InterruptedException if the calling thread was interrupted.
|
||||
* @deprecated use {@link #sendMessage(MessageBuilder)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove in Smack 4.5.
|
||||
public void sendMessage(Message message) throws NotConnectedException, InterruptedException {
|
||||
message.setTo(room);
|
||||
message.setType(Message.Type.groupchat);
|
||||
sendMessage(message.asBuilder());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a Message to the chat room.
|
||||
*
|
||||
* @param messageBuilder the message.
|
||||
* @throws NotConnectedException if the XMPP connection is not connected.
|
||||
* @throws InterruptedException if the calling thread was interrupted.
|
||||
*/
|
||||
public void sendMessage(MessageBuilder messageBuilder) throws NotConnectedException, InterruptedException {
|
||||
Message message = messageBuilder.to(room).ofType(Message.Type.groupchat).build();
|
||||
connection.sendStanza(message);
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,9 @@ public class RemoteDisablingProvider extends ExtensionElementProvider<RemoteDisa
|
|||
|
||||
String affiliation = parser.getAttributeValue("", "affiliation");
|
||||
if (affiliation == null || !affiliation.equals("none")) {
|
||||
return null;
|
||||
// TODO: Is this correct? We previously returned null here, but was certainly wrong, as
|
||||
// providers should always return an element or throw.
|
||||
throw new IOException("Invalid affiliation: " + affiliation);
|
||||
}
|
||||
}
|
||||
} else if (eventType == XmlPullParser.Event.END_ELEMENT) {
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.jivesoftware.smackx.chat_markers;
|
|||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.StanzaBuilder;
|
||||
import org.jivesoftware.smack.packet.StreamOpen;
|
||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||
import org.jivesoftware.smack.xml.XmlPullParser;
|
||||
|
@ -28,7 +29,6 @@ import org.jivesoftware.smackx.chat_markers.element.ChatMarkersElements.Acknowle
|
|||
import org.jivesoftware.smackx.chat_markers.provider.AcknowledgedProvider;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.jxmpp.jid.impl.JidCreate;
|
||||
|
||||
public class AcknowledgedExtensionTest {
|
||||
|
||||
|
@ -39,9 +39,10 @@ public class AcknowledgedExtensionTest {
|
|||
|
||||
@Test
|
||||
public void checkDisplayedExtension() throws Exception {
|
||||
Message message = new Message(JidCreate.from("northumberland@shakespeare.lit/westminster"));
|
||||
message.setStanzaId("message-2");
|
||||
message.addExtension(new ChatMarkersElements.AcknowledgedExtension("message-1"));
|
||||
Message message = StanzaBuilder.buildMessage("message-2")
|
||||
.to("northumberland@shakespeare.lit/westminster")
|
||||
.addExtension(new ChatMarkersElements.AcknowledgedExtension("message-1"))
|
||||
.build();
|
||||
assertEquals(acknowledgedMessageStanza, message.toXML(StreamOpen.CLIENT_NAMESPACE).toString());
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.jivesoftware.smackx.chat_markers;
|
|||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.StanzaBuilder;
|
||||
import org.jivesoftware.smack.packet.StreamOpen;
|
||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||
import org.jivesoftware.smack.xml.XmlPullParser;
|
||||
|
@ -28,7 +29,6 @@ import org.jivesoftware.smackx.chat_markers.element.ChatMarkersElements.Displaye
|
|||
import org.jivesoftware.smackx.chat_markers.provider.DisplayedProvider;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.jxmpp.jid.impl.JidCreate;
|
||||
|
||||
public class DisplayedExtensionTest {
|
||||
|
||||
|
@ -39,9 +39,10 @@ public class DisplayedExtensionTest {
|
|||
|
||||
@Test
|
||||
public void checkDisplayedExtension() throws Exception {
|
||||
Message message = new Message(JidCreate.from("northumberland@shakespeare.lit/westminster"));
|
||||
message.setStanzaId("message-2");
|
||||
message.addExtension(new ChatMarkersElements.DisplayedExtension("message-1"));
|
||||
Message message = StanzaBuilder.buildMessage("message-2")
|
||||
.to("northumberland@shakespeare.lit/westminster")
|
||||
.addExtension(new ChatMarkersElements.DisplayedExtension("message-1"))
|
||||
.build();
|
||||
assertEquals(displayedMessageStanza, message.toXML(StreamOpen.CLIENT_NAMESPACE).toString());
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.jivesoftware.smackx.chat_markers;
|
|||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.StanzaBuilder;
|
||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||
import org.jivesoftware.smack.xml.XmlPullParser;
|
||||
|
||||
|
@ -39,10 +40,12 @@ public class MarkableExtensionTest {
|
|||
|
||||
@Test
|
||||
public void checkMarkableExtension() throws Exception {
|
||||
Message message = new Message(JidCreate.from("ingrichard@royalty.england.lit/throne"));
|
||||
message.setStanzaId("message-1");
|
||||
message.setBody("My lord, dispatch; read o'er these articles.");
|
||||
message.addExtension(ChatMarkersElements.MarkableExtension.INSTANCE);
|
||||
Message message = StanzaBuilder.buildMessage("message-1")
|
||||
.to(JidCreate.from("ingrichard@royalty.england.lit/throne"))
|
||||
.setBody("My lord, dispatch; read o'er these articles.")
|
||||
.addExtension(ChatMarkersElements.MarkableExtension.INSTANCE)
|
||||
.build();
|
||||
|
||||
assertEquals(markableMessageStanza, message.toXML().toString());
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.jivesoftware.smackx.chat_markers;
|
|||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.StanzaBuilder;
|
||||
import org.jivesoftware.smack.packet.StreamOpen;
|
||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||
import org.jivesoftware.smack.xml.XmlPullParser;
|
||||
|
@ -28,7 +29,6 @@ import org.jivesoftware.smackx.chat_markers.element.ChatMarkersElements.Received
|
|||
import org.jivesoftware.smackx.chat_markers.provider.ReceivedProvider;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.jxmpp.jid.impl.JidCreate;
|
||||
|
||||
public class ReceivedExtensionTest {
|
||||
|
||||
|
@ -39,9 +39,10 @@ public class ReceivedExtensionTest {
|
|||
|
||||
@Test
|
||||
public void checkReceivedExtension() throws Exception {
|
||||
Message message = new Message(JidCreate.from("northumberland@shakespeare.lit/westminster"));
|
||||
message.setStanzaId("message-2");
|
||||
message.addExtension(new ChatMarkersElements.ReceivedExtension("message-1"));
|
||||
Message message = StanzaBuilder.buildMessage("message-2")
|
||||
.to("northumberland@shakespeare.lit/westminster")
|
||||
.addExtension(new ChatMarkersElements.ReceivedExtension("message-1"))
|
||||
.build();
|
||||
assertEquals(receivedMessageStanza, message.toXML(StreamOpen.CLIENT_NAMESPACE).toString());
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,8 @@ import java.util.List;
|
|||
|
||||
import org.jivesoftware.smack.packet.ExtensionElement;
|
||||
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.smackx.eme.element.ExplicitMessageEncryptionElement;
|
||||
|
@ -35,7 +37,7 @@ public class ExplicitMessageEncryptionElementTest extends SmackTestSuite {
|
|||
|
||||
@Test
|
||||
public void addToMessageTest() {
|
||||
Message message = new Message();
|
||||
Message message = StanzaBuilder.buildMessage().build();
|
||||
|
||||
// Check inital state (no elements)
|
||||
assertNull(ExplicitMessageEncryptionElement.from(message));
|
||||
|
@ -45,9 +47,12 @@ public class ExplicitMessageEncryptionElementTest extends SmackTestSuite {
|
|||
List<ExtensionElement> extensions = message.getExtensions();
|
||||
assertEquals(0, extensions.size());
|
||||
|
||||
MessageBuilder messageBuilder = StanzaBuilder.buildMessage();
|
||||
// Add OMEMO
|
||||
ExplicitMessageEncryptionElement.set(message,
|
||||
ExplicitMessageEncryptionElement.set(messageBuilder,
|
||||
ExplicitMessageEncryptionElement.ExplicitMessageEncryptionProtocol.omemoVAxolotl);
|
||||
|
||||
message = messageBuilder.build();
|
||||
extensions = message.getExtensions();
|
||||
assertEquals(1, extensions.size());
|
||||
assertTrue(ExplicitMessageEncryptionElement.hasProtocol(message,
|
||||
|
@ -59,8 +64,10 @@ public class ExplicitMessageEncryptionElementTest extends SmackTestSuite {
|
|||
assertFalse(ExplicitMessageEncryptionElement.hasProtocol(message,
|
||||
ExplicitMessageEncryptionElement.ExplicitMessageEncryptionProtocol.openpgpV0.getNamespace()));
|
||||
|
||||
ExplicitMessageEncryptionElement.set(message,
|
||||
ExplicitMessageEncryptionElement.set(messageBuilder,
|
||||
ExplicitMessageEncryptionElement.ExplicitMessageEncryptionProtocol.openpgpV0);
|
||||
|
||||
message = messageBuilder.build();
|
||||
extensions = message.getExtensions();
|
||||
assertEquals(2, extensions.size());
|
||||
assertTrue(ExplicitMessageEncryptionElement.hasProtocol(message,
|
||||
|
@ -69,9 +76,10 @@ public class ExplicitMessageEncryptionElementTest extends SmackTestSuite {
|
|||
ExplicitMessageEncryptionElement.ExplicitMessageEncryptionProtocol.omemoVAxolotl));
|
||||
|
||||
// Check, if adding additional OMEMO wont add another element
|
||||
ExplicitMessageEncryptionElement.set(message,
|
||||
ExplicitMessageEncryptionElement.set(messageBuilder,
|
||||
ExplicitMessageEncryptionElement.ExplicitMessageEncryptionProtocol.omemoVAxolotl);
|
||||
|
||||
message = messageBuilder.build();
|
||||
extensions = message.getExtensions();
|
||||
assertEquals(2, extensions.size());
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import java.util.TimeZone;
|
|||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.Message.Type;
|
||||
import org.jivesoftware.smack.packet.StanzaBuilder;
|
||||
import org.jivesoftware.smack.packet.StreamOpen;
|
||||
|
||||
import org.jivesoftware.smackx.delay.packet.DelayInformation;
|
||||
|
@ -62,21 +63,21 @@ public class QueryArchiveTest extends MamTest {
|
|||
|
||||
@Test
|
||||
public void checkMamQueryResults() throws Exception {
|
||||
Message message = new Message();
|
||||
message.setStanzaId("iasd207");
|
||||
message.setFrom(JidCreate.from("coven@chat.shakespeare.lit"));
|
||||
message.setTo(JidCreate.from("hag66@shakespeare.lit/pda"));
|
||||
Message message = StanzaBuilder.buildMessage("iasd207")
|
||||
.from("coven@chat.shakespeare.lit")
|
||||
.to("hag66@shakespeare.lit/pda")
|
||||
.build();
|
||||
|
||||
GregorianCalendar calendar = new GregorianCalendar(2002, 10 - 1, 13, 23, 58, 37);
|
||||
calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
Date date = calendar.getTime();
|
||||
|
||||
DelayInformation delay = new DelayInformation(date);
|
||||
Message forwardedMessage = new Message();
|
||||
forwardedMessage.setFrom(JidCreate.from("coven@chat.shakespeare.lit/firstwitch"));
|
||||
forwardedMessage.setStanzaId("162BEBB1-F6DB-4D9A-9BD8-CFDCC801A0B2");
|
||||
forwardedMessage.setType(Type.chat);
|
||||
forwardedMessage.setBody("Thrice the brinded cat hath mew.");
|
||||
Message forwardedMessage = StanzaBuilder.buildMessage("162BEBB1-F6DB-4D9A-9BD8-CFDCC801A0B2")
|
||||
.from(JidCreate.from("coven@chat.shakespeare.lit/firstwitch"))
|
||||
.ofType(Type.chat)
|
||||
.setBody("Thrice the brinded cat hath mew.")
|
||||
.build();
|
||||
|
||||
Forwarded forwarded = new Forwarded(delay, forwardedMessage);
|
||||
|
||||
|
|
|
@ -18,7 +18,9 @@ package org.jivesoftware.smackx.push_notifications;
|
|||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||
|
@ -56,18 +58,12 @@ public class RemoteDisablingPushNotificationsTest {
|
|||
|
||||
@Test
|
||||
public void checkWrongRemoteDisablighPushNotifications() throws Exception {
|
||||
Message message1 = PacketParserUtils.parseStanza(wrongRemoteDisabling1);
|
||||
RemoteDisablingExtension remoteDisablingExtension1 = RemoteDisablingExtension.from(message1);
|
||||
assertNull(remoteDisablingExtension1);
|
||||
assertThrows(IOException.class, () -> PacketParserUtils.parseStanza(wrongRemoteDisabling1));
|
||||
|
||||
Message message2 = PacketParserUtils.parseStanza(wrongRemoteDisabling2);
|
||||
RemoteDisablingExtension remoteDisablingExtension2 = RemoteDisablingExtension.from(message2);
|
||||
assertNull(remoteDisablingExtension2);
|
||||
assertThrows(IOException.class, () -> PacketParserUtils.parseStanza(wrongRemoteDisabling2));
|
||||
|
||||
Message message3 = PacketParserUtils.parseStanza(wrongRemoteDisabling3);
|
||||
assertNotNull(message3);
|
||||
// RemoteDisablingExtension remoteDisablingExtension3 = RemoteDisablingExtension.from(message3);
|
||||
// assertNull(remoteDisablingExtension3);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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.StanzaBuilder;
|
||||
import org.jivesoftware.smack.test.util.SmackTestSuite;
|
||||
import org.jivesoftware.smack.test.util.TestUtils;
|
||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||
|
@ -70,7 +71,7 @@ public class StableUniqueStanzaIdTest extends SmackTestSuite {
|
|||
|
||||
@Test
|
||||
public void fromMessageTest() {
|
||||
Message message = new Message();
|
||||
Message message = StanzaBuilder.buildMessage().build();
|
||||
assertFalse(OriginIdElement.hasOriginId(message));
|
||||
assertFalse(StanzaIdElement.hasStanzaId(message));
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
|||
import java.util.Map;
|
||||
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.StanzaBuilder;
|
||||
import org.jivesoftware.smack.test.util.SmackTestSuite;
|
||||
import org.jivesoftware.smack.test.util.TestUtils;
|
||||
import org.jivesoftware.smack.xml.XmlPullParser;
|
||||
|
@ -40,7 +41,7 @@ public class SpoilerTest extends SmackTestSuite {
|
|||
public void emptySpoilerTest() throws Exception {
|
||||
final String xml = "<spoiler xmlns='urn:xmpp:spoiler:0'/>";
|
||||
|
||||
Message message = new Message();
|
||||
Message message = StanzaBuilder.buildMessage().build();
|
||||
SpoilerElement.addSpoiler(message);
|
||||
|
||||
SpoilerElement empty = message.getExtension(SpoilerElement.ELEMENT, SpoilerManager.NAMESPACE_0);
|
||||
|
@ -59,7 +60,7 @@ public class SpoilerTest extends SmackTestSuite {
|
|||
public void hintSpoilerTest() throws Exception {
|
||||
final String xml = "<spoiler xmlns='urn:xmpp:spoiler:0'>Love story end</spoiler>";
|
||||
|
||||
Message message = new Message();
|
||||
Message message = StanzaBuilder.buildMessage().build();
|
||||
SpoilerElement.addSpoiler(message, "Love story end");
|
||||
|
||||
SpoilerElement withHint = message.getExtension(SpoilerElement.ELEMENT, SpoilerManager.NAMESPACE_0);
|
||||
|
@ -79,7 +80,7 @@ public class SpoilerTest extends SmackTestSuite {
|
|||
public void i18nHintSpoilerTest() throws Exception {
|
||||
final String xml = "<spoiler xml:lang='de' xmlns='urn:xmpp:spoiler:0'>Der Kuchen ist eine Lüge!</spoiler>";
|
||||
|
||||
Message message = new Message();
|
||||
Message message = StanzaBuilder.buildMessage().build();
|
||||
SpoilerElement.addSpoiler(message, "de", "Der Kuchen ist eine Lüge!");
|
||||
|
||||
SpoilerElement i18nHint = message.getExtension(SpoilerElement.ELEMENT, SpoilerManager.NAMESPACE_0);
|
||||
|
@ -98,7 +99,7 @@ public class SpoilerTest extends SmackTestSuite {
|
|||
|
||||
@Test
|
||||
public void getSpoilersTest() {
|
||||
Message m = new Message();
|
||||
Message m = StanzaBuilder.buildMessage().build();
|
||||
assertTrue(SpoilerElement.getSpoilers(m).isEmpty());
|
||||
|
||||
SpoilerElement.addSpoiler(m);
|
||||
|
|
|
@ -40,9 +40,12 @@ public final class Chat extends Manager {
|
|||
}
|
||||
|
||||
public void send(CharSequence message) throws NotConnectedException, InterruptedException {
|
||||
Message stanza = new Message();
|
||||
stanza.setBody(message);
|
||||
stanza.setType(Message.Type.chat);
|
||||
Message stanza = connection()
|
||||
.getStanzaFactory()
|
||||
.buildMessageStanza()
|
||||
.ofType(Message.Type.chat)
|
||||
.setBody(message)
|
||||
.build();
|
||||
send(stanza);
|
||||
}
|
||||
|
||||
|
|
|
@ -159,7 +159,7 @@ public class MultipleRecipientManager {
|
|||
}
|
||||
// Any <thread/> element from the initial message MUST be copied into the reply.
|
||||
if (original.getThread() != null) {
|
||||
reply.setThread(original.getThread());
|
||||
reply.asBuilder().setThread(original.getThread()).build();
|
||||
}
|
||||
MultipleAddresses.Address replyAddress = info.getReplyAddress();
|
||||
if (replyAddress != null && replyAddress.getJid() != null) {
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.jivesoftware.smack.filter.StanzaTypeFilter;
|
|||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.Stanza;
|
||||
import org.jivesoftware.smack.packet.StanzaBuilder;
|
||||
import org.jivesoftware.smack.packet.StanzaError;
|
||||
import org.jivesoftware.smack.util.stringencoder.Base64;
|
||||
|
||||
|
@ -835,8 +836,9 @@ public class InBandBytestreamSession implements BytestreamSession {
|
|||
@Override
|
||||
protected synchronized void writeToXML(DataPacketExtension data) throws NotConnectedException, InterruptedException {
|
||||
// create message stanza containing data packet
|
||||
Message message = new Message(remoteJID);
|
||||
message.addExtension(data);
|
||||
Message message = StanzaBuilder.buildMessage().to(remoteJID)
|
||||
.addExtension(data)
|
||||
.build();
|
||||
|
||||
connection.sendStanza(message);
|
||||
|
||||
|
|
|
@ -718,7 +718,7 @@ public final class Socks5BytestreamManager extends Manager implements Bytestream
|
|||
* @throws InterruptedException if the calling thread was interrupted.
|
||||
*/
|
||||
protected void replyRejectPacket(IQ packet) throws NotConnectedException, InterruptedException {
|
||||
StanzaError.Builder xmppError = StanzaError.getBuilder(StanzaError.Condition.not_acceptable);
|
||||
StanzaError xmppError = StanzaError.getBuilder(StanzaError.Condition.not_acceptable).build();
|
||||
IQ errorIQ = IQ.createErrorResponse(packet, xmppError);
|
||||
connection().sendStanza(errorIQ);
|
||||
}
|
||||
|
|
|
@ -333,7 +333,7 @@ public class Socks5BytestreamRequest implements BytestreamRequest {
|
|||
errorMessage = couldNotConnectException.getMessage();
|
||||
}
|
||||
|
||||
StanzaError.Builder error = StanzaError.from(StanzaError.Condition.item_not_found, errorMessage);
|
||||
StanzaError error = StanzaError.from(StanzaError.Condition.item_not_found, errorMessage).build();
|
||||
IQ errorIQ = IQ.createErrorResponse(this.bytestreamRequest, error);
|
||||
this.manager.getConnection().sendStanza(errorIQ);
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ import org.jivesoftware.smack.filter.StanzaFilter;
|
|||
import org.jivesoftware.smack.packet.ExtensionElement;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.Stanza;
|
||||
import org.jivesoftware.smack.packet.StanzaBuilder;
|
||||
|
||||
import org.jivesoftware.smackx.chatstates.packet.ChatStateExtension;
|
||||
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
||||
|
@ -218,7 +219,7 @@ public final class ChatStateManager extends Manager {
|
|||
if (!updateChatState(chat, newState)) {
|
||||
return;
|
||||
}
|
||||
Message message = new Message();
|
||||
Message message = StanzaBuilder.buildMessage().build();
|
||||
ChatStateExtension extension = new ChatStateExtension(newState);
|
||||
message.addExtension(extension);
|
||||
|
||||
|
|
|
@ -329,7 +329,10 @@ public final class AdHocCommandManager extends Manager {
|
|||
}
|
||||
catch (InstantiationException | IllegalAccessException | IllegalArgumentException
|
||||
| InvocationTargetException | NoSuchMethodException | SecurityException e) {
|
||||
StanzaError.Builder xmppError = StanzaError.getBuilder().setCondition(StanzaError.Condition.internal_server_error).setDescriptiveEnText(e.getMessage());
|
||||
StanzaError xmppError = StanzaError.getBuilder()
|
||||
.setCondition(StanzaError.Condition.internal_server_error)
|
||||
.setDescriptiveEnText(e.getMessage())
|
||||
.build();
|
||||
return respondError(response, xmppError);
|
||||
}
|
||||
|
||||
|
@ -393,7 +396,7 @@ public final class AdHocCommandManager extends Manager {
|
|||
response.setStatus(Status.canceled);
|
||||
executingCommands.remove(sessionId);
|
||||
}
|
||||
return respondError(response, StanzaError.getBuilder(error));
|
||||
return respondError(response, error);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -503,7 +506,7 @@ public final class AdHocCommandManager extends Manager {
|
|||
response.setStatus(Status.canceled);
|
||||
executingCommands.remove(sessionId);
|
||||
}
|
||||
return respondError(response, StanzaError.getBuilder(error));
|
||||
return respondError(response, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -559,7 +562,7 @@ public final class AdHocCommandManager extends Manager {
|
|||
*/
|
||||
private static IQ respondError(AdHocCommandData response,
|
||||
StanzaError.Condition condition) {
|
||||
return respondError(response, StanzaError.getBuilder(condition));
|
||||
return respondError(response, StanzaError.getBuilder(condition).build());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -572,7 +575,9 @@ public final class AdHocCommandManager extends Manager {
|
|||
*/
|
||||
private static IQ respondError(AdHocCommandData response, StanzaError.Condition condition,
|
||||
AdHocCommand.SpecificErrorCondition specificCondition) {
|
||||
StanzaError.Builder error = StanzaError.getBuilder(condition).addExtension(new AdHocCommandData.SpecificError(specificCondition));
|
||||
StanzaError error = StanzaError.getBuilder(condition)
|
||||
.addExtension(new AdHocCommandData.SpecificError(specificCondition))
|
||||
.build();
|
||||
return respondError(response, error);
|
||||
}
|
||||
|
||||
|
@ -583,7 +588,7 @@ public final class AdHocCommandManager extends Manager {
|
|||
* @param error the error to send.
|
||||
* @throws NotConnectedException if the XMPP connection is not connected.
|
||||
*/
|
||||
private static IQ respondError(AdHocCommandData response, StanzaError.Builder error) {
|
||||
private static IQ respondError(AdHocCommandData response, StanzaError error) {
|
||||
response.setType(IQ.Type.error);
|
||||
response.setError(error);
|
||||
return response;
|
||||
|
|
|
@ -112,7 +112,7 @@ public class AdHocCommandDataProvider extends IQProvider<AdHocCommandData> {
|
|||
adHocCommandData.addNote(new AdHocCommandNote(type, value));
|
||||
}
|
||||
else if (parser.getName().equals("error")) {
|
||||
StanzaError.Builder error = PacketParserUtils.parseError(parser);
|
||||
StanzaError error = PacketParserUtils.parseError(parser);
|
||||
adHocCommandData.setError(error);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -146,7 +146,7 @@ public final class ServiceDiscoveryManager extends Manager {
|
|||
// Return <item-not-found/> error since client doesn't contain
|
||||
// the specified node
|
||||
response.setType(IQ.Type.error);
|
||||
response.setError(StanzaError.getBuilder(StanzaError.Condition.item_not_found));
|
||||
response.setError(StanzaError.getBuilder(StanzaError.Condition.item_not_found).build());
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
@ -184,7 +184,7 @@ public final class ServiceDiscoveryManager extends Manager {
|
|||
} else {
|
||||
// Return <item-not-found/> error since specified node was not found
|
||||
response.setType(IQ.Type.error);
|
||||
response.setError(StanzaError.getBuilder(StanzaError.Condition.item_not_found));
|
||||
response.setError(StanzaError.getBuilder(StanzaError.Condition.item_not_found).build());
|
||||
}
|
||||
}
|
||||
return response;
|
||||
|
|
|
@ -172,7 +172,7 @@ public final class FileTransferManager extends Manager {
|
|||
// 'not-acceptable' should be returned. This is done by Smack in
|
||||
// Socks5BytestreamManager.replyRejectPacket(IQ).
|
||||
IQ rejection = IQ.createErrorResponse(initiation, StanzaError.getBuilder(
|
||||
StanzaError.Condition.forbidden));
|
||||
StanzaError.Condition.forbidden).build());
|
||||
connection().sendStanza(rejection);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -194,7 +194,7 @@ public final class FileTransferNegotiator extends Manager {
|
|||
|
||||
if (streamMethodField == null) {
|
||||
String errorMessage = "No stream methods contained in stanza.";
|
||||
StanzaError.Builder error = StanzaError.from(StanzaError.Condition.bad_request, errorMessage);
|
||||
StanzaError error = StanzaError.from(StanzaError.Condition.bad_request, errorMessage).build();
|
||||
IQ iqPacket = IQ.createErrorResponse(si, error);
|
||||
connection().sendStanza(iqPacket);
|
||||
throw new FileTransferException.NoStreamMethodsOfferedException();
|
||||
|
@ -206,7 +206,7 @@ public final class FileTransferNegotiator extends Manager {
|
|||
selectedStreamNegotiator = getNegotiator(streamMethodField);
|
||||
}
|
||||
catch (NoAcceptableTransferMechanisms e) {
|
||||
IQ iqPacket = IQ.createErrorResponse(si, StanzaError.from(StanzaError.Condition.bad_request, "No acceptable transfer mechanism"));
|
||||
IQ iqPacket = IQ.createErrorResponse(si, StanzaError.from(StanzaError.Condition.bad_request, "No acceptable transfer mechanism").build());
|
||||
connection().sendStanza(iqPacket);
|
||||
throw e;
|
||||
}
|
||||
|
|
|
@ -80,8 +80,10 @@ public final class GeoLocationManager extends Manager {
|
|||
|
||||
final XMPPConnection connection = connection();
|
||||
|
||||
Message geoLocationMessage = new Message(jid);
|
||||
geoLocationMessage.addExtension(geoLocation);
|
||||
Message geoLocationMessage = connection.getStanzaFactory().buildMessageStanza()
|
||||
.to(jid)
|
||||
.addExtension(geoLocation)
|
||||
.build();
|
||||
|
||||
connection.sendStanza(geoLocationMessage);
|
||||
|
||||
|
|
|
@ -424,9 +424,10 @@ public class JingleUtil {
|
|||
*/
|
||||
|
||||
public IQ createErrorUnknownSession(Jingle request) {
|
||||
StanzaError.Builder error = StanzaError.getBuilder();
|
||||
error.setCondition(StanzaError.Condition.item_not_found)
|
||||
.addExtension(JingleError.UNKNOWN_SESSION);
|
||||
StanzaError error = StanzaError.getBuilder()
|
||||
.setCondition(StanzaError.Condition.item_not_found)
|
||||
.addExtension(JingleError.UNKNOWN_SESSION)
|
||||
.build();
|
||||
return IQ.createErrorResponse(request, error);
|
||||
}
|
||||
|
||||
|
@ -445,9 +446,10 @@ public class JingleUtil {
|
|||
}
|
||||
|
||||
public IQ createErrorUnsupportedInfo(Jingle request) {
|
||||
StanzaError.Builder error = StanzaError.getBuilder();
|
||||
error.setCondition(StanzaError.Condition.feature_not_implemented)
|
||||
.addExtension(JingleError.UNSUPPORTED_INFO);
|
||||
StanzaError error = StanzaError.getBuilder()
|
||||
.setCondition(StanzaError.Condition.feature_not_implemented)
|
||||
.addExtension(JingleError.UNSUPPORTED_INFO)
|
||||
.build();
|
||||
return IQ.createErrorResponse(request, error);
|
||||
}
|
||||
|
||||
|
@ -457,9 +459,10 @@ public class JingleUtil {
|
|||
}
|
||||
|
||||
public IQ createErrorTieBreak(Jingle request) {
|
||||
StanzaError.Builder error = StanzaError.getBuilder();
|
||||
error.setCondition(StanzaError.Condition.conflict)
|
||||
.addExtension(JingleError.TIE_BREAK);
|
||||
StanzaError error = StanzaError.getBuilder()
|
||||
.setCondition(StanzaError.Condition.conflict)
|
||||
.addExtension(JingleError.TIE_BREAK)
|
||||
.build();
|
||||
return IQ.createErrorResponse(request, error);
|
||||
}
|
||||
|
||||
|
@ -469,9 +472,10 @@ public class JingleUtil {
|
|||
}
|
||||
|
||||
public IQ createErrorOutOfOrder(Jingle request) {
|
||||
StanzaError.Builder error = StanzaError.getBuilder();
|
||||
error.setCondition(StanzaError.Condition.unexpected_request)
|
||||
.addExtension(JingleError.OUT_OF_ORDER);
|
||||
StanzaError error = StanzaError.getBuilder()
|
||||
.setCondition(StanzaError.Condition.unexpected_request)
|
||||
.addExtension(JingleError.OUT_OF_ORDER)
|
||||
.build();
|
||||
return IQ.createErrorResponse(request, error);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@ import java.util.Collections;
|
|||
import java.util.Map;
|
||||
|
||||
import org.jivesoftware.smack.packet.Stanza;
|
||||
import org.jivesoftware.smack.packet.StanzaBuilder;
|
||||
import org.jivesoftware.smack.packet.StanzaView;
|
||||
|
||||
import org.jivesoftware.smackx.jiveproperties.packet.JivePropertiesExtension;
|
||||
|
||||
|
@ -54,7 +56,10 @@ public class JivePropertiesManager {
|
|||
* @param packet the stanza to add the property to.
|
||||
* @param name the name of the property to add.
|
||||
* @param value the value of the property to add.
|
||||
* @deprecated use {@link #addProperty(StanzaBuilder, String, Object)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove in Smack 4.5.
|
||||
public static void addProperty(Stanza packet, String name, Object value) {
|
||||
JivePropertiesExtension jpe = (JivePropertiesExtension) packet.getExtension(JivePropertiesExtension.NAMESPACE);
|
||||
if (jpe == null) {
|
||||
|
@ -64,6 +69,22 @@ public class JivePropertiesManager {
|
|||
jpe.setProperty(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to add a property to a stanza.
|
||||
*
|
||||
* @param stanzaBuilder the stanza to add the property to.
|
||||
* @param name the name of the property to add.
|
||||
* @param value the value of the property to add.
|
||||
*/
|
||||
public static void addProperty(StanzaBuilder<?> stanzaBuilder, String name, Object value) {
|
||||
JivePropertiesExtension jpe = (JivePropertiesExtension) stanzaBuilder.getExtension(JivePropertiesExtension.QNAME);
|
||||
if (jpe == null) {
|
||||
jpe = new JivePropertiesExtension();
|
||||
stanzaBuilder.addExtension(jpe);
|
||||
}
|
||||
jpe.setProperty(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to get a property from a packet. Will return null if the stanza contains
|
||||
* not property with the given name.
|
||||
|
@ -72,9 +93,9 @@ public class JivePropertiesManager {
|
|||
* @param name TODO javadoc me please
|
||||
* @return the property or <code>null</code> if none found.
|
||||
*/
|
||||
public static Object getProperty(Stanza packet, String name) {
|
||||
public static Object getProperty(StanzaView packet, String name) {
|
||||
Object res = null;
|
||||
JivePropertiesExtension jpe = (JivePropertiesExtension) packet.getExtension(JivePropertiesExtension.NAMESPACE);
|
||||
JivePropertiesExtension jpe = (JivePropertiesExtension) packet.getExtension(JivePropertiesExtension.QNAME);
|
||||
if (jpe != null) {
|
||||
res = jpe.getProperty(name);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@ import java.util.Map;
|
|||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import org.jivesoftware.smack.packet.ExtensionElement;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.util.XmlStringBuilder;
|
||||
|
@ -47,6 +49,8 @@ public class JivePropertiesExtension implements ExtensionElement {
|
|||
|
||||
public static final String ELEMENT = "properties";
|
||||
|
||||
public static final QName QNAME = new QName(NAMESPACE, ELEMENT);
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(JivePropertiesExtension.class.getName());
|
||||
|
||||
private final Map<String, Object> properties;
|
||||
|
|
|
@ -18,7 +18,10 @@ package org.jivesoftware.smackx.muc;
|
|||
|
||||
import java.util.Date;
|
||||
|
||||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smack.packet.Presence;
|
||||
import org.jivesoftware.smack.packet.PresenceBuilder;
|
||||
import org.jivesoftware.smack.util.Consumer;
|
||||
import org.jivesoftware.smack.util.Objects;
|
||||
|
||||
import org.jivesoftware.smackx.muc.packet.MUCInitialPresence;
|
||||
|
@ -58,7 +61,7 @@ public final class MucEnterConfiguration {
|
|||
timeout = builder.timeout;
|
||||
|
||||
if (builder.joinPresence == null) {
|
||||
joinPresence = new Presence(Presence.Type.available);
|
||||
joinPresence = builder.joinPresenceBuilder.ofType(Presence.Type.available).build();
|
||||
}
|
||||
else {
|
||||
joinPresence = builder.joinPresence.clone();
|
||||
|
@ -87,11 +90,17 @@ public final class MucEnterConfiguration {
|
|||
private int seconds = -1;
|
||||
private Date since;
|
||||
private long timeout;
|
||||
|
||||
private final PresenceBuilder joinPresenceBuilder;
|
||||
private Presence joinPresence;
|
||||
|
||||
Builder(Resourcepart nickname, long timeout) {
|
||||
Builder(Resourcepart nickname, XMPPConnection connection) {
|
||||
this.nickname = Objects.requireNonNull(nickname, "Nickname must not be null");
|
||||
|
||||
timeout = connection.getReplyTimeout();
|
||||
timeoutAfter(timeout);
|
||||
|
||||
joinPresenceBuilder = connection.getStanzaFactory().buildPresenceStanza();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -103,7 +112,10 @@ public final class MucEnterConfiguration {
|
|||
*
|
||||
* @param presence TODO javadoc me please
|
||||
* @return a reference to this builder.
|
||||
* @deprecated use {@link #withPresence(Consumer)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove in Smack 4.5.
|
||||
public Builder withPresence(Presence presence) {
|
||||
if (presence.getType() != Presence.Type.available) {
|
||||
throw new IllegalArgumentException("Presence must be of type 'available'");
|
||||
|
@ -113,6 +125,26 @@ public final class MucEnterConfiguration {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the presence used to join the MUC room.
|
||||
* <p>
|
||||
* The consumer must not modify the presence type, otherwise an {@link IllegalArgumentException} will be thrown.
|
||||
* <p>
|
||||
*
|
||||
* @param presenceBuilderConsumer a consumer which will be passed the presence build.
|
||||
* @return a reference to this builder.
|
||||
* @since 4.5
|
||||
*/
|
||||
public Builder withPresence(Consumer<? super PresenceBuilder> presenceBuilderConsumer) {
|
||||
presenceBuilderConsumer.accept(joinPresenceBuilder);
|
||||
|
||||
if (joinPresenceBuilder.getType() != Presence.Type.available) {
|
||||
throw new IllegalArgumentException("Presence must be of type 'available'");
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the given password to join the MUC room.
|
||||
*
|
||||
|
|
|
@ -56,6 +56,7 @@ import org.jivesoftware.smack.filter.StanzaTypeFilter;
|
|||
import org.jivesoftware.smack.filter.ToMatchesFilter;
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.MessageBuilder;
|
||||
import org.jivesoftware.smack.packet.Presence;
|
||||
import org.jivesoftware.smack.packet.Stanza;
|
||||
import org.jivesoftware.smack.util.Objects;
|
||||
|
@ -419,7 +420,7 @@ public class MultiUserChat {
|
|||
* @since 4.2
|
||||
*/
|
||||
public MucEnterConfiguration.Builder getEnterConfigurationBuilder(Resourcepart nickname) {
|
||||
return new MucEnterConfiguration.Builder(nickname, connection.getReplyTimeout());
|
||||
return new MucEnterConfiguration.Builder(nickname, connection);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -744,8 +745,10 @@ public class MultiUserChat {
|
|||
|
||||
// We leave a room by sending a presence packet where the "to"
|
||||
// field is in the form "roomName@service/nickname"
|
||||
Presence leavePresence = new Presence(Presence.Type.unavailable);
|
||||
leavePresence.setTo(myRoomJid);
|
||||
Presence leavePresence = connection.getStanzaFactory().buildPresenceStanza()
|
||||
.ofType(Presence.Type.unavailable)
|
||||
.to(myRoomJid)
|
||||
.build();
|
||||
|
||||
StanzaFilter reflectedLeavePresenceFilter = new AndFilter(
|
||||
StanzaTypeFilter.PRESENCE,
|
||||
|
@ -927,7 +930,7 @@ public class MultiUserChat {
|
|||
* @throws InterruptedException if the calling thread was interrupted.
|
||||
*/
|
||||
public void invite(EntityBareJid user, String reason) throws NotConnectedException, InterruptedException {
|
||||
invite(new Message(), user, reason);
|
||||
invite(connection.getStanzaFactory().buildMessageStanza(), user, reason);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -942,7 +945,10 @@ public class MultiUserChat {
|
|||
* @param reason the reason why the user is being invited.
|
||||
* @throws NotConnectedException if the XMPP connection is not connected.
|
||||
* @throws InterruptedException if the calling thread was interrupted.
|
||||
* @deprecated use {@link #invite(MessageBuilder, EntityBareJid, String)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove in Smack 4.5.
|
||||
public void invite(Message message, EntityBareJid user, String reason) throws NotConnectedException, InterruptedException {
|
||||
// TODO listen for 404 error code when inviter supplies a non-existent JID
|
||||
message.setTo(room);
|
||||
|
@ -957,6 +963,34 @@ public class MultiUserChat {
|
|||
connection.sendStanza(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invites another user to the room in which one is an occupant using a given Message. The invitation
|
||||
* will be sent to the room which in turn will forward the invitation to the invitee.<p>
|
||||
*
|
||||
* If the room is password-protected, the invitee will receive a password to use to join
|
||||
* the room. If the room is members-only, the the invitee may be added to the member list.
|
||||
*
|
||||
* @param messageBuilder the message to use for sending the invitation.
|
||||
* @param user the user to invite to the room.(e.g. hecate@shakespeare.lit)
|
||||
* @param reason the reason why the user is being invited.
|
||||
* @throws NotConnectedException if the XMPP connection is not connected.
|
||||
* @throws InterruptedException if the calling thread was interrupted.
|
||||
*/
|
||||
public void invite(MessageBuilder messageBuilder, EntityBareJid user, String reason) throws NotConnectedException, InterruptedException {
|
||||
// TODO listen for 404 error code when inviter supplies a non-existent JID
|
||||
messageBuilder.to(room);
|
||||
|
||||
// Create the MUCUser packet that will include the invitation
|
||||
MUCUser mucUser = new MUCUser();
|
||||
MUCUser.Invite invite = new MUCUser.Invite(reason, user);
|
||||
mucUser.setInvite(invite);
|
||||
// Add the MUCUser packet that includes the invitation to the message
|
||||
messageBuilder.addExtension(mucUser);
|
||||
|
||||
Message message = messageBuilder.build();
|
||||
connection.sendStanza(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a listener to invitation rejections notifications. The listener will be fired anytime
|
||||
* an invitation is declined.
|
||||
|
@ -1126,8 +1160,10 @@ public class MultiUserChat {
|
|||
// We change the nickname by sending a presence packet where the "to"
|
||||
// field is in the form "roomName@service/nickname"
|
||||
// We don't have to signal the MUC support again
|
||||
Presence joinPresence = new Presence(Presence.Type.available);
|
||||
joinPresence.setTo(jid);
|
||||
Presence joinPresence = connection.getStanzaFactory().buildPresenceStanza()
|
||||
.to(jid)
|
||||
.ofType(Presence.Type.available)
|
||||
.build();
|
||||
|
||||
// Wait for a presence packet back from the server.
|
||||
StanzaFilter responseFilter =
|
||||
|
@ -1167,10 +1203,12 @@ public class MultiUserChat {
|
|||
}
|
||||
// We change the availability status by sending a presence packet to the room with the
|
||||
// new presence status and mode
|
||||
Presence joinPresence = new Presence(Presence.Type.available);
|
||||
joinPresence.setStatus(status);
|
||||
joinPresence.setMode(mode);
|
||||
joinPresence.setTo(myRoomJid);
|
||||
Presence joinPresence = connection.getStanzaFactory().buildPresenceStanza()
|
||||
.to(myRoomJid)
|
||||
.ofType(Presence.Type.available)
|
||||
.setStatus(status)
|
||||
.setMode(mode)
|
||||
.build();
|
||||
|
||||
// Send join packet.
|
||||
connection.sendStanza(joinPresence);
|
||||
|
@ -1220,8 +1258,11 @@ public class MultiUserChat {
|
|||
requestVoiceField.setLabel("Requested role");
|
||||
requestVoiceField.addValue("participant");
|
||||
form.addField(requestVoiceField.build());
|
||||
Message message = new Message(room);
|
||||
message.addExtension(form);
|
||||
|
||||
Message message = connection.getStanzaFactory().buildMessageStanza()
|
||||
.to(room)
|
||||
.addExtension(form)
|
||||
.build();
|
||||
connection.sendStanza(message);
|
||||
}
|
||||
|
||||
|
@ -1887,8 +1928,9 @@ public class MultiUserChat {
|
|||
* @throws InterruptedException if the calling thread was interrupted.
|
||||
*/
|
||||
public void sendMessage(String text) throws NotConnectedException, InterruptedException {
|
||||
Message message = createMessage();
|
||||
message.setBody(text);
|
||||
Message message = buildMessage()
|
||||
.setBody(text)
|
||||
.build();
|
||||
connection.sendStanza(message);
|
||||
}
|
||||
|
||||
|
@ -1914,9 +1956,28 @@ public class MultiUserChat {
|
|||
* Creates a new Message to send to the chat room.
|
||||
*
|
||||
* @return a new Message addressed to the chat room.
|
||||
* @deprecated use {@link #buildMessage()} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove when stanza builder is ready.
|
||||
public Message createMessage() {
|
||||
return new Message(room, Message.Type.groupchat);
|
||||
return connection.getStanzaFactory().buildMessageStanza()
|
||||
.ofType(Message.Type.groupchat)
|
||||
.to(room)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new message builder for messages send to this MUC room.
|
||||
*
|
||||
* @return a new message builder.
|
||||
*/
|
||||
public MessageBuilder buildMessage() {
|
||||
return connection.getStanzaFactory()
|
||||
.buildMessageStanza()
|
||||
.ofType(Message.Type.groupchat)
|
||||
.to(room)
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1925,10 +1986,23 @@ public class MultiUserChat {
|
|||
* @param message the message.
|
||||
* @throws NotConnectedException if the XMPP connection is not connected.
|
||||
* @throws InterruptedException if the calling thread was interrupted.
|
||||
* @deprecated use {@link #sendMessage(MessageBuilder)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
// TODO: Remove in Smack 4.5.
|
||||
public void sendMessage(Message message) throws NotConnectedException, InterruptedException {
|
||||
message.setTo(room);
|
||||
message.setType(Message.Type.groupchat);
|
||||
sendMessage(message.asBuilder());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a Message to the chat room.
|
||||
*
|
||||
* @param messageBuilder the message.
|
||||
* @throws NotConnectedException if the XMPP connection is not connected.
|
||||
* @throws InterruptedException if the calling thread was interrupted.
|
||||
*/
|
||||
public void sendMessage(MessageBuilder messageBuilder) throws NotConnectedException, InterruptedException {
|
||||
Message message = messageBuilder.to(room).ofType(Message.Type.groupchat).build();
|
||||
connection.sendStanza(message);
|
||||
}
|
||||
|
||||
|
@ -2024,7 +2098,7 @@ public class MultiUserChat {
|
|||
* @throws InterruptedException if the calling thread was interrupted.
|
||||
*/
|
||||
public void changeSubject(final String subject) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
Message message = createMessage();
|
||||
MessageBuilder message = buildMessage();
|
||||
message.setSubject(subject);
|
||||
// Wait for an error or confirmation message back from the server.
|
||||
StanzaFilter responseFilter = new AndFilter(fromRoomGroupchatFilter, new StanzaFilter() {
|
||||
|
@ -2034,7 +2108,7 @@ public class MultiUserChat {
|
|||
return subject.equals(msg.getSubject());
|
||||
}
|
||||
});
|
||||
StanzaCollector response = connection.createStanzaCollectorAndSend(responseFilter, message);
|
||||
StanzaCollector response = connection.createStanzaCollectorAndSend(responseFilter, message.build());
|
||||
// Wait up to a certain number of seconds for a reply.
|
||||
response.nextResultOrThrow();
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ 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.util.Async;
|
||||
import org.jivesoftware.smack.util.CleaningWeakReferenceMap;
|
||||
|
@ -438,16 +439,18 @@ public final class MultiUserChatManager extends Manager {
|
|||
* @throws InterruptedException if the calling thread was interrupted.
|
||||
*/
|
||||
public void decline(EntityBareJid room, EntityBareJid inviter, String reason) throws NotConnectedException, InterruptedException {
|
||||
Message message = new Message(room);
|
||||
XMPPConnection connection = connection();
|
||||
|
||||
MessageBuilder messageBuilder = connection.getStanzaFactory().buildMessageStanza().to(room);
|
||||
|
||||
// Create the MUCUser packet that will include the rejection
|
||||
MUCUser mucUser = new MUCUser();
|
||||
MUCUser.Decline decline = new MUCUser.Decline(reason, inviter);
|
||||
mucUser.setDecline(decline);
|
||||
// Add the MUCUser packet that includes the rejection
|
||||
message.addExtension(mucUser);
|
||||
messageBuilder.addExtension(mucUser);
|
||||
|
||||
connection().sendStanza(message);
|
||||
connection.sendStanza(messageBuilder.build());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -193,8 +193,9 @@ public final class PingManager extends Manager {
|
|||
}
|
||||
};
|
||||
|
||||
Ping ping = new Ping(jid);
|
||||
connection().sendIqRequestAsync(ping, pongTimeout)
|
||||
XMPPConnection connection = connection();
|
||||
Ping ping = new Ping(connection, jid);
|
||||
connection.sendIqRequestAsync(ping, pongTimeout)
|
||||
.onSuccess(new SuccessCallback<IQ>() {
|
||||
@Override
|
||||
public void onSuccess(IQ result) {
|
||||
|
@ -233,7 +234,7 @@ public final class PingManager extends Manager {
|
|||
if (!connection.isAuthenticated()) {
|
||||
throw new NotConnectedException();
|
||||
}
|
||||
Ping ping = new Ping(jid);
|
||||
Ping ping = new Ping(connection, jid);
|
||||
try {
|
||||
connection.createStanzaCollectorAndSend(ping).nextResultOrThrow(pingTimeout);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2012-2015 Florian Schmaus
|
||||
* Copyright 2012-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,7 +16,9 @@
|
|||
*/
|
||||
package org.jivesoftware.smackx.ping.packet;
|
||||
|
||||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.IqBuilder;
|
||||
import org.jivesoftware.smack.packet.SimpleIQ;
|
||||
|
||||
import org.jxmpp.jid.Jid;
|
||||
|
@ -36,6 +38,18 @@ public class Ping extends SimpleIQ {
|
|||
setType(IQ.Type.get);
|
||||
}
|
||||
|
||||
public Ping(XMPPConnection connection, Jid to) {
|
||||
this(connection.getStanzaFactory().buildIqStanza(), to);
|
||||
}
|
||||
|
||||
public Ping(IqBuilder iqBuilder, Jid to) {
|
||||
super(iqBuilder.to(to).ofType(IQ.Type.get), ELEMENT, NAMESPACE);
|
||||
}
|
||||
|
||||
public Ping(IqBuilder iqBuilder) {
|
||||
super(iqBuilder, ELEMENT, NAMESPACE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an XMPP Pong for this Ping.
|
||||
*
|
||||
|
|
|
@ -39,6 +39,7 @@ import org.jivesoftware.smack.filter.StanzaFilter;
|
|||
import org.jivesoftware.smack.filter.StanzaTypeFilter;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.Stanza;
|
||||
import org.jivesoftware.smack.packet.StanzaBuilder;
|
||||
import org.jivesoftware.smack.roster.Roster;
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
|
||||
|
@ -342,8 +343,11 @@ public final class DeliveryReceiptManager extends Manager {
|
|||
if (StringUtils.isNullOrEmpty(stanzaId)) {
|
||||
return null;
|
||||
}
|
||||
Message message = new Message(messageWithReceiptRequest.getFrom(), messageWithReceiptRequest.getType());
|
||||
message.addExtension(new DeliveryReceipt(stanzaId));
|
||||
Message message = StanzaBuilder.buildMessage()
|
||||
.ofType(messageWithReceiptRequest.getType())
|
||||
.to(messageWithReceiptRequest.getFrom())
|
||||
.addExtension(new DeliveryReceipt(stanzaId))
|
||||
.build();
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.io.IOException;
|
|||
|
||||
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.XmlEnvironment;
|
||||
import org.jivesoftware.smack.provider.ExtensionElementProvider;
|
||||
|
@ -81,12 +82,28 @@ public class DeliveryReceiptRequest implements ExtensionElement {
|
|||
* @param message Message object to add a request to
|
||||
* @return the Message ID which will be used as receipt ID
|
||||
*/
|
||||
// TODO: Deprecate in favor of addTo(MessageBuilder) once connection's stanza interceptors use StanzaBuilder.
|
||||
public static String addTo(Message message) {
|
||||
message.ensureStanzaIdSet();
|
||||
message.throwIfNoStanzaId();
|
||||
|
||||
message.addExtension(new DeliveryReceiptRequest());
|
||||
return message.getStanzaId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a delivery receipt request to an outgoing packet.
|
||||
*
|
||||
* Only message packets may contain receipt requests as of XEP-0184,
|
||||
* therefore only allow Message as the parameter type.
|
||||
*
|
||||
* @param messageBuilder Message object to add a request to
|
||||
*/
|
||||
public static void addTo(MessageBuilder messageBuilder) {
|
||||
messageBuilder.throwIfNoStanzaId();
|
||||
|
||||
messageBuilder.overrideExtension(new DeliveryReceiptRequest());
|
||||
}
|
||||
|
||||
/**
|
||||
* This Provider parses and returns DeliveryReceiptRequest packets.
|
||||
*/
|
||||
|
|
|
@ -98,13 +98,15 @@ public final class VCardManager extends Manager {
|
|||
* @throws NotConnectedException if the XMPP connection is not connected.
|
||||
* @throws InterruptedException if the calling thread was interrupted.
|
||||
*/
|
||||
// TODO: Split VCard into VCardIq and VCardData, then create saveVCard(VCardData) and deprecate this method.
|
||||
@SuppressWarnings("deprecation")
|
||||
public void saveVCard(VCard vcard) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
// XEP-54 § 3.2 "A user may publish or update his or her vCard by sending an IQ of type "set" with no 'to' address…"
|
||||
vcard.setTo((Jid) null);
|
||||
vcard.setType(IQ.Type.set);
|
||||
// Also make sure to generate a new stanza id (the given vcard could be a vcard result), in which case we don't
|
||||
// want to use the same stanza id again (although it wouldn't break if we did)
|
||||
vcard.setNewStanzaId();
|
||||
vcard.setStanzaId();
|
||||
connection().createStanzaCollectorAndSend(vcard).nextResultOrThrow();
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ public class IBBPacketUtils {
|
|||
* @return an error IQ
|
||||
*/
|
||||
public static IQ createErrorIQ(Jid from, Jid to, StanzaError.Condition condition) {
|
||||
StanzaError.Builder xmppError = StanzaError.getBuilder(condition);
|
||||
StanzaError xmppError = StanzaError.getBuilder(condition).build();
|
||||
IQ errorIQ = new ErrorIQ(xmppError);
|
||||
errorIQ.setType(IQ.Type.error);
|
||||
errorIQ.setFrom(from);
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.jivesoftware.smack.XMPPConnection;
|
|||
import org.jivesoftware.smack.XMPPException;
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.StanzaBuilder;
|
||||
import org.jivesoftware.smack.util.stringencoder.Base64;
|
||||
|
||||
import org.jivesoftware.smackx.InitExtensions;
|
||||
|
@ -266,8 +267,9 @@ public class InBandBytestreamSessionMessageTest extends InitExtensions {
|
|||
// build invalid packet with out of order sequence
|
||||
String base64Data = Base64.encode("Data");
|
||||
DataPacketExtension dpe = new DataPacketExtension(sessionID, 123, base64Data);
|
||||
Message dataMessage = new Message();
|
||||
dataMessage.addExtension(dpe);
|
||||
Message dataMessage = StanzaBuilder.buildMessage()
|
||||
.addExtension(dpe)
|
||||
.build();
|
||||
|
||||
// add data packets
|
||||
listener.processStanza(dataMessage);
|
||||
|
@ -307,8 +309,9 @@ public class InBandBytestreamSessionMessageTest extends InitExtensions {
|
|||
for (int i = 0; i < controlData.length / blockSize; i++) {
|
||||
String base64Data = Base64.encodeToString(controlData, i * blockSize, blockSize);
|
||||
DataPacketExtension dpe = new DataPacketExtension(sessionID, i, base64Data);
|
||||
Message dataMessage = new Message();
|
||||
dataMessage.addExtension(dpe);
|
||||
Message dataMessage = StanzaBuilder.buildMessage()
|
||||
.addExtension(dpe)
|
||||
.build();
|
||||
listener.processStanza(dataMessage);
|
||||
}
|
||||
|
||||
|
@ -352,8 +355,9 @@ public class InBandBytestreamSessionMessageTest extends InitExtensions {
|
|||
for (int i = 0; i < controlData.length / blockSize; i++) {
|
||||
String base64Data = Base64.encodeToString(controlData, i * blockSize, blockSize);
|
||||
DataPacketExtension dpe = new DataPacketExtension(sessionID, i, base64Data);
|
||||
Message dataMessage = new Message();
|
||||
dataMessage.addExtension(dpe);
|
||||
Message dataMessage = StanzaBuilder.buildMessage()
|
||||
.addExtension(dpe)
|
||||
.build();
|
||||
listener.processStanza(dataMessage);
|
||||
}
|
||||
|
||||
|
|
|
@ -413,8 +413,8 @@ public class Socks5ByteStreamManagerTest {
|
|||
Verification.requestTypeGET);
|
||||
|
||||
// build error packet to reject SOCKS5 Bytestream
|
||||
StanzaError.Builder builder = StanzaError.getBuilder(StanzaError.Condition.not_acceptable);
|
||||
IQ rejectPacket = new ErrorIQ(builder);
|
||||
StanzaError stanzaError = StanzaError.getBuilder(StanzaError.Condition.not_acceptable).build();
|
||||
IQ rejectPacket = new ErrorIQ(stanzaError);
|
||||
rejectPacket.setFrom(targetJID);
|
||||
rejectPacket.setTo(initiatorJID);
|
||||
|
||||
|
|
|
@ -184,7 +184,7 @@ public class Socks5ClientForInitiatorTest {
|
|||
XMPPConnection connection = ConnectionUtils.createMockedConnection(protocol, initiatorJID);
|
||||
|
||||
// build error response as reply to the stream activation
|
||||
IQ error = new ErrorIQ(StanzaError.getBuilder(StanzaError.Condition.internal_server_error));
|
||||
IQ error = new ErrorIQ(StanzaError.getBuilder(StanzaError.Condition.internal_server_error).build());
|
||||
error.setFrom(proxyJID);
|
||||
error.setTo(initiatorJID);
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import static org.jivesoftware.smack.test.util.XmlUnitUtils.assertXmlSimilar;
|
|||
import java.util.Date;
|
||||
|
||||
import org.jivesoftware.smack.packet.Presence;
|
||||
import org.jivesoftware.smack.packet.StanzaBuilder;
|
||||
import org.jivesoftware.smack.test.util.SmackTestSuite;
|
||||
import org.jivesoftware.smack.test.util.TestUtils;
|
||||
import org.jivesoftware.smack.xml.XmlPullParser;
|
||||
|
@ -50,7 +51,9 @@ public class IdleTest extends SmackTestSuite {
|
|||
|
||||
@Test
|
||||
public void helperTest() {
|
||||
Presence presence = new Presence(Presence.Type.available);
|
||||
Presence presence = StanzaBuilder.buildPresence()
|
||||
.ofType(Presence.Type.available)
|
||||
.build();
|
||||
IdleElement.addToPresence(presence);
|
||||
IdleElement element = IdleElement.fromPresence(presence);
|
||||
assertNotNull(element);
|
||||
|
|
|
@ -22,6 +22,7 @@ import static junit.framework.TestCase.assertNotNull;
|
|||
import static junit.framework.TestCase.assertTrue;
|
||||
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.StanzaBuilder;
|
||||
import org.jivesoftware.smack.test.util.SmackTestSuite;
|
||||
|
||||
import org.jivesoftware.smackx.mood.element.MoodElement;
|
||||
|
@ -32,7 +33,7 @@ public class MoodManagerTest extends SmackTestSuite {
|
|||
|
||||
@Test
|
||||
public void addMessageTest() {
|
||||
Message message = new Message();
|
||||
Message message = StanzaBuilder.buildMessage().build();
|
||||
MoodManager.addMoodToMessage(message, Mood.sad);
|
||||
|
||||
assertTrue(message.hasExtension(MoodElement.ELEMENT, MoodElement.NAMESPACE));
|
||||
|
@ -43,7 +44,7 @@ public class MoodManagerTest extends SmackTestSuite {
|
|||
assertFalse(element.hasConcretisation());
|
||||
assertFalse(element.hasText());
|
||||
|
||||
message = new Message();
|
||||
message = StanzaBuilder.buildMessage().build();
|
||||
MoodManager.addMoodToMessage(message, Mood.happy, new MoodConcretisationTest.EcstaticMoodConcretisation());
|
||||
element = MoodElement.fromMessage(message);
|
||||
assertTrue(element.hasConcretisation());
|
||||
|
|
|
@ -67,7 +67,7 @@ public class ConfigureFormTest extends InitExtensions {
|
|||
PubSub errorIq = new PubSub();
|
||||
errorIq.setType(Type.error);
|
||||
errorIq.setFrom(PubSubManagerTest.DUMMY_PUBSUB_SERVICE);
|
||||
StanzaError.Builder error = StanzaError.getBuilder(Condition.forbidden);
|
||||
StanzaError error = StanzaError.getBuilder(Condition.forbidden).build();
|
||||
errorIq.setError(error);
|
||||
con.addIQReply(errorIq);
|
||||
|
||||
|
|
|
@ -27,7 +27,9 @@ import java.util.Properties;
|
|||
|
||||
import org.jivesoftware.smack.DummyConnection;
|
||||
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.test.util.WaitForPacketListener;
|
||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||
import org.jivesoftware.smack.xml.XmlPullParser;
|
||||
|
@ -38,7 +40,6 @@ import org.jivesoftware.smackx.receipts.DeliveryReceiptManager.AutoReceiptMode;
|
|||
import com.jamesmurty.utils.XMLBuilder;
|
||||
import org.junit.Test;
|
||||
import org.jxmpp.jid.Jid;
|
||||
import org.jxmpp.jid.impl.JidCreate;
|
||||
|
||||
public class DeliveryReceiptTest extends InitExtensions {
|
||||
|
||||
|
@ -66,10 +67,13 @@ public class DeliveryReceiptTest extends InitExtensions {
|
|||
|
||||
assertTrue(DeliveryReceiptManager.hasDeliveryReceiptRequest(p));
|
||||
|
||||
Message m = new Message(JidCreate.from("romeo@montague.com"), Message.Type.normal);
|
||||
assertFalse(DeliveryReceiptManager.hasDeliveryReceiptRequest(m));
|
||||
DeliveryReceiptRequest.addTo(m);
|
||||
assertTrue(DeliveryReceiptManager.hasDeliveryReceiptRequest(m));
|
||||
MessageBuilder messageBuilder = StanzaBuilder.buildMessage("request-id")
|
||||
.to("romeo@montague.com")
|
||||
.ofType(Message.Type.normal)
|
||||
;
|
||||
assertFalse(DeliveryReceiptManager.hasDeliveryReceiptRequest(messageBuilder.build()));
|
||||
DeliveryReceiptRequest.addTo(messageBuilder);
|
||||
assertTrue(DeliveryReceiptManager.hasDeliveryReceiptRequest(messageBuilder.build()));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -81,10 +85,12 @@ public class DeliveryReceiptTest extends InitExtensions {
|
|||
TestReceiptReceivedListener rrl = new TestReceiptReceivedListener();
|
||||
drm.addReceiptReceivedListener(rrl);
|
||||
|
||||
Message m = new Message(JidCreate.from("romeo@montague.com"), Message.Type.normal);
|
||||
m.setFrom(JidCreate.from("julia@capulet.com"));
|
||||
m.setStanzaId("reply-id");
|
||||
m.addExtension(new DeliveryReceipt("original-test-id"));
|
||||
Message m = StanzaBuilder.buildMessage("reply-id")
|
||||
.from("julia@capulet.com")
|
||||
.to("romeo@montague.com")
|
||||
.ofType(Message.Type.normal)
|
||||
.addExtension(new DeliveryReceipt("original-test-id"))
|
||||
.build();
|
||||
c.processStanza(m);
|
||||
|
||||
rrl.waitUntilInvocationOrTimeout();
|
||||
|
@ -110,13 +116,15 @@ public class DeliveryReceiptTest extends InitExtensions {
|
|||
assertEquals(AutoReceiptMode.always, drm.getAutoReceiptMode());
|
||||
|
||||
// test auto-receipts
|
||||
Message m = new Message(JidCreate.from("julia@capulet.com"), Message.Type.normal);
|
||||
m.setFrom(JidCreate.from("romeo@montague.com"));
|
||||
m.setStanzaId("test-receipt-request");
|
||||
DeliveryReceiptRequest.addTo(m);
|
||||
MessageBuilder messageBuilder = StanzaBuilder.buildMessage("test-receipt-request")
|
||||
.to("julia@capulet.com")
|
||||
.from("romeo@montague.com")
|
||||
.ofType(Message.Type.normal)
|
||||
;
|
||||
DeliveryReceiptRequest.addTo(messageBuilder);
|
||||
|
||||
// the DRM will send a reply-packet
|
||||
c.processStanza(m);
|
||||
c.processStanza(messageBuilder.build());
|
||||
|
||||
Stanza reply = c.getSentPacket();
|
||||
DeliveryReceipt r = DeliveryReceipt.from((Message) reply);
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.net.URI;
|
|||
import java.net.URISyntaxException;
|
||||
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.StanzaBuilder;
|
||||
import org.jivesoftware.smack.test.util.SmackTestSuite;
|
||||
import org.jivesoftware.smackx.usertune.element.UserTuneElement;
|
||||
|
||||
|
@ -45,8 +46,9 @@ public class UserTuneManagerTest extends SmackTestSuite{
|
|||
builder.setUri(uri);
|
||||
UserTuneElement userTuneElement = builder.build();
|
||||
|
||||
Message message = new Message();
|
||||
message.addExtension(userTuneElement);
|
||||
Message message = StanzaBuilder.buildMessage()
|
||||
.addExtension(userTuneElement)
|
||||
.build();
|
||||
|
||||
assertTrue(message.hasExtension(UserTuneElement.ELEMENT, UserTuneElement.NAMESPACE));
|
||||
assertTrue(UserTuneElement.hasUserTuneElement(message));
|
||||
|
|
|
@ -24,6 +24,8 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
||||
import org.jivesoftware.smack.StanzaCollector;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.MessageBuilder;
|
||||
import org.jivesoftware.smack.packet.StanzaBuilder;
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
|
||||
import org.jxmpp.jid.EntityJid;
|
||||
|
@ -98,11 +100,28 @@ public class Chat {
|
|||
* @throws InterruptedException if the calling thread was interrupted.
|
||||
*/
|
||||
public void sendMessage(String text) throws NotConnectedException, InterruptedException {
|
||||
Message message = new Message();
|
||||
message.setBody(text);
|
||||
MessageBuilder message = StanzaBuilder.buildMessage()
|
||||
.setBody(text);
|
||||
sendMessage(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message to the other chat participant. The thread ID, recipient,
|
||||
* and message type of the message will automatically set to those of this chat.
|
||||
*
|
||||
* @param message the message to send.
|
||||
* @throws NotConnectedException if the XMPP connection is not connected.
|
||||
* @throws InterruptedException if the calling thread was interrupted.
|
||||
*/
|
||||
public void sendMessage(MessageBuilder message) throws NotConnectedException, InterruptedException {
|
||||
// Force the recipient, message type, and thread ID since the user elected
|
||||
// to send the message through this chat object.
|
||||
message.to(participant);
|
||||
message.ofType(Message.Type.chat);
|
||||
message.setThread(threadID);
|
||||
chatManager.sendMessage(this, message.build());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message to the other chat participant. The thread ID, recipient,
|
||||
* and message type of the message will automatically set to those of this chat.
|
||||
|
|
|
@ -56,7 +56,9 @@ import org.jivesoftware.smack.iqrequest.AbstractIqRequestHandler;
|
|||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.IQ.Type;
|
||||
import org.jivesoftware.smack.packet.Presence;
|
||||
import org.jivesoftware.smack.packet.PresenceBuilder;
|
||||
import org.jivesoftware.smack.packet.Stanza;
|
||||
import org.jivesoftware.smack.packet.StanzaBuilder;
|
||||
import org.jivesoftware.smack.packet.StanzaError.Condition;
|
||||
import org.jivesoftware.smack.roster.SubscribeListener.SubscribeAnswer;
|
||||
import org.jivesoftware.smack.roster.packet.RosterPacket;
|
||||
|
@ -286,23 +288,26 @@ public final class Roster extends Manager {
|
|||
return;
|
||||
}
|
||||
|
||||
Presence response;
|
||||
Presence.Type type;
|
||||
switch (subscribeAnswer) {
|
||||
case ApproveAndAlsoRequestIfRequired:
|
||||
BareJid bareFrom = from.asBareJid();
|
||||
RosterUtil.askForSubscriptionIfRequired(Roster.this, bareFrom);
|
||||
// The fall through is intended.
|
||||
case Approve:
|
||||
response = new Presence(Presence.Type.subscribed);
|
||||
type = Presence.Type.subscribed;
|
||||
break;
|
||||
case Deny:
|
||||
response = new Presence(Presence.Type.unsubscribed);
|
||||
type = Presence.Type.unsubscribed;
|
||||
break;
|
||||
default:
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
response.setTo(presence.getFrom());
|
||||
Presence response = connection.getStanzaFactory().buildPresenceStanza()
|
||||
.ofType(type)
|
||||
.to(presence.getFrom())
|
||||
.build();
|
||||
connection.sendStanza(response);
|
||||
}
|
||||
}, PresenceTypeFilter.SUBSCRIBE);
|
||||
|
@ -747,8 +752,10 @@ public final class Roster extends Manager {
|
|||
throw new FeatureNotSupportedException("Pre-approving");
|
||||
}
|
||||
|
||||
Presence presencePacket = new Presence(Presence.Type.subscribed);
|
||||
presencePacket.setTo(user);
|
||||
Presence presencePacket = connection.getStanzaFactory().buildPresenceStanza()
|
||||
.ofType(Presence.Type.subscribed)
|
||||
.to(user)
|
||||
.build();
|
||||
connection.sendStanza(presencePacket);
|
||||
}
|
||||
|
||||
|
@ -768,8 +775,10 @@ public final class Roster extends Manager {
|
|||
final XMPPConnection connection = getAuthenticatedConnectionOrThrow();
|
||||
|
||||
// Create a presence subscription packet and send.
|
||||
Presence presencePacket = new Presence(Presence.Type.subscribe);
|
||||
presencePacket.setTo(jid);
|
||||
Presence presencePacket = connection.getStanzaFactory().buildPresenceStanza()
|
||||
.ofType(Presence.Type.subscribe)
|
||||
.to(jid)
|
||||
.build();
|
||||
connection.sendStanza(presencePacket);
|
||||
}
|
||||
|
||||
|
@ -1000,8 +1009,7 @@ public final class Roster extends Manager {
|
|||
public Presence getPresence(BareJid jid) {
|
||||
Map<Resourcepart, Presence> userPresences = getPresencesInternal(jid);
|
||||
if (userPresences == null) {
|
||||
Presence presence = new Presence(Presence.Type.unavailable);
|
||||
presence.setFrom(jid);
|
||||
Presence presence = synthesizeUnvailablePresence(jid);
|
||||
return presence;
|
||||
}
|
||||
else {
|
||||
|
@ -1042,8 +1050,7 @@ public final class Roster extends Manager {
|
|||
return unavailable.clone();
|
||||
}
|
||||
else {
|
||||
presence = new Presence(Presence.Type.unavailable);
|
||||
presence.setFrom(jid);
|
||||
presence = synthesizeUnvailablePresence(jid);
|
||||
return presence;
|
||||
}
|
||||
}
|
||||
|
@ -1067,15 +1074,13 @@ public final class Roster extends Manager {
|
|||
Resourcepart resource = userWithResource.getResourcepart();
|
||||
Map<Resourcepart, Presence> userPresences = getPresencesInternal(key);
|
||||
if (userPresences == null) {
|
||||
Presence presence = new Presence(Presence.Type.unavailable);
|
||||
presence.setFrom(userWithResource);
|
||||
Presence presence = synthesizeUnvailablePresence(userWithResource);
|
||||
return presence;
|
||||
}
|
||||
else {
|
||||
Presence presence = userPresences.get(resource);
|
||||
if (presence == null) {
|
||||
presence = new Presence(Presence.Type.unavailable);
|
||||
presence.setFrom(userWithResource);
|
||||
presence = synthesizeUnvailablePresence(userWithResource);
|
||||
return presence;
|
||||
}
|
||||
else {
|
||||
|
@ -1097,8 +1102,7 @@ public final class Roster extends Manager {
|
|||
List<Presence> res;
|
||||
if (userPresences == null) {
|
||||
// Create an unavailable presence if none was found
|
||||
Presence unavailable = new Presence(Presence.Type.unavailable);
|
||||
unavailable.setFrom(bareJid);
|
||||
Presence unavailable = synthesizeUnvailablePresence(bareJid);
|
||||
res = new ArrayList<>(Arrays.asList(unavailable));
|
||||
} else {
|
||||
res = new ArrayList<>(userPresences.values().size());
|
||||
|
@ -1143,8 +1147,7 @@ public final class Roster extends Manager {
|
|||
List<Presence> res;
|
||||
Map<Resourcepart, Presence> userPresences = getPresencesInternal(jid);
|
||||
if (userPresences == null) {
|
||||
Presence presence = new Presence(Presence.Type.unavailable);
|
||||
presence.setFrom(jid);
|
||||
Presence presence = synthesizeUnvailablePresence(jid);
|
||||
res = Arrays.asList(presence);
|
||||
}
|
||||
else {
|
||||
|
@ -1166,8 +1169,7 @@ public final class Roster extends Manager {
|
|||
res = Arrays.asList(unavailable.clone());
|
||||
}
|
||||
else {
|
||||
Presence presence = new Presence(Presence.Type.unavailable);
|
||||
presence.setFrom(jid);
|
||||
Presence presence = synthesizeUnvailablePresence(jid);
|
||||
res = Arrays.asList(presence);
|
||||
}
|
||||
}
|
||||
|
@ -1266,20 +1268,20 @@ public final class Roster extends Manager {
|
|||
* presence sent from the server.
|
||||
*/
|
||||
private void setOfflinePresences() {
|
||||
Presence packetUnavailable;
|
||||
outerloop: for (Jid user : presenceMap.keySet()) {
|
||||
Map<Resourcepart, Presence> resources = presenceMap.get(user);
|
||||
if (resources != null) {
|
||||
for (Resourcepart resource : resources.keySet()) {
|
||||
packetUnavailable = new Presence(Presence.Type.unavailable);
|
||||
PresenceBuilder presenceBuilder = StanzaBuilder.buildPresence()
|
||||
.ofType(Presence.Type.unavailable);
|
||||
EntityBareJid bareUserJid = user.asEntityBareJidIfPossible();
|
||||
if (bareUserJid == null) {
|
||||
LOGGER.warning("Can not transform user JID to bare JID: '" + user + "'");
|
||||
continue;
|
||||
}
|
||||
packetUnavailable.setFrom(JidCreate.fullFrom(bareUserJid, resource));
|
||||
presenceBuilder.from(JidCreate.fullFrom(bareUserJid, resource));
|
||||
try {
|
||||
presencePacketListener.processStanza(packetUnavailable);
|
||||
presencePacketListener.processStanza(presenceBuilder.build());
|
||||
}
|
||||
catch (NotConnectedException e) {
|
||||
throw new IllegalStateException(
|
||||
|
@ -1471,6 +1473,13 @@ public final class Roster extends Manager {
|
|||
}
|
||||
}
|
||||
|
||||
private static Presence synthesizeUnvailablePresence(Jid from) {
|
||||
return StanzaBuilder.buildPresence()
|
||||
.ofType(Presence.Type.unavailable)
|
||||
.from(from)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the server supports roster versioning.
|
||||
*
|
||||
|
|
|
@ -218,8 +218,12 @@ public final class RosterEntry extends Manager {
|
|||
* @since 4.2
|
||||
*/
|
||||
public void cancelSubscription() throws NotConnectedException, InterruptedException {
|
||||
Presence unsubscribed = new Presence(item.getJid(), Type.unsubscribed);
|
||||
connection().sendStanza(unsubscribed);
|
||||
XMPPConnection connection = connection();
|
||||
Presence unsubscribed = connection.getStanzaFactory().buildPresenceStanza()
|
||||
.to(item.getJid())
|
||||
.ofType(Type.unsubscribed)
|
||||
.build();
|
||||
connection.sendStanza(unsubscribed);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,7 +19,6 @@ package org.jivesoftware.smack.roster.provider;
|
|||
import org.jivesoftware.smack.packet.XmlEnvironment;
|
||||
import org.jivesoftware.smack.provider.ExtensionElementProvider;
|
||||
import org.jivesoftware.smack.roster.packet.RosterVer;
|
||||
|
||||
import org.jivesoftware.smack.xml.XmlPullParser;
|
||||
|
||||
public class RosterVerStreamFeatureProvider extends ExtensionElementProvider<RosterVer> {
|
||||
|
|
|
@ -19,7 +19,6 @@ package org.jivesoftware.smack.roster.provider;
|
|||
import org.jivesoftware.smack.packet.XmlEnvironment;
|
||||
import org.jivesoftware.smack.provider.ExtensionElementProvider;
|
||||
import org.jivesoftware.smack.roster.packet.SubscriptionPreApproval;
|
||||
|
||||
import org.jivesoftware.smack.xml.XmlPullParser;
|
||||
|
||||
public class SubscriptionPreApprovalStreamFeatureProvider extends ExtensionElementProvider<SubscriptionPreApproval> {
|
||||
|
|
|
@ -25,7 +25,9 @@ import static org.junit.Assert.assertTrue;
|
|||
import org.jivesoftware.smack.DummyConnection;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.Message.Type;
|
||||
import org.jivesoftware.smack.packet.MessageBuilder;
|
||||
import org.jivesoftware.smack.packet.Stanza;
|
||||
import org.jivesoftware.smack.packet.StanzaBuilder;
|
||||
import org.jivesoftware.smack.test.util.WaitForPacketListener;
|
||||
|
||||
import org.junit.After;
|
||||
|
@ -89,49 +91,49 @@ public class ChatConnectionTest {
|
|||
|
||||
@Test
|
||||
public void validateMessageTypeWithDefaults1() {
|
||||
Message incomingChat = createChatPacket("134", true);
|
||||
incomingChat.setType(Type.chat);
|
||||
processServerMessage(incomingChat);
|
||||
MessageBuilder incomingChat = createChatPacket("134", true);
|
||||
incomingChat.ofType(Type.chat);
|
||||
processServerMessage(incomingChat.build());
|
||||
assertNotNull(listener.getNewChat());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateMessageTypeWithDefaults2() {
|
||||
Message incomingChat = createChatPacket("134", true);
|
||||
incomingChat.setType(Type.normal);
|
||||
processServerMessage(incomingChat);
|
||||
MessageBuilder incomingChat = createChatPacket("134", true);
|
||||
incomingChat.ofType(Type.normal);
|
||||
processServerMessage(incomingChat.build());
|
||||
assertNotNull(listener.getNewChat());
|
||||
}
|
||||
@Test
|
||||
public void validateMessageTypeWithDefaults3() {
|
||||
Message incomingChat = createChatPacket("134", true);
|
||||
incomingChat.setType(Type.groupchat);
|
||||
processServerMessage(incomingChat);
|
||||
MessageBuilder incomingChat = createChatPacket("134", true);
|
||||
incomingChat.ofType(Type.groupchat);
|
||||
processServerMessage(incomingChat.build());
|
||||
assertNull(listener.getNewChat());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateMessageTypeWithDefaults4() {
|
||||
Message incomingChat = createChatPacket("134", true);
|
||||
incomingChat.setType(Type.headline);
|
||||
MessageBuilder incomingChat = createChatPacket("134", true);
|
||||
incomingChat.ofType(Type.headline);
|
||||
assertNull(listener.getNewChat());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateMessageTypeWithNoNormal1() {
|
||||
cm.setNormalIncluded(false);
|
||||
Message incomingChat = createChatPacket("134", true);
|
||||
incomingChat.setType(Type.chat);
|
||||
processServerMessage(incomingChat);
|
||||
MessageBuilder incomingChat = createChatPacket("134", true);
|
||||
incomingChat.ofType(Type.chat);
|
||||
processServerMessage(incomingChat.build());
|
||||
assertNotNull(listener.getNewChat());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateMessageTypeWithNoNormal2() {
|
||||
cm.setNormalIncluded(false);
|
||||
Message incomingChat = createChatPacket("134", true);
|
||||
incomingChat.setType(Type.normal);
|
||||
processServerMessage(incomingChat);
|
||||
MessageBuilder incomingChat = createChatPacket("134", true);
|
||||
incomingChat.ofType(Type.normal);
|
||||
processServerMessage(incomingChat.build());
|
||||
assertNull(listener.getNewChat());
|
||||
}
|
||||
|
||||
|
@ -142,18 +144,18 @@ public class ChatConnectionTest {
|
|||
TestMessageListener msgListener = new TestMessageListener();
|
||||
TestChatManagerListener listener = new TestChatManagerListener(msgListener);
|
||||
cm.addChatListener(listener);
|
||||
Stanza incomingChat = createChatPacket(null, true);
|
||||
Stanza incomingChat = createChatMessage(null, true);
|
||||
processServerMessage(incomingChat);
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
|
||||
// Should match on chat with full jid
|
||||
incomingChat = createChatPacket(null, true);
|
||||
incomingChat = createChatMessage(null, true);
|
||||
processServerMessage(incomingChat);
|
||||
assertEquals(2, msgListener.getNumMessages());
|
||||
|
||||
// Should match on chat with bare jid
|
||||
incomingChat = createChatPacket(null, false);
|
||||
incomingChat = createChatMessage(null, false);
|
||||
processServerMessage(incomingChat);
|
||||
assertEquals(3, msgListener.getNumMessages());
|
||||
}
|
||||
|
@ -164,21 +166,21 @@ public class ChatConnectionTest {
|
|||
TestChatManagerListener listener = new TestChatManagerListener(msgListener);
|
||||
cm.setMatchMode(ChatManager.MatchMode.SUPPLIED_JID);
|
||||
cm.addChatListener(listener);
|
||||
Stanza incomingChat = createChatPacket(null, true);
|
||||
Stanza incomingChat = createChatMessage(null, true);
|
||||
processServerMessage(incomingChat);
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
cm.removeChatListener(listener);
|
||||
|
||||
// Should match on chat with full jid
|
||||
incomingChat = createChatPacket(null, true);
|
||||
incomingChat = createChatMessage(null, true);
|
||||
processServerMessage(incomingChat);
|
||||
assertEquals(2, msgListener.getNumMessages());
|
||||
|
||||
// Should not match on chat with bare jid
|
||||
TestChatManagerListener listener2 = new TestChatManagerListener();
|
||||
cm.addChatListener(listener2);
|
||||
incomingChat = createChatPacket(null, false);
|
||||
incomingChat = createChatMessage(null, false);
|
||||
processServerMessage(incomingChat);
|
||||
assertEquals(2, msgListener.getNumMessages());
|
||||
assertNotNull(listener2.getNewChat());
|
||||
|
@ -190,7 +192,7 @@ public class ChatConnectionTest {
|
|||
TestChatManagerListener listener = new TestChatManagerListener(msgListener);
|
||||
cm.setMatchMode(ChatManager.MatchMode.NONE);
|
||||
cm.addChatListener(listener);
|
||||
Stanza incomingChat = createChatPacket(null, true);
|
||||
Stanza incomingChat = createChatMessage(null, true);
|
||||
processServerMessage(incomingChat);
|
||||
Chat newChat = listener.getNewChat();
|
||||
assertNotNull(newChat);
|
||||
|
@ -200,7 +202,7 @@ public class ChatConnectionTest {
|
|||
// Should not match on chat with full jid
|
||||
TestChatManagerListener listener2 = new TestChatManagerListener();
|
||||
cm.addChatListener(listener2);
|
||||
incomingChat = createChatPacket(null, true);
|
||||
incomingChat = createChatMessage(null, true);
|
||||
processServerMessage(incomingChat);
|
||||
assertEquals(1, msgListener.getNumMessages());
|
||||
assertNotNull(newChat);
|
||||
|
@ -209,7 +211,7 @@ public class ChatConnectionTest {
|
|||
// Should not match on chat with bare jid
|
||||
TestChatManagerListener listener3 = new TestChatManagerListener();
|
||||
cm.addChatListener(listener3);
|
||||
incomingChat = createChatPacket(null, false);
|
||||
incomingChat = createChatMessage(null, false);
|
||||
processServerMessage(incomingChat);
|
||||
assertEquals(1, msgListener.getNumMessages());
|
||||
assertNotNull(listener3.getNewChat());
|
||||
|
@ -223,7 +225,7 @@ public class ChatConnectionTest {
|
|||
public void chatFoundWhenNoThreadEntityFullJid() {
|
||||
Chat outgoing = cm.createChat(JidTestUtil.DUMMY_AT_EXAMPLE_ORG, null);
|
||||
|
||||
Stanza incomingChat = createChatPacket(null, true);
|
||||
Stanza incomingChat = createChatMessage(null, true);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
Chat newChat = listener.getNewChat();
|
||||
|
@ -239,7 +241,7 @@ public class ChatConnectionTest {
|
|||
public void chatFoundWhenNoThreadBaseJid() {
|
||||
Chat outgoing = cm.createChat(JidTestUtil.DUMMY_AT_EXAMPLE_ORG, null);
|
||||
|
||||
Stanza incomingChat = createChatPacket(null, false);
|
||||
Stanza incomingChat = createChatMessage(null, false);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
Chat newChat = listener.getNewChat();
|
||||
|
@ -255,7 +257,7 @@ public class ChatConnectionTest {
|
|||
public void chatFoundWithSameThreadEntityFullJid() {
|
||||
Chat outgoing = cm.createChat(JidTestUtil.DUMMY_AT_EXAMPLE_ORG, null);
|
||||
|
||||
Stanza incomingChat = createChatPacket(outgoing.getThreadID(), true);
|
||||
Stanza incomingChat = createChatMessage(outgoing.getThreadID(), true);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
Chat newChat = listener.getNewChat();
|
||||
|
@ -271,7 +273,7 @@ public class ChatConnectionTest {
|
|||
public void chatFoundWithSameThreadBaseJid() {
|
||||
Chat outgoing = cm.createChat(JidTestUtil.DUMMY_AT_EXAMPLE_ORG, null);
|
||||
|
||||
Stanza incomingChat = createChatPacket(outgoing.getThreadID(), false);
|
||||
Stanza incomingChat = createChatMessage(outgoing.getThreadID(), false);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
Chat newChat = listener.getNewChat();
|
||||
|
@ -287,7 +289,7 @@ public class ChatConnectionTest {
|
|||
public void chatNotFoundWithDiffThreadBaseJid() {
|
||||
Chat outgoing = cm.createChat(JidTestUtil.DUMMY_AT_EXAMPLE_ORG, null);
|
||||
|
||||
Stanza incomingChat = createChatPacket(outgoing.getThreadID() + "ff", false);
|
||||
Stanza incomingChat = createChatMessage(outgoing.getThreadID() + "ff", false);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
Chat newChat = listener.getNewChat();
|
||||
|
@ -303,7 +305,7 @@ public class ChatConnectionTest {
|
|||
public void chatNotFoundWithDiffThreadEntityFullJid() {
|
||||
Chat outgoing = cm.createChat(JidTestUtil.DUMMY_AT_EXAMPLE_ORG, null);
|
||||
|
||||
Stanza incomingChat = createChatPacket(outgoing.getThreadID() + "ff", true);
|
||||
Stanza incomingChat = createChatMessage(outgoing.getThreadID() + "ff", true);
|
||||
processServerMessage(incomingChat);
|
||||
|
||||
Chat newChat = listener.getNewChat();
|
||||
|
@ -315,15 +317,17 @@ public class ChatConnectionTest {
|
|||
public void chatNotMatchedWithTypeNormal() {
|
||||
cm.setNormalIncluded(false);
|
||||
|
||||
Message incomingChat = createChatPacket(null, false);
|
||||
incomingChat.setType(Type.normal);
|
||||
processServerMessage(incomingChat);
|
||||
MessageBuilder incomingChat = createChatPacket(null, false);
|
||||
incomingChat.ofType(Type.normal);
|
||||
processServerMessage(incomingChat.build());
|
||||
|
||||
assertNull(listener.getNewChat());
|
||||
}
|
||||
|
||||
private static Message createChatPacket(final String threadId, final boolean isEntityFullJid) {
|
||||
Message chatMsg = new Message(JidTestUtil.BARE_JID_1, Message.Type.chat);
|
||||
private static MessageBuilder createChatPacket(final String threadId, final boolean isEntityFullJid) {
|
||||
MessageBuilder chatMsg = StanzaBuilder.buildMessage()
|
||||
.ofType(Message.Type.chat)
|
||||
.to(JidTestUtil.BARE_JID_1);
|
||||
chatMsg.setBody("the body message - " + System.currentTimeMillis());
|
||||
Jid jid;
|
||||
if (isEntityFullJid) {
|
||||
|
@ -331,11 +335,15 @@ public class ChatConnectionTest {
|
|||
} else {
|
||||
jid = JidTestUtil.DUMMY_AT_EXAMPLE_ORG;
|
||||
}
|
||||
chatMsg.setFrom(jid);
|
||||
chatMsg.from(jid);
|
||||
chatMsg.setThread(threadId);
|
||||
return chatMsg;
|
||||
}
|
||||
|
||||
private static Message createChatMessage(final String threadId, final boolean isEntityFullJid) {
|
||||
return createChatPacket(threadId, isEntityFullJid).build();
|
||||
}
|
||||
|
||||
private void processServerMessage(Stanza incomingChat) {
|
||||
TestChatServer chatServer = new TestChatServer(incomingChat, dc);
|
||||
chatServer.start();
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue