From 5db6191110ba7ed2e08f91b7653a4911dbeaa990 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Thu, 24 Oct 2019 15:45:08 +0200 Subject: [PATCH 01/16] Introduce StanzaBuilder As first step to immutable Stanza types. --- documentation/overview.md | 6 +- .../smack/bosh/XMPPBOSHConnection.java | 4 +- .../smack/AbstractXMPPConnection.java | 24 +- .../smack/ConnectionConfiguration.java | 23 ++ .../smack/SmackInitialization.java | 1 - .../jivesoftware/smack/XMPPConnection.java | 3 + .../compress/provider/FailureProvider.java | 4 +- .../smack/packet/EmptyResultIQ.java | 10 +- .../jivesoftware/smack/packet/ErrorIQ.java | 8 +- .../smack/packet/FullyQualifiedElement.java | 8 +- .../org/jivesoftware/smack/packet/IQ.java | 72 ++--- .../jivesoftware/smack/packet/IqBuilder.java | 57 ++++ .../org/jivesoftware/smack/packet/IqView.java | 28 ++ .../jivesoftware/smack/packet/Message.java | 118 +++++-- .../smack/packet/MessageBuilder.java | 164 ++++++++++ .../smack/packet/MessageView.java | 29 ++ .../jivesoftware/smack/packet/Presence.java | 72 +++-- .../smack/packet/PresenceBuilder.java | 140 ++++++++ .../smack/packet/PresenceView.java | 59 ++++ .../jivesoftware/smack/packet/SimpleIQ.java | 6 +- .../org/jivesoftware/smack/packet/Stanza.java | 233 +++++++++----- .../smack/packet/StanzaBuilder.java | 301 ++++++++++++++++++ .../smack/packet/StanzaError.java | 24 +- .../smack/packet/StanzaFactory.java | 49 +++ .../jivesoftware/smack/packet/StanzaView.java | 82 +++++ .../smack/packet/XmlEnvironment.java | 1 - .../smack/packet/XmlLangElement.java | 28 ++ .../packet/id/RandomStringStanzaIdSource.java | 54 ++++ ...dUtil.java => StandardStanzaIdSource.java} | 24 +- .../smack/packet/id/StanzaIdSource.java | 21 ++ .../packet/id/StanzaIdSourceFactory.java | 21 ++ .../smack/packet/id/UuidStanzaIdSource.java | 41 +++ .../org/jivesoftware/smack/util/Function.java | 23 ++ .../org/jivesoftware/smack/util/MultiMap.java | 15 +- .../smack/util/PacketParserUtils.java | 69 ++-- .../jivesoftware/smack/util/StringUtils.java | 13 +- .../jivesoftware/smack/util/ToStringUtil.java | 75 +++++ .../smack/util/XmppElementUtil.java | 20 ++ .../smack/filter/FromMatchesFilterTest.java | 20 +- .../smack/packet/IQResponseTest.java | 6 +- .../smack/packet/MessageTest.java | 75 +++-- .../smack/packet/PresenceTest.java | 63 ++-- .../smack/packet/ToStringTest.java | 16 +- .../smack/packet/XMPPErrorTest.java | 5 +- .../smack/util/PacketParserUtilsTest.java | 27 +- .../smackx/dox/DnsOverXmppManager.java | 3 +- .../ExplicitMessageEncryptionElement.java | 26 +- .../smackx/hints/element/StoreHint.java | 17 +- .../iot/control/element/IoTSetResponse.java | 12 +- .../smackx/iot/data/IoTDataManager.java | 10 +- .../provisioning/IoTProvisioningManager.java | 27 +- .../smackx/muclight/MultiUserChatLight.java | 44 ++- .../provider/RemoteDisablingProvider.java | 4 +- .../AcknowledgedExtensionTest.java | 9 +- .../chat_markers/DisplayedExtensionTest.java | 9 +- .../chat_markers/MarkableExtensionTest.java | 11 +- .../chat_markers/ReceivedExtensionTest.java | 9 +- .../ExplicitMessageEncryptionElementTest.java | 16 +- .../smackx/mam/QueryArchiveTest.java | 19 +- .../RemoteDisablingPushNotificationsTest.java | 14 +- .../smackx/sid/StableUniqueStanzaIdTest.java | 3 +- .../smackx/spoiler/SpoilerTest.java | 9 +- .../org/jivesoftware/smack/chat2/Chat.java | 9 +- .../address/MultipleRecipientManager.java | 2 +- .../ibb/InBandBytestreamSession.java | 6 +- .../socks5/Socks5BytestreamManager.java | 2 +- .../socks5/Socks5BytestreamRequest.java | 2 +- .../smackx/chatstates/ChatStateManager.java | 3 +- .../smackx/commands/AdHocCommandManager.java | 17 +- .../provider/AdHocCommandDataProvider.java | 2 +- .../smackx/disco/ServiceDiscoveryManager.java | 4 +- .../filetransfer/FileTransferManager.java | 2 +- .../filetransfer/FileTransferNegotiator.java | 4 +- .../smackx/geoloc/GeoLocationManager.java | 6 +- .../smackx/jingle/JingleUtil.java | 28 +- .../jiveproperties/JivePropertiesManager.java | 25 +- .../packet/JivePropertiesExtension.java | 4 + .../smackx/muc/MucEnterConfiguration.java | 36 ++- .../smackx/muc/MultiUserChat.java | 112 +++++-- .../smackx/muc/MultiUserChatManager.java | 9 +- .../jivesoftware/smackx/ping/PingManager.java | 7 +- .../jivesoftware/smackx/ping/packet/Ping.java | 16 +- .../receipts/DeliveryReceiptManager.java | 8 +- .../receipts/DeliveryReceiptRequest.java | 19 +- .../smackx/vcardtemp/VCardManager.java | 4 +- .../bytestreams/ibb/IBBPacketUtils.java | 2 +- .../InBandBytestreamSessionMessageTest.java | 16 +- .../socks5/Socks5ByteStreamManagerTest.java | 4 +- .../socks5/Socks5ClientForInitiatorTest.java | 2 +- .../smackx/last_interaction/IdleTest.java | 5 +- .../smackx/mood/MoodManagerTest.java | 5 +- .../smackx/pubsub/ConfigureFormTest.java | 2 +- .../smackx/receipts/DeliveryReceiptTest.java | 36 ++- .../smackx/usertune/UserTuneManagerTest.java | 6 +- .../org/jivesoftware/smack/chat/Chat.java | 23 +- .../org/jivesoftware/smack/roster/Roster.java | 61 ++-- .../smack/roster/RosterEntry.java | 8 +- .../RosterVerStreamFeatureProvider.java | 1 - ...ptionPreApprovalStreamFeatureProvider.java | 1 - .../smack/chat/ChatConnectionTest.java | 84 ++--- .../smack/XmppConnectionStressTest.java | 10 +- .../java/org/jivesoftware/smack/ChatTest.java | 22 +- .../smack/StreamManagementTest.java | 6 +- .../chatstate/ChatStateIntegrationTest.java | 1 + .../smackx/mam/MamIntegrationTest.java | 14 +- .../muc/MultiUserChatIntegrationTest.java | 1 + .../omemo/AbstractOmemoMessageListener.java | 1 + .../MessageEncryptionIntegrationTest.java | 12 +- .../smackx/omemo/OmemoMamDecryptionTest.java | 8 +- .../smackx/omemo/OmemoManagerSetupHelper.java | 1 + .../omemo/ReadOnlyDeviceIntegrationTest.java | 1 + .../SessionRenegotiationIntegrationTest.java | 15 +- .../ox/AbstractOpenPgpIntegrationTest.java | 1 + .../ox/OXSecretKeyBackupIntegrationTest.java | 1 + .../OXInstantMessagingIntegrationTest.java | 1 + .../usertune/UserTuneIntegrationTest.java | 2 +- .../jivesoftware/smackx/xdata/FormTest.java | 24 +- ...SmackIntegrationTestFrameworkUnitTest.java | 3 +- .../smackx/jingleold/JingleSession.java | 6 +- .../smackx/workgroup/agent/AgentRoster.java | 18 +- .../smackx/workgroup/agent/AgentSession.java | 44 +-- .../smackx/workgroup/user/Workgroup.java | 7 +- .../smackx/xevent/MessageEventManager.java | 43 ++- .../smackx/xroster/RosterExchangeManager.java | 26 +- .../smackx/omemo/SignalOmemoManagerTest.java | 7 +- .../smackx/omemo/OmemoManager.java | 10 +- .../smackx/omemo/OmemoMessage.java | 18 +- .../smackx/omemo/OmemoService.java | 12 +- .../smackx/omemo/WrapperObjectsTest.java | 1 + .../ox_im/OXInstantMessagingManager.java | 31 +- .../ox_im/OXInstantMessagingManagerTest.java | 10 +- .../igniterealtime/smack/smackrepl/Nio.java | 6 +- .../smack/smackrepl/OmemoClient.java | 4 +- .../smack/tcp/PacketWriterTest.java | 6 +- 134 files changed, 2576 insertions(+), 764 deletions(-) create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/packet/IqBuilder.java create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/packet/IqView.java create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/packet/MessageBuilder.java create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/packet/MessageView.java create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/packet/PresenceBuilder.java create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/packet/PresenceView.java create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaBuilder.java create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaFactory.java create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaView.java create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/packet/XmlLangElement.java create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/packet/id/RandomStringStanzaIdSource.java rename smack-core/src/main/java/org/jivesoftware/smack/packet/id/{StanzaIdUtil.java => StandardStanzaIdSource.java} (59%) create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/packet/id/StanzaIdSource.java create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/packet/id/StanzaIdSourceFactory.java create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/packet/id/UuidStanzaIdSource.java create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/util/Function.java create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/util/ToStringUtil.java diff --git a/documentation/overview.md b/documentation/overview.md index 79049183b..2e169a8b6 100644 --- a/documentation/overview.md +++ b/documentation/overview.md @@ -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); ``` diff --git a/smack-bosh/src/main/java/org/jivesoftware/smack/bosh/XMPPBOSHConnection.java b/smack-bosh/src/main/java/org/jivesoftware/smack/bosh/XMPPBOSHConnection.java index 475bd1403..824dedc44 100644 --- a/smack-bosh/src/main/java/org/jivesoftware/smack/bosh/XMPPBOSHConnection.java +++ b/smack-bosh/src/main/java/org/jivesoftware/smack/bosh/XMPPBOSHConnection.java @@ -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); diff --git a/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java b/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java index fca97f54c..fc957c5fb 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java @@ -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 setIqRequestHandler = new HashMap<>(); private final Map 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(() -> { diff --git a/smack-core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java b/smack-core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java index 7aa8c7acb..33d1bfdd4 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java @@ -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. *

@@ -612,6 +623,7 @@ public abstract class ConnectionConfiguration { private Set 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(); diff --git a/smack-core/src/main/java/org/jivesoftware/smack/SmackInitialization.java b/smack-core/src/main/java/org/jivesoftware/smack/SmackInitialization.java index cf3a646a2..92c122571 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/SmackInitialization.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/SmackInitialization.java @@ -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; diff --git a/smack-core/src/main/java/org/jivesoftware/smack/XMPPConnection.java b/smack-core/src/main/java/org/jivesoftware/smack/XMPPConnection.java index 437e72082..d7df0a825 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/XMPPConnection.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/XMPPConnection.java @@ -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. * diff --git a/smack-core/src/main/java/org/jivesoftware/smack/compress/provider/FailureProvider.java b/smack-core/src/main/java/org/jivesoftware/smack/compress/provider/FailureProvider.java index cf90f594b..fff539602 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/compress/provider/FailureProvider.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/compress/provider/FailureProvider.java @@ -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 { 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); diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/EmptyResultIQ.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/EmptyResultIQ.java index c4b16f3ea..fd3b576c1 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/EmptyResultIQ.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/EmptyResultIQ.java @@ -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 diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/ErrorIQ.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/ErrorIQ.java index c09a09f38..23bf999b0 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/ErrorIQ.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/ErrorIQ.java @@ -27,13 +27,13 @@ public class ErrorIQ extends SimpleIQ { *

* According to RFC 6120 § 8.3.1 "4. An error stanza MUST contain an <error/> child element.", so the xmppError argument is mandatory. *

- * @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); } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/FullyQualifiedElement.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/FullyQualifiedElement.java index 2e93d23bd..40da81351 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/FullyQualifiedElement.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/FullyQualifiedElement.java @@ -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; } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/IQ.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/IQ.java index 3d875b7e1..d202eb2cc 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/IQ.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/IQ.java @@ -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:
    - *
  • The sender set to the recipient of the originating IQ. - *
  • The recipient set to the sender of the originating IQ. - *
  • The type set to {@link Type#error IQ.Type.error}. - *
  • The id set to the id of the originating IQ. - *
  • The child element contained in the associated originating IQ. - *
  • The provided {@link StanzaError XMPPError}. - *
- * - * @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()); } /** diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/IqBuilder.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/IqBuilder.java new file mode 100644 index 000000000..a0994555f --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/IqBuilder.java @@ -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 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; + } +} diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/IqView.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/IqView.java new file mode 100644 index 000000000..a888712eb --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/IqView.java @@ -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(); + +} diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/Message.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/Message.java index b6f426139..ef3dd9aec 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/Message.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/Message.java @@ -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 { +public final class Message extends Stanza implements MessageView, TypedCloneable { public static final String ELEMENT = "message"; public static final String BODY = "body"; @@ -66,11 +68,12 @@ public final class Message extends Stanza implements TypedCloneable { private Type type; private String thread = null; - private final Set subjects = new HashSet(); - /** * 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 { * 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 { * * @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 { * * @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 { * @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 { * @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. *

@@ -141,15 +165,9 @@ public final class Message extends Stanza implements TypedCloneable { 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 { * 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 { 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 { * @return a collection of all subjects in this message. */ public Set getSubjects() { - return Collections.unmodifiableSet(subjects); + List subjectList = getExtensions(Subject.class); + + Set subjects = new HashSet<>(subjectList.size()); + subjects.addAll(subjectList); + + return subjects; } /** @@ -218,7 +245,10 @@ public final class Message extends Stanza implements TypedCloneable { * 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 { * @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 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 { * @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 { * @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 { public List getSubjectLanguages() { Subject defaultSubject = getMessageSubject(null); List languages = new ArrayList(); - 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 { * @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 { * 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 { * @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 { * * @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 { * @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 { * 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 { 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 { 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 { 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."); } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/MessageBuilder.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/MessageBuilder.java new file mode 100644 index 000000000..b73880d0c --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/MessageBuilder.java @@ -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 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; + } +} diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/MessageView.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/MessageView.java new file mode 100644 index 000000000..046b9274f --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/MessageView.java @@ -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(); + +} diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/Presence.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/Presence.java index 62630ecfb..8a8db7030 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/Presence.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/Presence.java @@ -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 { +public final class Presence extends Stanza implements PresenceView, TypedCloneable { public static final String ELEMENT = "presence"; @@ -81,7 +82,10 @@ public final class Presence extends Stanza implements TypedCloneable { * 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 { * @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 { * @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 { setMode(mode); } + Presence(PresenceBuilder presenceBuilder) { + super(presenceBuilder); + type = presenceBuilder.type; + status = presenceBuilder.status; + priority = presenceBuilder.priority; + mode = presenceBuilder.mode; + } + /** * Copy constructor. *

@@ -163,11 +181,7 @@ public final class Presence extends Stanza implements TypedCloneable { 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 { * 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 null 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 { * 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 RFC 6121 § 4.7.2.3. Priority Element - */ + @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 { * @param priority the priority of the presence. * @throws IllegalArgumentException if the priority is outside the valid range. * @see RFC 6121 § 4.7.2.3. Priority Element + * @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 { 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 { * 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 { 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 { */ public Presence cloneWithNewId() { Presence clone = clone(); - clone.setStanzaId(StanzaIdUtil.newStanzaId()); + clone.setNewStanzaId(); return clone; } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/PresenceBuilder.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/PresenceBuilder.java new file mode 100644 index 000000000..795c9a824 --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/PresenceBuilder.java @@ -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 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; + } + +} diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/PresenceView.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/PresenceView.java new file mode 100644 index 000000000..80b44badb --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/PresenceView.java @@ -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 null 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 RFC 6121 § 4.7.2.3. Priority Element + */ + int getPriority(); + + /** + * Returns the priority of the presence. + * + * @return the priority. + * @see RFC 6121 § 4.7.2.3. Priority Element + */ + byte getPriorityByte(); + + /** + * Returns the mode of the presence update. + * + * @return the mode. + */ + Presence.Mode getMode(); +} diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/SimpleIQ.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/SimpleIQ.java index cd20108d8..5cd260c5f 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/SimpleIQ.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/SimpleIQ.java @@ -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(); diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/Stanza.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/Stanza.java index 9d93f8b14..b884468f7 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/Stanza.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/Stanza.java @@ -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. If you think you need to subclass this class, then you are doing something wrong. *

+ *

+ * 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. + *

* * @author Matt Tucker * @author Florian Schmaus * @see RFC 6120 § 8. XML Stanzas */ -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 extensionElements = new MultiMap<>(); + private final MultiMap 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 null. - * - * @return the packet's unique ID or null 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 null if - * the value is not set. The XMPP protocol often makes the "to" - * attribute optional, so it does not always need to be set.

+ * Throws an {@link IllegalArgumentException} if this stanza has no stanza ID set. * - * @return who the stanza is being sent to, or null 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 null if - * the value is not set. The XMPP protocol often makes the "from" - * attribute optional, so it does not always need to be set.

- * - * @return who the stanza is being sent from, or null 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 null if there are - * no errors. - * - * @return the error sub-packet or null 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 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 getExtensionsMap() { + return cloneExtensionsMap(); + } + + final MultiMap cloneExtensionsMap() { + synchronized (extensionElements) { + return extensionElements.clone(); + } + } + /** * Return a list of all extensions with the given element name and namespace. *

@@ -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 getExtensions(QName qname) { + List res; + synchronized (extensionElements) { + res = extensionElements.getAll(qname); + } + return Collections.unmodifiableList(res); + } + + @Override + public List getExtensions(Class 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 getExtension(QName qname) { + synchronized (extensionElements) { + return (E) extensionElements.getFirst(qname); + } + } + /** * Adds a stanza extension to the packet. Does nothing if extension is null. + *

+ * Please note that although this method is not yet marked as deprecated, it is recommended to use + * {@link StanzaBuilder#addExtension(ExtensionElement)} instead. + *

* * @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. + *

+ * Please note that although this method is not yet marked as deprecated, it is recommended to use + * {@link StanzaBuilder#overrideExtension(ExtensionElement)} instead. + *

* * @param extension the extension element to add. * @return one of the removed extensions or null 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 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) { diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaBuilder.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaBuilder.java new file mode 100644 index 000000000..4b2cba391 --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaBuilder.java @@ -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> implements StanzaView { + + final StanzaIdSource stanzaIdSource; + final String stanzaId; + + Jid to; + Jid from; + + StanzaError stanzaError; + + String language; + + MultiMap 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 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 getExtension(QName qname) { + return (E) extensionElements.getFirst(qname); + } + + @Override + public final List getExtensions() { + return extensionElements.values(); + } + + @Override + public final List getExtensions(QName qname) { + return extensionElements.getAll(qname); + } + + @Override + public final List getExtensions(Class 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); + } +} diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaError.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaError.java index 7c43fb5b2..590de8c81 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaError.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaError.java @@ -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 descriptiveTexts, - List extensions, Stanza stanza) { + List 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 // , 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 diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaFactory.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaFactory.java new file mode 100644 index 000000000..4a7a85ce8 --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaFactory.java @@ -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); + } + +} diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaView.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaView.java new file mode 100644 index 000000000..4de119fef --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaView.java @@ -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 null. + * + * @return the packet's unique ID or null if the id is not available. + */ + String getStanzaId(); + + /** + * Returns who the stanza is being sent "to", or null if + * the value is not set. The XMPP protocol often makes the "to" + * attribute optional, so it does not always need to be set.

+ * + * @return who the stanza is being sent to, or null if the + * value has not been set. + */ + Jid getTo(); + + /** + * Returns who the stanza is being sent "from" or null if + * the value is not set. The XMPP protocol often makes the "from" + * attribute optional, so it does not always need to be set.

+ * + * @return who the stanza is being sent from, or null if the + * value has not been set. + */ + Jid getFrom(); + + /** + * Returns the error associated with this packet, or null if there are + * no errors. + * + * @return the error sub-packet or null if there isn't an error. + */ + StanzaError getError(); + + E getExtension(QName qname); + + @SuppressWarnings("unchecked") + default E getExtension(Class 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 getExtensions(); + + List getExtensions(QName qname); + + List getExtensions(Class extensionElementClass); +} diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/XmlEnvironment.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/XmlEnvironment.java index 810d8f75f..defc09868 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/XmlEnvironment.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/XmlEnvironment.java @@ -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 { diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/XmlLangElement.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/XmlLangElement.java new file mode 100644 index 000000000..27bf34d98 --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/XmlLangElement.java @@ -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(); + +} diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/id/RandomStringStanzaIdSource.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/id/RandomStringStanzaIdSource.java new file mode 100644 index 000000000..9d3768a1f --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/id/RandomStringStanzaIdSource.java @@ -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; + } + + } +} diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/id/StanzaIdUtil.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/id/StandardStanzaIdSource.java similarity index 59% rename from smack-core/src/main/java/org/jivesoftware/smack/packet/id/StanzaIdUtil.java rename to smack-core/src/main/java/org/jivesoftware/smack/packet/id/StandardStanzaIdSource.java index b13a877d3..45fcbaf3c 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/id/StanzaIdUtil.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/id/StandardStanzaIdSource.java @@ -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()); } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/id/StanzaIdSource.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/id/StanzaIdSource.java new file mode 100644 index 000000000..4d75094ca --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/id/StanzaIdSource.java @@ -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(); +} diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/id/StanzaIdSourceFactory.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/id/StanzaIdSourceFactory.java new file mode 100644 index 000000000..ed6c08b40 --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/id/StanzaIdSourceFactory.java @@ -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(); +} diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/id/UuidStanzaIdSource.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/id/UuidStanzaIdSource.java new file mode 100644 index 000000000..dbe9b8a10 --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/id/UuidStanzaIdSource.java @@ -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; + } + + } +} diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/Function.java b/smack-core/src/main/java/org/jivesoftware/smack/util/Function.java new file mode 100644 index 000000000..760d3cf5d --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/Function.java @@ -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 apply(T t); + +} diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/MultiMap.java b/smack-core/src/main/java/org/jivesoftware/smack/util/MultiMap.java index d9ad987b6..ea58e469e 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/MultiMap.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/MultiMap.java @@ -34,7 +34,7 @@ import java.util.Set; * @param the type of the keys the map uses. * @param the type of the values the map uses. */ -public class MultiMap { +public class MultiMap implements TypedCloneable> { /** * The constant value {@value}. @@ -252,6 +252,19 @@ public class MultiMap { return new MultiMap(Collections.unmodifiableMap(mapCopy)); } + @Override + public MultiMap clone() { + Map> clonedMap = new LinkedHashMap<>(map.size()); + + // TODO: Use Map.forEach() once Smack's minimum Android API is 24 or higher. + for (Entry> entry : map.entrySet()) { + List clonedList = CollectionUtil.newListWith(entry.getValue()); + clonedMap.put(entry.getKey(), clonedList); + } + + return new MultiMap<>(clonedMap); + } + private static final class SimpleMapEntry implements Map.Entry { private final K key; diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java b/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java index 665e90564..57aaab932 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java @@ -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 get(String stanzaId); + } + + private static > SB parseCommonStanzaAttributes(StanzaBuilderSupplier 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 { // '' 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 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(); } /** diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/StringUtils.java b/smack-core/src/main/java/org/jivesoftware/smack/util/StringUtils.java index eefccf862..09b3407ff 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/StringUtils.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/StringUtils.java @@ -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 collection, String delimiter) { StringBuilder sb = new StringBuilder(collection.size() * 20); + appendTo(collection, delimiter, sb); + return sb; + } + + public static void appendTo(Collection collection, String delimiter, StringBuilder sb) { for (Iterator 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) { diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/ToStringUtil.java b/smack-core/src/main/java/org/jivesoftware/smack/util/ToStringUtil.java new file mode 100644 index 000000000..447f1444f --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/ToStringUtil.java @@ -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 Builder add(String name, Collection values, Function toStringFunction) { + if (values.isEmpty()) { + return this; + } + + sb.append(' ').append(name).append('['); + + List 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(); + } + } +} diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/XmppElementUtil.java b/smack-core/src/main/java/org/jivesoftware/smack/util/XmppElementUtil.java index 492b551c6..315edfe2c 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/XmppElementUtil.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/XmppElementUtil.java @@ -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 List getElementsFrom( + MultiMap elementMap, Class extensionElementClass) { + QName qname = XmppElementUtil.getQNameFor(extensionElementClass); + + List extensionElements = elementMap.getAll(qname); + + if (extensionElements.isEmpty()) { + return Collections.emptyList(); + } + + List res = new ArrayList<>(extensionElements.size()); + for (E extensionElement : extensionElements) { + R e = extensionElementClass.cast(extensionElement); + res.add(e); + } + return res; + } } diff --git a/smack-core/src/test/java/org/jivesoftware/smack/filter/FromMatchesFilterTest.java b/smack-core/src/test/java/org/jivesoftware/smack/filter/FromMatchesFilterTest.java index c6f7089d4..98e14cb04 100644 --- a/smack-core/src/test/java/org/jivesoftware/smack/filter/FromMatchesFilterTest.java +++ b/smack-core/src/test/java/org/jivesoftware/smack/filter/FromMatchesFilterTest.java @@ -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)); diff --git a/smack-core/src/test/java/org/jivesoftware/smack/packet/IQResponseTest.java b/smack-core/src/test/java/org/jivesoftware/smack/packet/IQResponseTest.java index 5807f5f0b..2d2f0524e 100644 --- a/smack-core/src/test/java/org/jivesoftware/smack/packet/IQResponseTest.java +++ b/smack-core/src/test/java/org/jivesoftware/smack/packet/IQResponseTest.java @@ -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); diff --git a/smack-core/src/test/java/org/jivesoftware/smack/packet/MessageTest.java b/smack-core/src/test/java/org/jivesoftware/smack/packet/MessageTest.java index 82ff71bf8..68d8535fa 100644 --- a/smack-core/src/test/java/org/jivesoftware/smack/packet/MessageTest.java +++ b/smack-core/src/test/java/org/jivesoftware/smack/packet/MessageTest.java @@ -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(""); 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(""); 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(""); 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(""); 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(""); 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 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(""); 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(""); 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; - } } diff --git a/smack-core/src/test/java/org/jivesoftware/smack/packet/PresenceTest.java b/smack-core/src/test/java/org/jivesoftware/smack/packet/PresenceTest.java index a86e07646..863e4b0ff 100644 --- a/smack-core/src/test/java/org/jivesoftware/smack/packet/PresenceTest.java +++ b/smack-core/src/test/java/org/jivesoftware/smack/packet/PresenceTest.java @@ -41,8 +41,9 @@ public class PresenceTest { .append(""); 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(""); 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(""); 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(""); 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(""); 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("") @@ -157,20 +161,20 @@ public class PresenceTest { .append(""); 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(""); 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; } } diff --git a/smack-core/src/test/java/org/jivesoftware/smack/packet/ToStringTest.java b/smack-core/src/test/java/org/jivesoftware/smack/packet/ToStringTest.java index a591585f9..1398c66f7 100644 --- a/smack-core/src/test/java/org/jivesoftware/smack/packet/ToStringTest.java +++ b/smack-core/src/test/java/org/jivesoftware/smack/packet/ToStringTest.java @@ -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); diff --git a/smack-core/src/test/java/org/jivesoftware/smack/packet/XMPPErrorTest.java b/smack-core/src/test/java/org/jivesoftware/smack/packet/XMPPErrorTest.java index c2807ad77..3ca877576 100644 --- a/smack-core/src/test/java/org/jivesoftware/smack/packet/XMPPErrorTest.java +++ b/smack-core/src/test/java/org/jivesoftware/smack/packet/XMPPErrorTest.java @@ -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 { diff --git a/smack-core/src/test/java/org/jivesoftware/smack/util/PacketParserUtilsTest.java b/smack-core/src/test/java/org/jivesoftware/smack/util/PacketParserUtilsTest.java index 90dd82b9d..d6e243351 100644 --- a/smack-core/src/test/java/org/jivesoftware/smack/util/PacketParserUtilsTest.java +++ b/smack-core/src/test/java/org/jivesoftware/smack/util/PacketParserUtilsTest.java @@ -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()); } } diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/dox/DnsOverXmppManager.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/dox/DnsOverXmppManager.java index 618cb1d67..1ffba5597 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/dox/DnsOverXmppManager.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/dox/DnsOverXmppManager.java @@ -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); diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/eme/element/ExplicitMessageEncryptionElement.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/eme/element/ExplicitMessageEncryptionElement.java index 5e47cd34f..4c6cf0015 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/eme/element/ExplicitMessageEncryptionElement.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/eme/element/ExplicitMessageEncryptionElement.java @@ -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 extensionElements = message.getExtensions( - ExplicitMessageEncryptionElement.ELEMENT, - ExplicitMessageEncryptionElement.NAMESPACE); + public static boolean hasProtocol(MessageView message, String protocolNamespace) { + List 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)); } diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/hints/element/StoreHint.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/hints/element/StoreHint.java index aea9de720..a7f6e052a 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/hints/element/StoreHint.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/hints/element/StoreHint.java @@ -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); } } diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/element/IoTSetResponse.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/element/IoTSetResponse.java index 68fce1441..1f89efa0e 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/element/IoTSetResponse.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/element/IoTSetResponse.java @@ -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 diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/IoTDataManager.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/IoTDataManager.java index 582fdbf0f..8375d01cf 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/IoTDataManager.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/IoTDataManager.java @@ -125,10 +125,14 @@ public final class IoTDataManager extends IoTManager { @Override public void momentaryReadOut(List 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); diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/provisioning/IoTProvisioningManager.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/provisioning/IoTProvisioningManager.java index e89d6b8d1..ce17ee27d 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/provisioning/IoTProvisioningManager.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/provisioning/IoTProvisioningManager.java @@ -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); } } diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/MultiUserChatLight.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/MultiUserChatLight.java index aa43bb535..8534e4021 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/MultiUserChatLight.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/MultiUserChatLight.java @@ -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); } diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/push_notifications/provider/RemoteDisablingProvider.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/push_notifications/provider/RemoteDisablingProvider.java index a19e53cce..2f6c55fbc 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/push_notifications/provider/RemoteDisablingProvider.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/push_notifications/provider/RemoteDisablingProvider.java @@ -50,7 +50,9 @@ public class RemoteDisablingProvider extends ExtensionElementProvider 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()); } diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/mam/QueryArchiveTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/mam/QueryArchiveTest.java index f523a8c3b..bc4360eef 100644 --- a/smack-experimental/src/test/java/org/jivesoftware/smackx/mam/QueryArchiveTest.java +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/mam/QueryArchiveTest.java @@ -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); diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/push_notifications/RemoteDisablingPushNotificationsTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/push_notifications/RemoteDisablingPushNotificationsTest.java index 2fe5dcbba..cc09aad4b 100644 --- a/smack-experimental/src/test/java/org/jivesoftware/smackx/push_notifications/RemoteDisablingPushNotificationsTest.java +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/push_notifications/RemoteDisablingPushNotificationsTest.java @@ -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); } } diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/sid/StableUniqueStanzaIdTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/sid/StableUniqueStanzaIdTest.java index a344b2bd6..3e6ac3027 100644 --- a/smack-experimental/src/test/java/org/jivesoftware/smackx/sid/StableUniqueStanzaIdTest.java +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/sid/StableUniqueStanzaIdTest.java @@ -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)); diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/spoiler/SpoilerTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/spoiler/SpoilerTest.java index 748035f9d..585d73a06 100644 --- a/smack-experimental/src/test/java/org/jivesoftware/smackx/spoiler/SpoilerTest.java +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/spoiler/SpoilerTest.java @@ -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 = ""; - 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 = "Love story end"; - 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 = "Der Kuchen ist eine Lüge!"; - 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); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smack/chat2/Chat.java b/smack-extensions/src/main/java/org/jivesoftware/smack/chat2/Chat.java index 2dd93d9ed..3b7c31d95 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smack/chat2/Chat.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smack/chat2/Chat.java @@ -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); } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/address/MultipleRecipientManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/address/MultipleRecipientManager.java index fc361c392..6406cbcd4 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/address/MultipleRecipientManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/address/MultipleRecipientManager.java @@ -159,7 +159,7 @@ public class MultipleRecipientManager { } // Any 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) { diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSession.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSession.java index 0b98123dc..ea2948f86 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSession.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSession.java @@ -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); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java index 7b8acc674..f257efa6e 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java @@ -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); } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamRequest.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamRequest.java index 41669b52e..a5756cdc2 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamRequest.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamRequest.java @@ -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); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/chatstates/ChatStateManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/chatstates/ChatStateManager.java index 5691685ff..0c4c9f4ef 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/chatstates/ChatStateManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/chatstates/ChatStateManager.java @@ -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); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandManager.java index ec6724215..588ca2116 100755 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/commands/AdHocCommandManager.java @@ -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; diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/commands/provider/AdHocCommandDataProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/commands/provider/AdHocCommandDataProvider.java index 22d7f7498..4aeb9a700 100755 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/commands/provider/AdHocCommandDataProvider.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/commands/provider/AdHocCommandDataProvider.java @@ -112,7 +112,7 @@ public class AdHocCommandDataProvider extends IQProvider { 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); } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java index d59bb2fc7..f6de2aca8 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java @@ -146,7 +146,7 @@ public final class ServiceDiscoveryManager extends Manager { // Return 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 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; diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferManager.java index f34ed352b..9c2221de0 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferManager.java @@ -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); } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java index c9195fa8c..cb5783206 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java @@ -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; } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/geoloc/GeoLocationManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/geoloc/GeoLocationManager.java index b8c0ff414..a12d975d1 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/geoloc/GeoLocationManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/geoloc/GeoLocationManager.java @@ -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); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/JingleUtil.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/JingleUtil.java index 4e5c6eddf..1ac93c448 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/JingleUtil.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jingle/JingleUtil.java @@ -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); } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jiveproperties/JivePropertiesManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jiveproperties/JivePropertiesManager.java index 8bbe7812d..b58970f23 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jiveproperties/JivePropertiesManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jiveproperties/JivePropertiesManager.java @@ -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 null 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); } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jiveproperties/packet/JivePropertiesExtension.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jiveproperties/packet/JivePropertiesExtension.java index 5a9061c4f..5ca0a7087 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jiveproperties/packet/JivePropertiesExtension.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jiveproperties/packet/JivePropertiesExtension.java @@ -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 properties; diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucEnterConfiguration.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucEnterConfiguration.java index 681d1e8a9..51b79fb57 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucEnterConfiguration.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MucEnterConfiguration.java @@ -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. + *

+ * The consumer must not modify the presence type, otherwise an {@link IllegalArgumentException} will be thrown. + *

+ * + * @param presenceBuilderConsumer a consumer which will be passed the presence build. + * @return a reference to this builder. + * @since 4.5 + */ + public Builder withPresence(Consumer 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. * diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java index 605eaff2e..b37f367ad 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java @@ -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.

+ * + * 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(); } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatManager.java index d2cb2e122..1a29ebe91 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatManager.java @@ -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()); } /** diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/PingManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/PingManager.java index 0bb1b0e65..f30e58a9e 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/PingManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/PingManager.java @@ -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() { @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); } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/packet/Ping.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/packet/Ping.java index 65d7186fa..13803354c 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/packet/Ping.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/packet/Ping.java @@ -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. * diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceiptManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceiptManager.java index 0fc5d1cdd..bab23aa5e 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceiptManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceiptManager.java @@ -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; } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceiptRequest.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceiptRequest.java index 23a129e24..7473d7a5f 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceiptRequest.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceiptRequest.java @@ -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. */ diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/VCardManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/VCardManager.java index 45c16f506..87346d513 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/VCardManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/VCardManager.java @@ -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(); } diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/IBBPacketUtils.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/IBBPacketUtils.java index 28404544b..9aa69919c 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/IBBPacketUtils.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/IBBPacketUtils.java @@ -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); diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSessionMessageTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSessionMessageTest.java index eb172880a..443cb24de 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSessionMessageTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSessionMessageTest.java @@ -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); } diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ByteStreamManagerTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ByteStreamManagerTest.java index a84a90996..39869435e 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ByteStreamManagerTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ByteStreamManagerTest.java @@ -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); diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ClientForInitiatorTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ClientForInitiatorTest.java index fe3807eed..c824bb102 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ClientForInitiatorTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ClientForInitiatorTest.java @@ -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); diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/last_interaction/IdleTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/last_interaction/IdleTest.java index 74247bba1..407f48b20 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/last_interaction/IdleTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/last_interaction/IdleTest.java @@ -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); diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/mood/MoodManagerTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/mood/MoodManagerTest.java index a650bc7b5..dfc4cf8f4 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/mood/MoodManagerTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/mood/MoodManagerTest.java @@ -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()); diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/pubsub/ConfigureFormTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/pubsub/ConfigureFormTest.java index 96034f920..a46a28bc4 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/pubsub/ConfigureFormTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/pubsub/ConfigureFormTest.java @@ -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); diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/receipts/DeliveryReceiptTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/receipts/DeliveryReceiptTest.java index 645b54271..01d1a60e8 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/receipts/DeliveryReceiptTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/receipts/DeliveryReceiptTest.java @@ -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); diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/usertune/UserTuneManagerTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/usertune/UserTuneManagerTest.java index bb21fae84..9e357963c 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/usertune/UserTuneManagerTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/usertune/UserTuneManagerTest.java @@ -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)); diff --git a/smack-im/src/main/java/org/jivesoftware/smack/chat/Chat.java b/smack-im/src/main/java/org/jivesoftware/smack/chat/Chat.java index f5df0834f..c57bc5e34 100644 --- a/smack-im/src/main/java/org/jivesoftware/smack/chat/Chat.java +++ b/smack-im/src/main/java/org/jivesoftware/smack/chat/Chat.java @@ -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. diff --git a/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java b/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java index e1d49d8ed..5bb91f283 100644 --- a/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java +++ b/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java @@ -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 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 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 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 res; Map 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 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. * diff --git a/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterEntry.java b/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterEntry.java index 60b50cce9..fbb0c1188 100644 --- a/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterEntry.java +++ b/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterEntry.java @@ -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 diff --git a/smack-im/src/main/java/org/jivesoftware/smack/roster/provider/RosterVerStreamFeatureProvider.java b/smack-im/src/main/java/org/jivesoftware/smack/roster/provider/RosterVerStreamFeatureProvider.java index 0f71fafea..e2c9acb02 100644 --- a/smack-im/src/main/java/org/jivesoftware/smack/roster/provider/RosterVerStreamFeatureProvider.java +++ b/smack-im/src/main/java/org/jivesoftware/smack/roster/provider/RosterVerStreamFeatureProvider.java @@ -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 { diff --git a/smack-im/src/main/java/org/jivesoftware/smack/roster/provider/SubscriptionPreApprovalStreamFeatureProvider.java b/smack-im/src/main/java/org/jivesoftware/smack/roster/provider/SubscriptionPreApprovalStreamFeatureProvider.java index 422ced505..40bd2ec39 100644 --- a/smack-im/src/main/java/org/jivesoftware/smack/roster/provider/SubscriptionPreApprovalStreamFeatureProvider.java +++ b/smack-im/src/main/java/org/jivesoftware/smack/roster/provider/SubscriptionPreApprovalStreamFeatureProvider.java @@ -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 { diff --git a/smack-im/src/test/java/org/jivesoftware/smack/chat/ChatConnectionTest.java b/smack-im/src/test/java/org/jivesoftware/smack/chat/ChatConnectionTest.java index c2f7bf049..a30c2e066 100644 --- a/smack-im/src/test/java/org/jivesoftware/smack/chat/ChatConnectionTest.java +++ b/smack-im/src/test/java/org/jivesoftware/smack/chat/ChatConnectionTest.java @@ -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(); diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java index aa0965306..712d75783 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/XmppConnectionStressTest.java @@ -31,6 +31,7 @@ import org.jivesoftware.smack.filter.AndFilter; import org.jivesoftware.smack.filter.MessageTypeFilter; import org.jivesoftware.smack.filter.StanzaExtensionFilter; 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.BooleansUtils; @@ -86,18 +87,19 @@ public class XmppConnectionStressTest { MultiMap toConnectionMessages = new MultiMap<>(); for (XMPPConnection toConnection : connections) { for (int i = 0; i < configuration.messagesPerConnection; i++) { - Message message = new Message(); - message.setTo(toConnection.getUser()); + MessageBuilder messageBuilder = fromConnection.getStanzaFactory().buildMessageStanza(); + messageBuilder.to(toConnection.getUser()); int payloadChunkCount = random.nextInt(configuration.maxPayloadChunks) + 1; for (int c = 0; c < payloadChunkCount; c++) { int payloadChunkSize = random.nextInt(configuration.maxPayloadChunkSize) + 1; String payloadCunk = StringUtils.randomString(payloadChunkSize, random); - JivePropertiesManager.addProperty(message, "payload-chunk-" + c, payloadCunk); + JivePropertiesManager.addProperty(messageBuilder, "payload-chunk-" + c, payloadCunk); } - JivePropertiesManager.addProperty(message, MESSAGE_NUMBER_PROPERTY, i); + JivePropertiesManager.addProperty(messageBuilder, MESSAGE_NUMBER_PROPERTY, i); + Message message = messageBuilder.build(); toConnectionMessages.put(toConnection, message); } } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smack/ChatTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smack/ChatTest.java index b206fdb5b..ec21761a5 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smack/ChatTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smack/ChatTest.java @@ -28,6 +28,9 @@ import java.util.Date; import org.jivesoftware.smack.chat.ChatManagerListener; import org.jivesoftware.smack.filter.ThreadFilter; import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.packet.MessageBuilder; +import org.jivesoftware.smack.packet.StanzaBuilder; + import org.jivesoftware.smackx.jiveproperties.JivePropertiesManager; import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest; @@ -69,17 +72,18 @@ public class ChatTest extends AbstractSmackIntegrationTest { org.jivesoftware.smack.chat.Chat newChat = chatManagerOne.createChat(conTwo.getUser()); StanzaCollector collector = conTwo.createStanzaCollector(new ThreadFilter(newChat.getThreadID())); - Message msg = new Message(); + MessageBuilder messageBuilder = StanzaBuilder.buildMessage(); - msg.setSubject("Subject of the chat"); - msg.setBody("Body of the chat"); - addProperty(msg, "favoriteColor", "red"); - addProperty(msg, "age", 30); - addProperty(msg, "distance", 30f); - addProperty(msg, "weight", 30d); - addProperty(msg, "male", true); - addProperty(msg, "birthdate", new Date()); + messageBuilder.setSubject("Subject of the chat"); + messageBuilder.setBody("Body of the chat"); + addProperty(messageBuilder, "favoriteColor", "red"); + addProperty(messageBuilder, "age", 30); + addProperty(messageBuilder, "distance", 30f); + addProperty(messageBuilder, "weight", 30d); + addProperty(messageBuilder, "male", true); + addProperty(messageBuilder, "birthdate", new Date()); + Message msg = messageBuilder.build(); newChat.sendMessage(msg); Message msg2 = collector.nextResult(2000); diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smack/StreamManagementTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smack/StreamManagementTest.java index 999f14684..a26cf8e17 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smack/StreamManagementTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smack/StreamManagementTest.java @@ -77,8 +77,10 @@ public class StreamManagementTest extends AbstractSmackSpecificLowLevelIntegrati private static void send(String messageString, XMPPConnection from, XMPPConnection to) throws NotConnectedException, InterruptedException { - Message message = new Message(to.getUser()); - message.setBody(messageString); + Message message = from.getStanzaFactory().buildMessageStanza() + .to(to.getUser()) + .setBody(messageString) + .build(); from.sendStanza(message); } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/chatstate/ChatStateIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/chatstate/ChatStateIntegrationTest.java index d2ffb6327..c236d8aa4 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/chatstate/ChatStateIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/chatstate/ChatStateIntegrationTest.java @@ -19,6 +19,7 @@ package org.jivesoftware.smackx.chatstate; import org.jivesoftware.smack.chat2.Chat; import org.jivesoftware.smack.chat2.ChatManager; import org.jivesoftware.smack.packet.Message; + import org.jivesoftware.smackx.chatstates.ChatState; import org.jivesoftware.smackx.chatstates.ChatStateListener; import org.jivesoftware.smackx.chatstates.ChatStateManager; diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/mam/MamIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/mam/MamIntegrationTest.java index f09832b25..0ee3d295b 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/mam/MamIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/mam/MamIntegrationTest.java @@ -32,6 +32,7 @@ import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.filter.MessageWithBodiesFilter; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Stanza; +import org.jivesoftware.smack.packet.StanzaBuilder; import org.jivesoftware.smackx.mam.MamManager.MamQuery; import org.jivesoftware.smackx.mam.MamManager.MamQueryArgs; @@ -66,10 +67,12 @@ public class MamIntegrationTest extends AbstractSmackIntegrationTest { EntityBareJid userOne = conOne.getUser().asEntityBareJid(); EntityBareJid userTwo = conTwo.getUser().asEntityBareJid(); - Message message = new Message(userTwo); - String messageId = message.ensureStanzaIdSet(); final String messageBody = "Test MAM message (" + testRunId + ')'; - message.setBody(messageBody); + Message message = conTwo.getStanzaFactory().buildMessageStanza() + .to(userTwo) + .setBody(messageBody) + .build(); + final String messageId = message.getStanzaId(); final SimpleResultSyncPoint messageReceived = new SimpleResultSyncPoint(); @@ -122,7 +125,10 @@ public class MamIntegrationTest extends AbstractSmackIntegrationTest { for (int i = 0; i < totalMessages; i++) { String messageBody = "MAM Page Test " + testRunId + ' ' + (i + 1); - Message message = new Message(userTwo, messageBody); + Message message = StanzaBuilder.buildMessage() + .to(userTwo) + .setBody(messageBody) + .build(); outgoingMessages.add(message); } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java index 5d96468c3..c7651a052 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/muc/MultiUserChatIntegrationTest.java @@ -28,6 +28,7 @@ import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smack.util.StringUtils; + import org.jivesoftware.smackx.muc.MultiUserChat.MucCreateConfigFormHandle; import org.jivesoftware.smackx.muc.MultiUserChatException.MucNotJoinedException; import org.jivesoftware.smackx.muc.MultiUserChatException.NotAMucServiceException; diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/AbstractOmemoMessageListener.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/AbstractOmemoMessageListener.java index 073c82e7e..48ffb202b 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/AbstractOmemoMessageListener.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/AbstractOmemoMessageListener.java @@ -18,6 +18,7 @@ package org.jivesoftware.smackx.omemo; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Stanza; + import org.jivesoftware.smackx.carbons.packet.CarbonExtension; import org.jivesoftware.smackx.omemo.listener.OmemoMessageListener; diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/MessageEncryptionIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/MessageEncryptionIntegrationTest.java index 6a9ba5e20..938696441 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/MessageEncryptionIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/MessageEncryptionIntegrationTest.java @@ -20,7 +20,10 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.packet.MessageBuilder; + import org.jivesoftware.smackx.omemo.element.OmemoBundleElement; import org.igniterealtime.smack.inttest.SmackIntegrationTest; @@ -68,7 +71,10 @@ public class MessageEncryptionIntegrationTest extends AbstractTwoUsersOmemoInteg new AbstractOmemoMessageListener.PreKeyMessageListener(body1); bob.addOmemoMessageListener(listener1); OmemoMessage.Sent e1 = alice.encrypt(bob.getOwnJid(), body1); - alice.getConnection().sendStanza(e1.asMessage(bob.getOwnJid())); + + XMPPConnection alicesConnection = alice.getConnection(); + MessageBuilder messageBuilder = alicesConnection.getStanzaFactory().buildMessageStanza(); + alicesConnection.sendStanza(e1.buildMessage(messageBuilder, bob.getOwnJid())); listener1.getSyncPoint().waitForResult(10 * 1000); bob.removeOmemoMessageListener(listener1); @@ -88,7 +94,9 @@ public class MessageEncryptionIntegrationTest extends AbstractTwoUsersOmemoInteg new AbstractOmemoMessageListener.MessageListener(body3); alice.addOmemoMessageListener(listener3); OmemoMessage.Sent e3 = bob.encrypt(alice.getOwnJid(), body3); - bob.getConnection().sendStanza(e3.asMessage(alice.getOwnJid())); + XMPPConnection bobsConnection = bob.getConnection(); + messageBuilder = bobsConnection.getStanzaFactory().buildMessageStanza(); + bobsConnection.sendStanza(e3.buildMessage(messageBuilder, alice.getOwnJid())); listener3.getSyncPoint().waitForResult(10 * 1000); alice.removeOmemoMessageListener(listener3); diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoMamDecryptionTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoMamDecryptionTest.java index b562db8f8..8a36a2f22 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoMamDecryptionTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoMamDecryptionTest.java @@ -22,7 +22,10 @@ import java.io.IOException; import java.util.List; import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.packet.MessageBuilder; + import org.jivesoftware.smackx.mam.MamManager; import org.jivesoftware.smackx.mam.element.MamPrefsIQ; import org.jivesoftware.smackx.omemo.exceptions.CryptoFailedException; @@ -62,7 +65,10 @@ public class OmemoMamDecryptionTest extends AbstractTwoUsersOmemoIntegrationTest String body = "This message will be stored in MAM!"; OmemoMessage.Sent encrypted = alice.encrypt(bob.getOwnJid(), body); - alice.getConnection().sendStanza(encrypted.asMessage(bob.getOwnJid())); + + XMPPConnection alicesConnection = alice.getConnection(); + MessageBuilder messageBuilder = alicesConnection.getStanzaFactory().buildMessageStanza(); + alicesConnection.sendStanza(encrypted.buildMessage(messageBuilder, bob.getOwnJid())); MamManager.MamQuery query = bobsMamManager.queryArchive(MamManager.MamQueryArgs.builder().limitResultsToJid(alice.getOwnJid()).build()); assertEquals(1, query.getMessageCount()); diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoManagerSetupHelper.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoManagerSetupHelper.java index fba866790..f330880ad 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoManagerSetupHelper.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/OmemoManagerSetupHelper.java @@ -28,6 +28,7 @@ import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.roster.Roster; import org.jivesoftware.smack.roster.RosterEntry; + import org.jivesoftware.smackx.omemo.exceptions.CannotEstablishOmemoSessionException; import org.jivesoftware.smackx.omemo.exceptions.CorruptedOmemoKeyException; import org.jivesoftware.smackx.omemo.internal.OmemoCachedDeviceList; diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/ReadOnlyDeviceIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/ReadOnlyDeviceIntegrationTest.java index 815d4a032..dc13bdb8f 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/ReadOnlyDeviceIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/ReadOnlyDeviceIntegrationTest.java @@ -24,6 +24,7 @@ import java.io.IOException; import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPException; + import org.jivesoftware.smackx.omemo.exceptions.CryptoFailedException; import org.jivesoftware.smackx.omemo.exceptions.ReadOnlyDeviceException; import org.jivesoftware.smackx.omemo.exceptions.UndecidedOmemoIdentityException; diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/SessionRenegotiationIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/SessionRenegotiationIntegrationTest.java index ae1324b22..fa863f1be 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/SessionRenegotiationIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/omemo/SessionRenegotiationIntegrationTest.java @@ -17,7 +17,9 @@ package org.jivesoftware.smackx.omemo; import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.packet.MessageBuilder; import org.igniterealtime.smack.inttest.SmackIntegrationTest; import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; @@ -46,7 +48,10 @@ public class SessionRenegotiationIntegrationTest extends AbstractTwoUsersOmemoIn new AbstractOmemoMessageListener.PreKeyMessageListener(body1); OmemoMessage.Sent e1 = alice.encrypt(bob.getOwnJid(), body1); bob.addOmemoMessageListener(listener1); - alice.getConnection().sendStanza(e1.asMessage(bob.getOwnJid())); + + XMPPConnection alicesConnection = alice.getConnection(); + MessageBuilder messageBuilder = alicesConnection.getStanzaFactory().buildMessageStanza(); + alicesConnection.sendStanza(e1.buildMessage(messageBuilder, bob.getOwnJid())); listener1.getSyncPoint().waitForResult(10 * 1000); bob.removeOmemoMessageListener(listener1); @@ -61,7 +66,9 @@ public class SessionRenegotiationIntegrationTest extends AbstractTwoUsersOmemoIn new AbstractOmemoMessageListener.PreKeyKeyTransportListener(); OmemoMessage.Sent e2 = alice.encrypt(bob.getOwnJid(), body2); alice.addOmemoMessageListener(listener2); - alice.getConnection().sendStanza(e2.asMessage(bob.getOwnJid())); + + messageBuilder = alicesConnection.getStanzaFactory().buildMessageStanza(); + alicesConnection.sendStanza(e2.buildMessage(messageBuilder, bob.getOwnJid())); listener2.getSyncPoint().waitForResult(10 * 1000); alice.removeOmemoMessageListener(listener2); @@ -70,7 +77,9 @@ public class SessionRenegotiationIntegrationTest extends AbstractTwoUsersOmemoIn AbstractOmemoMessageListener.MessageListener listener3 = new AbstractOmemoMessageListener.MessageListener(body3); OmemoMessage.Sent e3 = alice.encrypt(bob.getOwnJid(), body3); bob.addOmemoMessageListener(listener3); - alice.getConnection().sendStanza(e3.asMessage(bob.getOwnJid())); + + messageBuilder = alicesConnection.getStanzaFactory().buildMessageStanza(); + alicesConnection.sendStanza(e3.buildMessage(messageBuilder, bob.getOwnJid())); listener3.getSyncPoint().waitForResult(10 * 1000); bob.removeOmemoMessageListener(listener3); diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox/AbstractOpenPgpIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox/AbstractOpenPgpIntegrationTest.java index 2399c6999..d02d4f3f5 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox/AbstractOpenPgpIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox/AbstractOpenPgpIntegrationTest.java @@ -19,6 +19,7 @@ package org.jivesoftware.smackx.ox; import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; + import org.jivesoftware.smackx.ox.util.OpenPgpPubSubUtil; import org.jivesoftware.smackx.pep.PepManager; diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox/OXSecretKeyBackupIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox/OXSecretKeyBackupIntegrationTest.java index b72636bc8..897dda339 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox/OXSecretKeyBackupIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox/OXSecretKeyBackupIntegrationTest.java @@ -33,6 +33,7 @@ import java.util.logging.Level; import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.util.StringUtils; + import org.jivesoftware.smackx.ox.callback.backup.AskForBackupCodeCallback; import org.jivesoftware.smackx.ox.callback.backup.DisplayBackupCodeCallback; import org.jivesoftware.smackx.ox.callback.backup.SecretKeyBackupSelectionCallback; diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox_im/OXInstantMessagingIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox_im/OXInstantMessagingIntegrationTest.java index 1b469953d..1f68eeb4d 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox_im/OXInstantMessagingIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/ox_im/OXInstantMessagingIntegrationTest.java @@ -27,6 +27,7 @@ import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.util.StringUtils; + import org.jivesoftware.smackx.ox.AbstractOpenPgpIntegrationTest; import org.jivesoftware.smackx.ox.OpenPgpContact; import org.jivesoftware.smackx.ox.OpenPgpManager; diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/usertune/UserTuneIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/usertune/UserTuneIntegrationTest.java index 86383a819..c766bc6e5 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/usertune/UserTuneIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/usertune/UserTuneIntegrationTest.java @@ -22,6 +22,7 @@ import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.SmackException.NotLoggedInException; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.packet.Message; + import org.jivesoftware.smackx.usertune.element.UserTuneElement; import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest; @@ -30,7 +31,6 @@ import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment; import org.igniterealtime.smack.inttest.util.IntegrationTestRosterUtil; import org.igniterealtime.smack.inttest.util.SimpleResultSyncPoint; import org.junit.AfterClass; - import org.jxmpp.jid.BareJid; public class UserTuneIntegrationTest extends AbstractSmackIntegrationTest { diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smackx/xdata/FormTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smackx/xdata/FormTest.java index 682f3b82f..cf89a68f2 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smackx/xdata/FormTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smackx/xdata/FormTest.java @@ -25,6 +25,8 @@ import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smack.StanzaCollector; import org.jivesoftware.smack.filter.ThreadFilter; import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.packet.StanzaBuilder; + import org.jivesoftware.smackx.xdata.FormField.Type; import org.jivesoftware.smackx.xdata.packet.DataForm; @@ -96,9 +98,10 @@ public class FormTest extends AbstractSmackIntegrationTest { StanzaCollector collector2 = conTwo.createStanzaCollector( new ThreadFilter(chat.getThreadID())); - Message msg = new Message(); - msg.setBody("To enter a case please fill out this form and send it back to me"); - msg.addExtension(formToSend.getDataFormToSend()); + Message msg = StanzaBuilder.buildMessage() + .setBody("To enter a case please fill out this form and send it back to me") + .addExtension(formToSend.getDataFormToSend()) + .build(); try { // Send the message with the form to fill out @@ -130,13 +133,14 @@ public class FormTest extends AbstractSmackIntegrationTest { completedForm.setAnswer("time", true); completedForm.setAnswer("age", 20); // Create a new message to send with the completed form - msg2 = new Message(); - msg2.setTo(conOne.getUser().asBareJid()); - msg2.setThread(msg.getThread()); - msg2.setType(Message.Type.chat); - msg2.setBody("To enter a case please fill out this form and send it back to me"); - // Add the completed form to the message - msg2.addExtension(completedForm.getDataFormToSend()); + msg2 = StanzaBuilder.buildMessage() + .to(conOne.getUser().asBareJid()) + .setThread(msg.getThread()) + .ofType(Message.Type.chat) + .setBody("To enter a case please fill out this form and send it back to me") + // Add the completed form to the message + .addExtension(completedForm.getDataFormToSend()) + .build(); // Send the message with the completed form conTwo.sendStanza(msg2); diff --git a/smack-integration-test/src/test/java/org/igniterealtime/smack/inttest/unittest/SmackIntegrationTestFrameworkUnitTest.java b/smack-integration-test/src/test/java/org/igniterealtime/smack/inttest/unittest/SmackIntegrationTestFrameworkUnitTest.java index d94a9b16c..fe943873b 100644 --- a/smack-integration-test/src/test/java/org/igniterealtime/smack/inttest/unittest/SmackIntegrationTestFrameworkUnitTest.java +++ b/smack-integration-test/src/test/java/org/igniterealtime/smack/inttest/unittest/SmackIntegrationTestFrameworkUnitTest.java @@ -31,6 +31,7 @@ import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.packet.StanzaBuilder; import org.jivesoftware.smack.packet.StanzaError; import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest; @@ -112,7 +113,7 @@ public class SmackIntegrationTestFrameworkUnitTest { @SmackIntegrationTest public void throwRuntimeExceptionTest() throws XMPPErrorException { - Message message = new Message(); + Message message = StanzaBuilder.buildMessage().build(); throw new XMPPException.XMPPErrorException(message, StanzaError.from(StanzaError.Condition.bad_request, DESCRIPTIVE_TEXT).build()); } diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/JingleSession.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/JingleSession.java index 03aba4ff4..43b92937f 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/JingleSession.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/JingleSession.java @@ -1070,8 +1070,10 @@ public final class JingleSession extends JingleNegotiator implements MediaReceiv IQ errorPacket = null; if (jingleError != null) { // TODO This is wrong according to XEP-166 § 10, but this jingle implementation is deprecated anyways - StanzaError.Builder builder = StanzaError.getBuilder(StanzaError.Condition.undefined_condition); - builder.addExtension(jingleError); + StanzaError builder = StanzaError.getBuilder() + .setCondition(StanzaError.Condition.undefined_condition) + .addExtension(jingleError) + .build(); errorPacket = IQ.createErrorResponse(iq, builder); diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentRoster.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentRoster.java index 1a0fc285f..199031b87 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentRoster.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentRoster.java @@ -34,7 +34,7 @@ import org.jivesoftware.smack.filter.StanzaFilter; import org.jivesoftware.smack.filter.StanzaTypeFilter; import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smack.packet.Stanza; - +import org.jivesoftware.smack.packet.StanzaBuilder; import org.jivesoftware.smackx.workgroup.packet.AgentStatus; import org.jivesoftware.smackx.workgroup.packet.AgentStatusRequest; @@ -213,8 +213,10 @@ public class AgentRoster { Jid key = getPresenceMapKey(user); Map userPresences = presenceMap.get(key); if (userPresences == null) { - Presence presence = new Presence(Presence.Type.unavailable); - presence.setFrom(user); + Presence presence = StanzaBuilder.buildPresence() + .ofType(Presence.Type.unavailable) + .from(user) + .build(); return presence; } else { @@ -236,8 +238,7 @@ public class AgentRoster { } } if (presence == null) { - presence = new Presence(Presence.Type.unavailable); - presence.setFrom(user); + presence = synthesizeUnvailablePresence(user); return presence; } else { @@ -289,6 +290,13 @@ public class AgentRoster { } } + private static Presence synthesizeUnvailablePresence(Jid from) { + return StanzaBuilder.buildPresence() + .ofType(Presence.Type.unavailable) + .from(from) + .build(); + } + /** * Listens for all presence packets and processes them. */ diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java index e608fc683..00461afd4 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java @@ -45,9 +45,9 @@ import org.jivesoftware.smack.iqrequest.IQRequestHandler.Mode; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Presence; +import org.jivesoftware.smack.packet.PresenceBuilder; import org.jivesoftware.smack.packet.StandardExtensionElement; import org.jivesoftware.smack.packet.Stanza; - import org.jivesoftware.smackx.muc.packet.MUCUser; import org.jivesoftware.smackx.search.ReportedData; import org.jivesoftware.smackx.workgroup.MetaData; @@ -335,8 +335,11 @@ public class AgentSession { // If the user is going online... if (online) { - presence = new Presence(Presence.Type.available); - presence.setTo(workgroupJID); + presence = connection.getStanzaFactory().buildPresenceStanza() + .ofType(Presence.Type.available) + .to(workgroupJID) + .build(); + presence.addExtension(new StandardExtensionElement(AgentStatus.ELEMENT_NAME, AgentStatus.NAMESPACE)); @@ -353,8 +356,10 @@ public class AgentSession { // Update this iv now since we don't care at this point of any error this.online = online; - presence = new Presence(Presence.Type.unavailable); - presence.setTo(workgroupJID); + presence = connection.getStanzaFactory().buildPresenceStanza() + .ofType(Presence.Type.unavailable) + .to(workgroupJID) + .build(); presence.addExtension(new StandardExtensionElement(AgentStatus.ELEMENT_NAME, AgentStatus.NAMESPACE)); connection.sendStanza(presence); @@ -427,21 +432,21 @@ public class AgentSession { this.presenceMode = presenceMode; this.maxChats = maxChats; - Presence presence = new Presence(Presence.Type.available); - presence.setMode(presenceMode); - presence.setTo(this.getWorkgroupJID()); - - if (status != null) { - presence.setStatus(status); - } + PresenceBuilder presenceBuilder = connection.getStanzaFactory().buildPresenceStanza() + .ofType(Presence.Type.available) + .setMode(presenceMode) + .to(workgroupJID) + .setStatus(status) + ; // Send information about max chats and current chats as a packet extension. StandardExtensionElement.Builder builder = StandardExtensionElement.builder(AgentStatus.ELEMENT_NAME, AgentStatus.NAMESPACE); builder.addElement("max_chats", Integer.toString(maxChats)); - presence.addExtension(builder.build()); - presence.addExtension(new MetaData(this.metaData)); + presenceBuilder.addExtension(builder.build()); + presenceBuilder.addExtension(new MetaData(this.metaData)); + Presence presence = presenceBuilder.build(); StanzaCollector collector = this.connection.createStanzaCollectorAndSend(new AndFilter( new StanzaTypeFilter(Presence.class), FromMatchesFilter.create(workgroupJID)), presence); @@ -478,13 +483,16 @@ public class AgentSession { } this.presenceMode = presenceMode; - Presence presence = new Presence(Presence.Type.available); - presence.setMode(presenceMode); - presence.setTo(this.getWorkgroupJID()); + PresenceBuilder presenceBuilder = connection.getStanzaFactory().buildPresenceStanza() + .ofType(Presence.Type.available) + .setMode(presenceMode) + .to(getWorkgroupJID()); if (status != null) { - presence.setStatus(status); + presenceBuilder.setStatus(status); } + + Presence presence = presenceBuilder.build(); presence.addExtension(new MetaData(this.metaData)); StanzaCollector collector = this.connection.createStanzaCollectorAndSend(new AndFilter(new StanzaTypeFilter(Presence.class), diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/user/Workgroup.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/user/Workgroup.java index 99907adc6..8f1319173 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/user/Workgroup.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/user/Workgroup.java @@ -188,8 +188,11 @@ public class Workgroup { * @throws InterruptedException if the calling thread was interrupted. */ public boolean isAvailable() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { - Presence directedPresence = new Presence(Presence.Type.available); - directedPresence.setTo(workgroupJID); + Presence directedPresence = connection.getStanzaFactory().buildPresenceStanza() + .ofType(Presence.Type.available) + .to(workgroupJID) + .build(); + StanzaFilter typeFilter = new StanzaTypeFilter(Presence.class); StanzaFilter fromFilter = FromMatchesFilter.create(workgroupJID); StanzaCollector collector = connection.createStanzaCollectorAndSend(new AndFilter(fromFilter, diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/xevent/MessageEventManager.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/xevent/MessageEventManager.java index a2ca8d17b..23b048ec0 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/xevent/MessageEventManager.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/xevent/MessageEventManager.java @@ -213,15 +213,18 @@ public final class MessageEventManager extends Manager { * @throws InterruptedException if the calling thread was interrupted. */ public void sendDeliveredNotification(Jid to, String packetID) throws NotConnectedException, InterruptedException { - // Create the message to send - Message msg = new Message(to); // Create a MessageEvent Package and add it to the message MessageEvent messageEvent = new MessageEvent(); messageEvent.setDelivered(true); messageEvent.setStanzaId(packetID); - msg.addExtension(messageEvent); + + XMPPConnection connection = connection(); + Message msg = connection.getStanzaFactory().buildMessageStanza() + .to(to) + .addExtension(messageEvent) + .build(); // Send the packet - connection().sendStanza(msg); + connection.sendStanza(msg); } /** @@ -233,15 +236,18 @@ public final class MessageEventManager extends Manager { * @throws InterruptedException if the calling thread was interrupted. */ public void sendDisplayedNotification(Jid to, String packetID) throws NotConnectedException, InterruptedException { - // Create the message to send - Message msg = new Message(to); // Create a MessageEvent Package and add it to the message MessageEvent messageEvent = new MessageEvent(); messageEvent.setDisplayed(true); messageEvent.setStanzaId(packetID); - msg.addExtension(messageEvent); + + XMPPConnection connection = connection(); + Message msg = connection.getStanzaFactory().buildMessageStanza() + .to(to) + .addExtension(messageEvent) + .build(); // Send the packet - connection().sendStanza(msg); + connection.sendStanza(msg); } /** @@ -253,15 +259,18 @@ public final class MessageEventManager extends Manager { * @throws InterruptedException if the calling thread was interrupted. */ public void sendComposingNotification(Jid to, String packetID) throws NotConnectedException, InterruptedException { - // Create the message to send - Message msg = new Message(to); // Create a MessageEvent Package and add it to the message MessageEvent messageEvent = new MessageEvent(); messageEvent.setComposing(true); messageEvent.setStanzaId(packetID); - msg.addExtension(messageEvent); + + XMPPConnection connection = connection(); + Message msg = connection.getStanzaFactory().buildMessageStanza() + .to(to) + .addExtension(messageEvent) + .build(); // Send the packet - connection().sendStanza(msg); + connection.sendStanza(msg); } /** @@ -273,13 +282,17 @@ public final class MessageEventManager extends Manager { * @throws InterruptedException if the calling thread was interrupted. */ public void sendCancelledNotification(Jid to, String packetID) throws NotConnectedException, InterruptedException { - // Create the message to send - Message msg = new Message(to); // Create a MessageEvent Package and add it to the message MessageEvent messageEvent = new MessageEvent(); messageEvent.setCancelled(true); messageEvent.setStanzaId(packetID); - msg.addExtension(messageEvent); + + XMPPConnection connection = connection(); + + Message msg = connection.getStanzaFactory().buildMessageStanza() + .to(to) + .addExtension(messageEvent) + .build(); // Send the packet connection().sendStanza(msg); } diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/xroster/RosterExchangeManager.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/xroster/RosterExchangeManager.java index 1f42c6f02..6af000028 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/xroster/RosterExchangeManager.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/xroster/RosterExchangeManager.java @@ -30,6 +30,7 @@ import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.filter.StanzaExtensionFilter; import org.jivesoftware.smack.filter.StanzaFilter; import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.packet.MessageBuilder; import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.roster.Roster; import org.jivesoftware.smack.roster.RosterEntry; @@ -121,15 +122,16 @@ public class RosterExchangeManager { * @throws InterruptedException if the calling thread was interrupted. */ public void send(Roster roster, Jid targetUserID) throws NotConnectedException, InterruptedException { + XMPPConnection connection = weakRefConnection.get(); + // Create a new message to send the roster - Message msg = new Message(targetUserID); + MessageBuilder messageBuilder = connection.getStanzaFactory().buildMessageStanza().to(targetUserID); // Create a RosterExchange Package and add it to the message RosterExchange rosterExchange = new RosterExchange(roster); - msg.addExtension(rosterExchange); + messageBuilder.addExtension(rosterExchange); - XMPPConnection connection = weakRefConnection.get(); // Send the message that contains the roster - connection.sendStanza(msg); + connection.sendStanza(messageBuilder.build()); } /** @@ -141,16 +143,17 @@ public class RosterExchangeManager { * @throws InterruptedException if the calling thread was interrupted. */ public void send(RosterEntry rosterEntry, Jid targetUserID) throws NotConnectedException, InterruptedException { + XMPPConnection connection = weakRefConnection.get(); + // Create a new message to send the roster - Message msg = new Message(targetUserID); + MessageBuilder messageBuilder = connection.getStanzaFactory().buildMessageStanza().to(targetUserID); // Create a RosterExchange Package and add it to the message RosterExchange rosterExchange = new RosterExchange(); rosterExchange.addRosterEntry(rosterEntry); - msg.addExtension(rosterExchange); + messageBuilder.addExtension(rosterExchange); - XMPPConnection connection = weakRefConnection.get(); // Send the message that contains the roster - connection.sendStanza(msg); + connection.sendStanza(messageBuilder.build()); } /** @@ -163,8 +166,10 @@ public class RosterExchangeManager { * @throws InterruptedException if the calling thread was interrupted. */ public void send(RosterGroup rosterGroup, Jid targetUserID) throws NotConnectedException, InterruptedException { + XMPPConnection connection = weakRefConnection.get(); + // Create a new message to send the roster - Message msg = new Message(targetUserID); + MessageBuilder msg = connection.getStanzaFactory().buildMessageStanza().to(targetUserID); // Create a RosterExchange Package and add it to the message RosterExchange rosterExchange = new RosterExchange(); for (RosterEntry entry : rosterGroup.getEntries()) { @@ -172,9 +177,8 @@ public class RosterExchangeManager { } msg.addExtension(rosterExchange); - XMPPConnection connection = weakRefConnection.get(); // Send the message that contains the roster - connection.sendStanza(msg); + connection.sendStanza(msg.build()); } /** diff --git a/smack-omemo-signal/src/test/java/org/jivesoftware/smackx/omemo/SignalOmemoManagerTest.java b/smack-omemo-signal/src/test/java/org/jivesoftware/smackx/omemo/SignalOmemoManagerTest.java index 64d07a9ff..15299a259 100644 --- a/smack-omemo-signal/src/test/java/org/jivesoftware/smackx/omemo/SignalOmemoManagerTest.java +++ b/smack-omemo-signal/src/test/java/org/jivesoftware/smackx/omemo/SignalOmemoManagerTest.java @@ -28,6 +28,7 @@ import static junit.framework.TestCase.assertTrue; import org.jivesoftware.smack.DummyConnection; 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.smackx.omemo.element.OmemoElement; @@ -83,9 +84,9 @@ public class SignalOmemoManagerTest extends SmackTestSuite { public void stanzaRecognitionTest() throws Exception { String omemoXML = "

MwohBfRqBm2atj3fT0/KUDg59Cnvfpgoe/PLNIu1xgSXujEZEAAYACIwKh6TTC7VBQZcCcKnQlO+6s1GQ9DIRKH4JU7XrJ+JJnkPUwJ4VLSeOEQD7HmFbhQPTLZO0u/qlng=sN0amy4e2NBrlb4G/OjNIQ==
4xVUAeg4M0Mhk+5n3YG1x12Dw/cYTc0Z"; OmemoElement omemoElement = new OmemoVAxolotlProvider().parse(TestUtils.getParser(omemoXML)); - Message m = new Message(); - m.addExtension(omemoElement); - Message n = new Message(); + + Message m = StanzaBuilder.buildMessage().addExtension(omemoElement).build(); + Message n = StanzaBuilder.buildMessage().build(); assertTrue(OmemoManager.stanzaContainsOmemoElement(m)); assertFalse(OmemoManager.stanzaContainsOmemoElement(n)); diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java index 04f226b9f..ba53e452c 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java @@ -43,6 +43,7 @@ import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.filter.StanzaFilter; import org.jivesoftware.smack.packet.ExtensionElement; import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.packet.MessageBuilder; import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.util.Async; @@ -491,16 +492,17 @@ public final class OmemoManager extends Manager { throws SmackException.NotLoggedInException, CorruptedOmemoKeyException, InterruptedException, SmackException.NoResponseException, NoSuchAlgorithmException, SmackException.NotConnectedException, CryptoFailedException, CannotEstablishOmemoSessionException, IOException { - Message message = new Message(); - message.setFrom(getOwnJid()); - message.setTo(recipient.getJid()); + XMPPConnection connection = connection(); + MessageBuilder message = connection.getStanzaFactory() + .buildMessageStanza() + .to(recipient.getJid()); OmemoElement element = getOmemoService().createRatchetUpdateElement(new LoggedInOmemoManager(this), recipient); message.addExtension(element); // Set MAM Storage hint StoreHint.set(message); - connection().sendStanza(message); + connection.sendStanza(message.build()); } /** diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoMessage.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoMessage.java index 0bfa1847e..2d5554e7f 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoMessage.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoMessage.java @@ -25,6 +25,7 @@ import java.util.HashSet; import java.util.Set; import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.packet.MessageBuilder; import org.jivesoftware.smackx.eme.element.ExplicitMessageEncryptionElement; import org.jivesoftware.smackx.hints.element.StoreHint; @@ -123,22 +124,23 @@ public class OmemoMessage { * as well as an optional clear text hint as body, a MAM storage hint * and an EME hint about OMEMO encryption. * + * @param messageBuilder a message builder which will be used to build the message. * @param recipient recipient for the to-field of the message. - * @return Message TODO javadoc me please + * @return the build message. */ - public Message asMessage(Jid recipient) { + public Message buildMessage(MessageBuilder messageBuilder, Jid recipient) { + messageBuilder.ofType(Message.Type.chat).to(recipient); - Message messageStanza = new Message(recipient, Message.Type.chat); - messageStanza.addExtension(getElement()); + messageBuilder.addExtension(getElement()); if (OmemoConfiguration.getAddOmemoHintBody()) { - messageStanza.setBody(BODY_OMEMO_HINT); + messageBuilder.setBody(BODY_OMEMO_HINT); } - StoreHint.set(messageStanza); - messageStanza.addExtension(new ExplicitMessageEncryptionElement(OMEMO_NAMESPACE_V_AXOLOTL, OMEMO)); + StoreHint.set(messageBuilder); + messageBuilder.addExtension(new ExplicitMessageEncryptionElement(OMEMO_NAMESPACE_V_AXOLOTL, OMEMO)); - return messageStanza; + return messageBuilder.build(); } } diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoService.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoService.java index c5cac27e5..b5ace3d69 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoService.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoService.java @@ -45,6 +45,7 @@ import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.packet.StanzaError; + import org.jivesoftware.smackx.carbons.packet.CarbonExtension; import org.jivesoftware.smackx.mam.MamManager; import org.jivesoftware.smackx.muc.MultiUserChat; @@ -1343,10 +1344,13 @@ public abstract class OmemoServicesingletonList(mBody)); - OpenPgpMetadata metadata = addOxMessage(message, contact, Collections.singletonList(mBody)); - + Message message = messageBuilder.build(); ChatManager.getInstanceFor(connection()).chatWith(contact.getJid().asEntityBareJidIfPossible()).send(message); return metadata; @@ -241,7 +246,7 @@ public final class OXInstantMessagingManager extends Manager { /** * Add an OX-IM message element to a message. * - * @param message message + * @param messageBuilder a message builder. * @param contact recipient of the message * @param payload payload which will be encrypted and signed * @@ -251,15 +256,15 @@ public final class OXInstantMessagingManager extends Manager { * @throws PGPException in case something goes wrong during encryption * @throws IOException IO is dangerous (we need to read keys) */ - public OpenPgpMetadata addOxMessage(Message message, OpenPgpContact contact, List payload) + public OpenPgpMetadata addOxMessage(MessageBuilder messageBuilder, OpenPgpContact contact, List payload) throws SmackException.NotLoggedInException, PGPException, IOException { - return addOxMessage(message, Collections.singleton(contact), payload); + return addOxMessage(messageBuilder, Collections.singleton(contact), payload); } /** * Add an OX-IM message element to a message. * - * @param message message + * @param messageBuilder message * @param contacts recipients of the message * @param payload payload which will be encrypted and signed * @@ -269,7 +274,7 @@ public final class OXInstantMessagingManager extends Manager { * @throws PGPException in case something goes wrong during encryption * @throws IOException IO is dangerous (we need to read keys) */ - public OpenPgpMetadata addOxMessage(Message message, Set contacts, List payload) + public OpenPgpMetadata addOxMessage(MessageBuilder messageBuilder, Set contacts, List payload) throws SmackException.NotLoggedInException, IOException, PGPException { HashSet recipients = new HashSet<>(contacts); @@ -277,13 +282,13 @@ public final class OXInstantMessagingManager extends Manager { recipients.add(self); OpenPgpElementAndMetadata openPgpElementAndMetadata = signAndEncrypt(recipients, payload); - message.addExtension(openPgpElementAndMetadata.getElement()); + messageBuilder.addExtension(openPgpElementAndMetadata.getElement()); // Set hints on message - ExplicitMessageEncryptionElement.set(message, + ExplicitMessageEncryptionElement.set(messageBuilder, ExplicitMessageEncryptionElement.ExplicitMessageEncryptionProtocol.openpgpV0); - StoreHint.set(message); - setOXBodyHint(message); + StoreHint.set(messageBuilder); + setOXBodyHint(messageBuilder); return openPgpElementAndMetadata.getMetadata(); } @@ -349,7 +354,7 @@ public final class OXInstantMessagingManager extends Manager { * * @param message message */ - private static void setOXBodyHint(Message message) { + private static void setOXBodyHint(MessageBuilder message) { message.setBody("This message is encrypted using XEP-0374: OpenPGP for XMPP: Instant Messaging."); } diff --git a/smack-openpgp/src/test/java/org/jivesoftware/smackx/ox_im/OXInstantMessagingManagerTest.java b/smack-openpgp/src/test/java/org/jivesoftware/smackx/ox_im/OXInstantMessagingManagerTest.java index 85de7aae0..fbf33e6a3 100644 --- a/smack-openpgp/src/test/java/org/jivesoftware/smackx/ox_im/OXInstantMessagingManagerTest.java +++ b/smack-openpgp/src/test/java/org/jivesoftware/smackx/ox_im/OXInstantMessagingManagerTest.java @@ -34,6 +34,8 @@ import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.XMPPException; 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.smack.util.StringUtils; import org.jivesoftware.smack.xml.XmlPullParserException; @@ -138,11 +140,13 @@ public class OXInstantMessagingManagerTest extends SmackTestSuite { assertFalse(aliceForBob.hasUndecidedKeys()); assertFalse(bobForAlice.hasUndecidedKeys()); - Message message = new Message(); - assertFalse(ExplicitMessageEncryptionElement.hasProtocol(message, ExplicitMessageEncryptionElement.ExplicitMessageEncryptionProtocol.openpgpV0)); + MessageBuilder messageBuilder = StanzaBuilder.buildMessage(); + assertFalse(ExplicitMessageEncryptionElement.hasProtocol(messageBuilder.build(), ExplicitMessageEncryptionElement.ExplicitMessageEncryptionProtocol.openpgpV0)); - aliceOxim.addOxMessage(message, bobForAlice, + aliceOxim.addOxMessage(messageBuilder, bobForAlice, Collections.singletonList(new Message.Body(null, "Hello World!"))); + + Message message = messageBuilder.build(); assertTrue(ExplicitMessageEncryptionElement.hasProtocol(message, ExplicitMessageEncryptionElement.ExplicitMessageEncryptionProtocol.openpgpV0)); assertNotNull(OpenPgpElement.fromStanza(message)); diff --git a/smack-repl/src/main/java/org/igniterealtime/smack/smackrepl/Nio.java b/smack-repl/src/main/java/org/igniterealtime/smack/smackrepl/Nio.java index 05f0096e7..9f73c42c5 100644 --- a/smack-repl/src/main/java/org/igniterealtime/smack/smackrepl/Nio.java +++ b/smack-repl/src/main/java/org/igniterealtime/smack/smackrepl/Nio.java @@ -95,8 +95,10 @@ public class Nio { connection.login(); - Message message = new Message("flo@geekplace.eu", - "It is alive! " + XmppDateTime.formatXEP0082Date(new Date())); + Message message = connection.getStanzaFactory().buildMessageStanza() + .to("flo@geekplace.eu") + .setBody("It is alive! " + XmppDateTime.formatXEP0082Date(new Date())) + .build(); connection.sendStanza(message); Thread.sleep(1000); diff --git a/smack-repl/src/main/java/org/igniterealtime/smack/smackrepl/OmemoClient.java b/smack-repl/src/main/java/org/igniterealtime/smack/smackrepl/OmemoClient.java index 7518ba18e..dc4b343e6 100644 --- a/smack-repl/src/main/java/org/igniterealtime/smack/smackrepl/OmemoClient.java +++ b/smack-repl/src/main/java/org/igniterealtime/smack/smackrepl/OmemoClient.java @@ -36,6 +36,7 @@ import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smack.SmackException.NotLoggedInException; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.packet.MessageBuilder; import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.tcp.XMPPTCPConnection; import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration; @@ -166,8 +167,9 @@ public class OmemoClient { BareJid recipient = JidCreate.bareFrom(com[1]); String body = com[2]; + MessageBuilder messageBuilder = connection.getStanzaFactory().buildMessageStanza(); try { - Message omemoMessage = omemoManager.encrypt(recipient, body).asMessage(recipient); + Message omemoMessage = omemoManager.encrypt(recipient, body).buildMessage(messageBuilder, recipient); connection.sendStanza(omemoMessage); } catch (UndecidedOmemoIdentityException e) { print("Undecided Identities!\n" + Arrays.toString(e.getUndecidedDevices().toArray())); diff --git a/smack-tcp/src/test/java/org/jivesoftware/smack/tcp/PacketWriterTest.java b/smack-tcp/src/test/java/org/jivesoftware/smack/tcp/PacketWriterTest.java index 940c8910f..9658b9f7f 100644 --- a/smack-tcp/src/test/java/org/jivesoftware/smack/tcp/PacketWriterTest.java +++ b/smack-tcp/src/test/java/org/jivesoftware/smack/tcp/PacketWriterTest.java @@ -31,7 +31,7 @@ import java.util.concurrent.atomic.AtomicReference; import org.jivesoftware.smack.AbstractXMPPConnection; import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.SmackException.NotConnectedException; -import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.packet.StanzaBuilder; import org.jivesoftware.smack.tcp.XMPPTCPConnection.PacketWriter; import org.jivesoftware.smack.util.ExceptionUtil; @@ -80,7 +80,7 @@ public class PacketWriterTest { // full capacity. The +1 is because the writer thread will dequeue one stanza and try to write it into the // blocking writer. for (int i = 0; i < XMPPTCPConnection.PacketWriter.QUEUE_SIZE + 1; i++) { - pw.sendStreamElement(new Message()); + pw.sendStreamElement(StanzaBuilder.buildMessage().build()); } final CyclicBarrier barrier = new CyclicBarrier(2); @@ -93,7 +93,7 @@ public class PacketWriterTest { public void run() { try { barrier.await(); - pw.sendStreamElement(new Message()); + pw.sendStreamElement(StanzaBuilder.buildMessage().build()); // should only return after the pw was interrupted if (!shutdown) { prematureUnblocked = true; From e2d206e741a31f94b407fbc10923ee2fd14ab4e1 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Fri, 25 Oct 2019 13:57:18 +0200 Subject: [PATCH 02/16] Introduce XMPPConnection.add(Message|Presence)Interceptor add deprecate addStanzaInterceptor(). --- .../smack/AbstractXMPPConnection.java | 124 +++++++++++++++++- .../jivesoftware/smack/XMPPConnection.java | 57 +++++++- .../smack/filter/StanzaFilter.java | 8 +- .../jivesoftware/smack/packet/Message.java | 5 +- .../smack/packet/MessageBuilder.java | 3 +- .../smack/packet/MessageOrPresence.java | 36 +++++ .../packet/MessageOrPresenceBuilder.java | 42 ++++++ .../jivesoftware/smack/packet/Presence.java | 4 +- .../smack/packet/PresenceBuilder.java | 3 +- .../org/jivesoftware/smack/packet/Stanza.java | 8 +- .../jivesoftware/smack/packet/StanzaView.java | 20 +++ .../jivesoftware/smack/util/Predicate.java | 24 ++++ .../chat_markers/ChatMarkersManager.java | 16 +-- .../sid/StableUniqueStanzaIdManager.java | 24 ++-- .../smackx/sid/element/OriginIdElement.java | 18 +++ .../smackx/sid/StableUniqueStanzaIdTest.java | 8 +- .../jivesoftware/smack/chat2/ChatManager.java | 36 +++-- .../chat2/OutgoingChatMessageListener.java | 6 +- .../smackx/caps/EntityCapsManager.java | 37 +++--- .../smackx/chatstates/ChatStateManager.java | 7 +- .../smackx/muc/MultiUserChat.java | 4 +- .../receipts/DeliveryReceiptManager.java | 17 +-- .../smackx/xhtmlim/packet/XHTMLExtension.java | 10 +- ...utgoingMessageListenerIntegrationTest.java | 4 +- 24 files changed, 419 insertions(+), 102 deletions(-) create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/packet/MessageOrPresence.java create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/packet/MessageOrPresenceBuilder.java create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/util/Predicate.java diff --git a/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java b/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java index fc957c5fb..42ba0903e 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java @@ -100,8 +100,12 @@ import org.jivesoftware.smack.packet.FullyQualifiedElement; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Mechanisms; import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.packet.MessageBuilder; +import org.jivesoftware.smack.packet.MessageOrPresence; +import org.jivesoftware.smack.packet.MessageOrPresenceBuilder; import org.jivesoftware.smack.packet.Nonza; import org.jivesoftware.smack.packet.Presence; +import org.jivesoftware.smack.packet.PresenceBuilder; import org.jivesoftware.smack.packet.Session; import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.packet.StanzaError; @@ -123,11 +127,13 @@ import org.jivesoftware.smack.sasl.core.SASLAnonymous; import org.jivesoftware.smack.sasl.packet.SaslNonza; import org.jivesoftware.smack.util.Async; import org.jivesoftware.smack.util.CollectionUtil; +import org.jivesoftware.smack.util.Consumer; import org.jivesoftware.smack.util.DNSUtil; import org.jivesoftware.smack.util.MultiMap; import org.jivesoftware.smack.util.Objects; import org.jivesoftware.smack.util.PacketParserUtils; import org.jivesoftware.smack.util.ParserUtils; +import org.jivesoftware.smack.util.Predicate; import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smack.util.dns.HostAddress; import org.jivesoftware.smack.util.dns.SmackDaneProvider; @@ -243,6 +249,10 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { private final Map interceptors = new HashMap<>(); + private final Map, GenericInterceptorWrapper> messageInterceptors = new HashMap<>(); + + private final Map, GenericInterceptorWrapper> presenceInterceptors = new HashMap<>(); + private XmlEnvironment incomingStreamXmlEnvironment; protected XmlEnvironment outgoingStreamXmlEnvironment; @@ -849,8 +859,8 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { } // Invoke interceptors for the new stanza that is about to be sent. Interceptors may modify // the content of the stanza. - firePacketInterceptors(stanza); - sendStanzaInternal(stanza); + Stanza stanzaAfterInterceptors = firePacketInterceptors(stanza); + sendStanzaInternal(stanzaAfterInterceptors); } /** @@ -1204,6 +1214,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { }); } + @Deprecated @Override public void addStanzaInterceptor(StanzaListener packetInterceptor, StanzaFilter packetFilter) { @@ -1216,6 +1227,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { } } + @Deprecated @Override public void removeStanzaInterceptor(StanzaListener packetInterceptor) { synchronized (interceptors) { @@ -1223,15 +1235,83 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { } } + private static , MP extends MessageOrPresence> void addInterceptor( + Map, GenericInterceptorWrapper> interceptors, Consumer interceptor, + Predicate filter) { + Objects.requireNonNull(interceptor, "Interceptor must not be null"); + + GenericInterceptorWrapper interceptorWrapper = new GenericInterceptorWrapper<>(interceptor, filter); + + synchronized (interceptors) { + interceptors.put(interceptor, interceptorWrapper); + } + } + + private static , MP extends MessageOrPresence> void removeInterceptor( + Map, GenericInterceptorWrapper> interceptors, Consumer interceptor) { + synchronized (interceptors) { + interceptors.remove(interceptor); + } + } + + @Override + public void addMessageInterceptor(Consumer messageInterceptor, Predicate messageFilter) { + addInterceptor(messageInterceptors, messageInterceptor, messageFilter); + } + + @Override + public void removeMessageInterceptor(Consumer messageInterceptor) { + removeInterceptor(messageInterceptors, messageInterceptor); + } + + @Override + public void addPresenceInterceptor(Consumer presenceInterceptor, + Predicate presenceFilter) { + addInterceptor(presenceInterceptors, presenceInterceptor, presenceFilter); + } + + @Override + public void removePresenceInterceptor(Consumer presenceInterceptor) { + removeInterceptor(presenceInterceptors, presenceInterceptor); + } + + private static , MP extends MessageOrPresence> MP fireMessageOrPresenceInterceptors( + MP messageOrPresence, Map, GenericInterceptorWrapper> interceptors) { + List> interceptorsToInvoke = new LinkedList<>(); + synchronized (interceptors) { + for (GenericInterceptorWrapper interceptorWrapper : interceptors.values()) { + if (interceptorWrapper.filterMatches(messageOrPresence)) { + Consumer interceptor = interceptorWrapper.getInterceptor(); + interceptorsToInvoke.add(interceptor); + } + } + } + + // Avoid transforming the stanza to a builder if there is no interceptor. + if (interceptorsToInvoke.isEmpty()) { + return messageOrPresence; + } + + MPB builder = messageOrPresence.asBuilder(); + for (Consumer interceptor : interceptorsToInvoke) { + interceptor.accept(builder); + } + + // Now that the interceptors have (probably) modified the stanza in its builder form, we need to re-assemble it. + messageOrPresence = builder.build(); + return messageOrPresence; + } + /** * Process interceptors. Interceptors may modify the stanza that is about to be sent. * Since the thread that requested to send the stanza will invoke all interceptors, it * is important that interceptors perform their work as soon as possible so that the * thread does not remain blocked for a long period. * - * @param packet the stanza that is going to be sent to the server + * @param packet the stanza that is going to be sent to the server. + * @return the, potentially modified stanza, after the interceptors are run. */ - private void firePacketInterceptors(Stanza packet) { + private Stanza firePacketInterceptors(Stanza packet) { List interceptorsToInvoke = new LinkedList<>(); synchronized (interceptors) { for (InterceptorWrapper interceptorWrapper : interceptors.values()) { @@ -1247,6 +1327,22 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { LOGGER.log(Level.SEVERE, "Packet interceptor threw exception", e); } } + + final Stanza stanzaAfterInterceptors; + if (packet instanceof Message) { + Message message = (Message) packet; + stanzaAfterInterceptors = fireMessageOrPresenceInterceptors(message, messageInterceptors); + } + else if (packet instanceof Presence) { + Presence presence = (Presence) packet; + stanzaAfterInterceptors = fireMessageOrPresenceInterceptors(presence, presenceInterceptors); + } else { + // We do not (yet) support interceptors for IQ stanzas. + assert packet instanceof IQ; + stanzaAfterInterceptors = packet; + } + + return stanzaAfterInterceptors; } /** @@ -1674,6 +1770,8 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { /** * A wrapper class to associate a stanza filter with an interceptor. */ + @Deprecated + // TODO: Remove once addStanzaInterceptor is gone. protected static class InterceptorWrapper { private final StanzaListener packetInterceptor; @@ -1699,6 +1797,24 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { } } + private static final class GenericInterceptorWrapper, MP extends MessageOrPresence> { + private final Consumer stanzaInterceptor; + private final Predicate stanzaFilter; + + private GenericInterceptorWrapper(Consumer stanzaInterceptor, Predicate stanzaFilter) { + this.stanzaInterceptor = stanzaInterceptor; + this.stanzaFilter = stanzaFilter; + } + + private boolean filterMatches(MP stanza) { + return stanzaFilter == null || stanzaFilter.test(stanza); + } + + public Consumer getInterceptor() { + return stanzaInterceptor; + } + } + @Override public int getConnectionCounter() { return connectionCounterValue; diff --git a/smack-core/src/main/java/org/jivesoftware/smack/XMPPConnection.java b/smack-core/src/main/java/org/jivesoftware/smack/XMPPConnection.java index d7df0a825..842007f1e 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/XMPPConnection.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/XMPPConnection.java @@ -27,9 +27,15 @@ import org.jivesoftware.smack.iqrequest.IQRequestHandler; import org.jivesoftware.smack.packet.ExtensionElement; import org.jivesoftware.smack.packet.FullyQualifiedElement; import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.packet.MessageBuilder; import org.jivesoftware.smack.packet.Nonza; +import org.jivesoftware.smack.packet.Presence; +import org.jivesoftware.smack.packet.PresenceBuilder; import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.packet.StanzaFactory; +import org.jivesoftware.smack.util.Consumer; +import org.jivesoftware.smack.util.Predicate; import org.jxmpp.jid.DomainBareJid; import org.jxmpp.jid.EntityFullJid; @@ -361,7 +367,7 @@ public interface XMPPConnection { boolean removeStanzaListener(StanzaListener stanzaListener); /** - * Registers a synchronous stanza listener with this connection. A stanza listener will be invoked only when + * Registers a synchronous stanza listener with this connection. A stanza listener will be invoked only when * an incoming stanza is received. A stanza filter determines which stanzas will be delivered to the listener. If * the same stanza listener is added again with a different filter, only the new filter will be used. *

@@ -446,16 +452,65 @@ public interface XMPPConnection { * * @param stanzaInterceptor the stanza interceptor to notify of stanzas about to be sent. * @param stanzaFilter the stanza filter to use. + * @deprecated use {@link #addMessageInterceptor(Consumer, Predicate)} or {@link #addPresenceInterceptor(Consumer, Predicate)} instead. */ + @Deprecated + // TODO: Remove in Smack 4.5. void addStanzaInterceptor(StanzaListener stanzaInterceptor, StanzaFilter stanzaFilter); /** * Removes a stanza interceptor. * * @param stanzaInterceptor the stanza interceptor to remove. + * @deprecated use {@link #removeMessageInterceptor(Consumer)} or {@link #removePresenceInterceptor(Consumer)} instead. */ + @Deprecated + // TODO: Remove in Smack 4.5. void removeStanzaInterceptor(StanzaListener stanzaInterceptor); + /** + * Registers a stanza interceptor with this connection. The interceptor will be + * invoked every time a stanza is about to be sent by this connection. Interceptors + * may modify the stanza to be sent. A stanza filter determines which stanzas + * will be delivered to the interceptor. + * + *

+ * NOTE: For a similar functionality on incoming stanzas, see {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)}. + *

+ * + * @param messageInterceptor the stanza interceptor to notify of stanzas about to be sent. + * @param messageFilter the stanza filter to use. + */ + void addMessageInterceptor(Consumer messageInterceptor, Predicate messageFilter); + + /** + * Removes a message interceptor. + * + * @param messageInterceptor the message interceptor to remove. + */ + void removeMessageInterceptor(Consumer messageInterceptor); + + /** + * Registers a stanza interceptor with this connection. The interceptor will be + * invoked every time a stanza is about to be sent by this connection. Interceptors + * may modify the stanza to be sent. A stanza filter determines which stanzas + * will be delivered to the interceptor. + * + *

+ * NOTE: For a similar functionality on incoming stanzas, see {@link #addAsyncStanzaListener(StanzaListener, StanzaFilter)}. + *

+ * + * @param presenceInterceptor the stanza interceptor to notify of stanzas about to be sent. + * @param presenceFilter the stanza filter to use. + */ + void addPresenceInterceptor(Consumer presenceInterceptor, Predicate presenceFilter); + + /** + * Removes a presence interceptor. + * + * @param presenceInterceptor the stanza interceptor to remove. + */ + void removePresenceInterceptor(Consumer presenceInterceptor); /** * Returns the current value of the reply timeout in milliseconds for request for this * XMPPConnection instance. diff --git a/smack-core/src/main/java/org/jivesoftware/smack/filter/StanzaFilter.java b/smack-core/src/main/java/org/jivesoftware/smack/filter/StanzaFilter.java index db0d1da72..f37d08b11 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/filter/StanzaFilter.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/filter/StanzaFilter.java @@ -18,6 +18,7 @@ package org.jivesoftware.smack.filter; import org.jivesoftware.smack.packet.Stanza; +import org.jivesoftware.smack.util.Predicate; /** * Defines a way to filter stanzas for particular attributes. Stanza filters are used when @@ -51,7 +52,7 @@ import org.jivesoftware.smack.packet.Stanza; * @see org.jivesoftware.smack.StanzaListener * @author Matt Tucker */ -public interface StanzaFilter { +public interface StanzaFilter extends Predicate { /** * Tests whether or not the specified stanza should pass the filter. @@ -60,4 +61,9 @@ public interface StanzaFilter { * @return true if and only if stanza passes the filter. */ boolean accept(Stanza stanza); + + @Override + default boolean test(Stanza stanza) { + return accept(stanza); + } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/Message.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/Message.java index ef3dd9aec..58d69da59 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/Message.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/Message.java @@ -60,7 +60,8 @@ import org.jxmpp.stringprep.XmppStringprepException; * * @author Matt Tucker */ -public final class Message extends Stanza implements MessageView, TypedCloneable { +public final class Message extends MessageOrPresence + implements MessageView, TypedCloneable { public static final String ELEMENT = "message"; public static final String BODY = "body"; @@ -534,6 +535,7 @@ public final class Message extends Stanza implements MessageView, TypedCloneable return ELEMENT; } + @Override public MessageBuilder asBuilder() { return StanzaBuilder.buildMessageFrom(this, getStanzaId()); } @@ -664,6 +666,7 @@ public final class Message extends Stanza implements MessageView, TypedCloneable public static final String ELEMENT = "body"; public static final String NAMESPACE = StreamOpen.CLIENT_NAMESPACE; + public static final QName QNAME = new QName(NAMESPACE, ELEMENT); enum BodyElementNamespace { client(StreamOpen.CLIENT_NAMESPACE), diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/MessageBuilder.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/MessageBuilder.java index b73880d0c..027e2b0cc 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/MessageBuilder.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/MessageBuilder.java @@ -22,7 +22,7 @@ import org.jivesoftware.smack.packet.id.StanzaIdSource; import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smack.util.ToStringUtil; -public final class MessageBuilder extends StanzaBuilder implements MessageView { +public final class MessageBuilder extends MessageOrPresenceBuilder implements MessageView { static final MessageBuilder EMPTY = new MessageBuilder(() -> { return null; }); @@ -153,6 +153,7 @@ public final class MessageBuilder extends StanzaBuilder implemen return this; } + @Override public Message build() { return new Message(this); } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/MessageOrPresence.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/MessageOrPresence.java new file mode 100644 index 000000000..c885e941c --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/MessageOrPresence.java @@ -0,0 +1,36 @@ +/** + * + * Copyright 2019 Florian Schmaus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jivesoftware.smack.packet; + +public abstract class MessageOrPresence> extends Stanza { + + @Deprecated + // TODO: Remove in Smack 4.5. + protected MessageOrPresence() { + } + + protected MessageOrPresence(StanzaBuilder stanzaBuilder) { + super(stanzaBuilder); + } + + protected MessageOrPresence(Stanza other) { + super(other); + } + + public abstract MPB asBuilder(); + +} diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/MessageOrPresenceBuilder.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/MessageOrPresenceBuilder.java new file mode 100644 index 000000000..9a3ff66a0 --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/MessageOrPresenceBuilder.java @@ -0,0 +1,42 @@ +/** + * + * Copyright 2019 Florian Schmaus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jivesoftware.smack.packet; + +import org.jivesoftware.smack.packet.id.StanzaIdSource; + +public abstract class MessageOrPresenceBuilder>, SB extends StanzaBuilder> + extends StanzaBuilder { + + protected MessageOrPresenceBuilder(Stanza stanza, StanzaIdSource stanzaIdSource) { + super(stanza, stanzaIdSource); + } + + protected MessageOrPresenceBuilder(Stanza stanza, String stanzaId) { + super(stanza, stanzaId); + } + + protected MessageOrPresenceBuilder(StanzaIdSource stanzaIdSource) { + super(stanzaIdSource); + } + + protected MessageOrPresenceBuilder(String stanzaId) { + super(stanzaId); + } + + public abstract MP build(); + +} diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/Presence.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/Presence.java index 8a8db7030..9a1d1a43d 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/Presence.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/Presence.java @@ -61,7 +61,8 @@ import org.jxmpp.jid.Jid; * * @author Matt Tucker */ -public final class Presence extends Stanza implements PresenceView, TypedCloneable { +public final class Presence extends MessageOrPresence + implements PresenceView, TypedCloneable { public static final String ELEMENT = "presence"; @@ -277,6 +278,7 @@ public final class Presence extends Stanza implements PresenceView, TypedCloneab return ELEMENT; } + @Override public PresenceBuilder asBuilder() { return StanzaBuilder.buildPresenceFrom(this, getStanzaId()); } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/PresenceBuilder.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/PresenceBuilder.java index 795c9a824..9c34fb89c 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/PresenceBuilder.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/PresenceBuilder.java @@ -21,7 +21,7 @@ import org.jivesoftware.smack.packet.id.StanzaIdSource; import org.jivesoftware.smack.util.Objects; import org.jivesoftware.smack.util.ToStringUtil; -public final class PresenceBuilder extends StanzaBuilder implements PresenceView { +public final class PresenceBuilder extends MessageOrPresenceBuilder implements PresenceView { static final PresenceBuilder EMPTY = new PresenceBuilder(() -> { return null; }); @@ -102,6 +102,7 @@ public final class PresenceBuilder extends StanzaBuilder implem return this; } + @Override public Presence build() { return new Presence(this); } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/Stanza.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/Stanza.java index b884468f7..4207efb6d 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/Stanza.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/Stanza.java @@ -456,12 +456,8 @@ public abstract class Stanza implements StanzaView, TopLevelStreamElement { } } - /** - * Check if a stanza extension with the given namespace exists. - * - * @param namespace TODO javadoc me please - * @return true if a stanza extension exists, false otherwise. - */ + // Overridden in order to avoid an extra copy. + @Override public boolean hasExtension(String namespace) { synchronized (extensionElements) { for (ExtensionElement packetExtension : extensionElements.values()) { diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaView.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaView.java index 4de119fef..ff9874f13 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaView.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaView.java @@ -63,6 +63,26 @@ public interface StanzaView extends XmlLangElement { E getExtension(QName qname); + default boolean hasExtension(QName qname) { + return getExtension(qname) != null; + } + + /** + * Check if a extension element with the given namespace exists. + * + * @param namespace the namespace of the extension element to check for. + * @return true if a stanza extension exists, false otherwise. + */ + default boolean hasExtension(String namespace) { + for (ExtensionElement packetExtension : getExtensions()) { + if (packetExtension.getNamespace().equals(namespace)) { + return true; + } + } + + return false; + } + @SuppressWarnings("unchecked") default E getExtension(Class extensionElementClass) { QName qname = XmppElementUtil.getQNameFor(extensionElementClass); diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/Predicate.java b/smack-core/src/main/java/org/jivesoftware/smack/util/Predicate.java new file mode 100644 index 000000000..ad4c11d0c --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/Predicate.java @@ -0,0 +1,24 @@ +/** + * + * Copyright 2019 Florian Schmaus + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jivesoftware.smack.util; + +// TODO: Replace with java.util.function.Predicate once Smack's minimum Android SDK level is 24 or higher. +public interface Predicate { + + boolean test(T t); + +} diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/chat_markers/ChatMarkersManager.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/chat_markers/ChatMarkersManager.java index 7854204be..b2f99bd76 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/chat_markers/ChatMarkersManager.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/chat_markers/ChatMarkersManager.java @@ -120,18 +120,10 @@ public final class ChatMarkersManager extends Manager { chatManager = ChatManager.getInstanceFor(connection); - connection.addStanzaInterceptor(new StanzaListener() { - @Override - public void processStanza(Stanza packet) - throws - NotConnectedException, - InterruptedException, - SmackException.NotLoggedInException { - Message message = (Message) packet; - // add a markable extension - message.addExtension(ChatMarkersElements.MarkableExtension.INSTANCE); - } - }, OUTGOING_MESSAGE_FILTER); + connection.addMessageInterceptor(mb -> mb.addExtension(ChatMarkersElements.MarkableExtension.INSTANCE), + m -> { + return OUTGOING_MESSAGE_FILTER.accept(m); + }); connection.addSyncStanzaListener(new StanzaListener() { @Override diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/sid/StableUniqueStanzaIdManager.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/sid/StableUniqueStanzaIdManager.java index fbe507e4e..f0515a74b 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/sid/StableUniqueStanzaIdManager.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/sid/StableUniqueStanzaIdManager.java @@ -21,7 +21,6 @@ import java.util.WeakHashMap; import org.jivesoftware.smack.ConnectionCreationListener; import org.jivesoftware.smack.Manager; -import org.jivesoftware.smack.StanzaListener; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPConnectionRegistry; import org.jivesoftware.smack.filter.AndFilter; @@ -31,8 +30,9 @@ import org.jivesoftware.smack.filter.StanzaExtensionFilter; import org.jivesoftware.smack.filter.StanzaFilter; import org.jivesoftware.smack.filter.ToTypeFilter; import org.jivesoftware.smack.packet.Message; -import org.jivesoftware.smack.packet.Stanza; - +import org.jivesoftware.smack.packet.MessageBuilder; +import org.jivesoftware.smack.util.Consumer; +import org.jivesoftware.smack.util.Predicate; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.sid.element.OriginIdElement; @@ -62,12 +62,12 @@ public final class StableUniqueStanzaIdManager extends Manager { private static final StanzaFilter ORIGIN_ID_FILTER = new StanzaExtensionFilter(OriginIdElement.ELEMENT, NAMESPACE); // Listener for outgoing stanzas that adds origin-ids to outgoing stanzas. - private static final StanzaListener ADD_ORIGIN_ID_INTERCEPTOR = new StanzaListener() { - @Override - public void processStanza(Stanza stanza) { - Message message = (Message) stanza; - OriginIdElement.addOriginId(message); - } + private static final Consumer ADD_ORIGIN_ID_INTERCEPTOR = mb -> OriginIdElement.addOriginId(mb); + + // We need a filter for outgoing messages that do not carry an origin-id already. + private static final StanzaFilter ADD_ORIGIN_ID_FILTER = new AndFilter(OUTGOING_FILTER, new NotFilter(ORIGIN_ID_FILTER)); + private static final Predicate ADD_ORIGIN_ID_PREDICATE = m -> { + return ADD_ORIGIN_ID_FILTER.accept(m); }; static { @@ -112,10 +112,8 @@ public final class StableUniqueStanzaIdManager extends Manager { * Start appending origin-id elements to outgoing stanzas and add the feature to disco. */ public synchronized void enable() { + connection().addMessageInterceptor(ADD_ORIGIN_ID_INTERCEPTOR, ADD_ORIGIN_ID_PREDICATE); ServiceDiscoveryManager.getInstanceFor(connection()).addFeature(NAMESPACE); - // We need a filter for outgoing messages that do not carry an origin-id already - StanzaFilter filter = new AndFilter(OUTGOING_FILTER, new NotFilter(ORIGIN_ID_FILTER)); - connection().addStanzaInterceptor(ADD_ORIGIN_ID_INTERCEPTOR, filter); } /** @@ -123,7 +121,7 @@ public final class StableUniqueStanzaIdManager extends Manager { */ public synchronized void disable() { ServiceDiscoveryManager.getInstanceFor(connection()).removeFeature(NAMESPACE); - connection().removeStanzaInterceptor(ADD_ORIGIN_ID_INTERCEPTOR); + connection().removeMessageInterceptor(ADD_ORIGIN_ID_INTERCEPTOR); } /** diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/sid/element/OriginIdElement.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/sid/element/OriginIdElement.java index 4291084bb..10531c4e3 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/sid/element/OriginIdElement.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/sid/element/OriginIdElement.java @@ -17,6 +17,7 @@ package org.jivesoftware.smackx.sid.element; import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.packet.MessageBuilder; import org.jivesoftware.smack.util.XmlStringBuilder; import org.jivesoftware.smackx.sid.StableUniqueStanzaIdManager; @@ -38,7 +39,10 @@ public class OriginIdElement extends StableAndUniqueIdElement { * * @param message message. * @return the added origin-id element. + * @deprecated use {@link #addOriginId(MessageBuilder)} instead. */ + @Deprecated + // TODO: Remove in Smack 4.5. public static OriginIdElement addOriginId(Message message) { OriginIdElement originId = new OriginIdElement(); message.addExtension(originId); @@ -47,6 +51,20 @@ public class OriginIdElement extends StableAndUniqueIdElement { return originId; } + /** + * Add an origin-id element to a message and set the stanzas id to the same id as in the origin-id element. + * + * @param messageBuilder the message builder to add an origin ID to. + * @return the added origin-id element. + */ + public static OriginIdElement addOriginId(MessageBuilder messageBuilder) { + OriginIdElement originId = new OriginIdElement(); + messageBuilder.addExtension(originId); + // TODO: Find solution to have both the originIds stanzaId and a nice to look at incremental stanzaID. + // message.setStanzaId(originId.getId()); + return originId; + } + /** * Return true, if the message contains a origin-id element. * diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/sid/StableUniqueStanzaIdTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/sid/StableUniqueStanzaIdTest.java index 3e6ac3027..c9c4367a8 100644 --- a/smack-experimental/src/test/java/org/jivesoftware/smackx/sid/StableUniqueStanzaIdTest.java +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/sid/StableUniqueStanzaIdTest.java @@ -23,6 +23,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.packet.MessageBuilder; import org.jivesoftware.smack.packet.StanzaBuilder; import org.jivesoftware.smack.test.util.SmackTestSuite; import org.jivesoftware.smack.test.util.TestUtils; @@ -71,12 +72,15 @@ public class StableUniqueStanzaIdTest extends SmackTestSuite { @Test public void fromMessageTest() { - Message message = StanzaBuilder.buildMessage().build(); + MessageBuilder messageBuilder = StanzaBuilder.buildMessage(); + + Message message = messageBuilder.build(); assertFalse(OriginIdElement.hasOriginId(message)); assertFalse(StanzaIdElement.hasStanzaId(message)); - OriginIdElement.addOriginId(message); + OriginIdElement.addOriginId(messageBuilder); + message = messageBuilder.build(); assertTrue(OriginIdElement.hasOriginId(message)); StanzaIdElement stanzaId = new StanzaIdElement("alice@wonderland.lit"); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smack/chat2/ChatManager.java b/smack-extensions/src/main/java/org/jivesoftware/smack/chat2/ChatManager.java index 4066b1d4d..e8349b6c6 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smack/chat2/ChatManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smack/chat2/ChatManager.java @@ -1,6 +1,6 @@ /** * - * Copyright 2017-2018 Florian Schmaus. + * Copyright 2017-2019 Florian Schmaus. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,7 +24,6 @@ import java.util.concurrent.CopyOnWriteArraySet; import org.jivesoftware.smack.AsyncButOrdered; import org.jivesoftware.smack.Manager; -import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smack.StanzaListener; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.filter.AndFilter; @@ -36,6 +35,7 @@ import org.jivesoftware.smack.filter.StanzaExtensionFilter; import org.jivesoftware.smack.filter.StanzaFilter; import org.jivesoftware.smack.filter.ToTypeFilter; import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.packet.MessageView; import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.roster.AbstractRosterListener; @@ -124,22 +124,20 @@ public final class ChatManager extends Manager { } }, INCOMING_MESSAGE_FILTER); - connection.addStanzaInterceptor(new StanzaListener() { - @Override - public void processStanza(Stanza stanza) throws NotConnectedException, InterruptedException { - Message message = (Message) stanza; - if (!shouldAcceptMessage(message)) { - return; - } - - final EntityBareJid to = message.getTo().asEntityBareJidOrThrow(); - final Chat chat = chatWith(to); - - for (OutgoingChatMessageListener listener : outgoingListeners) { - listener.newOutgoingMessage(to, message, chat); - } + connection.addMessageInterceptor(messageBuilder -> { + if (!shouldAcceptMessage(messageBuilder)) { + return; } - }, OUTGOING_MESSAGE_FILTER); + + final EntityBareJid to = messageBuilder.getTo().asEntityBareJidOrThrow(); + final Chat chat = chatWith(to); + + for (OutgoingChatMessageListener listener : outgoingListeners) { + listener.newOutgoingMessage(to, messageBuilder, chat); + } + }, m -> { + return OUTGOING_MESSAGE_FILTER.accept(m); + }); Roster roster = Roster.getInstanceFor(connection); roster.addRosterListener(new AbstractRosterListener() { @@ -181,8 +179,8 @@ public final class ChatManager extends Manager { }); } - private boolean shouldAcceptMessage(Message message) { - if (!message.getBodies().isEmpty()) { + private boolean shouldAcceptMessage(MessageView message) { + if (message.hasExtension(Message.Body.QNAME)) { return true; } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smack/chat2/OutgoingChatMessageListener.java b/smack-extensions/src/main/java/org/jivesoftware/smack/chat2/OutgoingChatMessageListener.java index 4ceba2c6f..75a9918fd 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smack/chat2/OutgoingChatMessageListener.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smack/chat2/OutgoingChatMessageListener.java @@ -1,6 +1,6 @@ /** * - * Copyright 2017 Florian Schmaus. + * Copyright 2017-2019 Florian Schmaus. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,12 +16,12 @@ */ package org.jivesoftware.smack.chat2; -import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.packet.MessageBuilder; import org.jxmpp.jid.EntityBareJid; public interface OutgoingChatMessageListener { - void newOutgoingMessage(EntityBareJid to, Message message, Chat chat); + void newOutgoingMessage(EntityBareJid to, MessageBuilder messageBuilder, Chat chat); } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java index 8d9b0df7f..c6b12c036 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java @@ -51,9 +51,11 @@ import org.jivesoftware.smack.filter.StanzaTypeFilter; import org.jivesoftware.smack.packet.ExtensionElement; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Presence; +import org.jivesoftware.smack.packet.PresenceBuilder; import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.roster.AbstractPresenceEventListener; import org.jivesoftware.smack.roster.Roster; +import org.jivesoftware.smack.util.Consumer; import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smack.util.stringencoder.Base64; @@ -308,6 +310,15 @@ public final class EntityCapsManager extends Manager { */ private String entityNode = DEFAULT_ENTITY_NODE; + // Intercept presence packages and add caps data when intended. + // XEP-0115 specifies that a client SHOULD include entity capabilities + // with every presence notification it sends. + private final Consumer presenceInterceptor = presenceBuilder -> { + CapsVersionAndHash capsVersionAndHash = getCapsVersionAndHash(); + CapsExtension caps = new CapsExtension(entityNode, capsVersionAndHash.version, capsVersionAndHash.hash); + presenceBuilder.overrideExtension(caps); + }; + private EntityCapsManager(XMPPConnection connection) { super(connection); this.sdm = ServiceDiscoveryManager.getInstanceFor(connection); @@ -379,23 +390,9 @@ public final class EntityCapsManager extends Manager { } }, PresenceTypeFilter.OUTGOING_PRESENCE_BROADCAST); - // Intercept presence packages and add caps data when intended. - // XEP-0115 specifies that a client SHOULD include entity capabilities - // with every presence notification it sends. - StanzaListener packetInterceptor = new StanzaListener() { - @Override - public void processStanza(Stanza packet) { - if (!entityCapsEnabled) { - // Be sure to not send stanzas with the caps extension if it's not enabled - packet.removeExtension(CapsExtension.ELEMENT, CapsExtension.NAMESPACE); - return; - } - CapsVersionAndHash capsVersionAndHash = getCapsVersionAndHash(); - CapsExtension caps = new CapsExtension(entityNode, capsVersionAndHash.version, capsVersionAndHash.hash); - packet.overrideExtension(caps); - } - }; - connection.addStanzaInterceptor(packetInterceptor, PresenceTypeFilter.AVAILABLE); + + enableEntityCaps(); + // It's important to do this as last action. Since it changes the // behavior of the SDM in some ways sdm.addEntityCapabilitiesChangedListener(new EntityCapabilitiesChangedListener() { @@ -424,6 +421,10 @@ public final class EntityCapsManager extends Manager { } public synchronized void enableEntityCaps() { + connection().addPresenceInterceptor(presenceInterceptor, p -> { + return PresenceTypeFilter.AVAILABLE.accept(p); + }); + // Add Entity Capabilities (XEP-0115) feature node. sdm.addFeature(NAMESPACE); updateLocalEntityCaps(); @@ -433,6 +434,8 @@ public final class EntityCapsManager extends Manager { public synchronized void disableEntityCaps() { entityCapsEnabled = false; sdm.removeFeature(NAMESPACE); + + connection().removePresenceInterceptor(presenceInterceptor); } public boolean entityCapsEnabled() { diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/chatstates/ChatStateManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/chatstates/ChatStateManager.java index 0c4c9f4ef..8e5060172 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/chatstates/ChatStateManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/chatstates/ChatStateManager.java @@ -37,11 +37,11 @@ import org.jivesoftware.smack.chat2.OutgoingChatMessageListener; import org.jivesoftware.smack.filter.AndFilter; import org.jivesoftware.smack.filter.FromTypeFilter; import org.jivesoftware.smack.filter.MessageTypeFilter; -import org.jivesoftware.smack.filter.NotFilter; import org.jivesoftware.smack.filter.StanzaExtensionFilter; import org.jivesoftware.smack.filter.StanzaFilter; import org.jivesoftware.smack.packet.ExtensionElement; import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.packet.MessageBuilder; import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.packet.StanzaBuilder; @@ -73,7 +73,6 @@ public final class ChatStateManager extends Manager { private static final Map INSTANCES = new WeakHashMap<>(); - private static final StanzaFilter filter = new NotFilter(new StanzaExtensionFilter(NAMESPACE)); private static final StanzaFilter INCOMING_MESSAGE_FILTER = new AndFilter(MessageTypeFilter.NORMAL_OR_CHAT, FromTypeFilter.ENTITY_FULL_JID); private static final StanzaFilter INCOMING_CHAT_STATE_FILTER = new AndFilter(INCOMING_MESSAGE_FILTER, new StanzaExtensionFilter(NAMESPACE)); @@ -117,13 +116,13 @@ public final class ChatStateManager extends Manager { ChatManager chatManager = ChatManager.getInstanceFor(connection); chatManager.addOutgoingListener(new OutgoingChatMessageListener() { @Override - public void newOutgoingMessage(EntityBareJid to, Message message, Chat chat) { + public void newOutgoingMessage(EntityBareJid to, MessageBuilder message, Chat chat) { if (chat == null) { return; } // if message already has a chatStateExtension, then do nothing, - if (!filter.accept(message)) { + if (message.hasExtension(ChatStateExtension.NAMESPACE)) { return; } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java index b37f367ad..8aa301fa0 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java @@ -358,7 +358,7 @@ public class MultiUserChat { ); // @formatter:on connection.addSyncStanzaListener(declinesListener, new AndFilter(fromRoomFilter, DECLINE_FILTER)); - connection.addStanzaInterceptor(presenceInterceptor, new AndFilter(ToMatchesFilter.create(room), + connection.addStanzaSendingListener(presenceInterceptor, new AndFilter(ToMatchesFilter.create(room), StanzaTypeFilter.PRESENCE)); messageCollector = connection.createStanzaCollector(fromRoomGroupchatFilter); @@ -2122,7 +2122,7 @@ public class MultiUserChat { connection.removeSyncStanzaListener(presenceListener); connection.removeSyncStanzaListener(subjectListener); connection.removeSyncStanzaListener(declinesListener); - connection.removeStanzaInterceptor(presenceInterceptor); + connection.removeStanzaSendingListener(presenceInterceptor); if (messageCollector != null) { messageCollector.cancel(); messageCollector = null; diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceiptManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceiptManager.java index bab23aa5e..b069709e1 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceiptManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceiptManager.java @@ -38,9 +38,11 @@ import org.jivesoftware.smack.filter.StanzaExtensionFilter; import org.jivesoftware.smack.filter.StanzaFilter; import org.jivesoftware.smack.filter.StanzaTypeFilter; import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.packet.MessageBuilder; import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.packet.StanzaBuilder; import org.jivesoftware.smack.roster.Roster; +import org.jivesoftware.smack.util.Consumer; import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; @@ -271,13 +273,7 @@ public final class DeliveryReceiptManager extends Manager { ); // @formatter:on - private static final StanzaListener AUTO_ADD_DELIVERY_RECEIPT_REQUESTS_LISTENER = new StanzaListener() { - @Override - public void processStanza(Stanza packet) throws NotConnectedException { - Message message = (Message) packet; - DeliveryReceiptRequest.addTo(message); - } - }; + private static final Consumer AUTO_ADD_DELIVERY_RECEIPT_REQUESTS_LISTENER = mb -> DeliveryReceiptRequest.addTo(mb); /** * Enables automatic requests of delivery receipts for outgoing messages of @@ -288,8 +284,9 @@ public final class DeliveryReceiptManager extends Manager { * @see #dontAutoAddDeliveryReceiptRequests() */ public void autoAddDeliveryReceiptRequests() { - connection().addStanzaInterceptor(AUTO_ADD_DELIVERY_RECEIPT_REQUESTS_LISTENER, - MESSAGES_TO_REQUEST_RECEIPTS_FOR); + connection().addMessageInterceptor(AUTO_ADD_DELIVERY_RECEIPT_REQUESTS_LISTENER, m -> { + return MESSAGES_TO_REQUEST_RECEIPTS_FOR.accept(m); + }); } /** @@ -299,7 +296,7 @@ public final class DeliveryReceiptManager extends Manager { * @see #autoAddDeliveryReceiptRequests() */ public void dontAutoAddDeliveryReceiptRequests() { - connection().removeStanzaInterceptor(AUTO_ADD_DELIVERY_RECEIPT_REQUESTS_LISTENER); + connection().removeMessageInterceptor(AUTO_ADD_DELIVERY_RECEIPT_REQUESTS_LISTENER); } /** diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/xhtmlim/packet/XHTMLExtension.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/xhtmlim/packet/XHTMLExtension.java index a87124fa5..39713f951 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/xhtmlim/packet/XHTMLExtension.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/xhtmlim/packet/XHTMLExtension.java @@ -21,8 +21,10 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import javax.xml.namespace.QName; + import org.jivesoftware.smack.packet.ExtensionElement; -import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.packet.MessageView; import org.jivesoftware.smack.util.XmlStringBuilder; /** @@ -40,6 +42,8 @@ public class XHTMLExtension implements ExtensionElement { public static final String ELEMENT = "html"; public static final String NAMESPACE = "http://jabber.org/protocol/xhtml-im"; + public static final QName QNAME = new QName(NAMESPACE, ELEMENT); + private final List bodies = new ArrayList<>(); /** @@ -125,7 +129,7 @@ public class XHTMLExtension implements ExtensionElement { } } - public static XHTMLExtension from(Message message) { - return message.getExtension(ELEMENT, NAMESPACE); + public static XHTMLExtension from(MessageView message) { + return message.getExtension(QNAME); } } diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smack/chat2/OutgoingMessageListenerIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smack/chat2/OutgoingMessageListenerIntegrationTest.java index 6ea68d7f4..c284495fa 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smack/chat2/OutgoingMessageListenerIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smack/chat2/OutgoingMessageListenerIntegrationTest.java @@ -17,6 +17,7 @@ package org.jivesoftware.smack.chat2; import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.packet.MessageBuilder; import org.jivesoftware.smack.util.StringUtils; import org.igniterealtime.smack.inttest.SmackIntegrationTest; @@ -36,7 +37,8 @@ public class OutgoingMessageListenerIntegrationTest extends AbstractChatIntegrat final SimpleResultSyncPoint syncPoint = new SimpleResultSyncPoint(); final OutgoingChatMessageListener listener = new OutgoingChatMessageListener() { @Override - public void newOutgoingMessage(EntityBareJid to, Message message, Chat chat) { + public void newOutgoingMessage(EntityBareJid to, MessageBuilder messageBuilder, Chat chat) { + Message message = messageBuilder.build(); if (message.getBody().equals(body)) { syncPoint.signal(); } From 4b01892129aaeb35bec775dec89f99b8b45774fb Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 27 Oct 2019 07:51:25 +0100 Subject: [PATCH 03/16] Remove unused DiscoverInfo instances in PingTest --- .../test/java/org/jivesoftware/smackx/ping/PingTest.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/ping/PingTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/ping/PingTest.java index 3eef31b83..0a9a54a75 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/ping/PingTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/ping/PingTest.java @@ -1,6 +1,6 @@ /** * - * Copyright 2012-2014 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. @@ -36,7 +36,6 @@ import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.util.PacketParserUtils; import org.jivesoftware.smackx.InitExtensions; -import org.jivesoftware.smackx.disco.packet.DiscoverInfo; import org.jivesoftware.smackx.ping.packet.Ping; import org.junit.Test; @@ -191,8 +190,6 @@ public class PingTest extends InitExtensions { @Test public void checkSuccessfulDiscoRequest() throws Exception { ThreadedDummyConnection con = getAuthenticatedDummyConnection(); - DiscoverInfo info = new DiscoverInfo(); - info.addFeature(Ping.NAMESPACE); // @formatter:off String reply = @@ -213,8 +210,6 @@ public class PingTest extends InitExtensions { @Test public void checkUnsuccessfulDiscoRequest() throws Exception { ThreadedDummyConnection con = getAuthenticatedDummyConnection(); - DiscoverInfo info = new DiscoverInfo(); - info.addFeature(Ping.NAMESPACE); // @formatter:off String reply = From 36072fb25a4dd186cf30459c9afa589ab2004a34 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Tue, 29 Oct 2019 10:40:41 +0100 Subject: [PATCH 04/16] test: created mocked connectionwith stanza factory --- .../src/test/java/org/jivesoftware/util/ConnectionUtils.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/smack-extensions/src/test/java/org/jivesoftware/util/ConnectionUtils.java b/smack-extensions/src/test/java/org/jivesoftware/util/ConnectionUtils.java index cc90c29ca..910d73ee7 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/util/ConnectionUtils.java +++ b/smack-extensions/src/test/java/org/jivesoftware/util/ConnectionUtils.java @@ -30,6 +30,8 @@ import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.filter.StanzaFilter; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Stanza; +import org.jivesoftware.smack.packet.StanzaFactory; +import org.jivesoftware.smack.packet.id.StandardStanzaIdSource; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; @@ -78,6 +80,9 @@ public class ConnectionUtils { when(connection.getUser()).thenReturn(initiatorJID); when(connection.getXMPPServiceDomain()).thenReturn(xmppServer); + final StanzaFactory stanzaFactory = new StanzaFactory(new StandardStanzaIdSource()); + when(connection.getStanzaFactory()).thenReturn(stanzaFactory); + // mock packet collector final StanzaCollector collector = mock(StanzaCollector.class); when(connection.createStanzaCollector(isA(StanzaFilter.class))).thenReturn( From 6e32305987e64ad68a66bfd29372e10fcafc04a9 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Tue, 29 Oct 2019 11:14:55 +0100 Subject: [PATCH 05/16] Apply builder pattern to DiscoverInfo This is the first transformation of an IQ type to the builder type. --- .../smack/packet/AbstractIqBuilder.java | 69 ++++++++++ .../smack/packet/EmptyResultIQ.java | 2 +- .../org/jivesoftware/smack/packet/IQ.java | 21 ++- .../jivesoftware/smack/packet/IqBuilder.java | 20 +-- .../smack/packet/IqBuilderWithBuild.java | 45 +++++++ .../smack/packet/StanzaBuilder.java | 33 +++-- .../smack/packet/StanzaFactory.java | 4 + .../smack/provider/AbstractProvider.java | 45 +++++++ .../smack/provider/IQProvider.java | 40 +++++- .../smack/provider/IQProviderInfo.java | 2 +- .../smack/provider/IqProvider.java | 46 +++++++ .../jivesoftware/smack/provider/Provider.java | 24 +--- .../smack/provider/ProviderFileLoader.java | 4 +- .../smack/provider/ProviderManager.java | 14 +- .../smack/util/PacketParserUtils.java | 26 +++- .../iot/control/element/IoTSetResponse.java | 4 +- .../smackx/caps/EntityCapsManager.java | 19 ++- .../smackx/disco/ServiceDiscoveryManager.java | 42 +++--- .../smackx/disco/packet/DiscoverInfo.java | 118 ++++++++++++----- .../disco/packet/DiscoverInfoBuilder.java | 123 ++++++++++++++++++ .../smackx/disco/packet/DiscoverInfoView.java | 49 +++++++ .../disco/provider/DiscoverInfoProvider.java | 58 ++++----- .../org/jivesoftware/smackx/pubsub/Node.java | 11 +- .../smackx/pubsub/PubSubManager.java | 10 +- .../smackx/xdata/packet/DataForm.java | 15 ++- .../socks5/Socks5ByteStreamManagerTest.java | 74 ++++++----- .../bytestreams/socks5/Socks5PacketUtils.java | 12 +- .../smackx/caps/EntityCapsManagerTest.java | 24 ++-- .../jivesoftware/smackx/muc/RoomInfoTest.java | 10 +- .../smackx/pubsub/ConfigureFormTest.java | 18 ++- 30 files changed, 749 insertions(+), 233 deletions(-) create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/packet/AbstractIqBuilder.java create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/packet/IqBuilderWithBuild.java create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/provider/AbstractProvider.java create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/provider/IqProvider.java create mode 100644 smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfoBuilder.java create mode 100644 smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfoView.java diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/AbstractIqBuilder.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/AbstractIqBuilder.java new file mode 100644 index 000000000..479bcb346 --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/AbstractIqBuilder.java @@ -0,0 +1,69 @@ +/** + * + * 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; +import org.jivesoftware.smack.util.ToStringUtil; + +public abstract class AbstractIqBuilder> extends StanzaBuilder implements IqView { + + protected IQ.Type type = IQ.Type.get; + + AbstractIqBuilder(AbstractIqBuilder other) { + super(other); + type = other.type; + } + + AbstractIqBuilder(StanzaIdSource stanzaIdSource) { + super(stanzaIdSource); + } + + AbstractIqBuilder(String stanzaId) { + super(stanzaId); + } + + public static IqBuilder createResponse(IqView request) { + return createResponse(request, IQ.ResponseType.result); + } + + public static IqBuilder createErrorResponse(IqView request) { + return createResponse(request, IQ.ResponseType.error); + } + + protected static IqBuilder createResponse(IqView request, IQ.ResponseType responseType) { + if (!(request.getType() == IQ.Type.get || request.getType() == IQ.Type.set)) { + throw new IllegalArgumentException("IQ request must be of type 'set' or 'get'. Original IQ: " + request); + } + + IqBuilder commonResponseIqData = buildResponse(request, s -> { + return StanzaBuilder.buildIq(s); + }); + commonResponseIqData.ofType(responseType.getType()); + + return commonResponseIqData; + } + + @Override + protected final void addStanzaSpecificAttributes(ToStringUtil.Builder builder) { + builder.addValue("type", getType()); + } + + @Override + public final IQ.Type getType() { + return type; + } +} diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/EmptyResultIQ.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/EmptyResultIQ.java index fd3b576c1..933bf089f 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/EmptyResultIQ.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/EmptyResultIQ.java @@ -29,7 +29,7 @@ public class EmptyResultIQ extends IQ { } public EmptyResultIQ(IQ request) { - this(StanzaBuilder.buildIqResultFor(request)); + this(AbstractIqBuilder.createResponse(request)); } @Override diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/IQ.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/IQ.java index d202eb2cc..db76ecdaa 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/IQ.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/IQ.java @@ -68,7 +68,7 @@ public abstract class IQ extends Stanza implements IqView { this(IqBuilder.EMPTY, childElementName, childElementNamespace); } - protected IQ(IqBuilder iqBuilder, String childElementName, String childElementNamespace) { + protected IQ(AbstractIqBuilder iqBuilder, String childElementName, String childElementNamespace) { super(iqBuilder); type = iqBuilder.type; @@ -376,6 +376,25 @@ public abstract class IQ extends Stanza implements IqView { } } + public enum ResponseType { + + result(Type.result), + + error(Type.error), + + ; + + final Type type; + + ResponseType(Type type) { + this.type = type; + } + + Type getType() { + return type; + } + } + public static class IQChildElementXmlStringBuilder extends XmlStringBuilder { private final String element; diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/IqBuilder.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/IqBuilder.java index a0994555f..e1bc905a2 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/IqBuilder.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/IqBuilder.java @@ -16,16 +16,18 @@ */ 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 implements IqView { +// TODO: Rename to IqData. +public final class IqBuilder extends AbstractIqBuilder { + static final IqBuilder EMPTY = new IqBuilder(StandardStanzaIdSource.DEFAULT); - IQ.Type type = Type.get; + IqBuilder(IqBuilder other) { + super(other); + } IqBuilder(StanzaIdSource stanzaIdSource) { super(stanzaIdSource); @@ -35,11 +37,6 @@ public final class IqBuilder extends StanzaBuilder implements IqView 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(); @@ -49,9 +46,4 @@ public final class IqBuilder extends StanzaBuilder implements IqView public IqBuilder getThis() { return this; } - - @Override - public IQ.Type getType() { - return type; - } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/IqBuilderWithBuild.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/IqBuilderWithBuild.java new file mode 100644 index 000000000..5d8c993de --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/IqBuilderWithBuild.java @@ -0,0 +1,45 @@ +/** + * + * 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.XMPPConnection; +import org.jivesoftware.smack.util.Objects; + +// TODO: Rename to IqBuilder. +public abstract class IqBuilderWithBuild, I extends IQ> + extends AbstractIqBuilder { + + protected IqBuilderWithBuild(AbstractIqBuilder other) { + super(other); + } + + protected IqBuilderWithBuild(XMPPConnection connection) { + super(connection.getStanzaFactory().getStanzaIdSource()); + } + + protected IqBuilderWithBuild(String stanzaId) { + super(stanzaId); + } + + public IB ofType(IQ.Type type) { + this.type = Objects.requireNonNull(type); + return getThis(); + } + + public abstract I build(); + +} diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaBuilder.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaBuilder.java index 4b2cba391..ec150e005 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaBuilder.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaBuilder.java @@ -21,8 +21,8 @@ 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.Function; import org.jivesoftware.smack.util.MultiMap; import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smack.util.ToStringUtil; @@ -46,6 +46,17 @@ public abstract class StanzaBuilder> implements Stanz MultiMap extensionElements = new MultiMap<>(); + protected StanzaBuilder(StanzaBuilder other) { + stanzaIdSource = other.stanzaIdSource; + stanzaId = other.stanzaId; + + to = other.to; + from = other.from; + stanzaError = other.stanzaError; + language = other.language; + extensionElements = other.extensionElements.clone(); + } + protected StanzaBuilder(StanzaIdSource stanzaIdSource) { this.stanzaIdSource = stanzaIdSource; this.stanzaId = null; @@ -282,20 +293,14 @@ public abstract class StanzaBuilder> implements Stanz 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()); - } + public static > SB buildResponse(StanzaView request, Function builderFromStanzaId) { + SB responseBuilder = builderFromStanzaId.apply(request.getStanzaId()); - return buildIq(request.getStanzaId()) - .to(request.getFrom()) - .from(request.getTo()) - .ofType(IQ.Type.result); + responseBuilder.to(request.getFrom()) + .from(request.getTo()) + ; + + return responseBuilder; } - public static EmptyResultIQ buildEmptyIqResultFor(IQ request) { - IqBuilder iqBuilder = buildIqResultFor(request); - return new EmptyResultIQ(iqBuilder); - } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaFactory.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaFactory.java index 4a7a85ce8..738477cf7 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaFactory.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaFactory.java @@ -22,6 +22,10 @@ public final class StanzaFactory { private final StanzaIdSource stanzaIdSource; + StanzaIdSource getStanzaIdSource() { + return stanzaIdSource; + } + public StanzaFactory(StanzaIdSource stanzaIdSource) { this.stanzaIdSource = stanzaIdSource; } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/provider/AbstractProvider.java b/smack-core/src/main/java/org/jivesoftware/smack/provider/AbstractProvider.java new file mode 100644 index 000000000..5eda3b494 --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/provider/AbstractProvider.java @@ -0,0 +1,45 @@ +/** + * + * 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.provider; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; + +import org.jivesoftware.smack.packet.Element; + +public class AbstractProvider { + + private final Class elementClass; + + @SuppressWarnings("unchecked") + protected AbstractProvider() { + Type currentType = getClass().getGenericSuperclass(); + while (!(currentType instanceof ParameterizedType)) { + Class currentClass = (Class) currentType; + currentType = currentClass.getGenericSuperclass(); + } + ParameterizedType parameterizedGenericSuperclass = (ParameterizedType) currentType; + Type[] actualTypeArguments = parameterizedGenericSuperclass.getActualTypeArguments(); + Type elementType = actualTypeArguments[0]; + + elementClass = (Class) elementType; + } + + public final Class getElementClass() { + return elementClass; + } +} diff --git a/smack-core/src/main/java/org/jivesoftware/smack/provider/IQProvider.java b/smack-core/src/main/java/org/jivesoftware/smack/provider/IQProvider.java index 66e7aa0f1..514b3e875 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/provider/IQProvider.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/provider/IQProvider.java @@ -17,15 +17,53 @@ package org.jivesoftware.smack.provider; +import java.io.IOException; + import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smack.packet.IqBuilder; +import org.jivesoftware.smack.packet.XmlEnvironment; +import org.jivesoftware.smack.parsing.SmackParsingException; +import org.jivesoftware.smack.util.ParserUtils; +import org.jivesoftware.smack.xml.XmlPullParser; +import org.jivesoftware.smack.xml.XmlPullParserException; /** + *

+ * Deprecation Notice: This class is deprecated, use {@link IQProvider} instead. + *

* An abstract class for parsing custom IQ packets. Each IQProvider must be registered with * the ProviderManager class for it to be used. Every implementation of this * abstract class must have a public, no-argument constructor. * * @author Matt Tucker */ -public abstract class IQProvider extends Provider { +public abstract class IQProvider extends IqProvider { + + public final I parse(XmlPullParser parser) throws IOException, XmlPullParserException, SmackParsingException { + return parse(parser, (XmlEnvironment) null); + } + + public final I parse(XmlPullParser parser, XmlEnvironment outerXmlEnvironment) throws IOException, XmlPullParserException, SmackParsingException { + // XPP3 calling convention assert: Parser should be at start tag + ParserUtils.assertAtStartTag(parser); + + final int initialDepth = parser.getDepth(); + final XmlEnvironment xmlEnvironment = XmlEnvironment.from(parser, outerXmlEnvironment); + + I e = parse(parser, initialDepth, xmlEnvironment); + + // XPP3 calling convention assert: Parser should be at end tag of the consumed/parsed element + ParserUtils.forwardToEndTagOfDepth(parser, initialDepth); + return e; + } + + @Override + public final I parse(XmlPullParser parser, int initialDepth, IqBuilder iqData, XmlEnvironment xmlEnvironment) + throws XmlPullParserException, IOException, SmackParsingException { + // Old-style IQ parsers do not need IqData. + return parse(parser, initialDepth, xmlEnvironment); + } + + public abstract I parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException; } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/provider/IQProviderInfo.java b/smack-core/src/main/java/org/jivesoftware/smack/provider/IQProviderInfo.java index abb14a62f..ec9baee99 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/provider/IQProviderInfo.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/provider/IQProviderInfo.java @@ -34,7 +34,7 @@ public final class IQProviderInfo extends AbstractProviderInfo { * @param namespace Namespace that provider parses. * @param iqProvider The provider implementation. */ - public IQProviderInfo(String elementName, String namespace, IQProvider iqProvider) { + public IQProviderInfo(String elementName, String namespace, IqProvider iqProvider) { super(elementName, namespace, iqProvider); } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/provider/IqProvider.java b/smack-core/src/main/java/org/jivesoftware/smack/provider/IqProvider.java new file mode 100644 index 000000000..cab79ee72 --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/provider/IqProvider.java @@ -0,0 +1,46 @@ +/** + * + * 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.provider; + +import java.io.IOException; + +import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smack.packet.IqBuilder; +import org.jivesoftware.smack.packet.XmlEnvironment; +import org.jivesoftware.smack.parsing.SmackParsingException; +import org.jivesoftware.smack.xml.XmlPullParser; +import org.jivesoftware.smack.xml.XmlPullParserException; + +public abstract class IqProvider extends AbstractProvider { + + public final I parse(XmlPullParser parser, IqBuilder iqCommon) + throws XmlPullParserException, IOException, SmackParsingException { + return parse(parser, iqCommon, null); + } + + public final I parse(XmlPullParser parser, IqBuilder iqData, XmlEnvironment outerXmlEnvironment) + throws XmlPullParserException, IOException, SmackParsingException { + final int initialDepth = parser.getDepth(); + final XmlEnvironment xmlEnvironment = XmlEnvironment.from(parser, outerXmlEnvironment); + + return parse(parser, initialDepth, iqData, xmlEnvironment); + } + + public abstract I parse(XmlPullParser parser, int initialDepth, IqBuilder iqData, XmlEnvironment xmlEnvironment) + throws XmlPullParserException, IOException, SmackParsingException; + +} diff --git a/smack-core/src/main/java/org/jivesoftware/smack/provider/Provider.java b/smack-core/src/main/java/org/jivesoftware/smack/provider/Provider.java index ef1a225d9..4fdce0103 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/provider/Provider.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/provider/Provider.java @@ -18,8 +18,6 @@ package org.jivesoftware.smack.provider; import java.io.IOException; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; import org.jivesoftware.smack.packet.Element; import org.jivesoftware.smack.packet.XmlEnvironment; @@ -40,27 +38,7 @@ import org.jivesoftware.smack.xml.XmlPullParserException; * @author Florian Schmaus * @param the type of the resulting element. */ -public abstract class Provider { - - private final Class elementClass; - - @SuppressWarnings("unchecked") - protected Provider() { - Type currentType = getClass().getGenericSuperclass(); - while (!(currentType instanceof ParameterizedType)) { - Class currentClass = (Class) currentType; - currentType = currentClass.getGenericSuperclass(); - } - ParameterizedType parameterizedGenericSuperclass = (ParameterizedType) currentType; - Type[] actualTypeArguments = parameterizedGenericSuperclass.getActualTypeArguments(); - Type elementType = actualTypeArguments[0]; - - elementClass = (Class) elementType; - } - - public final Class getElementClass() { - return elementClass; - } +public abstract class Provider extends AbstractProvider { public final E parse(XmlPullParser parser) throws IOException, XmlPullParserException, SmackParsingException { return parse(parser, null); diff --git a/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderFileLoader.java b/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderFileLoader.java index e39f81d26..6d3ea9f76 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderFileLoader.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderFileLoader.java @@ -80,8 +80,8 @@ public class ProviderFileLoader implements ProviderLoader { // an IQ class, add the class object itself, then we'll use // reflection later to create instances of the class. // Add the provider to the map. - if (IQProvider.class.isAssignableFrom(provider)) { - IQProvider iqProvider = (IQProvider) provider.getConstructor().newInstance(); + if (IqProvider.class.isAssignableFrom(provider)) { + IqProvider iqProvider = (IqProvider) provider.getConstructor().newInstance(); iqProviders.add(new IQProviderInfo(elementName, namespace, iqProvider)); } else { diff --git a/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderManager.java b/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderManager.java index 377e6e47b..7527b330f 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderManager.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/provider/ProviderManager.java @@ -113,7 +113,7 @@ import org.jivesoftware.smack.util.XmppElementUtil; public final class ProviderManager { private static final Map> extensionProviders = new ConcurrentHashMap<>(); - private static final Map> iqProviders = new ConcurrentHashMap<>(); + private static final Map> iqProviders = new ConcurrentHashMap<>(); private static final Map> streamFeatureProviders = new ConcurrentHashMap<>(); private static final Map> nonzaProviders = new ConcurrentHashMap<>(); @@ -167,7 +167,7 @@ public final class ProviderManager { * @param namespace the XML namespace. * @return the IQ provider. */ - public static IQProvider getIQProvider(String elementName, String namespace) { + public static IqProvider getIQProvider(String elementName, String namespace) { QName key = getQName(elementName, namespace); return iqProviders.get(key); } @@ -179,8 +179,8 @@ public final class ProviderManager { * * @return all IQProvider instances. */ - public static List> getIQProviders() { - List> providers = new ArrayList<>(iqProviders.size()); + public static List> getIQProviders() { + List> providers = new ArrayList<>(iqProviders.size()); providers.addAll(iqProviders.values()); return providers; } @@ -200,10 +200,10 @@ public final class ProviderManager { validate(elementName, namespace); // First remove existing providers QName key = removeIQProvider(elementName, namespace); - if (provider instanceof IQProvider) { - iqProviders.put(key, (IQProvider) provider); + if (provider instanceof IqProvider) { + iqProviders.put(key, (IqProvider) provider); } else { - throw new IllegalArgumentException("Provider must be an IQProvider"); + throw new IllegalArgumentException("Provider must be an instance of IqProvider"); } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java b/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java index 57aaab932..eb7833f12 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java @@ -36,6 +36,7 @@ import org.jivesoftware.smack.packet.EmptyResultIQ; import org.jivesoftware.smack.packet.ErrorIQ; import org.jivesoftware.smack.packet.ExtensionElement; import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smack.packet.IqBuilder; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.MessageBuilder; import org.jivesoftware.smack.packet.Presence; @@ -51,7 +52,7 @@ import org.jivesoftware.smack.packet.XmlEnvironment; import org.jivesoftware.smack.parsing.SmackParsingException; import org.jivesoftware.smack.parsing.StandardExtensionElementProvider; import org.jivesoftware.smack.provider.ExtensionElementProvider; -import org.jivesoftware.smack.provider.IQProvider; +import org.jivesoftware.smack.provider.IqProvider; import org.jivesoftware.smack.provider.ProviderManager; import org.jivesoftware.smack.xml.SmackXmlParser; import org.jivesoftware.smack.xml.XmlPullParser; @@ -542,9 +543,16 @@ public class PacketParserUtils { StanzaError error = null; final String id = parser.getAttributeValue("", "id"); + IqBuilder iqData = StanzaBuilder.buildIq(id); + final Jid to = ParserUtils.getJidAttribute(parser, "to"); + iqData.to(to); + final Jid from = ParserUtils.getJidAttribute(parser, "from"); + iqData.from(from); + final IQ.Type type = IQ.Type.fromString(parser.getAttributeValue("", "type")); + iqData.ofType(type); outerloop: while (true) { XmlPullParser.Event eventType = parser.next(); @@ -560,9 +568,9 @@ public class PacketParserUtils { // Otherwise, see if there is a registered provider for // this element name and namespace. default: - IQProvider provider = ProviderManager.getIQProvider(elementName, namespace); + IqProvider provider = ProviderManager.getIQProvider(elementName, namespace); if (provider != null) { - iqPacket = provider.parse(parser, outerXmlEnvironment); + iqPacket = provider.parse(parser, iqData, outerXmlEnvironment); } // Note that if we reach this code, it is guranteed that the result IQ contained a child element // (RFC 6120 § 8.2.3 6) because otherwhise we would have reached the END_ELEMENT first. @@ -915,6 +923,18 @@ public class PacketParserUtils { return new Session.Feature(optional); } + public static void addExtensionElement(StanzaBuilder stanzaBuilder, XmlPullParser parser, XmlEnvironment outerXmlEnvironment) + throws XmlPullParserException, IOException, SmackParsingException { + ParserUtils.assertAtStartTag(parser); + addExtensionElement(stanzaBuilder, parser, parser.getName(), parser.getNamespace(), outerXmlEnvironment); + } + + public static void addExtensionElement(StanzaBuilder stanzaBuilder, XmlPullParser parser, String elementName, + String namespace, XmlEnvironment outerXmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException { + ExtensionElement extensionElement = parseExtensionElement(elementName, namespace, parser, outerXmlEnvironment); + stanzaBuilder.addExtension(extensionElement); + } + public static void addExtensionElement(Stanza packet, XmlPullParser parser, XmlEnvironment outerXmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException { ParserUtils.assertAtStartTag(parser); diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/element/IoTSetResponse.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/element/IoTSetResponse.java index 1f89efa0e..ef4513d1e 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/element/IoTSetResponse.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/element/IoTSetResponse.java @@ -16,9 +16,9 @@ */ package org.jivesoftware.smackx.iot.control.element; +import org.jivesoftware.smack.packet.AbstractIqBuilder; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IqBuilder; -import org.jivesoftware.smack.packet.StanzaBuilder; public class IoTSetResponse extends IQ { @@ -35,7 +35,7 @@ public class IoTSetResponse extends IQ { } public IoTSetResponse(IoTSetRequest iotSetRequest) { - this(StanzaBuilder.buildIqResultFor(iotSetRequest)); + this(AbstractIqBuilder.createResponse(iotSetRequest)); } @Override diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java index c6b12c036..6591d7512 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java @@ -68,6 +68,8 @@ import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.packet.DiscoverInfo; import org.jivesoftware.smackx.disco.packet.DiscoverInfo.Feature; import org.jivesoftware.smackx.disco.packet.DiscoverInfo.Identity; +import org.jivesoftware.smackx.disco.packet.DiscoverInfoBuilder; +import org.jivesoftware.smackx.disco.packet.DiscoverInfoView; import org.jivesoftware.smackx.xdata.FormField; import org.jivesoftware.smackx.xdata.packet.DataForm; @@ -521,16 +523,19 @@ public final class EntityCapsManager extends Manager { private void updateLocalEntityCaps() { XMPPConnection connection = connection(); - DiscoverInfo discoverInfo = new DiscoverInfo(); - discoverInfo.setType(IQ.Type.result); - sdm.addDiscoverInfoTo(discoverInfo); + DiscoverInfoBuilder discoverInfoBuilder = DiscoverInfo.builder("synthetized-disco-info-response") + .ofType(IQ.Type.result); + sdm.addDiscoverInfoTo(discoverInfoBuilder); // getLocalNodeVer() will return a result only after currentCapsVersion is set. Therefore // set it first and then call getLocalNodeVer() - currentCapsVersion = generateVerificationString(discoverInfo); + currentCapsVersion = generateVerificationString(discoverInfoBuilder); final String localNodeVer = getLocalNodeVer(); - discoverInfo.setNode(localNodeVer); + discoverInfoBuilder.setNode(localNodeVer); + + final DiscoverInfo discoverInfo = discoverInfoBuilder.build(); addDiscoverInfoByNode(localNodeVer, discoverInfo); + if (lastLocalCapsVersions.size() > 10) { CapsVersionAndHash oldCapsVersion = lastLocalCapsVersions.poll(); sdm.removeNodeInformationProvider(entityNode + '#' + oldCapsVersion.version); @@ -630,7 +635,7 @@ public final class EntityCapsManager extends Manager { return false; } - protected static CapsVersionAndHash generateVerificationString(DiscoverInfo discoverInfo) { + protected static CapsVersionAndHash generateVerificationString(DiscoverInfoView discoverInfo) { return generateVerificationString(discoverInfo, null); } @@ -646,7 +651,7 @@ public final class EntityCapsManager extends Manager { * @return The generated verification String or null if the hash is not * supported */ - protected static CapsVersionAndHash generateVerificationString(DiscoverInfo discoverInfo, String hash) { + protected static CapsVersionAndHash generateVerificationString(DiscoverInfoView discoverInfo, String hash) { if (hash == null) { hash = DEFAULT_HASH; } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java index f6de2aca8..62fc38d1d 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java @@ -47,6 +47,7 @@ import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smackx.disco.packet.DiscoverInfo; import org.jivesoftware.smackx.disco.packet.DiscoverInfo.Identity; +import org.jivesoftware.smackx.disco.packet.DiscoverInfoBuilder; import org.jivesoftware.smackx.disco.packet.DiscoverItems; import org.jivesoftware.smackx.xdata.packet.DataForm; @@ -159,34 +160,33 @@ public final class ServiceDiscoveryManager extends Manager { public IQ handleIQRequest(IQ iqRequest) { DiscoverInfo discoverInfo = (DiscoverInfo) iqRequest; // Answer the client's supported features if the request is of the GET type - DiscoverInfo response = new DiscoverInfo(); - response.setType(IQ.Type.result); - response.setTo(discoverInfo.getFrom()); - response.setStanzaId(discoverInfo.getStanzaId()); - response.setNode(discoverInfo.getNode()); + DiscoverInfoBuilder responseBuilder = DiscoverInfoBuilder.buildResponseFor(discoverInfo, IQ.ResponseType.result); + // Add the client's identity and features only if "node" is null // and if the request was not send to a node. If Entity Caps are // enabled the client's identity and features are may also added // if the right node is chosen if (discoverInfo.getNode() == null) { - addDiscoverInfoTo(response); + addDiscoverInfoTo(responseBuilder); } else { // Disco#info was sent to a node. Check if we have information of the // specified node NodeInformationProvider nodeInformationProvider = getNodeInformationProvider(discoverInfo.getNode()); if (nodeInformationProvider != null) { // Node was found. Add node features - response.addFeatures(nodeInformationProvider.getNodeFeatures()); + responseBuilder.addFeatures(nodeInformationProvider.getNodeFeatures()); // Add node identities - response.addIdentities(nodeInformationProvider.getNodeIdentities()); + responseBuilder.addIdentities(nodeInformationProvider.getNodeIdentities()); // Add packet extensions - response.addExtensions(nodeInformationProvider.getNodePacketExtensions()); + responseBuilder.addExtensions(nodeInformationProvider.getNodePacketExtensions()); } else { // Return error since specified node was not found - response.setType(IQ.Type.error); - response.setError(StanzaError.getBuilder(StanzaError.Condition.item_not_found).build()); + responseBuilder.ofType(IQ.Type.error); + responseBuilder.setError(StanzaError.getBuilder(StanzaError.Condition.item_not_found).build()); } } + + DiscoverInfo response = responseBuilder.build(); return response; } }); @@ -299,7 +299,7 @@ public final class ServiceDiscoveryManager extends Manager { * * @param response the discover info response packet */ - public synchronized void addDiscoverInfoTo(DiscoverInfo response) { + public synchronized void addDiscoverInfoTo(DiscoverInfoBuilder response) { // First add the identities of the connection response.addIdentities(getIdentities()); @@ -307,7 +307,9 @@ public final class ServiceDiscoveryManager extends Manager { for (String feature : getFeatures()) { response.addFeature(feature); } - response.addExtension(extendedInfo); + if (extendedInfo != null) { + response.addExtension(extendedInfo); + } } /** @@ -522,13 +524,15 @@ public final class ServiceDiscoveryManager extends Manager { * @throws InterruptedException if the calling thread was interrupted. */ public DiscoverInfo discoverInfo(Jid entityID, String node) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { - // Discover the entity's info - DiscoverInfo disco = new DiscoverInfo(); - disco.setType(IQ.Type.get); - disco.setTo(entityID); - disco.setNode(node); + XMPPConnection connection = connection(); - Stanza result = connection().createStanzaCollectorAndSend(disco).nextResultOrThrow(); + // Discover the entity's info + DiscoverInfo discoInfoRequest = DiscoverInfo.builder(connection) + .to(entityID) + .setNode(node) + .build(); + + Stanza result = connection.createStanzaCollectorAndSend(discoInfoRequest).nextResultOrThrow(); return (DiscoverInfo) result; } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java index 62e9cef67..6f47bb9d3 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java @@ -24,7 +24,9 @@ import java.util.LinkedList; import java.util.List; import java.util.Set; +import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smack.packet.IqBuilder; import org.jivesoftware.smack.util.EqualsUtil; import org.jivesoftware.smack.util.HashCode; import org.jivesoftware.smack.util.StringUtils; @@ -42,18 +44,53 @@ import org.jxmpp.util.XmppStringUtils; * * @author Gaston Dombiak */ -public class DiscoverInfo extends IQ implements TypedCloneable { +public class DiscoverInfo extends IQ implements DiscoverInfoView, TypedCloneable { public static final String ELEMENT = QUERY_ELEMENT; public static final String NAMESPACE = "http://jabber.org/protocol/disco#info"; - private final List features = new LinkedList<>(); + private final List features = new ArrayList<>(); private final Set featuresSet = new HashSet<>(); - private final List identities = new LinkedList<>(); + private final List identities = new ArrayList<>(); private final Set identitiesSet = new HashSet<>(); private String node; private boolean containsDuplicateFeatures; + DiscoverInfo(DiscoverInfoBuilder builder, boolean validate) { + super(builder, ELEMENT, NAMESPACE); + + features.addAll(builder.getFeatures()); + identities.addAll(builder.getIdentities()); + node = builder.getNode(); + + + for (Feature feature : features) { + boolean featureIsNew = featuresSet.add(feature); + if (!featureIsNew) { + containsDuplicateFeatures = true; + } + } + + for (Identity identity : identities) { + identitiesSet.add(identity.getKey()); + } + + if (!validate) { + return; + } + + if (containsDuplicateFeatures) { + throw new IllegalArgumentException("The disco#info request contains duplicate features."); + } + } + + /** + * Deprecated. + * + * @deprecated use {@link DiscoverInfoBuilder} instead. + */ + @Deprecated + // TODO: Remove in Smack 4.5. public DiscoverInfo() { super(ELEMENT, NAMESPACE); } @@ -67,17 +104,15 @@ public class DiscoverInfo extends IQ implements TypedCloneable { super(d); // Set node - setNode(d.getNode()); + node = d.getNode(); // Copy features - for (Feature f : d.features) { - addFeature(f.clone()); - } + features.addAll(d.features); + featuresSet.addAll(d.featuresSet); // Copy identities - for (Identity i : d.identities) { - addIdentity(i.clone()); - } + identities.addAll(d.identities); + identitiesSet.addAll(d.identitiesSet); } /** @@ -85,7 +120,10 @@ public class DiscoverInfo extends IQ implements TypedCloneable { * * @param feature the discovered feature * @return true if the feature did not already exist. + * @deprecated use {@link DiscoverInfoBuilder#addFeature(String)} instead. */ + @Deprecated + // TODO: Remove in Smack 4.5. public boolean addFeature(String feature) { return addFeature(new Feature(feature)); } @@ -94,7 +132,10 @@ public class DiscoverInfo extends IQ implements TypedCloneable { * Adds a collection of features to the packet. Does noting if featuresToAdd is null. * * @param featuresToAdd TODO javadoc me please + * @deprecated use {@link DiscoverInfoBuilder#addFeatures(Collection)} instead. */ + @Deprecated + // TODO: Remove in Smack 4.5. public void addFeatures(Collection featuresToAdd) { if (featuresToAdd == null) return; for (String feature : featuresToAdd) { @@ -102,6 +143,15 @@ public class DiscoverInfo extends IQ implements TypedCloneable { } } + /** + * Deprecated. + * + * @param feature the future. + * @return true if the feature is new. + * @deprecated use {@link DiscoverInfoBuilder#addFeature(Feature)} instead. + */ + @Deprecated + // TODO: Remove in Smack 4.5. public boolean addFeature(Feature feature) { features.add(feature); boolean featureIsNew = featuresSet.add(feature); @@ -111,11 +161,7 @@ public class DiscoverInfo extends IQ implements TypedCloneable { return featureIsNew; } - /** - * Returns the discovered features of an XMPP entity. - * - * @return an unmodifiable list of the discovered features of an XMPP entity - */ + @Override public List getFeatures() { return Collections.unmodifiableList(features); } @@ -124,7 +170,10 @@ public class DiscoverInfo extends IQ implements TypedCloneable { * Adds a new identity of the requested entity to the discovered information. * * @param identity the discovered entity's identity + * @deprecated use {@link DiscoverInfoBuilder#addIdentity(Identity)} instead. */ + @Deprecated + // TODO: Remove in Smack 4.5. public void addIdentity(Identity identity) { identities.add(identity); identitiesSet.add(identity.getKey()); @@ -134,7 +183,10 @@ public class DiscoverInfo extends IQ implements TypedCloneable { * Adds identities to the DiscoverInfo stanza. * * @param identitiesToAdd TODO javadoc me please + * @deprecated use {@link DiscoverInfoBuilder#addIdentities(Collection)} instead. */ + @Deprecated + // TODO: Remove in Smack 4.5. public void addIdentities(Collection identitiesToAdd) { if (identitiesToAdd == null) return; for (Identity identity : identitiesToAdd) { @@ -142,11 +194,7 @@ public class DiscoverInfo extends IQ implements TypedCloneable { } } - /** - * Returns the discovered identities of an XMPP entity. - * - * @return an unmodifiable list of the discovered identities - */ + @Override public List getIdentities() { return Collections.unmodifiableList(identities); } @@ -180,15 +228,7 @@ public class DiscoverInfo extends IQ implements TypedCloneable { return res; } - /** - * Returns the node attribute that supplements the 'jid' attribute. A node is merely - * something that is associated with a JID and for which the JID can provide information.

- * - * Node attributes SHOULD be used only when trying to provide or query information which - * is not directly addressable. - * - * @return the node attribute that supplements the 'jid' attribute - */ + @Override public String getNode() { return node; } @@ -201,7 +241,10 @@ public class DiscoverInfo extends IQ implements TypedCloneable { * is not directly addressable. * * @param node the node attribute that supplements the 'jid' attribute + * @deprecated use {@link DiscoverInfoBuilder#setNode(String)} instead. */ + @Deprecated + // TODO: Remove in Smack 4.5. public void setNode(String node) { this.node = StringUtils.requireNullOrNotEmpty(node, "The node can not be the empty string"); } @@ -256,11 +299,28 @@ public class DiscoverInfo extends IQ implements TypedCloneable { return containsDuplicateFeatures; } + public DiscoverInfoBuilder asBuilder() { + return new DiscoverInfoBuilder(this); + } + + // TODO: Deprecate in favor of asBuilder(). @Override public DiscoverInfo clone() { return new DiscoverInfo(this); } + public static DiscoverInfoBuilder builder(XMPPConnection connection) { + return new DiscoverInfoBuilder(connection); + } + + public static DiscoverInfoBuilder builder(IqBuilder iqData) { + return new DiscoverInfoBuilder(iqData); + } + + public static DiscoverInfoBuilder builder(String stanzaId) { + return new DiscoverInfoBuilder(stanzaId); + } + /** * Represents the identity of a given XMPP entity. An entity may have many identities but all * the identities SHOULD have the same name.

diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfoBuilder.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfoBuilder.java new file mode 100644 index 000000000..3f4f25578 --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfoBuilder.java @@ -0,0 +1,123 @@ +/** + * + * 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.smackx.disco.packet; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.jivesoftware.smack.XMPPConnection; +import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smack.packet.IqBuilder; +import org.jivesoftware.smack.packet.IqBuilderWithBuild; + +import org.jivesoftware.smackx.disco.packet.DiscoverInfo.Feature; +import org.jivesoftware.smackx.disco.packet.DiscoverInfo.Identity; + +public class DiscoverInfoBuilder extends IqBuilderWithBuild + implements DiscoverInfoView { + + private final List features = new ArrayList<>(); + private final List identities = new ArrayList<>(); + + private String node; + + DiscoverInfoBuilder(IqBuilder iqCommon) { + super(iqCommon); + } + + DiscoverInfoBuilder(XMPPConnection connection) { + super(connection); + } + + DiscoverInfoBuilder(String stanzaId) { + super(stanzaId); + } + + public DiscoverInfoBuilder(DiscoverInfo discoverInfo) { + super(discoverInfo.getStanzaId()); + features.addAll(discoverInfo.getFeatures()); + identities.addAll(discoverInfo.getIdentities()); + node = discoverInfo.getNode(); + } + + @Override + public DiscoverInfoBuilder getThis() { + return this; + } + + public DiscoverInfoBuilder addFeatures(Collection features) { + for (String feature : features) { + addFeature(feature); + } + return getThis(); + } + + public DiscoverInfoBuilder addFeature(String feature) { + return addFeature(new Feature(feature)); + } + + public DiscoverInfoBuilder addFeature(Feature feature) { + features.add(feature); + return getThis(); + } + + public DiscoverInfoBuilder addIdentities(Collection identities) { + this.identities.addAll(identities); + return getThis(); + } + + public DiscoverInfoBuilder addIdentity(Identity identity) { + identities.add(identity); + return getThis(); + } + + public DiscoverInfoBuilder setNode(String node) { + this.node = node; + return getThis(); + } + + @Override + public DiscoverInfo build() { + return new DiscoverInfo(this, true); + } + + public DiscoverInfo buildWithoutValidiation() { + return new DiscoverInfo(this, false); + } + + @Override + public List getFeatures() { + return features; + } + + @Override + public List getIdentities() { + return identities; + } + + @Override + public String getNode() { + return node; + } + + public static DiscoverInfoBuilder buildResponseFor(DiscoverInfo request, IQ.ResponseType responseType) { + DiscoverInfoBuilder builder = new DiscoverInfoBuilder(createResponse(request, responseType)); + builder.setNode(request.getNode()); + return builder; + } +} diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfoView.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfoView.java new file mode 100644 index 000000000..8252f21f7 --- /dev/null +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfoView.java @@ -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.smackx.disco.packet; + +import java.util.List; + +import org.jivesoftware.smack.packet.IqView; + +public interface DiscoverInfoView extends IqView { + + /** + * Returns the discovered features of an XMPP entity. + * + * @return an unmodifiable list of the discovered features of an XMPP entity + */ + List getFeatures(); + + /** + * Returns the discovered identities of an XMPP entity. + * + * @return an unmodifiable list of the discovered identities + */ + List getIdentities(); + + /** + * Returns the node attribute that supplements the 'jid' attribute. A node is merely + * something that is associated with a JID and for which the JID can provide information.

+ * + * Node attributes SHOULD be used only when trying to provide or query information which + * is not directly addressable. + * + * @return the node attribute that supplements the 'jid' attribute + */ + String getNode(); +} diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/provider/DiscoverInfoProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/provider/DiscoverInfoProvider.java index 415c4eb15..7bc2f407f 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/provider/DiscoverInfoProvider.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/provider/DiscoverInfoProvider.java @@ -19,34 +19,34 @@ package org.jivesoftware.smackx.disco.provider; import java.io.IOException; +import org.jivesoftware.smack.packet.IqBuilder; import org.jivesoftware.smack.packet.XmlEnvironment; import org.jivesoftware.smack.parsing.SmackParsingException; -import org.jivesoftware.smack.provider.IQProvider; +import org.jivesoftware.smack.provider.IqProvider; import org.jivesoftware.smack.util.PacketParserUtils; +import org.jivesoftware.smack.util.ParserUtils; import org.jivesoftware.smack.xml.XmlPullParser; import org.jivesoftware.smack.xml.XmlPullParserException; import org.jivesoftware.smackx.disco.packet.DiscoverInfo; +import org.jivesoftware.smackx.disco.packet.DiscoverInfoBuilder; /** * The DiscoverInfoProvider parses Service Discovery information packets. * * @author Gaston Dombiak */ -public class DiscoverInfoProvider extends IQProvider { +public class DiscoverInfoProvider extends IqProvider { @Override - public DiscoverInfo parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException { - DiscoverInfo discoverInfo = new DiscoverInfo(); - boolean done = false; - DiscoverInfo.Identity identity; - String category = ""; - String identityName = ""; - String type = ""; - String variable = ""; - String lang = ""; - discoverInfo.setNode(parser.getAttributeValue("", "node")); - while (!done) { + public DiscoverInfo parse(XmlPullParser parser, int initialDepth, IqBuilder iqData, XmlEnvironment xmlEnvironment) + throws XmlPullParserException, IOException, SmackParsingException { + DiscoverInfoBuilder discoverInfoBuilder = DiscoverInfo.builder(iqData); + + String node = parser.getAttributeValue("node"); + discoverInfoBuilder.setNode(node); + + outerloop: while (true) { XmlPullParser.Event eventType = parser.next(); if (eventType == XmlPullParser.Event.START_ELEMENT) { final String name = parser.getName(); @@ -54,39 +54,31 @@ public class DiscoverInfoProvider extends IQProvider { if (namespace.equals(DiscoverInfo.NAMESPACE)) { switch (name) { case "identity": - // Initialize the variables from the parsed XML - category = parser.getAttributeValue("", "category"); - identityName = parser.getAttributeValue("", "name"); - type = parser.getAttributeValue("", "type"); - lang = parser.getAttributeValue(parser.getNamespace("xml"), "lang"); + String category = parser.getAttributeValue("category"); + String identityName = parser.getAttributeValue("name"); + String type = parser.getAttributeValue("type"); + String lang = ParserUtils.getXmlLang(parser); + DiscoverInfo.Identity identity = new DiscoverInfo.Identity(category, type, identityName, lang); + discoverInfoBuilder.addIdentity(identity); break; case "feature": - // Initialize the variables from the parsed XML - variable = parser.getAttributeValue("", "var"); + String feature = parser.getAttributeValue("var"); + discoverInfoBuilder.addFeature(feature); break; } } // Otherwise, it must be a packet extension. else { - PacketParserUtils.addExtensionElement(discoverInfo, parser, xmlEnvironment); + PacketParserUtils.addExtensionElement(discoverInfoBuilder, parser, xmlEnvironment); } } else if (eventType == XmlPullParser.Event.END_ELEMENT) { - if (parser.getName().equals("identity")) { - // Create a new identity and add it to the discovered info. - identity = new DiscoverInfo.Identity(category, type, identityName, lang); - discoverInfo.addIdentity(identity); - } - if (parser.getName().equals("feature")) { - // Create a new feature and add it to the discovered info. - boolean notADuplicateFeature = discoverInfo.addFeature(variable); - assert notADuplicateFeature; - } - if (parser.getName().equals("query")) { - done = true; + if (parser.getDepth() == initialDepth) { + break outerloop; } } } + DiscoverInfo discoverInfo = discoverInfoBuilder.buildWithoutValidiation(); return discoverInfo; } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/Node.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/Node.java index 2af5c3b19..815a05bd2 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/Node.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/Node.java @@ -24,6 +24,7 @@ import java.util.concurrent.ConcurrentHashMap; import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smack.StanzaListener; +import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.filter.FlexibleStanzaTypeFilter; import org.jivesoftware.smack.filter.OrFilter; @@ -120,10 +121,12 @@ public abstract class Node { * @throws InterruptedException if the calling thread was interrupted. */ public DiscoverInfo discoverInfo() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { - DiscoverInfo info = new DiscoverInfo(); - info.setTo(pubSubManager.getServiceJid()); - info.setNode(getId()); - return pubSubManager.getConnection().createStanzaCollectorAndSend(info).nextResultOrThrow(); + XMPPConnection connection = pubSubManager.getConnection(); + DiscoverInfo discoverInfoRequest = DiscoverInfo.builder(connection) + .to(pubSubManager.getServiceJid()) + .setNode(getId()) + .build(); + return connection.createStanzaCollectorAndSend(discoverInfoRequest).nextResultOrThrow(); } /** diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java index be92f373b..89dd1c761 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java @@ -289,11 +289,13 @@ public final class PubSubManager extends Manager { Node node = nodeMap.get(id); if (node == null) { - DiscoverInfo info = new DiscoverInfo(); - info.setTo(pubSubService); - info.setNode(id); + XMPPConnection connection = connection(); + DiscoverInfo info = DiscoverInfo.builder(connection) + .to(pubSubService) + .setNode(id) + .build(); - DiscoverInfo infoReply = connection().createStanzaCollectorAndSend(info).nextResultOrThrow(); + DiscoverInfo infoReply = connection.createStanzaCollectorAndSend(info).nextResultOrThrow(); if (infoReply.hasIdentity(PubSub.ELEMENT, "leaf")) { node = new LeafNode(this, id); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/packet/DataForm.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/packet/DataForm.java index 79360a471..12d3bcab8 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/packet/DataForm.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/packet/DataForm.java @@ -25,9 +25,11 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import javax.xml.namespace.QName; + import org.jivesoftware.smack.packet.Element; import org.jivesoftware.smack.packet.ExtensionElement; -import org.jivesoftware.smack.packet.Stanza; +import org.jivesoftware.smack.packet.StanzaView; import org.jivesoftware.smack.packet.XmlEnvironment; import org.jivesoftware.smack.util.XmlStringBuilder; @@ -44,6 +46,8 @@ public class DataForm implements ExtensionElement { public static final String NAMESPACE = "jabber:x:data"; public static final String ELEMENT = "x"; + public static final QName QNAME = new QName(NAMESPACE, ELEMENT); + public enum Type { /** * This stanza contains a form to fill out. Display it to the user (if your program can). @@ -351,12 +355,13 @@ public class DataForm implements ExtensionElement { } /** - * Get data form from stanza. - * @param packet TODO javadoc me please + * Get data form from a stanza. + * + * @param stanzaView the stanza to get data form from. * @return the DataForm or null */ - public static DataForm from(Stanza packet) { - return (DataForm) packet.getExtension(ELEMENT, NAMESPACE); + public static DataForm from(StanzaView stanzaView) { + return (DataForm) stanzaView.getExtension(QNAME); } /** diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ByteStreamManagerTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ByteStreamManagerTest.java index 39869435e..7c2e2b46e 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ByteStreamManagerTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ByteStreamManagerTest.java @@ -49,6 +49,7 @@ import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream.StreamHost; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.packet.DiscoverInfo; import org.jivesoftware.smackx.disco.packet.DiscoverInfo.Identity; +import org.jivesoftware.smackx.disco.packet.DiscoverInfoBuilder; import org.jivesoftware.smackx.disco.packet.DiscoverItems; import org.jivesoftware.smackx.disco.packet.DiscoverItems.Item; @@ -145,7 +146,7 @@ public class Socks5ByteStreamManagerTest { FeatureNotSupportedException e = assertThrows(FeatureNotSupportedException.class, () -> { // build empty discover info as reply if targets features are queried - DiscoverInfo discoverInfo = new DiscoverInfo(); + DiscoverInfo discoverInfo = DiscoverInfo.builder("disco-1").build(); protocol.addResponse(discoverInfo); // start SOCKS5 Bytestream @@ -181,11 +182,11 @@ public class Socks5ByteStreamManagerTest { */ // build discover info that supports the SOCKS5 feature - DiscoverInfo discoverInfo = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); + DiscoverInfoBuilder discoverInfo = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); discoverInfo.addFeature(Bytestream.NAMESPACE); // return that SOCKS5 is supported if target is queried - protocol.addResponse(discoverInfo, Verification.correspondingSenderReceiver, + protocol.addResponse(discoverInfo.build(), Verification.correspondingSenderReceiver, Verification.requestTypeGET); // build discover items with no proxy items @@ -233,11 +234,11 @@ public class Socks5ByteStreamManagerTest { */ // build discover info that supports the SOCKS5 feature - DiscoverInfo discoverInfo = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); + DiscoverInfoBuilder discoverInfo = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); discoverInfo.addFeature(Bytestream.NAMESPACE); // return that SOCKS5 is supported if target is queried - protocol.addResponse(discoverInfo, Verification.correspondingSenderReceiver, + protocol.addResponse(discoverInfo.build(), Verification.correspondingSenderReceiver, Verification.requestTypeGET); // build discover items containing a proxy item @@ -252,12 +253,12 @@ public class Socks5ByteStreamManagerTest { // build discover info for proxy containing information about NOT being a Socks5 // proxy - DiscoverInfo proxyInfo = Socks5PacketUtils.createDiscoverInfo(proxyJID, initiatorJID); + DiscoverInfoBuilder proxyInfo = Socks5PacketUtils.createDiscoverInfo(proxyJID, initiatorJID); Identity identity = new Identity("noproxy", proxyJID.toString(), "bytestreams"); proxyInfo.addIdentity(identity); // return the proxy identity if proxy is queried - protocol.addResponse(proxyInfo, Verification.correspondingSenderReceiver, + protocol.addResponse(proxyInfo.build(), Verification.correspondingSenderReceiver, Verification.requestTypeGET); SmackException e = assertThrows(SmackException.class, () -> { @@ -294,9 +295,10 @@ public class Socks5ByteStreamManagerTest { */ // build discover info that supports the SOCKS5 feature - DiscoverInfo discoverInfo = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); - discoverInfo.addFeature(Bytestream.NAMESPACE); + DiscoverInfoBuilder discoverInfoBuilder = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); + discoverInfoBuilder.addFeature(Bytestream.NAMESPACE); + DiscoverInfo discoverInfo = discoverInfoBuilder.build(); // return that SOCKS5 is supported if target is queried protocol.addResponse(discoverInfo, Verification.correspondingSenderReceiver, Verification.requestTypeGET); @@ -313,12 +315,12 @@ public class Socks5ByteStreamManagerTest { // build discover info for proxy containing information about NOT being a Socks5 // proxy - DiscoverInfo proxyInfo = Socks5PacketUtils.createDiscoverInfo(proxyJID, initiatorJID); + DiscoverInfoBuilder proxyInfo = Socks5PacketUtils.createDiscoverInfo(proxyJID, initiatorJID); Identity identity = new Identity("noproxy", proxyJID.toString(), "bytestreams"); proxyInfo.addIdentity(identity); // return the proxy identity if proxy is queried - protocol.addResponse(proxyInfo, Verification.correspondingSenderReceiver, + protocol.addResponse(proxyInfo.build(), Verification.correspondingSenderReceiver, Verification.requestTypeGET); SmackException e = assertThrows(SmackException.class, () -> { @@ -376,11 +378,11 @@ public class Socks5ByteStreamManagerTest { */ // build discover info that supports the SOCKS5 feature - DiscoverInfo discoverInfo = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); + DiscoverInfoBuilder discoverInfo = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); discoverInfo.addFeature(Bytestream.NAMESPACE); // return that SOCKS5 is supported if target is queried - protocol.addResponse(discoverInfo, Verification.correspondingSenderReceiver, + protocol.addResponse(discoverInfo.build(), Verification.correspondingSenderReceiver, Verification.requestTypeGET); // build discover items containing a proxy item @@ -394,12 +396,12 @@ public class Socks5ByteStreamManagerTest { Verification.requestTypeGET); // build discover info for proxy containing information about being a SOCKS5 proxy - DiscoverInfo proxyInfo = Socks5PacketUtils.createDiscoverInfo(proxyJID, initiatorJID); + DiscoverInfoBuilder proxyInfo = Socks5PacketUtils.createDiscoverInfo(proxyJID, initiatorJID); Identity identity = new Identity("proxy", proxyJID.toString(), "bytestreams"); proxyInfo.addIdentity(identity); // return the socks5 bytestream proxy identity if proxy is queried - protocol.addResponse(proxyInfo, Verification.correspondingSenderReceiver, + protocol.addResponse(proxyInfo.build(), Verification.correspondingSenderReceiver, Verification.requestTypeGET); // build a socks5 stream host info containing the address and the port of the @@ -458,11 +460,11 @@ public class Socks5ByteStreamManagerTest { */ // build discover info that supports the SOCKS5 feature - DiscoverInfo discoverInfo = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); + DiscoverInfoBuilder discoverInfo = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); discoverInfo.addFeature(Bytestream.NAMESPACE); // return that SOCKS5 is supported if target is queried - protocol.addResponse(discoverInfo, Verification.correspondingSenderReceiver, + protocol.addResponse(discoverInfo.build(), Verification.correspondingSenderReceiver, Verification.requestTypeGET); // build discover items containing a proxy item @@ -476,12 +478,12 @@ public class Socks5ByteStreamManagerTest { Verification.requestTypeGET); // build discover info for proxy containing information about being a SOCKS5 proxy - DiscoverInfo proxyInfo = Socks5PacketUtils.createDiscoverInfo(proxyJID, initiatorJID); + DiscoverInfoBuilder proxyInfo = Socks5PacketUtils.createDiscoverInfo(proxyJID, initiatorJID); Identity identity = new Identity("proxy", proxyJID.toString(), "bytestreams"); proxyInfo.addIdentity(identity); // return the socks5 bytestream proxy identity if proxy is queried - protocol.addResponse(proxyInfo, Verification.correspondingSenderReceiver, + protocol.addResponse(proxyInfo.build(), Verification.correspondingSenderReceiver, Verification.requestTypeGET); // build a socks5 stream host info containing the address and the port of the @@ -545,11 +547,11 @@ public class Socks5ByteStreamManagerTest { */ // build discover info that supports the SOCKS5 feature - DiscoverInfo discoverInfo = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); - discoverInfo.addFeature(Bytestream.NAMESPACE); + DiscoverInfoBuilder discoverInfoBuilder = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); + discoverInfoBuilder.addFeature(Bytestream.NAMESPACE); // return that SOCKS5 is supported if target is queried - protocol.addResponse(discoverInfo, Verification.correspondingSenderReceiver, + protocol.addResponse(discoverInfoBuilder.build(), Verification.correspondingSenderReceiver, Verification.requestTypeGET); // build discover items containing a proxy item @@ -563,12 +565,12 @@ public class Socks5ByteStreamManagerTest { Verification.requestTypeGET); // build discover info for proxy containing information about being a SOCKS5 proxy - DiscoverInfo proxyInfo = Socks5PacketUtils.createDiscoverInfo(proxyJID, initiatorJID); + DiscoverInfoBuilder proxyInfo = Socks5PacketUtils.createDiscoverInfo(proxyJID, initiatorJID); Identity identity = new Identity("proxy", proxyJID.toString(), "bytestreams"); proxyInfo.addIdentity(identity); // return the socks5 bytestream proxy identity if proxy is queried - protocol.addResponse(proxyInfo, Verification.correspondingSenderReceiver, + protocol.addResponse(proxyInfo.build(), Verification.correspondingSenderReceiver, Verification.requestTypeGET); // build a socks5 stream host info containing the address and the port of the @@ -639,11 +641,11 @@ public class Socks5ByteStreamManagerTest { */ // build discover info that supports the SOCKS5 feature - DiscoverInfo discoverInfo = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); + DiscoverInfoBuilder discoverInfo = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); discoverInfo.addFeature(Bytestream.NAMESPACE); // return that SOCKS5 is supported if target is queried - protocol.addResponse(discoverInfo, Verification.correspondingSenderReceiver, + protocol.addResponse(discoverInfo.build(), Verification.correspondingSenderReceiver, Verification.requestTypeGET); // build discover items containing a proxy item @@ -657,12 +659,12 @@ public class Socks5ByteStreamManagerTest { Verification.requestTypeGET); // build discover info for proxy containing information about being a SOCKS5 proxy - DiscoverInfo proxyInfo = Socks5PacketUtils.createDiscoverInfo(proxyJID, initiatorJID); + DiscoverInfoBuilder proxyInfo = Socks5PacketUtils.createDiscoverInfo(proxyJID, initiatorJID); Identity identity = new Identity("proxy", proxyJID.toString(), "bytestreams"); proxyInfo.addIdentity(identity); // return the socks5 bytestream proxy identity if proxy is queried - protocol.addResponse(proxyInfo, Verification.correspondingSenderReceiver, + protocol.addResponse(proxyInfo.build(), Verification.correspondingSenderReceiver, Verification.requestTypeGET); // build a socks5 stream host info containing the address and the port of the @@ -765,11 +767,11 @@ public class Socks5ByteStreamManagerTest { */ // build discover info that supports the SOCKS5 feature - DiscoverInfo discoverInfo = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); + DiscoverInfoBuilder discoverInfo = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); discoverInfo.addFeature(Bytestream.NAMESPACE); // return that SOCKS5 is supported if target is queried - protocol.addResponse(discoverInfo, Verification.correspondingSenderReceiver, + protocol.addResponse(discoverInfo.build(), Verification.correspondingSenderReceiver, Verification.requestTypeGET); // build discover items containing no proxy item @@ -1009,11 +1011,11 @@ public class Socks5ByteStreamManagerTest { Verification streamHostUsedVerification, Socks5TestProxy socks5TestProxy) throws XmppStringprepException { // build discover info that supports the SOCKS5 feature - DiscoverInfo discoverInfo = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); + DiscoverInfoBuilder discoverInfo = Socks5PacketUtils.createDiscoverInfo(targetJID, initiatorJID); discoverInfo.addFeature(Bytestream.NAMESPACE); // return that SOCKS5 is supported if target is queried - protocol.addResponse(discoverInfo, Verification.correspondingSenderReceiver, + protocol.addResponse(discoverInfo.build(), Verification.correspondingSenderReceiver, Verification.requestTypeGET); // build discover items containing a proxy item @@ -1030,22 +1032,22 @@ public class Socks5ByteStreamManagerTest { * build discover info for proxy "proxy2.xmpp-server" containing information about being a * SOCKS5 proxy */ - DiscoverInfo proxyInfo1 = Socks5PacketUtils.createDiscoverInfo(JidCreate.from("proxy2.xmpp-server"), + DiscoverInfoBuilder proxyInfo1 = Socks5PacketUtils.createDiscoverInfo(JidCreate.from("proxy2.xmpp-server"), initiatorJID); Identity identity1 = new Identity("proxy", "proxy2.xmpp-server", "bytestreams"); proxyInfo1.addIdentity(identity1); // return the SOCKS5 bytestream proxy identity if proxy is queried - protocol.addResponse(proxyInfo1, Verification.correspondingSenderReceiver, + protocol.addResponse(proxyInfo1.build(), Verification.correspondingSenderReceiver, Verification.requestTypeGET); // build discover info for proxy containing information about being a SOCKS5 proxy - DiscoverInfo proxyInfo2 = Socks5PacketUtils.createDiscoverInfo(proxyJID, initiatorJID); + DiscoverInfoBuilder proxyInfo2 = Socks5PacketUtils.createDiscoverInfo(proxyJID, initiatorJID); Identity identity2 = new Identity("proxy", proxyJID.toString(), "bytestreams"); proxyInfo2.addIdentity(identity2); // return the SOCKS5 bytestream proxy identity if proxy is queried - protocol.addResponse(proxyInfo2, Verification.correspondingSenderReceiver, + protocol.addResponse(proxyInfo2.build(), Verification.correspondingSenderReceiver, Verification.requestTypeGET); /* diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5PacketUtils.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5PacketUtils.java index d6e9ca3b1..b5cee4cc7 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5PacketUtils.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5PacketUtils.java @@ -21,6 +21,7 @@ import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smackx.bytestreams.socks5.packet.Bytestream; import org.jivesoftware.smackx.disco.packet.DiscoverInfo; +import org.jivesoftware.smackx.disco.packet.DiscoverInfoBuilder; import org.jivesoftware.smackx.disco.packet.DiscoverItems; import org.jxmpp.jid.Jid; @@ -88,11 +89,12 @@ public class Socks5PacketUtils { * @param to the initiator * @return response to an info discovery request */ - public static DiscoverInfo createDiscoverInfo(Jid from, Jid to) { - DiscoverInfo discoverInfo = new DiscoverInfo(); - discoverInfo.setFrom(from); - discoverInfo.setTo(to); - discoverInfo.setType(IQ.Type.result); + public static DiscoverInfoBuilder createDiscoverInfo(Jid from, Jid to) { + DiscoverInfoBuilder discoverInfo = DiscoverInfo.builder("disco-1") + .from(from) + .to(to) + .ofType(IQ.Type.result) + ; return discoverInfo; } diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/caps/EntityCapsManagerTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/caps/EntityCapsManagerTest.java index 518d0142e..739cae26e 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/caps/EntityCapsManagerTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/caps/EntityCapsManagerTest.java @@ -34,6 +34,7 @@ import org.jivesoftware.smackx.InitExtensions; import org.jivesoftware.smackx.caps.cache.EntityCapsPersistentCache; import org.jivesoftware.smackx.caps.cache.SimpleDirectoryPersistentCache; import org.jivesoftware.smackx.disco.packet.DiscoverInfo; +import org.jivesoftware.smackx.disco.packet.DiscoverInfoBuilder; import org.jivesoftware.smackx.xdata.FormField; import org.jivesoftware.smackx.xdata.packet.DataForm; @@ -97,11 +98,10 @@ public class EntityCapsManagerTest extends InitExtensions { } private static DiscoverInfo createComplexSamplePacket() throws XmppStringprepException { - DiscoverInfo di = new DiscoverInfo(); - di.setFrom(JidCreate.from("benvolio@capulet.lit/230193")); - di.setStanzaId("disco1"); - di.setTo(JidCreate.from("juliet@capulet.lit/chamber")); - di.setType(IQ.Type.result); + DiscoverInfoBuilder di = DiscoverInfo.builder("disco1"); + di.from(JidCreate.from("benvolio@capulet.lit/230193")); + di.to(JidCreate.from("juliet@capulet.lit/chamber")); + di.ofType(IQ.Type.result); Collection identities = new LinkedList(); DiscoverInfo.Identity i = new DiscoverInfo.Identity("client", "pc", "Psi 0.11", "en"); @@ -144,15 +144,14 @@ public class EntityCapsManagerTest extends InitExtensions { df.addField(ff.build()); di.addExtension(df); - return di; + return di.build(); } private static DiscoverInfo createMalformedDiscoverInfo() throws XmppStringprepException { - DiscoverInfo di = new DiscoverInfo(); - di.setFrom(JidCreate.from("benvolio@capulet.lit/230193")); - di.setStanzaId("disco1"); - di.setTo(JidCreate.from(")juliet@capulet.lit/chamber")); - di.setType(IQ.Type.result); + DiscoverInfoBuilder di = DiscoverInfo.builder("disco1"); + di.from("benvolio@capulet.lit/230193"); + di.to(")juliet@capulet.lit/chamber"); + di.ofType(IQ.Type.result); Collection identities = new LinkedList(); DiscoverInfo.Identity i = new DiscoverInfo.Identity("client", "pc", "Psi 0.11", "en"); @@ -217,7 +216,8 @@ public class EntityCapsManagerTest extends InitExtensions { di.addExtension(df); - return di; + DiscoverInfo discoverInfo = di.buildWithoutValidiation(); + return discoverInfo; } public static File createTempDirectory() throws IOException { diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/muc/RoomInfoTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/muc/RoomInfoTest.java index ddf453218..f809ca094 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/muc/RoomInfoTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/muc/RoomInfoTest.java @@ -30,8 +30,9 @@ public class RoomInfoTest { public void validateRoomWithEmptyForm() { DataForm dataForm = new DataForm(DataForm.Type.result); - DiscoverInfo discoInfo = new DiscoverInfo(); - discoInfo.addExtension(dataForm); + DiscoverInfo discoInfo = DiscoverInfo.builder("disco1") + .addExtension(dataForm) + .build(); RoomInfo roomInfo = new RoomInfo(discoInfo); assertTrue(roomInfo.getDescription().isEmpty()); assertTrue(roomInfo.getSubject().isEmpty()); @@ -54,8 +55,9 @@ public class RoomInfoTest { occupants.addValue("3"); dataForm.addField(occupants.build()); - DiscoverInfo discoInfo = new DiscoverInfo(); - discoInfo.addExtension(dataForm); + DiscoverInfo discoInfo = DiscoverInfo.builder("disco1") + .addExtension(dataForm) + .build(); RoomInfo roomInfo = new RoomInfo(discoInfo); assertEquals("The place for all good witches!", roomInfo.getDescription()); assertEquals("Spells", roomInfo.getSubject()); diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/pubsub/ConfigureFormTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/pubsub/ConfigureFormTest.java index a46a28bc4..d9fff1e03 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/pubsub/ConfigureFormTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/pubsub/ConfigureFormTest.java @@ -26,6 +26,7 @@ import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.ThreadedDummyConnection; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.XMPPException.XMPPErrorException; +import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IQ.Type; import org.jivesoftware.smack.packet.StanzaError; import org.jivesoftware.smack.packet.StanzaError.Condition; @@ -33,6 +34,7 @@ import org.jivesoftware.smack.packet.StanzaError.Condition; import org.jivesoftware.smackx.InitExtensions; import org.jivesoftware.smackx.disco.packet.DiscoverInfo; import org.jivesoftware.smackx.disco.packet.DiscoverInfo.Identity; +import org.jivesoftware.smackx.disco.packet.DiscoverInfoBuilder; import org.jivesoftware.smackx.pubsub.packet.PubSub; import org.jivesoftware.smackx.xdata.packet.DataForm; @@ -55,12 +57,14 @@ public class ConfigureFormTest extends InitExtensions { public void getConfigFormWithInsufficientPrivileges() throws XMPPException, SmackException, IOException, InterruptedException { ThreadedDummyConnection con = ThreadedDummyConnection.newInstance(); PubSubManager mgr = new PubSubManager(con, PubSubManagerTest.DUMMY_PUBSUB_SERVICE); - DiscoverInfo info = new DiscoverInfo(); - info.setType(Type.result); - info.setFrom(PubSubManagerTest.DUMMY_PUBSUB_SERVICE); + DiscoverInfoBuilder info = DiscoverInfo.builder("disco-result") + .ofType(IQ.Type.result) + .from(PubSubManagerTest.DUMMY_PUBSUB_SERVICE); Identity ident = new Identity("pubsub", null, "leaf"); info.addIdentity(ident); - con.addIQReply(info); + + DiscoverInfo discoverInfo = info.build(); + con.addIQReply(discoverInfo); Node node = mgr.getNode("princely_musings"); @@ -84,10 +88,12 @@ public class ConfigureFormTest extends InitExtensions { public void getConfigFormWithTimeout() throws XMPPException, SmackException, InterruptedException { ThreadedDummyConnection con = new ThreadedDummyConnection(); PubSubManager mgr = new PubSubManager(con, PubSubManagerTest.DUMMY_PUBSUB_SERVICE); - DiscoverInfo info = new DiscoverInfo(); + DiscoverInfoBuilder info = DiscoverInfo.builder("disco-result"); Identity ident = new Identity("pubsub", null, "leaf"); info.addIdentity(ident); - con.addIQReply(info); + + DiscoverInfo discoverInfo = info.build(); + con.addIQReply(discoverInfo); Node node = mgr.getNode("princely_musings"); From 69767e953871c4bc61c1cde6de22905997144946 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Tue, 29 Oct 2019 19:21:31 +0100 Subject: [PATCH 06/16] Rename AbstractIqBuilder subclasses to their designated names --- .../smack/packet/AbstractIqBuilder.java | 10 +++---- .../smack/packet/EmptyResultIQ.java | 2 +- .../org/jivesoftware/smack/packet/IQ.java | 2 +- .../jivesoftware/smack/packet/IqBuilder.java | 25 +++++++---------- .../{IqBuilderWithBuild.java => IqData.java} | 27 +++++++++---------- .../jivesoftware/smack/packet/SimpleIQ.java | 2 +- .../smack/packet/StanzaBuilder.java | 4 +-- .../smack/packet/StanzaFactory.java | 4 +-- .../smack/provider/IQProvider.java | 4 +-- .../smack/provider/IqProvider.java | 8 +++--- .../smack/util/PacketParserUtils.java | 4 +-- .../iot/control/element/IoTSetResponse.java | 4 +-- .../smackx/disco/packet/DiscoverInfo.java | 8 +++--- .../disco/packet/DiscoverInfoBuilder.java | 6 ++--- .../disco/provider/DiscoverInfoProvider.java | 4 +-- .../jivesoftware/smackx/ping/packet/Ping.java | 8 +++--- 16 files changed, 58 insertions(+), 64 deletions(-) rename smack-core/src/main/java/org/jivesoftware/smack/packet/{IqBuilderWithBuild.java => IqData.java} (59%) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/AbstractIqBuilder.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/AbstractIqBuilder.java index 479bcb346..d975db0ef 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/AbstractIqBuilder.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/AbstractIqBuilder.java @@ -36,21 +36,21 @@ public abstract class AbstractIqBuilder> extend super(stanzaId); } - public static IqBuilder createResponse(IqView request) { + public static IqData createResponse(IqView request) { return createResponse(request, IQ.ResponseType.result); } - public static IqBuilder createErrorResponse(IqView request) { + public static IqData createErrorResponse(IqView request) { return createResponse(request, IQ.ResponseType.error); } - protected static IqBuilder createResponse(IqView request, IQ.ResponseType responseType) { + protected static IqData createResponse(IqView request, IQ.ResponseType responseType) { if (!(request.getType() == IQ.Type.get || request.getType() == IQ.Type.set)) { throw new IllegalArgumentException("IQ request must be of type 'set' or 'get'. Original IQ: " + request); } - IqBuilder commonResponseIqData = buildResponse(request, s -> { - return StanzaBuilder.buildIq(s); + IqData commonResponseIqData = buildResponse(request, s -> { + return StanzaBuilder.buildIqData(s); }); commonResponseIqData.ofType(responseType.getType()); diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/EmptyResultIQ.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/EmptyResultIQ.java index 933bf089f..248f0ebaa 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/EmptyResultIQ.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/EmptyResultIQ.java @@ -18,7 +18,7 @@ package org.jivesoftware.smack.packet; public class EmptyResultIQ extends IQ { - EmptyResultIQ(IqBuilder iqBuilder) { + EmptyResultIQ(IqData iqBuilder) { super(iqBuilder, null, null); } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/IQ.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/IQ.java index db76ecdaa..0dd9ca521 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/IQ.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/IQ.java @@ -65,7 +65,7 @@ public abstract class IQ extends Stanza implements IqView { // TODO: Deprecate when stanza builder is ready. protected IQ(String childElementName, String childElementNamespace) { - this(IqBuilder.EMPTY, childElementName, childElementNamespace); + this(IqData.EMPTY, childElementName, childElementNamespace); } protected IQ(AbstractIqBuilder iqBuilder, String childElementName, String childElementNamespace) { diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/IqBuilder.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/IqBuilder.java index e1bc905a2..2e24f53b2 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/IqBuilder.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/IqBuilder.java @@ -16,34 +16,29 @@ */ package org.jivesoftware.smack.packet; -import org.jivesoftware.smack.packet.id.StandardStanzaIdSource; -import org.jivesoftware.smack.packet.id.StanzaIdSource; +import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.util.Objects; -// TODO: Rename to IqData. -public final class IqBuilder extends AbstractIqBuilder { +public abstract class IqBuilder, I extends IQ> + extends AbstractIqBuilder { - static final IqBuilder EMPTY = new IqBuilder(StandardStanzaIdSource.DEFAULT); - - IqBuilder(IqBuilder other) { + protected IqBuilder(AbstractIqBuilder other) { super(other); } - IqBuilder(StanzaIdSource stanzaIdSource) { - super(stanzaIdSource); + protected IqBuilder(XMPPConnection connection) { + super(connection.getStanzaFactory().getStanzaIdSource()); } - IqBuilder(String stanzaId) { + protected IqBuilder(String stanzaId) { super(stanzaId); } - public IqBuilder ofType(IQ.Type type) { + public IB ofType(IQ.Type type) { this.type = Objects.requireNonNull(type); return getThis(); } - @Override - public IqBuilder getThis() { - return this; - } + public abstract I build(); + } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/IqBuilderWithBuild.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/IqData.java similarity index 59% rename from smack-core/src/main/java/org/jivesoftware/smack/packet/IqBuilderWithBuild.java rename to smack-core/src/main/java/org/jivesoftware/smack/packet/IqData.java index 5d8c993de..deba5486e 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/IqBuilderWithBuild.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/IqData.java @@ -16,30 +16,29 @@ */ package org.jivesoftware.smack.packet; -import org.jivesoftware.smack.XMPPConnection; +import org.jivesoftware.smack.packet.id.StandardStanzaIdSource; +import org.jivesoftware.smack.packet.id.StanzaIdSource; import org.jivesoftware.smack.util.Objects; -// TODO: Rename to IqBuilder. -public abstract class IqBuilderWithBuild, I extends IQ> - extends AbstractIqBuilder { +public final class IqData extends AbstractIqBuilder { - protected IqBuilderWithBuild(AbstractIqBuilder other) { - super(other); + static final IqData EMPTY = new IqData(StandardStanzaIdSource.DEFAULT); + + IqData(StanzaIdSource stanzaIdSource) { + super(stanzaIdSource); } - protected IqBuilderWithBuild(XMPPConnection connection) { - super(connection.getStanzaFactory().getStanzaIdSource()); - } - - protected IqBuilderWithBuild(String stanzaId) { + IqData(String stanzaId) { super(stanzaId); } - public IB ofType(IQ.Type type) { + public IqData ofType(IQ.Type type) { this.type = Objects.requireNonNull(type); return getThis(); } - public abstract I build(); - + @Override + public IqData getThis() { + return this; + } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/SimpleIQ.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/SimpleIQ.java index 5cd260c5f..f230949fd 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/SimpleIQ.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/SimpleIQ.java @@ -29,7 +29,7 @@ public abstract class SimpleIQ extends IQ { super(childElementName, childElementNamespace); } - protected SimpleIQ(IqBuilder iqBuilder, String childElementName, String childElementNamespace) { + protected SimpleIQ(IqData iqBuilder, String childElementName, String childElementNamespace) { super(iqBuilder, childElementName, childElementNamespace); } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaBuilder.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaBuilder.java index ec150e005..3539d22bd 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaBuilder.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaBuilder.java @@ -289,8 +289,8 @@ public abstract class StanzaBuilder> implements Stanz return new PresenceBuilder(presence, stanzaIdSource); } - public static IqBuilder buildIq(String stanzaId) { - return new IqBuilder(stanzaId); + public static IqData buildIqData(String stanzaId) { + return new IqData(stanzaId); } public static > SB buildResponse(StanzaView request, Function builderFromStanzaId) { diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaFactory.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaFactory.java index 738477cf7..9f69ee638 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaFactory.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/StanzaFactory.java @@ -46,8 +46,8 @@ public final class StanzaFactory { return new PresenceBuilder(presence, stanzaIdSource); } - public IqBuilder buildIqStanza() { - return new IqBuilder(stanzaIdSource); + public IqData buildIqData() { + return new IqData(stanzaIdSource); } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/provider/IQProvider.java b/smack-core/src/main/java/org/jivesoftware/smack/provider/IQProvider.java index 514b3e875..d0e1f8fc3 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/provider/IQProvider.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/provider/IQProvider.java @@ -20,7 +20,7 @@ package org.jivesoftware.smack.provider; import java.io.IOException; import org.jivesoftware.smack.packet.IQ; -import org.jivesoftware.smack.packet.IqBuilder; +import org.jivesoftware.smack.packet.IqData; import org.jivesoftware.smack.packet.XmlEnvironment; import org.jivesoftware.smack.parsing.SmackParsingException; import org.jivesoftware.smack.util.ParserUtils; @@ -58,7 +58,7 @@ public abstract class IQProvider extends IqProvider { } @Override - public final I parse(XmlPullParser parser, int initialDepth, IqBuilder iqData, XmlEnvironment xmlEnvironment) + public final I parse(XmlPullParser parser, int initialDepth, IqData iqData, XmlEnvironment xmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException { // Old-style IQ parsers do not need IqData. return parse(parser, initialDepth, xmlEnvironment); diff --git a/smack-core/src/main/java/org/jivesoftware/smack/provider/IqProvider.java b/smack-core/src/main/java/org/jivesoftware/smack/provider/IqProvider.java index cab79ee72..14ceecd15 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/provider/IqProvider.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/provider/IqProvider.java @@ -19,7 +19,7 @@ package org.jivesoftware.smack.provider; import java.io.IOException; import org.jivesoftware.smack.packet.IQ; -import org.jivesoftware.smack.packet.IqBuilder; +import org.jivesoftware.smack.packet.IqData; import org.jivesoftware.smack.packet.XmlEnvironment; import org.jivesoftware.smack.parsing.SmackParsingException; import org.jivesoftware.smack.xml.XmlPullParser; @@ -27,12 +27,12 @@ import org.jivesoftware.smack.xml.XmlPullParserException; public abstract class IqProvider extends AbstractProvider { - public final I parse(XmlPullParser parser, IqBuilder iqCommon) + public final I parse(XmlPullParser parser, IqData iqCommon) throws XmlPullParserException, IOException, SmackParsingException { return parse(parser, iqCommon, null); } - public final I parse(XmlPullParser parser, IqBuilder iqData, XmlEnvironment outerXmlEnvironment) + public final I parse(XmlPullParser parser, IqData iqData, XmlEnvironment outerXmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException { final int initialDepth = parser.getDepth(); final XmlEnvironment xmlEnvironment = XmlEnvironment.from(parser, outerXmlEnvironment); @@ -40,7 +40,7 @@ public abstract class IqProvider extends AbstractProvider { return parse(parser, initialDepth, iqData, xmlEnvironment); } - public abstract I parse(XmlPullParser parser, int initialDepth, IqBuilder iqData, XmlEnvironment xmlEnvironment) + public abstract I parse(XmlPullParser parser, int initialDepth, IqData iqData, XmlEnvironment xmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException; } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java b/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java index eb7833f12..a3553475c 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java @@ -36,7 +36,7 @@ import org.jivesoftware.smack.packet.EmptyResultIQ; import org.jivesoftware.smack.packet.ErrorIQ; import org.jivesoftware.smack.packet.ExtensionElement; import org.jivesoftware.smack.packet.IQ; -import org.jivesoftware.smack.packet.IqBuilder; +import org.jivesoftware.smack.packet.IqData; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.MessageBuilder; import org.jivesoftware.smack.packet.Presence; @@ -543,7 +543,7 @@ public class PacketParserUtils { StanzaError error = null; final String id = parser.getAttributeValue("", "id"); - IqBuilder iqData = StanzaBuilder.buildIq(id); + IqData iqData = StanzaBuilder.buildIqData(id); final Jid to = ParserUtils.getJidAttribute(parser, "to"); iqData.to(to); diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/element/IoTSetResponse.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/element/IoTSetResponse.java index ef4513d1e..1d64aebeb 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/element/IoTSetResponse.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/element/IoTSetResponse.java @@ -18,14 +18,14 @@ package org.jivesoftware.smackx.iot.control.element; import org.jivesoftware.smack.packet.AbstractIqBuilder; import org.jivesoftware.smack.packet.IQ; -import org.jivesoftware.smack.packet.IqBuilder; +import org.jivesoftware.smack.packet.IqData; public class IoTSetResponse extends IQ { public static final String ELEMENT = "setResponse"; public static final String NAMESPACE = Constants.IOT_CONTROL_NAMESPACE; - public IoTSetResponse(IqBuilder iqBuilder) { + public IoTSetResponse(IqData iqBuilder) { super(iqBuilder, ELEMENT, NAMESPACE); } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java index 6f47bb9d3..0213d99b8 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java @@ -26,7 +26,7 @@ import java.util.Set; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.packet.IQ; -import org.jivesoftware.smack.packet.IqBuilder; +import org.jivesoftware.smack.packet.IqData; import org.jivesoftware.smack.util.EqualsUtil; import org.jivesoftware.smack.util.HashCode; import org.jivesoftware.smack.util.StringUtils; @@ -148,7 +148,7 @@ public class DiscoverInfo extends IQ implements DiscoverInfoView, TypedCloneable * * @param feature the future. * @return true if the feature is new. - * @deprecated use {@link DiscoverInfoBuilder#addFeature(Feature)} instead. + * @deprecated use {@link DiscoverInfoBuilder#addFeature(DiscoverInfo.Feature)} instead. */ @Deprecated // TODO: Remove in Smack 4.5. @@ -170,7 +170,7 @@ public class DiscoverInfo extends IQ implements DiscoverInfoView, TypedCloneable * Adds a new identity of the requested entity to the discovered information. * * @param identity the discovered entity's identity - * @deprecated use {@link DiscoverInfoBuilder#addIdentity(Identity)} instead. + * @deprecated use {@link DiscoverInfoBuilder#addIdentity(DiscoverInfo.Identity)} instead. */ @Deprecated // TODO: Remove in Smack 4.5. @@ -313,7 +313,7 @@ public class DiscoverInfo extends IQ implements DiscoverInfoView, TypedCloneable return new DiscoverInfoBuilder(connection); } - public static DiscoverInfoBuilder builder(IqBuilder iqData) { + public static DiscoverInfoBuilder builder(IqData iqData) { return new DiscoverInfoBuilder(iqData); } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfoBuilder.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfoBuilder.java index 3f4f25578..66f965de4 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfoBuilder.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfoBuilder.java @@ -23,12 +23,12 @@ import java.util.List; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IqBuilder; -import org.jivesoftware.smack.packet.IqBuilderWithBuild; +import org.jivesoftware.smack.packet.IqData; import org.jivesoftware.smackx.disco.packet.DiscoverInfo.Feature; import org.jivesoftware.smackx.disco.packet.DiscoverInfo.Identity; -public class DiscoverInfoBuilder extends IqBuilderWithBuild +public class DiscoverInfoBuilder extends IqBuilder implements DiscoverInfoView { private final List features = new ArrayList<>(); @@ -36,7 +36,7 @@ public class DiscoverInfoBuilder extends IqBuilderWithBuild { @Override - public DiscoverInfo parse(XmlPullParser parser, int initialDepth, IqBuilder iqData, XmlEnvironment xmlEnvironment) + public DiscoverInfo parse(XmlPullParser parser, int initialDepth, IqData iqData, XmlEnvironment xmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException { DiscoverInfoBuilder discoverInfoBuilder = DiscoverInfo.builder(iqData); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/packet/Ping.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/packet/Ping.java index 13803354c..ac46a76c4 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/packet/Ping.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/packet/Ping.java @@ -18,7 +18,7 @@ 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.IqData; import org.jivesoftware.smack.packet.SimpleIQ; import org.jxmpp.jid.Jid; @@ -39,14 +39,14 @@ public class Ping extends SimpleIQ { } public Ping(XMPPConnection connection, Jid to) { - this(connection.getStanzaFactory().buildIqStanza(), to); + this(connection.getStanzaFactory().buildIqData(), to); } - public Ping(IqBuilder iqBuilder, Jid to) { + public Ping(IqData iqBuilder, Jid to) { super(iqBuilder.to(to).ofType(IQ.Type.get), ELEMENT, NAMESPACE); } - public Ping(IqBuilder iqBuilder) { + public Ping(IqData iqBuilder) { super(iqBuilder, ELEMENT, NAMESPACE); } From e2223254cf87b095fd680897e5616477f895de3c Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Tue, 29 Oct 2019 21:12:22 +0100 Subject: [PATCH 07/16] Organize imports everywhere --- .../jivesoftware/smack/compress/provider/CompressedProvider.java | 1 - .../smack/parsing/StandardExtensionElementProvider.java | 1 - .../org/jivesoftware/smack/provider/BodyElementProvider.java | 1 - .../jivesoftware/smack/provider/EmbeddedExtensionProvider.java | 1 - .../org/jivesoftware/smack/provider/IntrospectionProvider.java | 1 - .../src/main/java/org/jivesoftware/smack/provider/Provider.java | 1 - .../java/org/jivesoftware/smack/provider/TlsFailureProvider.java | 1 - .../java/org/jivesoftware/smack/provider/TlsProceedProvider.java | 1 - .../main/java/org/jivesoftware/smackx/hashes/HashManager.java | 1 + .../org/jivesoftware/smackx/iot/data/element/NodeElement.java | 1 + .../jivesoftware/smackx/jid_prep/provider/JidPrepIqProvider.java | 1 + .../org/jivesoftware/smackx/muclight/MultiUserChatLight.java | 1 + .../org/jivesoftware/smackx/sid/StableUniqueStanzaIdManager.java | 1 + .../smackx/xmlelement/element/DataFormsXmlElement.java | 1 + .../smackx/xmlelement/provider/DataFormsXmlElementProvider.java | 1 + .../org/jivesoftware/smackx/colors/ConsistentColorsTest.java | 1 + .../main/java/org/jivesoftware/smackx/pubsub/ConfigureForm.java | 1 + .../main/java/org/jivesoftware/smackx/pubsub/SubscribeForm.java | 1 + .../java/org/jivesoftware/smackx/usertune/UserTuneListener.java | 1 + .../java/org/jivesoftware/smackx/usertune/UserTuneManager.java | 1 + .../jivesoftware/smackx/usertune/provider/UserTuneProvider.java | 1 + .../org/jivesoftware/smackx/usertune/UserTuneElementTest.java | 1 + .../org/jivesoftware/smackx/usertune/UserTuneManagerTest.java | 1 + .../org/jivesoftware/smackx/workgroup/agent/AgentRoster.java | 1 + .../org/jivesoftware/smackx/workgroup/agent/AgentSession.java | 1 + .../jivesoftware/smackx/omemo/LegacySignalOmemoKeyUtilTest.java | 1 + .../org/jivesoftware/smackx/omemo/SignalOmemoManagerTest.java | 1 + .../src/main/java/org/igniterealtime/smack/smackrepl/DoX.java | 1 + .../src/main/java/org/igniterealtime/smack/smackrepl/IoT.java | 1 + 29 files changed, 21 insertions(+), 8 deletions(-) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/compress/provider/CompressedProvider.java b/smack-core/src/main/java/org/jivesoftware/smack/compress/provider/CompressedProvider.java index fbed9abd3..c8a4cc02d 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/compress/provider/CompressedProvider.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/compress/provider/CompressedProvider.java @@ -19,7 +19,6 @@ package org.jivesoftware.smack.compress.provider; import org.jivesoftware.smack.compress.packet.Compressed; import org.jivesoftware.smack.packet.XmlEnvironment; import org.jivesoftware.smack.provider.NonzaProvider; - import org.jivesoftware.smack.xml.XmlPullParser; public final class CompressedProvider extends NonzaProvider { diff --git a/smack-core/src/main/java/org/jivesoftware/smack/parsing/StandardExtensionElementProvider.java b/smack-core/src/main/java/org/jivesoftware/smack/parsing/StandardExtensionElementProvider.java index cceaf4216..607c64198 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/parsing/StandardExtensionElementProvider.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/parsing/StandardExtensionElementProvider.java @@ -25,7 +25,6 @@ import org.jivesoftware.smack.packet.XmlEnvironment; import org.jivesoftware.smack.provider.ExtensionElementProvider; import org.jivesoftware.smack.util.ParserUtils; import org.jivesoftware.smack.util.StringUtils; - import org.jivesoftware.smack.xml.XmlPullParser; import org.jivesoftware.smack.xml.XmlPullParserException; diff --git a/smack-core/src/main/java/org/jivesoftware/smack/provider/BodyElementProvider.java b/smack-core/src/main/java/org/jivesoftware/smack/provider/BodyElementProvider.java index df85d067c..80a33781c 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/provider/BodyElementProvider.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/provider/BodyElementProvider.java @@ -23,7 +23,6 @@ import java.io.IOException; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.XmlEnvironment; import org.jivesoftware.smack.util.ParserUtils; - import org.jivesoftware.smack.xml.XmlPullParser; import org.jivesoftware.smack.xml.XmlPullParserException; diff --git a/smack-core/src/main/java/org/jivesoftware/smack/provider/EmbeddedExtensionProvider.java b/smack-core/src/main/java/org/jivesoftware/smack/provider/EmbeddedExtensionProvider.java index 40ab16fb5..995751211 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/provider/EmbeddedExtensionProvider.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/provider/EmbeddedExtensionProvider.java @@ -26,7 +26,6 @@ import org.jivesoftware.smack.packet.ExtensionElement; import org.jivesoftware.smack.packet.XmlEnvironment; import org.jivesoftware.smack.parsing.SmackParsingException; import org.jivesoftware.smack.util.PacketParserUtils; - import org.jivesoftware.smack.xml.XmlPullParser; import org.jivesoftware.smack.xml.XmlPullParserException; diff --git a/smack-core/src/main/java/org/jivesoftware/smack/provider/IntrospectionProvider.java b/smack-core/src/main/java/org/jivesoftware/smack/provider/IntrospectionProvider.java index a4c58f406..2f3df5724 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/provider/IntrospectionProvider.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/provider/IntrospectionProvider.java @@ -23,7 +23,6 @@ import org.jivesoftware.smack.packet.ExtensionElement; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.XmlEnvironment; import org.jivesoftware.smack.util.ParserUtils; - import org.jivesoftware.smack.xml.XmlPullParser; import org.jivesoftware.smack.xml.XmlPullParserException; diff --git a/smack-core/src/main/java/org/jivesoftware/smack/provider/Provider.java b/smack-core/src/main/java/org/jivesoftware/smack/provider/Provider.java index 4fdce0103..b41ae7161 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/provider/Provider.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/provider/Provider.java @@ -23,7 +23,6 @@ import org.jivesoftware.smack.packet.Element; import org.jivesoftware.smack.packet.XmlEnvironment; import org.jivesoftware.smack.parsing.SmackParsingException; import org.jivesoftware.smack.util.ParserUtils; - import org.jivesoftware.smack.xml.XmlPullParser; import org.jivesoftware.smack.xml.XmlPullParserException; diff --git a/smack-core/src/main/java/org/jivesoftware/smack/provider/TlsFailureProvider.java b/smack-core/src/main/java/org/jivesoftware/smack/provider/TlsFailureProvider.java index 2509d89c8..2100e4e42 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/provider/TlsFailureProvider.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/provider/TlsFailureProvider.java @@ -18,7 +18,6 @@ package org.jivesoftware.smack.provider; import org.jivesoftware.smack.packet.TlsProceed; import org.jivesoftware.smack.packet.XmlEnvironment; - import org.jivesoftware.smack.xml.XmlPullParser; public final class TlsFailureProvider extends NonzaProvider { diff --git a/smack-core/src/main/java/org/jivesoftware/smack/provider/TlsProceedProvider.java b/smack-core/src/main/java/org/jivesoftware/smack/provider/TlsProceedProvider.java index f8e8b1158..282e4c2f1 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/provider/TlsProceedProvider.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/provider/TlsProceedProvider.java @@ -18,7 +18,6 @@ package org.jivesoftware.smack.provider; import org.jivesoftware.smack.packet.TlsFailure; import org.jivesoftware.smack.packet.XmlEnvironment; - import org.jivesoftware.smack.xml.XmlPullParser; public final class TlsProceedProvider extends NonzaProvider { diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/hashes/HashManager.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/hashes/HashManager.java index 318a7dad9..096a7b85b 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/hashes/HashManager.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/hashes/HashManager.java @@ -43,6 +43,7 @@ import java.util.WeakHashMap; import org.jivesoftware.smack.Manager; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.util.SecurityUtil; + import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.hashes.element.HashElement; diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/element/NodeElement.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/element/NodeElement.java index bde5d94f8..e84ec5f80 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/element/NodeElement.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/element/NodeElement.java @@ -20,6 +20,7 @@ import java.util.Collections; import java.util.List; import org.jivesoftware.smack.util.XmlStringBuilder; + import org.jivesoftware.smackx.iot.element.NodeInfo; public class NodeElement extends IoTDataExtensionElement { diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/jid_prep/provider/JidPrepIqProvider.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/jid_prep/provider/JidPrepIqProvider.java index 82f81f1a9..d7ee7b072 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/jid_prep/provider/JidPrepIqProvider.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/jid_prep/provider/JidPrepIqProvider.java @@ -23,6 +23,7 @@ import org.jivesoftware.smack.parsing.SmackParsingException; import org.jivesoftware.smack.provider.IQProvider; import org.jivesoftware.smack.xml.XmlPullParser; import org.jivesoftware.smack.xml.XmlPullParserException; + import org.jivesoftware.smackx.jid_prep.element.JidPrepIq; public class JidPrepIqProvider extends IQProvider { diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/MultiUserChatLight.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/MultiUserChatLight.java index 8534e4021..6ada795b3 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/MultiUserChatLight.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/muclight/MultiUserChatLight.java @@ -37,6 +37,7 @@ 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; diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/sid/StableUniqueStanzaIdManager.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/sid/StableUniqueStanzaIdManager.java index f0515a74b..d8911aa3e 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/sid/StableUniqueStanzaIdManager.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/sid/StableUniqueStanzaIdManager.java @@ -33,6 +33,7 @@ import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.MessageBuilder; import org.jivesoftware.smack.util.Consumer; import org.jivesoftware.smack.util.Predicate; + import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.sid.element.OriginIdElement; diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/xmlelement/element/DataFormsXmlElement.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/xmlelement/element/DataFormsXmlElement.java index a23296e9c..bb2364af6 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/xmlelement/element/DataFormsXmlElement.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/xmlelement/element/DataFormsXmlElement.java @@ -21,6 +21,7 @@ import javax.xml.namespace.QName; import org.jivesoftware.smack.packet.StandardExtensionElement; import org.jivesoftware.smack.packet.XmlEnvironment; import org.jivesoftware.smack.util.XmlStringBuilder; + import org.jivesoftware.smackx.xdata.FormField; import org.jivesoftware.smackx.xdata.FormFieldChildElement; diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/xmlelement/provider/DataFormsXmlElementProvider.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/xmlelement/provider/DataFormsXmlElementProvider.java index 4de486db2..9f7058e97 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/xmlelement/provider/DataFormsXmlElementProvider.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/xmlelement/provider/DataFormsXmlElementProvider.java @@ -26,6 +26,7 @@ import org.jivesoftware.smack.parsing.SmackParsingException; import org.jivesoftware.smack.parsing.StandardExtensionElementProvider; import org.jivesoftware.smack.xml.XmlPullParser; import org.jivesoftware.smack.xml.XmlPullParserException; + import org.jivesoftware.smackx.xdata.provider.FormFieldChildElementProvider; import org.jivesoftware.smackx.xmlelement.element.DataFormsXmlElement; diff --git a/smack-experimental/src/test/java/org/jivesoftware/smackx/colors/ConsistentColorsTest.java b/smack-experimental/src/test/java/org/jivesoftware/smackx/colors/ConsistentColorsTest.java index 3bf012d9d..931208284 100644 --- a/smack-experimental/src/test/java/org/jivesoftware/smackx/colors/ConsistentColorsTest.java +++ b/smack-experimental/src/test/java/org/jivesoftware/smackx/colors/ConsistentColorsTest.java @@ -19,6 +19,7 @@ package org.jivesoftware.smackx.colors; import static org.junit.jupiter.api.Assertions.assertEquals; import org.jivesoftware.smack.test.util.SmackTestSuite; + import org.jivesoftware.smackx.colors.ConsistentColor.Deficiency; import org.junit.jupiter.api.Test; diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/ConfigureForm.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/ConfigureForm.java index 4c99a8867..91921eee7 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/ConfigureForm.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/ConfigureForm.java @@ -20,6 +20,7 @@ import java.util.ArrayList; import java.util.List; import org.jivesoftware.smack.util.ParserUtils; + import org.jivesoftware.smackx.xdata.Form; import org.jivesoftware.smackx.xdata.FormField; import org.jivesoftware.smackx.xdata.packet.DataForm; diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/SubscribeForm.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/SubscribeForm.java index 857c61054..cdcaffaf5 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/SubscribeForm.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/SubscribeForm.java @@ -24,6 +24,7 @@ import java.util.List; import java.util.UnknownFormatConversionException; import org.jivesoftware.smack.util.ParserUtils; + import org.jivesoftware.smackx.xdata.Form; import org.jivesoftware.smackx.xdata.FormField; import org.jivesoftware.smackx.xdata.packet.DataForm; diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/usertune/UserTuneListener.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/usertune/UserTuneListener.java index c513579fc..e020e4ec2 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/usertune/UserTuneListener.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/usertune/UserTuneListener.java @@ -17,6 +17,7 @@ package org.jivesoftware.smackx.usertune; import org.jivesoftware.smack.packet.Message; + import org.jivesoftware.smackx.usertune.element.UserTuneElement; import org.jxmpp.jid.BareJid; diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/usertune/UserTuneManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/usertune/UserTuneManager.java index 70dd900b1..415c53dcc 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/usertune/UserTuneManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/usertune/UserTuneManager.java @@ -31,6 +31,7 @@ import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.ExtensionElement; import org.jivesoftware.smack.packet.Message; + import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.pep.PepListener; import org.jivesoftware.smackx.pep.PepManager; diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/usertune/provider/UserTuneProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/usertune/provider/UserTuneProvider.java index 5b1c423ef..3679c993d 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/usertune/provider/UserTuneProvider.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/usertune/provider/UserTuneProvider.java @@ -25,6 +25,7 @@ import org.jivesoftware.smack.provider.ExtensionElementProvider; import org.jivesoftware.smack.util.ParserUtils; import org.jivesoftware.smack.xml.XmlPullParser; import org.jivesoftware.smack.xml.XmlPullParserException; + import org.jivesoftware.smackx.usertune.element.UserTuneElement; /** diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/usertune/UserTuneElementTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/usertune/UserTuneElementTest.java index 9aea03774..56fb1af4e 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/usertune/UserTuneElementTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/usertune/UserTuneElementTest.java @@ -28,6 +28,7 @@ import org.jivesoftware.smack.test.util.SmackTestUtil; import org.jivesoftware.smack.test.util.SmackTestUtil.XmlPullParserKind; import org.jivesoftware.smack.xml.XmlPullParser; import org.jivesoftware.smack.xml.XmlPullParserException; + import org.jivesoftware.smackx.usertune.element.UserTuneElement; import org.jivesoftware.smackx.usertune.provider.UserTuneProvider; diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/usertune/UserTuneManagerTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/usertune/UserTuneManagerTest.java index 9e357963c..64928de56 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/usertune/UserTuneManagerTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/usertune/UserTuneManagerTest.java @@ -26,6 +26,7 @@ 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; import org.junit.Test; diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentRoster.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentRoster.java index 199031b87..35e32eba6 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentRoster.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentRoster.java @@ -35,6 +35,7 @@ import org.jivesoftware.smack.filter.StanzaTypeFilter; import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.packet.StanzaBuilder; + import org.jivesoftware.smackx.workgroup.packet.AgentStatus; import org.jivesoftware.smackx.workgroup.packet.AgentStatusRequest; diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java index 00461afd4..a141b50c0 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java @@ -48,6 +48,7 @@ import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smack.packet.PresenceBuilder; import org.jivesoftware.smack.packet.StandardExtensionElement; import org.jivesoftware.smack.packet.Stanza; + import org.jivesoftware.smackx.muc.packet.MUCUser; import org.jivesoftware.smackx.search.ReportedData; import org.jivesoftware.smackx.workgroup.MetaData; diff --git a/smack-omemo-signal/src/test/java/org/jivesoftware/smackx/omemo/LegacySignalOmemoKeyUtilTest.java b/smack-omemo-signal/src/test/java/org/jivesoftware/smackx/omemo/LegacySignalOmemoKeyUtilTest.java index 737d3b24c..e7b91e0a8 100644 --- a/smack-omemo-signal/src/test/java/org/jivesoftware/smackx/omemo/LegacySignalOmemoKeyUtilTest.java +++ b/smack-omemo-signal/src/test/java/org/jivesoftware/smackx/omemo/LegacySignalOmemoKeyUtilTest.java @@ -27,6 +27,7 @@ import static junit.framework.TestCase.assertTrue; import static junit.framework.TestCase.fail; import org.jivesoftware.smack.test.util.SmackTestSuite; + import org.jivesoftware.smackx.omemo.exceptions.CorruptedOmemoKeyException; import org.jivesoftware.smackx.omemo.signal.SignalOmemoKeyUtil; diff --git a/smack-omemo-signal/src/test/java/org/jivesoftware/smackx/omemo/SignalOmemoManagerTest.java b/smack-omemo-signal/src/test/java/org/jivesoftware/smackx/omemo/SignalOmemoManagerTest.java index 15299a259..b551d323e 100644 --- a/smack-omemo-signal/src/test/java/org/jivesoftware/smackx/omemo/SignalOmemoManagerTest.java +++ b/smack-omemo-signal/src/test/java/org/jivesoftware/smackx/omemo/SignalOmemoManagerTest.java @@ -31,6 +31,7 @@ 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.smackx.omemo.element.OmemoElement; import org.jivesoftware.smackx.omemo.provider.OmemoVAxolotlProvider; import org.jivesoftware.smackx.omemo.signal.SignalOmemoService; diff --git a/smack-repl/src/main/java/org/igniterealtime/smack/smackrepl/DoX.java b/smack-repl/src/main/java/org/igniterealtime/smack/smackrepl/DoX.java index aa0525eb2..093a5aea9 100644 --- a/smack-repl/src/main/java/org/igniterealtime/smack/smackrepl/DoX.java +++ b/smack-repl/src/main/java/org/igniterealtime/smack/smackrepl/DoX.java @@ -28,6 +28,7 @@ import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.debugger.ConsoleDebugger; import org.jivesoftware.smack.tcp.XMPPTCPConnection; import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration; + import org.jivesoftware.smackx.dox.DnsOverXmppManager; import org.jivesoftware.smackx.dox.resolver.minidns.DnsOverXmppMiniDnsResolver; diff --git a/smack-repl/src/main/java/org/igniterealtime/smack/smackrepl/IoT.java b/smack-repl/src/main/java/org/igniterealtime/smack/smackrepl/IoT.java index a77f5f1ac..66a968c31 100644 --- a/smack-repl/src/main/java/org/igniterealtime/smack/smackrepl/IoT.java +++ b/smack-repl/src/main/java/org/igniterealtime/smack/smackrepl/IoT.java @@ -33,6 +33,7 @@ import org.jivesoftware.smack.roster.RosterUtil; import org.jivesoftware.smack.tcp.XMPPTCPConnection; import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration; import org.jivesoftware.smack.util.StringUtils; + import org.jivesoftware.smackx.iot.IoTDiscoveryIntegrationTest; import org.jivesoftware.smackx.iot.Thing; import org.jivesoftware.smackx.iot.data.IoTDataManager; From 63ba52475829ce6122a1d3615e12b3b3f7fb0dee Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 30 Oct 2019 08:20:25 +0100 Subject: [PATCH 08/16] Make IQ(IQ) constructor protected --- smack-core/src/main/java/org/jivesoftware/smack/packet/IQ.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/IQ.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/IQ.java index 0dd9ca521..0f412b602 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/IQ.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/IQ.java @@ -54,8 +54,7 @@ public abstract class IQ extends Stanza implements IqView { private Type type = Type.get; - // TODO: This method should be protected! - public IQ(IQ iq) { + protected IQ(IQ iq) { super(iq); type = iq.getType(); this.childElementName = iq.childElementName; From 63a4212f7ea917fdf75eed95bdf5378508371448 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 30 Oct 2019 08:22:47 +0100 Subject: [PATCH 09/16] Remove clone() from DiscoverInfo.Identity there is no need to clone immutable types. --- .../org/jivesoftware/smackx/disco/packet/DiscoverInfo.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java index 0213d99b8..9c5674f70 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java @@ -330,7 +330,7 @@ public class DiscoverInfo extends IQ implements DiscoverInfoView, TypedCloneable * attributes. * */ - public static final class Identity implements Comparable, TypedCloneable { + public static final class Identity implements Comparable { private final String category; private final String type; @@ -512,11 +512,6 @@ public class DiscoverInfo extends IQ implements DiscoverInfoView, TypedCloneable } } - @Override - public Identity clone() { - return new Identity(this); - } - @Override public String toString() { return toXML().toString(); From ee699f24dd37ad4a511a5fb7899a3aea0c392092 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 30 Oct 2019 08:24:13 +0100 Subject: [PATCH 10/16] Remove DiscoverInfo.Identity(Identity) copy constructor as there is no need to copy an immutable type. --- .../jivesoftware/smackx/disco/packet/DiscoverInfo.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java index 9c5674f70..796e51857 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java @@ -338,14 +338,6 @@ public class DiscoverInfo extends IQ implements DiscoverInfoView, TypedCloneable private final String name; private final String lang; // 'xml:lang; - public Identity(Identity identity) { - this.category = identity.category; - this.type = identity.type; - this.key = identity.type; - this.name = identity.name; - this.lang = identity.lang; - } - /** * Creates a new identity for an XMPP entity. * From 6d1252755b378dd9572106a6ea101e0c68d28966 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 30 Oct 2019 09:23:01 +0100 Subject: [PATCH 11/16] Mark more methods in Stanza as final --- .../org/jivesoftware/smack/packet/Stanza.java | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/Stanza.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/Stanza.java index 4207efb6d..b4bdd6aba 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/Stanza.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/Stanza.java @@ -130,7 +130,7 @@ public abstract class Stanza implements StanzaView, TopLevelStreamElement { } @Override - public String getStanzaId() { + public final String getStanzaId() { return id; } @@ -153,7 +153,7 @@ public abstract class Stanza implements StanzaView, TopLevelStreamElement { * @return true if the stanza ID is set, false otherwise. * @since 4.1 */ - public boolean hasStanzaIdSet() { + public final boolean hasStanzaIdSet() { // setStanzaId ensures that the id is either null or not empty, // so we can assume that it is set if it's not null. return id != null; @@ -208,7 +208,7 @@ public abstract class Stanza implements StanzaView, TopLevelStreamElement { } @Override - public Jid getTo() { + public final Jid getTo() { return to; } @@ -224,7 +224,7 @@ public abstract class Stanza implements StanzaView, TopLevelStreamElement { } @Override - public Jid getFrom() { + public final Jid getFrom() { return from; } @@ -241,7 +241,7 @@ public abstract class Stanza implements StanzaView, TopLevelStreamElement { } @Override - public StanzaError getError() { + public final StanzaError getError() { return error; } @@ -267,7 +267,7 @@ public abstract class Stanza implements StanzaView, TopLevelStreamElement { } @Override - public String getLanguage() { + public final String getLanguage() { return language; } @@ -284,7 +284,7 @@ public abstract class Stanza implements StanzaView, TopLevelStreamElement { } @Override - public List getExtensions() { + public final List getExtensions() { synchronized (extensionElements) { // No need to create a new list, values() will already create a new one for us return extensionElements.values(); @@ -312,7 +312,7 @@ public abstract class Stanza implements StanzaView, TopLevelStreamElement { * @return a set of all matching extensions. * @since 4.1 */ - public List getExtensions(String elementName, String namespace) { + public final List getExtensions(String elementName, String namespace) { requireNotNullNorEmpty(elementName, "elementName must not be null nor empty"); requireNotNullNorEmpty(namespace, "namespace must not be null nor empty"); QName key = new QName(namespace, elementName); @@ -320,7 +320,7 @@ public abstract class Stanza implements StanzaView, TopLevelStreamElement { } @Override - public List getExtensions(QName qname) { + public final List getExtensions(QName qname) { List res; synchronized (extensionElements) { res = extensionElements.getAll(qname); @@ -329,7 +329,7 @@ public abstract class Stanza implements StanzaView, TopLevelStreamElement { } @Override - public List getExtensions(Class extensionElementClass) { + public final List getExtensions(Class extensionElementClass) { synchronized (extensionElements) { return XmppElementUtil.getElementsFrom(extensionElements, extensionElementClass); } @@ -344,7 +344,7 @@ public abstract class Stanza implements StanzaView, TopLevelStreamElement { * @param namespace the namespace of the extension that is desired. * @return the stanza extension with the given namespace. */ - public ExtensionElement getExtension(String namespace) { + public final ExtensionElement getExtension(String namespace) { return PacketUtil.extensionElementFrom(getExtensions(), null, namespace); } @@ -360,7 +360,7 @@ public abstract class Stanza implements StanzaView, TopLevelStreamElement { * @return the extension, or null if it doesn't exist. */ @SuppressWarnings("unchecked") - public PE getExtension(String elementName, String namespace) { + public final PE getExtension(String elementName, String namespace) { if (namespace == null) { return null; } @@ -390,7 +390,7 @@ public abstract class Stanza implements StanzaView, TopLevelStreamElement { * @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) { + public final void addExtension(ExtensionElement extension) { if (extension == null) return; QName key = extension.getQName(); synchronized (extensionElements) { @@ -411,7 +411,7 @@ public abstract class Stanza implements StanzaView, TopLevelStreamElement { * @since 4.1.2 */ // TODO: Mark this as deprecated once StanzaBuilder is ready and all call sites are gone. - public ExtensionElement overrideExtension(ExtensionElement extension) { + public final ExtensionElement overrideExtension(ExtensionElement extension) { if (extension == null) return null; synchronized (extensionElements) { // Note that we need to use removeExtension(String, String) here. If would use @@ -429,7 +429,7 @@ public abstract class Stanza implements StanzaView, 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 extensions) { + public final void addExtensions(Collection extensions) { if (extensions == null) return; for (ExtensionElement packetExtension : extensions) { addExtension(packetExtension); @@ -446,7 +446,7 @@ public abstract class Stanza implements StanzaView, TopLevelStreamElement { * @param namespace TODO javadoc me please * @return true if a stanza extension exists, false otherwise. */ - public boolean hasExtension(String elementName, String namespace) { + public final boolean hasExtension(String elementName, String namespace) { if (elementName == null) { return hasExtension(namespace); } @@ -458,7 +458,7 @@ public abstract class Stanza implements StanzaView, TopLevelStreamElement { // Overridden in order to avoid an extra copy. @Override - public boolean hasExtension(String namespace) { + public final boolean hasExtension(String namespace) { synchronized (extensionElements) { for (ExtensionElement packetExtension : extensionElements.values()) { if (packetExtension.getNamespace().equals(namespace)) { @@ -477,7 +477,7 @@ public abstract class Stanza implements StanzaView, TopLevelStreamElement { * @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) { + public final ExtensionElement removeExtension(String elementName, String namespace) { QName key = new QName(namespace, elementName); synchronized (extensionElements) { return extensionElements.remove(key); @@ -493,7 +493,7 @@ public abstract class Stanza implements StanzaView, TopLevelStreamElement { */ @Deprecated // TODO: Remove in Smack 4.5. - public ExtensionElement removeExtension(ExtensionElement extension) { + public final ExtensionElement removeExtension(ExtensionElement extension) { QName key = extension.getQName(); synchronized (extensionElements) { List list = extensionElements.getAll(key); @@ -553,7 +553,7 @@ public abstract class Stanza implements StanzaView, TopLevelStreamElement { * * @param xml the XmlStringBuilder to append the error to. */ - protected void appendErrorIfExists(XmlStringBuilder xml) { + protected final void appendErrorIfExists(XmlStringBuilder xml) { StanzaError error = getError(); if (error != null) { xml.append(error); From 2915101843180e0d37ab92d4baf2d6308ca9ec9e Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 30 Oct 2019 11:56:55 +0100 Subject: [PATCH 12/16] Use isEmpty() in StringUtils.requireNullOrNotEmpty() --- .../src/main/java/org/jivesoftware/smack/util/StringUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/StringUtils.java b/smack-core/src/main/java/org/jivesoftware/smack/util/StringUtils.java index 09b3407ff..ff01779ed 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/StringUtils.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/StringUtils.java @@ -535,7 +535,7 @@ public class StringUtils { if (cs == null) { return null; } - if (cs.toString().isEmpty()) { + if (isEmpty(cs)) { throw new IllegalArgumentException(message); } return cs; From b0277d7e7452ac6ef9af352a962301e79133d11c Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 30 Oct 2019 11:59:51 +0100 Subject: [PATCH 13/16] Emit as empty element when possible --- .../org/jivesoftware/smack/packet/StartTls.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/StartTls.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/StartTls.java index 3da2c3a53..aebb1ad3f 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/StartTls.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/StartTls.java @@ -1,6 +1,6 @@ /** * - * Copyright © 2014-2018 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. @@ -52,9 +52,15 @@ public class StartTls implements Nonza { @Override public XmlStringBuilder toXML(org.jivesoftware.smack.packet.XmlEnvironment enclosingNamespace) { XmlStringBuilder xml = new XmlStringBuilder(this, enclosingNamespace); - xml.rightAngleBracket(); - xml.condEmptyElement(required, "required"); - xml.closeElement(this); + + if (required) { + xml.rightAngleBracket(); + xml.emptyElement("required"); + xml.closeElement(this); + } else { + xml.closeEmptyElement(); + } + return xml; } From eb4c2c557259a5f6f426e896212694fa2b11a3f4 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 30 Oct 2019 12:02:36 +0100 Subject: [PATCH 14/16] s/occured/occurred/ --- resources/fix-a-javadoc.sh | 10 +-- .../smack/AbstractXMPPConnection.java | 12 ++-- .../smack/SASLAuthentication.java | 8 +-- .../Java7ZlibInputOutputStream.java | 2 +- .../parsing/ParsingExceptionCallback.java | 2 +- .../smack/sasl/SASLMechanism.java | 2 +- .../smack/sasl/core/ScramMechanism.java | 2 +- .../jivesoftware/smack/util/FileUtils.java | 2 +- .../smack/util/PacketParserUtils.java | 46 ++++++------- .../smack/util/XmlStringBuilder.java | 2 +- .../AbstractHttpOverXmppProvider.java | 8 +-- .../httpfileupload/HttpFileUploadManager.java | 2 +- .../smackx/MessageEventManagerTest.java | 6 +- .../smackx/RosterExchangeManagerTest.java | 8 +-- .../jivesoftware/smackx/XHTMLManagerTest.java | 6 +- .../smackx/packet/MessageEventTest.java | 4 +- .../smackx/packet/RosterExchangeTest.java | 6 +- .../smackx/packet/XHTMLExtensionTest.java | 6 +- .../amp/provider/AMPExtensionProvider.java | 4 +- .../bytestreams/socks5/Socks5Client.java | 2 +- .../cache/SimpleDirectoryPersistentCache.java | 2 +- .../filetransfer/IncomingFileTransfer.java | 2 +- .../smackx/iqlast/LastActivityManager.java | 2 +- .../provider/PrivateDataProvider.java | 4 +- .../JivePropertiesExtensionProvider.java | 4 +- .../smackx/muc/MultiUserChat.java | 2 +- .../smackx/muc/provider/MUCUserProvider.java | 4 +- .../offline/packet/OfflineMessageInfo.java | 4 +- .../socks5/Socks5ByteStreamManagerTest.java | 20 +++--- .../jivesoftware/smackx/ping/PingTest.java | 4 +- .../smack/roster/RosterGroup.java | 2 +- .../smack/LoginIntegrationTest.java | 2 +- .../smackx/jingle/JingleManagerTest.java | 12 ++-- .../smackx/jingle/nat/STUNResolverTest.java | 2 +- .../mediaimpl/jspeex/AudioMediaSession.java | 2 +- .../JingleContentDescriptionProvider.java | 4 +- .../provider/JingleDescriptionProvider.java | 4 +- .../jingleold/provider/JingleProvider.java | 4 +- .../provider/JingleTransportProvider.java | 4 +- .../workgroup/packet/MetaDataProvider.java | 4 +- .../packet/WorkgroupInformation.java | 4 +- .../xevent/provider/MessageEventProvider.java | 4 +- .../provider/RosterExchangeProvider.java | 4 +- .../smackx/omemo/SignalOmemoStoreTest.java | 2 +- .../smackx/omemo/OmemoManager.java | 30 ++++---- .../smackx/omemo/OmemoRatchet.java | 4 +- .../smackx/omemo/OmemoService.java | 40 +++++------ .../jivesoftware/smackx/omemo/OmemoStore.java | 68 +++++++++---------- .../omemo/util/OmemoMessageBuilder.java | 2 +- .../smack/tcp/XMPPTCPConnection.java | 6 +- 50 files changed, 196 insertions(+), 196 deletions(-) diff --git a/resources/fix-a-javadoc.sh b/resources/fix-a-javadoc.sh index 07209cd22..6354147d6 100755 --- a/resources/fix-a-javadoc.sh +++ b/resources/fix-a-javadoc.sh @@ -28,17 +28,17 @@ SMACK_EXCEPTIONS[InterruptedException]="if the calling thread was interrupted." SMACK_EXCEPTIONS[XMPPErrorException]="if there was an XMPP error returned." SMACK_EXCEPTIONS[NoResponseException]="if there was no response from the remote entity." SMACK_EXCEPTIONS[NotLoggedInException]="if the XMPP connection is not authenticated." -SMACK_EXCEPTIONS[BOSHException]="if an BOSH related error occured." -SMACK_EXCEPTIONS[IOException]="if an I/O error occured." +SMACK_EXCEPTIONS[BOSHException]="if an BOSH related error occurred." +SMACK_EXCEPTIONS[IOException]="if an I/O error occurred." SMACK_EXCEPTIONS[SmackException]="if Smack detected an exceptional situation." SMACK_EXCEPTIONS[XMPPException]="if an XMPP protocol error was received." -SMACK_EXCEPTIONS[SmackSaslException]="if a SASL specific error occured." +SMACK_EXCEPTIONS[SmackSaslException]="if a SASL specific error occurred." SMACK_EXCEPTIONS[SASLErrorException]="if a SASL protocol error was returned." SMACK_EXCEPTIONS[NotAMucServiceException]="if the entity is not a MUC serivce." SMACK_EXCEPTIONS[NoSuchAlgorithmException]="if no such algorithm is available." SMACK_EXCEPTIONS[KeyManagementException]="if there was a key mangement error." SMACK_EXCEPTIONS[XmppStringprepException]="if the provided string is invalid." -SMACK_EXCEPTIONS[XmlPullParserException]="if an error in the XML parser occured." +SMACK_EXCEPTIONS[XmlPullParserException]="if an error in the XML parser occurred." SMACK_EXCEPTIONS[SmackParsingException]="if the Smack parser (provider) encountered invalid input." SMACK_EXCEPTIONS[MucNotJoinedException]="if not joined to the Multi-User Chat." SMACK_EXCEPTIONS[MucAlreadyJoinedException]="if already joined the Multi-User Chat."7y @@ -54,7 +54,7 @@ SMACK_EXCEPTIONS[IllegalArgumentException]="if an illegal argument was given." SMACK_EXCEPTIONS[NotAPubSubNodeException]="if a involved node is not a PubSub node." SMACK_EXCEPTIONS[NoAcceptableTransferMechanisms]="if no acceptable transfer mechanisms are available" SMACK_EXCEPTIONS[NoSuchMethodException]="if no such method is declared" -SMACK_EXCEPTIONS[Exception]="if an exception occured." +SMACK_EXCEPTIONS[Exception]="if an exception occurred." SMACK_EXCEPTIONS[TestNotPossibleException]="if the test is not possible." SMACK_EXCEPTIONS[TimeoutException]="if there was a timeout." SMACK_EXCEPTIONS[IllegalStateException]="if an illegal state was encountered" diff --git a/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java b/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java index 42ba0903e..4d344376d 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java @@ -535,7 +535,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { * * @throws XMPPException if an error occurs on the XMPP protocol level. * @throws SmackException if an error occurs somewhere else besides XMPP protocol level. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. * @return a reference to this object, to chain connect() with login(). * @throws InterruptedException if the calling thread was interrupted. */ @@ -575,7 +575,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { * login if the previous connection state was logged (authenticated). * * @throws SmackException if Smack detected an exceptional situation. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. * @throws XMPPException if an XMPP protocol error was received. * @throws InterruptedException if the calling thread was interrupted. */ @@ -628,7 +628,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { * @param password TODO javadoc me please * @throws XMPPException if an XMPP protocol error was received. * @throws SmackException if Smack detected an exceptional situation. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. * @throws InterruptedException if the calling thread was interrupted. * @see #login */ @@ -646,7 +646,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { * @param resource TODO javadoc me please * @throws XMPPException if an XMPP protocol error was received. * @throws SmackException if Smack detected an exceptional situation. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. * @throws InterruptedException if the calling thread was interrupted. * @see #login */ @@ -873,9 +873,9 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { * @return the used SASLMechanism. * @throws XMPPErrorException if there was an XMPP error returned. * @throws SASLErrorException if a SASL protocol error was returned. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. * @throws InterruptedException if the calling thread was interrupted. - * @throws SmackSaslException if a SASL specific error occured. + * @throws SmackSaslException if a SASL specific error occurred. * @throws NotConnectedException if the XMPP connection is not connected. * @throws NoResponseException if there was no response from the remote entity. * @throws SmackWrappedException in case of an exception. diff --git a/smack-core/src/main/java/org/jivesoftware/smack/SASLAuthentication.java b/smack-core/src/main/java/org/jivesoftware/smack/SASLAuthentication.java index 91018d6d8..6c1c31a5d 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/SASLAuthentication.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/SASLAuthentication.java @@ -175,9 +175,9 @@ public final class SASLAuthentication { * @return the used SASLMechanism. * @throws XMPPErrorException if there was an XMPP error returned. * @throws SASLErrorException if a SASL protocol error was returned. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. * @throws InterruptedException if the calling thread was interrupted. - * @throws SmackSaslException if a SASL specific error occured. + * @throws SmackSaslException if a SASL specific error occurred. * @throws NotConnectedException if the XMPP connection is not connected. * @throws NoResponseException if there was no response from the remote entity. */ @@ -233,7 +233,7 @@ public final class SASLAuthentication { * * @param challenge a base64 encoded string representing the challenge. * @param finalChallenge true if this is the last challenge send by the server within the success stanza - * @throws SmackSaslException if a SASL specific error occured. + * @throws SmackSaslException if a SASL specific error occurred. * @throws NotConnectedException if the XMPP connection is not connected. * @throws InterruptedException if the calling thread was interrupted. */ @@ -252,7 +252,7 @@ public final class SASLAuthentication { * @throws SmackException if Smack detected an exceptional situation. * @throws InterruptedException if the calling thread was interrupted. * @throws NotConnectedException if the XMPP connection is not connected. - * @throws SmackSaslException if a SASL specific error occured. + * @throws SmackSaslException if a SASL specific error occurred. */ void authenticated(Success success) throws InterruptedException, SmackSaslException, NotConnectedException { // RFC6120 6.3.10 "At the end of the authentication exchange, the SASL server (the XMPP diff --git a/smack-core/src/main/java/org/jivesoftware/smack/compression/Java7ZlibInputOutputStream.java b/smack-core/src/main/java/org/jivesoftware/smack/compression/Java7ZlibInputOutputStream.java index b5e190a73..fd71d90ef 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/compression/Java7ZlibInputOutputStream.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/compression/Java7ZlibInputOutputStream.java @@ -76,7 +76,7 @@ public class Java7ZlibInputOutputStream extends XMPPInputOutputStream { * byte without blocking, 0 means that the system is known to block for more input. * * @return 0 if no data is available, 1 otherwise - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. */ @Override public int available() throws IOException { diff --git a/smack-core/src/main/java/org/jivesoftware/smack/parsing/ParsingExceptionCallback.java b/smack-core/src/main/java/org/jivesoftware/smack/parsing/ParsingExceptionCallback.java index e5b3c1b4d..c2fda0d4d 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/parsing/ParsingExceptionCallback.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/parsing/ParsingExceptionCallback.java @@ -39,7 +39,7 @@ public interface ParsingExceptionCallback { * Called when parsing a stanza caused an exception. * * @param stanzaData the raw stanza data that caused the exception - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. */ void handleUnparsableStanza(UnparseableStanza stanzaData) throws IOException; diff --git a/smack-core/src/main/java/org/jivesoftware/smack/sasl/SASLMechanism.java b/smack-core/src/main/java/org/jivesoftware/smack/sasl/SASLMechanism.java index e2d674bc0..e821e8e91 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/sasl/SASLMechanism.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/sasl/SASLMechanism.java @@ -222,7 +222,7 @@ public abstract class SASLMechanism implements Comparable { * empty array here. * * @return the initial response or null - * @throws SmackSaslException if a SASL specific error occured. + * @throws SmackSaslException if a SASL specific error occurred. */ protected abstract byte[] getAuthenticationText() throws SmackSaslException; diff --git a/smack-core/src/main/java/org/jivesoftware/smack/sasl/core/ScramMechanism.java b/smack-core/src/main/java/org/jivesoftware/smack/sasl/core/ScramMechanism.java index ff34fd979..6fadfd3a8 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/sasl/core/ScramMechanism.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/sasl/core/ScramMechanism.java @@ -259,7 +259,7 @@ public abstract class ScramMechanism extends SASLMechanism { /** * * @return the Channel Binding data. - * @throws SmackSaslException if a SASL specific error occured. + * @throws SmackSaslException if a SASL specific error occurred. */ protected byte[] getChannelBindingData() throws SmackSaslException { return null; diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/FileUtils.java b/smack-core/src/main/java/org/jivesoftware/smack/util/FileUtils.java index 74effc014..2cdac90a4 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/FileUtils.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/FileUtils.java @@ -110,7 +110,7 @@ public final class FileUtils { * * @param file TODO javadoc me please * @return the content of file or null in case of an error - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. */ @SuppressWarnings("DefaultCharset") public static String readFileOrThrow(File file) throws IOException { diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java b/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java index a3553475c..4943b91bf 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/PacketParserUtils.java @@ -106,9 +106,9 @@ public class PacketParserUtils { * @param parser TODO javadoc me please * @param outerXmlEnvironment the outer XML environment (optional). * @return a stanza which is either a Message, IQ or Presence. - * @throws XmlPullParserException if an error in the XML parser occured. + * @throws XmlPullParserException if an error in the XML parser occurred. * @throws SmackParsingException if the Smack parser (provider) encountered invalid input. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. */ public static Stanza parseStanza(XmlPullParser parser, XmlEnvironment outerXmlEnvironment) throws XmlPullParserException, SmackParsingException, IOException { ParserUtils.assertAtStartTag(parser); @@ -156,8 +156,8 @@ public class PacketParserUtils { * @param parser the XML parser, positioned at the start of a message packet. * @param outerXmlEnvironment the outer XML environment (optional). * @return a Message packet. - * @throws XmlPullParserException if an error in the XML parser occured. - * @throws IOException if an I/O error occured. + * @throws XmlPullParserException if an error in the XML parser occurred. + * @throws IOException if an I/O error occurred. * @throws SmackParsingException if the Smack parser (provider) encountered invalid input. */ public static Message parseMessage(XmlPullParser parser, XmlEnvironment outerXmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException { @@ -238,8 +238,8 @@ public class PacketParserUtils { * * @param parser TODO javadoc me please * @return the textual content of the element as String - * @throws XmlPullParserException if an error in the XML parser occured. - * @throws IOException if an I/O error occured. + * @throws XmlPullParserException if an error in the XML parser occurred. + * @throws IOException if an I/O error occurred. */ public static String parseElementText(XmlPullParser parser) throws XmlPullParserException, IOException { assert parser.getEventType() == XmlPullParser.Event.START_ELEMENT; @@ -277,8 +277,8 @@ public class PacketParserUtils { * * @param parser the XML pull parser * @return the element as string - * @throws XmlPullParserException if an error in the XML parser occured. - * @throws IOException if an I/O error occured. + * @throws XmlPullParserException if an error in the XML parser occurred. + * @throws IOException if an I/O error occurred. */ public static CharSequence parseElement(XmlPullParser parser) throws XmlPullParserException, IOException { return parseElement(parser, false); @@ -316,8 +316,8 @@ public class PacketParserUtils { * @param depth TODO javadoc me please * @param fullNamespaces TODO javadoc me please * @return the content of the current depth - * @throws XmlPullParserException if an error in the XML parser occured. - * @throws IOException if an I/O error occured. + * @throws XmlPullParserException if an error in the XML parser occurred. + * @throws IOException if an I/O error occurred. */ public static CharSequence parseContentDepth(XmlPullParser parser, int depth, boolean fullNamespaces) throws XmlPullParserException, IOException { if (parser.supportsRoundtrip()) { @@ -442,8 +442,8 @@ public class PacketParserUtils { * @param parser the XML parser, positioned at the start of a presence packet. * @param outerXmlEnvironment the outer XML environment (optional). * @return a Presence packet. - * @throws IOException if an I/O error occured. - * @throws XmlPullParserException if an error in the XML parser occured. + * @throws IOException if an I/O error occurred. + * @throws XmlPullParserException if an error in the XML parser occurred. * @throws SmackParsingException if the Smack parser (provider) encountered invalid input. */ public static Presence parsePresence(XmlPullParser parser, XmlEnvironment outerXmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException { @@ -530,9 +530,9 @@ public class PacketParserUtils { * @param parser the XML parser, positioned at the start of an IQ packet. * @param outerXmlEnvironment the outer XML environment (optional). * @return an IQ object. - * @throws XmlPullParserException if an error in the XML parser occured. + * @throws XmlPullParserException if an error in the XML parser occurred. * @throws XmppStringprepException if the provided string is invalid. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. * @throws SmackParsingException if the Smack parser (provider) encountered invalid input. */ public static IQ parseIQ(XmlPullParser parser, XmlEnvironment outerXmlEnvironment) throws XmlPullParserException, XmppStringprepException, IOException, SmackParsingException { @@ -622,8 +622,8 @@ public class PacketParserUtils { * * @param parser the XML parser, positioned at the start of the mechanisms stanza. * @return a collection of Stings with the mechanisms included in the mechanisms stanza. - * @throws IOException if an I/O error occured. - * @throws XmlPullParserException if an error in the XML parser occured. + * @throws IOException if an I/O error occurred. + * @throws XmlPullParserException if an error in the XML parser occurred. */ public static Collection parseMechanisms(XmlPullParser parser) throws XmlPullParserException, IOException { @@ -652,7 +652,7 @@ public class PacketParserUtils { * * @param parser the XML parser, positioned at the start of the compression stanza. * @return The CompressionFeature stream element - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. * @throws XmlPullParserException if an exception occurs while parsing the stanza. */ public static Compress.Feature parseCompressionFeature(XmlPullParser parser) @@ -719,8 +719,8 @@ public class PacketParserUtils { * @param parser the XML parser. * @param outerXmlEnvironment the outer XML environment (optional). * @return an stream error packet. - * @throws IOException if an I/O error occured. - * @throws XmlPullParserException if an error in the XML parser occured. + * @throws IOException if an I/O error occurred. + * @throws XmlPullParserException if an error in the XML parser occurred. * @throws SmackParsingException if the Smack parser (provider) encountered invalid input. */ public static StreamError parseStreamError(XmlPullParser parser, XmlEnvironment outerXmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException { @@ -781,8 +781,8 @@ public class PacketParserUtils { * @param parser the XML parser. * @param outerXmlEnvironment the outer XML environment (optional). * @return an error sub-packet. - * @throws IOException if an I/O error occured. - * @throws XmlPullParserException if an error in the XML parser occured. + * @throws IOException if an I/O error occurred. + * @throws XmlPullParserException if an error in the XML parser occurred. * @throws SmackParsingException if the Smack parser (provider) encountered invalid input. */ public static StanzaError parseError(XmlPullParser parser, XmlEnvironment outerXmlEnvironment) throws XmlPullParserException, IOException, SmackParsingException { @@ -845,8 +845,8 @@ public class PacketParserUtils { * @param outerXmlEnvironment the outer XML environment (optional). * * @return an extension element. - * @throws XmlPullParserException if an error in the XML parser occured. - * @throws IOException if an I/O error occured. + * @throws XmlPullParserException if an error in the XML parser occurred. + * @throws IOException if an I/O error occurred. * @throws SmackParsingException if the Smack parser (provider) encountered invalid input. */ public static ExtensionElement parseExtensionElement(String elementName, String namespace, diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java b/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java index 436f9e5ad..b9c7e5ca6 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java @@ -628,7 +628,7 @@ public class XmlStringBuilder implements Appendable, CharSequence, Element { * * @param writer TODO javadoc me please * @param enclosingXmlEnvironment the enclosing XML environment. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. */ public void write(Writer writer, XmlEnvironment enclosingXmlEnvironment) throws IOException { try { diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/provider/AbstractHttpOverXmppProvider.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/provider/AbstractHttpOverXmppProvider.java index 5805d090a..18cbf9fd0 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/provider/AbstractHttpOverXmppProvider.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/hoxt/provider/AbstractHttpOverXmppProvider.java @@ -55,8 +55,8 @@ public abstract class AbstractHttpOverXmppProvider * * @param parser the XML parser, positioned at the starting element of the extension. * @return a PacketExtension. - * @throws IOException if an I/O error occured. - * @throws XmlPullParserException if an error in the XML parser occured. + * @throws IOException if an I/O error occurred. + * @throws XmlPullParserException if an error in the XML parser occurred. */ @Override public AMPExtension parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Client.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Client.java index fb7368576..7f80e8260 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Client.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Client.java @@ -130,7 +130,7 @@ public class Socks5Client { * supported by the Socks5Client. * * @param socket connected to a SOCKS5 proxy - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. * @throws SmackMessageException if there was an error. */ protected void establish(Socket socket) throws IOException, SmackMessageException { diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/cache/SimpleDirectoryPersistentCache.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/cache/SimpleDirectoryPersistentCache.java index f965f7a72..7a93df444 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/cache/SimpleDirectoryPersistentCache.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/cache/SimpleDirectoryPersistentCache.java @@ -127,7 +127,7 @@ public class SimpleDirectoryPersistentCache implements EntityCapsPersistentCache * * @param file TODO javadoc me please * @param info TODO javadoc me please - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. */ private static void writeInfoToFile(File file, DiscoverInfo info) throws IOException { try (DataOutputStream dos = new DataOutputStream(new FileOutputStream(file))) { diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/IncomingFileTransfer.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/IncomingFileTransfer.java index 0e972b26d..5c66d4e04 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/IncomingFileTransfer.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/IncomingFileTransfer.java @@ -110,7 +110,7 @@ public class IncomingFileTransfer extends FileTransfer { * * @param file The location to save the file. * @throws SmackException when the file transfer fails - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. * @throws IllegalArgumentException This exception is thrown when the the provided file is * either null, or cannot be written to. */ diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqlast/LastActivityManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqlast/LastActivityManager.java index 3b3ea38a7..f01839f57 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqlast/LastActivityManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqlast/LastActivityManager.java @@ -229,7 +229,7 @@ public final class LastActivityManager extends Manager { * the JID of the user. * @return the LastActivity stanza of the jid. * @throws XMPPErrorException if there was an XMPP error returned. - * thrown if a server error has occured. + * thrown if a server error has occurred. * @throws NoResponseException if there was no response from the server. * @throws NotConnectedException if the XMPP connection is not connected. * @throws InterruptedException if the calling thread was interrupted. diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqprivate/provider/PrivateDataProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqprivate/provider/PrivateDataProvider.java index 4f21a318c..60bd1e900 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqprivate/provider/PrivateDataProvider.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqprivate/provider/PrivateDataProvider.java @@ -41,8 +41,8 @@ public interface PrivateDataProvider { * * @param parser an XML parser. * @return a new PrivateData instance. - * @throws XmlPullParserException if an error in the XML parser occured. - * @throws IOException if an I/O error occured. + * @throws XmlPullParserException if an error in the XML parser occurred. + * @throws IOException if an I/O error occurred. */ PrivateData parsePrivateData(XmlPullParser parser) throws XmlPullParserException, IOException; } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/jiveproperties/provider/JivePropertiesExtensionProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/jiveproperties/provider/JivePropertiesExtensionProvider.java index d88b30708..5d0efbb24 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/jiveproperties/provider/JivePropertiesExtensionProvider.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/jiveproperties/provider/JivePropertiesExtensionProvider.java @@ -48,8 +48,8 @@ public class JivePropertiesExtensionProvider extends ExtensionElementProviderOccupant that have the specified room role. - * @throws XMPPErrorException if an error occured while performing the request to the server or you + * @throws XMPPErrorException if an error occurred while performing the request to the server or you * don't have enough privileges to get this information. * @throws NoResponseException if there was no response from the server. * @throws NotConnectedException if the XMPP connection is not connected. diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/provider/MUCUserProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/provider/MUCUserProvider.java index 4eed95435..879319c9e 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/provider/MUCUserProvider.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/provider/MUCUserProvider.java @@ -43,8 +43,8 @@ public class MUCUserProvider extends ExtensionElementProvider { * * @param parser the XML parser, positioned at the starting element of the extension. * @return a PacketExtension. - * @throws IOException if an I/O error occured. - * @throws XmlPullParserException if an error in the XML parser occured. + * @throws IOException if an I/O error occurred. + * @throws XmlPullParserException if an error in the XML parser occurred. */ @Override public MUCUser parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment) throws XmlPullParserException, IOException { diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/offline/packet/OfflineMessageInfo.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/offline/packet/OfflineMessageInfo.java index ee80d5a9b..8ce910ca1 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/offline/packet/OfflineMessageInfo.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/offline/packet/OfflineMessageInfo.java @@ -99,8 +99,8 @@ public class OfflineMessageInfo implements ExtensionElement { * * @param parser the XML parser, positioned at the starting element of the extension. * @return a PacketExtension. - * @throws IOException if an I/O error occured. - * @throws XmlPullParserException if an error in the XML parser occured. + * @throws IOException if an I/O error occurred. + * @throws XmlPullParserException if an error in the XML parser occurred. */ @Override public OfflineMessageInfo parse(XmlPullParser parser, diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ByteStreamManagerTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ByteStreamManagerTest.java index 7c2e2b46e..6c9b2f9f7 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ByteStreamManagerTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ByteStreamManagerTest.java @@ -135,7 +135,7 @@ public class Socks5ByteStreamManagerTest { * @throws XMPPException if an XMPP protocol error was received. * @throws InterruptedException if the calling thread was interrupted. * @throws SmackException if Smack detected an exceptional situation. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. */ @Test public void shouldFailIfTargetDoesNotSupportSocks5() @@ -163,7 +163,7 @@ public class Socks5ByteStreamManagerTest { * @throws InterruptedException if the calling thread was interrupted. * @throws SmackException if Smack detected an exceptional situation. * @throws XMPPException if an XMPP protocol error was received. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. */ @Test public void shouldFailIfNoSocks5ProxyFound1() @@ -215,7 +215,7 @@ public class Socks5ByteStreamManagerTest { * @throws InterruptedException if the calling thread was interrupted. * @throws SmackException if Smack detected an exceptional situation. * @throws XMPPException if an XMPP protocol error was received. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. */ @Test public void shouldFailIfNoSocks5ProxyFound2() @@ -277,7 +277,7 @@ public class Socks5ByteStreamManagerTest { * @throws InterruptedException if the calling thread was interrupted. * @throws SmackException if Smack detected an exceptional situation. * @throws XMPPException if an XMPP protocol error was received. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. */ @Test public void shouldBlacklistNonSocks5Proxies() throws SmackException, InterruptedException, IOException, XMPPException { @@ -360,7 +360,7 @@ public class Socks5ByteStreamManagerTest { * @throws InterruptedException if the calling thread was interrupted. * @throws SmackException if Smack detected an exceptional situation. * @throws XMPPException if an XMPP protocol error was received. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. */ @Test public void shouldFailIfTargetDoesNotAcceptSocks5Bytestream() throws SmackException, InterruptedException, IOException, XMPPException { @@ -440,7 +440,7 @@ public class Socks5ByteStreamManagerTest { * @throws InterruptedException if the calling thread was interrupted. * @throws SmackException if Smack detected an exceptional situation. * @throws XMPPException if an XMPP protocol error was received. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. */ @Test public void shouldFailIfTargetUsesInvalidSocks5Proxy() @@ -622,7 +622,7 @@ public class Socks5ByteStreamManagerTest { * @throws InterruptedException if the calling thread was interrupted. * @throws SmackException if Smack detected an exceptional situation. * @throws XMPPException if an XMPP protocol error was received. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. */ @Test public void shouldNegotiateSocks5BytestreamAndTransferData() @@ -741,7 +741,7 @@ public class Socks5ByteStreamManagerTest { * * @throws InterruptedException if the calling thread was interrupted. * @throws SmackException if Smack detected an exceptional situation. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. * @throws XMPPException if an XMPP protocol error was received. * @throws TimeoutException if there was a timeout. */ @@ -848,7 +848,7 @@ public class Socks5ByteStreamManagerTest { * @throws InterruptedException if the calling thread was interrupted. * @throws SmackException if Smack detected an exceptional situation. * @throws XMPPException if an XMPP protocol error was received. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. * */ @Test @@ -934,7 +934,7 @@ public class Socks5ByteStreamManagerTest { * should successfully negotiate a SOCKS5 Bytestream via the second SOCKS5 proxy. The second * negotiation should run in the same manner if prioritization is disabled. * - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. * @throws InterruptedException if the calling thread was interrupted. * @throws SmackException if Smack detected an exceptional situation. * @throws XMPPException if an XMPP protocol error was received. diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/ping/PingTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/ping/PingTest.java index 0a9a54a75..37082a358 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/ping/PingTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/ping/PingTest.java @@ -99,7 +99,7 @@ public class PingTest extends InitExtensions { * DummyConnection will not reply so it will timeout. * @throws SmackException if Smack detected an exceptional situation. * @throws XMPPException if an XMPP protocol error was received. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. * @throws InterruptedException if the calling thread was interrupted. */ @Test @@ -239,7 +239,7 @@ public class PingTest extends InitExtensions { * * @return * @throws XMPPException if an XMPP protocol error was received. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. * @throws SmackException if Smack detected an exceptional situation. * @throws InterruptedException if the calling thread was interrupted. */ diff --git a/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterGroup.java b/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterGroup.java index e67f3e6fc..19e7cacab 100644 --- a/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterGroup.java +++ b/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterGroup.java @@ -165,7 +165,7 @@ public class RosterGroup extends Manager { * to receive the updated roster. * * @param entry a roster entry. - * @throws XMPPErrorException if an error occured while trying to add the entry to the group. + * @throws XMPPErrorException if an error occurred while trying to add the entry to the group. * @throws NoResponseException if there was no response from the server. * @throws NotConnectedException if the XMPP connection is not connected. * @throws InterruptedException if the calling thread was interrupted. diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smack/LoginIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smack/LoginIntegrationTest.java index 541de5163..07a239b00 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smack/LoginIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smack/LoginIntegrationTest.java @@ -43,7 +43,7 @@ public class LoginIntegrationTest extends AbstractSmackLowLevelIntegrationTest { * * @throws InterruptedException if the calling thread was interrupted. * @throws XMPPException if an XMPP protocol error was received. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. * @throws SmackException if Smack detected an exceptional situation. * @throws NoSuchAlgorithmException if no such algorithm is available. * @throws KeyManagementException if there was a key mangement error. diff --git a/smack-jingle-old/src/integration-test/java/org/jivesoftware/smackx/jingle/JingleManagerTest.java b/smack-jingle-old/src/integration-test/java/org/jivesoftware/smackx/jingle/JingleManagerTest.java index 49c89c355..13cdd8e0e 100644 --- a/smack-jingle-old/src/integration-test/java/org/jivesoftware/smackx/jingle/JingleManagerTest.java +++ b/smack-jingle-old/src/integration-test/java/org/jivesoftware/smackx/jingle/JingleManagerTest.java @@ -234,7 +234,7 @@ public class JingleManagerTest extends SmackTestCase { } catch (Exception e) { LOGGER.log(Level.WARNING, "exception", e); - fail("An error occured with Jingle"); + fail("An error occurred with Jingle"); } } @@ -294,7 +294,7 @@ public class JingleManagerTest extends SmackTestCase { } catch (Exception e) { LOGGER.log(Level.WARNING, "exception", e); - fail("An error occured with Jingle"); + fail("An error occurred with Jingle"); } } @@ -385,7 +385,7 @@ public class JingleManagerTest extends SmackTestCase { } catch (Exception e) { LOGGER.log(Level.WARNING, "exception", e); - fail("An error occured with Jingle"); + fail("An error occurred with Jingle"); } } @@ -499,7 +499,7 @@ public class JingleManagerTest extends SmackTestCase { } catch (Exception e) { LOGGER.log(Level.WARNING, "exception", e); - fail("An error occured with Jingle"); + fail("An error occurred with Jingle"); } } @@ -589,7 +589,7 @@ public class JingleManagerTest extends SmackTestCase { } catch (Exception e) { LOGGER.log(Level.WARNING, "exception", e); - fail("An error occured with Jingle"); + fail("An error occurred with Jingle"); } } @@ -985,7 +985,7 @@ public class JingleManagerTest extends SmackTestCase { // // } catch (Exception e) { // LOGGER.log(Level.WARNING, "exception", e); -// fail("An error occured with Jingle"); +// fail("An error occurred with Jingle"); // } // } diff --git a/smack-jingle-old/src/integration-test/java/org/jivesoftware/smackx/jingle/nat/STUNResolverTest.java b/smack-jingle-old/src/integration-test/java/org/jivesoftware/smackx/jingle/nat/STUNResolverTest.java index 2f1ee9b92..5d9425a92 100644 --- a/smack-jingle-old/src/integration-test/java/org/jivesoftware/smackx/jingle/nat/STUNResolverTest.java +++ b/smack-jingle-old/src/integration-test/java/org/jivesoftware/smackx/jingle/nat/STUNResolverTest.java @@ -396,7 +396,7 @@ public class STUNResolverTest extends SmackTestCase { } catch (Exception e) { LOGGER.log(Level.WARNING, "exception", e); - fail("An error occured with Jingle"); + fail("An error occurred with Jingle"); } } diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/jspeex/AudioMediaSession.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/jspeex/AudioMediaSession.java index 229a1521f..555836732 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/jspeex/AudioMediaSession.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/mediaimpl/jspeex/AudioMediaSession.java @@ -70,7 +70,7 @@ public class AudioMediaSession extends JingleMediaSession implements MediaSessio * @return MediaSession TODO javadoc me please * @throws NoProcessorException if there is no media processor. * @throws UnsupportedFormatException if the format is not supported. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. * @throws GeneralSecurityException if there was a geneeral security exception. */ public static MediaSession createSession(String localhost, int localPort, String remoteHost, int remotePort, MediaSessionListener eventHandler, int quality, boolean secure, boolean micOn) throws NoProcessorException, UnsupportedFormatException, IOException, GeneralSecurityException { diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/provider/JingleContentDescriptionProvider.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/provider/JingleContentDescriptionProvider.java index 5d2f90bc3..afba58713 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/provider/JingleContentDescriptionProvider.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/provider/JingleContentDescriptionProvider.java @@ -65,8 +65,8 @@ public abstract class JingleContentDescriptionProvider extends ExtensionElementP * * @param parser the input to parse * @return a description element - * @throws IOException if an I/O error occured. - * @throws XmlPullParserException if an error in the XML parser occured. + * @throws IOException if an I/O error occurred. + * @throws XmlPullParserException if an error in the XML parser occurred. */ @Override public JingleContentDescription parse(XmlPullParser parser, diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/provider/JingleDescriptionProvider.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/provider/JingleDescriptionProvider.java index 124258680..c446a3958 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/provider/JingleDescriptionProvider.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/provider/JingleDescriptionProvider.java @@ -66,8 +66,8 @@ public abstract class JingleDescriptionProvider extends ExtensionElementProvider * @param parser TODO javadoc me please * the input to parse * @return a description element - * @throws IOException if an I/O error occured. - * @throws XmlPullParserException if an error in the XML parser occured. + * @throws IOException if an I/O error occurred. + * @throws XmlPullParserException if an error in the XML parser occurred. */ @Override public JingleDescription parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment) throws XmlPullParserException, IOException { diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/provider/JingleProvider.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/provider/JingleProvider.java index f717d7303..0d6003351 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/provider/JingleProvider.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/provider/JingleProvider.java @@ -45,8 +45,8 @@ public class JingleProvider extends IQProvider { /** * Parse a iq/jingle element. - * @throws XmlPullParserException if an error in the XML parser occured. - * @throws IOException if an I/O error occured. + * @throws XmlPullParserException if an error in the XML parser occurred. + * @throws IOException if an I/O error occurred. * @throws SmackParsingException if the Smack parser (provider) encountered invalid input. */ @Override diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/provider/JingleTransportProvider.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/provider/JingleTransportProvider.java index 87d39360b..12d98e8a1 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/provider/JingleTransportProvider.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/provider/JingleTransportProvider.java @@ -49,8 +49,8 @@ public abstract class JingleTransportProvider extends ExtensionElementProvider { /** * PacketExtensionProvider implementation. - * @throws IOException if an I/O error occured. - * @throws XmlPullParserException if an error in the XML parser occured. + * @throws IOException if an I/O error occurred. + * @throws XmlPullParserException if an error in the XML parser occurred. */ @Override public MetaData parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment) throws XmlPullParserException, IOException { diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/WorkgroupInformation.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/WorkgroupInformation.java index 9880f5eac..6df4ad29e 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/WorkgroupInformation.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/packet/WorkgroupInformation.java @@ -79,8 +79,8 @@ public class WorkgroupInformation implements ExtensionElement { /** * PacketExtensionProvider implementation. - * @throws IOException if an I/O error occured. - * @throws XmlPullParserException if an error in the XML parser occured. + * @throws IOException if an I/O error occurred. + * @throws XmlPullParserException if an error in the XML parser occurred. */ @Override public WorkgroupInformation parse(XmlPullParser parser, diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/xevent/provider/MessageEventProvider.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/xevent/provider/MessageEventProvider.java index da31a5f5f..dff03a746 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/xevent/provider/MessageEventProvider.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/xevent/provider/MessageEventProvider.java @@ -39,8 +39,8 @@ public class MessageEventProvider extends ExtensionElementProvider * * @param parser the XML parser, positioned at the starting element of the extension. * @return a PacketExtension. - * @throws IOException if an I/O error occured. - * @throws XmlPullParserException if an error in the XML parser occured. + * @throws IOException if an I/O error occurred. + * @throws XmlPullParserException if an error in the XML parser occurred. */ @Override public MessageEvent parse(XmlPullParser parser, int initialDepth, XmlEnvironment xmlEnvironment) diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/xroster/provider/RosterExchangeProvider.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/xroster/provider/RosterExchangeProvider.java index 3013b92a8..c0248c99b 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/xroster/provider/RosterExchangeProvider.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/xroster/provider/RosterExchangeProvider.java @@ -44,8 +44,8 @@ public class RosterExchangeProvider extends ExtensionElementProvider getParameters() throws IOException { diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java index ba53e452c..a3d2ff48d 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java @@ -235,7 +235,7 @@ public final class OmemoManager extends Manager { * @throws XMPPException.XMPPErrorException if there was an XMPP error returned. * @throws SmackException.NotLoggedInException if the XMPP connection is not authenticated. * @throws PubSubException.NotALeafNodeException if a PubSub leaf node operation was attempted on a non-leaf node. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. */ public synchronized void initialize() throws SmackException.NotLoggedInException, CorruptedOmemoKeyException, InterruptedException, @@ -279,7 +279,7 @@ public final class OmemoManager extends Manager { * @see #requestDeviceListUpdateFor(BareJid) * @param contact contact we want to get a set of device of. * @return set of known devices of that contact. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. */ public Set getDevicesOf(BareJid contact) throws IOException { OmemoCachedDeviceList list = getOmemoService().getOmemoStoreBackend().loadCachedDeviceList(getOwnDevice(), contact); @@ -305,7 +305,7 @@ public final class OmemoManager extends Manager { * @throws SmackException.NotConnectedException if the XMPP connection is not connected. * @throws SmackException.NoResponseException if there was no response from the remote entity. * @throws SmackException.NotLoggedInException if the XMPP connection is not authenticated. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. */ public OmemoMessage.Sent encrypt(BareJid recipient, String message) throws CryptoFailedException, UndecidedOmemoIdentityException, @@ -328,7 +328,7 @@ public final class OmemoManager extends Manager { * @throws SmackException.NotConnectedException if the XMPP connection is not connected. * @throws SmackException.NoResponseException if there was no response from the remote entity. * @throws SmackException.NotLoggedInException if the XMPP connection is not authenticated. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. */ public synchronized OmemoMessage.Sent encrypt(Set recipients, String message) throws CryptoFailedException, UndecidedOmemoIdentityException, @@ -356,7 +356,7 @@ public final class OmemoManager extends Manager { * @throws SmackException.NoResponseException if there was no response from the remote entity. * @throws NoOmemoSupportException When the muc doesn't support OMEMO. * @throws SmackException.NotLoggedInException if the XMPP connection is not authenticated. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. */ public synchronized OmemoMessage.Sent encrypt(MultiUserChat muc, String message) throws UndecidedOmemoIdentityException, CryptoFailedException, @@ -388,7 +388,7 @@ public final class OmemoManager extends Manager { * @throws CorruptedOmemoKeyException if our or their key is corrupted * @throws NoRawSessionException if the message was not a preKeyMessage, but we had no session with the contact * @throws CryptoFailedException if decryption fails - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. */ public OmemoMessage.Received decrypt(BareJid sender, OmemoElement omemoElement) throws SmackException.NotLoggedInException, CorruptedOmemoKeyException, NoRawSessionException, @@ -403,7 +403,7 @@ public final class OmemoManager extends Manager { * @param mamQuery The MAM query * @return list of decrypted OmemoMessages * @throws SmackException.NotLoggedInException if the Manager is not authenticated. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. */ public List decryptMamQueryResult(MamManager.MamQuery mamQuery) throws SmackException.NotLoggedInException, IOException { @@ -486,7 +486,7 @@ public final class OmemoManager extends Manager { * @throws SmackException.NoResponseException if there was no response from the remote entity. * @throws NoSuchAlgorithmException if no such algorithm is available. * @throws SmackException.NotConnectedException if the XMPP connection is not connected. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. */ public synchronized void sendRatchetUpdateMessage(OmemoDevice recipient) throws SmackException.NotLoggedInException, CorruptedOmemoKeyException, InterruptedException, @@ -515,7 +515,7 @@ public final class OmemoManager extends Manager { * @throws SmackException.NoResponseException if there was no response from the remote entity. * @throws PubSubException.NotALeafNodeException if a PubSub leaf node operation was attempted on a non-leaf node. * @throws XMPPException.XMPPErrorException if there was an XMPP error returned. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. */ public synchronized boolean contactSupportsOmemo(BareJid contact) throws InterruptedException, PubSubException.NotALeafNodeException, XMPPException.XMPPErrorException, @@ -567,7 +567,7 @@ public final class OmemoManager extends Manager { * @return fingerprint TODO javadoc me please * @throws SmackException.NotLoggedInException if we don't know our bareJid yet. * @throws CorruptedOmemoKeyException if our identityKey is corrupted. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. */ public synchronized OmemoFingerprint getOwnFingerprint() throws SmackException.NotLoggedInException, CorruptedOmemoKeyException, IOException { @@ -588,7 +588,7 @@ public final class OmemoManager extends Manager { * @throws SmackException.NotConnectedException if the XMPP connection is not connected. * @throws InterruptedException if the calling thread was interrupted. * @throws SmackException.NoResponseException if there was no response from the remote entity. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. */ public synchronized OmemoFingerprint getFingerprint(OmemoDevice device) throws CannotEstablishOmemoSessionException, SmackException.NotLoggedInException, @@ -618,7 +618,7 @@ public final class OmemoManager extends Manager { * @throws SmackException.NotConnectedException if the XMPP connection is not connected. * @throws InterruptedException if the calling thread was interrupted. * @throws SmackException.NoResponseException if there was no response from the remote entity. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. */ public synchronized HashMap getActiveFingerprints(BareJid contact) throws SmackException.NotLoggedInException, CorruptedOmemoKeyException, @@ -688,7 +688,7 @@ public final class OmemoManager extends Manager { * @throws XMPPException.XMPPErrorException if there was an XMPP error returned. * @throws SmackException.NotConnectedException if the XMPP connection is not connected. * @throws SmackException.NoResponseException if there was no response from the remote entity. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. */ public synchronized void requestDeviceListUpdateFor(BareJid contact) throws InterruptedException, PubSubException.NotALeafNodeException, XMPPException.XMPPErrorException, @@ -704,7 +704,7 @@ public final class OmemoManager extends Manager { * @throws XMPPException.XMPPErrorException if there was an XMPP error returned. * @throws SmackException.NotConnectedException if the XMPP connection is not connected. * @throws SmackException.NoResponseException if there was no response from the remote entity. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. * @throws PubSubException.NotALeafNodeException if a PubSub leaf node operation was attempted on a non-leaf node. */ public void purgeDeviceList() @@ -724,7 +724,7 @@ public final class OmemoManager extends Manager { * @throws SmackException.NotConnectedException XMPP error * @throws SmackException.NoResponseException XMPP error * @throws SmackException.NotLoggedInException if the XMPP connection is not authenticated. - * @throws IOException if an I/O error occured. + * @throws IOException if an I/O error occurred. * @throws PubSubException.NotALeafNodeException if a PubSub leaf node operation was attempted on a non-leaf node. */ public synchronized void rotateSignedPreKey() diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoRatchet.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoRatchet.java index 988c2b197..e00815283 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoRatchet.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoRatchet.java @@ -66,7 +66,7 @@ public abstract class OmemoRatchet contactsDevices, @@ -442,7 +442,7 @@ public abstract class OmemoService contactsDevices, @@ -520,7 +520,7 @@ public abstract class OmemoService contactsDevices, @@ -653,7 +653,7 @@ public abstract class OmemoService buildMissingSessionsWithDevices(XMPPConnection connection, OmemoDevice userDevice, @@ -842,7 +842,7 @@ public abstract class OmemoService getUndecidedDevices(OmemoDevice userDevice, OmemoTrustCallback callback, Set devices) throws IOException { Set undecidedDevices = new HashSet<>(); @@ -873,7 +873,7 @@ public abstract class OmemoService decryptMamQueryResult(OmemoManager.LoggedInOmemoManager managerGuard, MamManager.MamQuery mamQuery) throws IOException { @@ -1221,7 +1221,7 @@ public abstract class OmemoService preKeyHashMap) throws IOException { for (Map.Entry entry : preKeyHashMap.entrySet()) { @@ -444,7 +444,7 @@ public abstract class OmemoStore loadOmemoPreKeys(OmemoDevice userDevice) throws IOException; @@ -454,7 +454,7 @@ public abstract class OmemoStore loadOmemoSignedPreKeys(OmemoDevice userDevice) throws IOException; @@ -490,7 +490,7 @@ public abstract class OmemoStore loadAllRawSessionsOf(OmemoDevice userDevice, BareJid contact) throws IOException; @@ -528,7 +528,7 @@ public abstract class OmemoStore Date: Wed, 6 Nov 2019 18:44:07 +0100 Subject: [PATCH 15/16] Use standard stanza listeners in MultiUserChat Those, relatively new, listeners guarantee that the individual listeners are not invoked in concurrently while preserving the order. Exactly what MultiUserChat previously did with AsyncButOrdered, which is now no longer needed and hence can be removed. --- .../smackx/muc/MultiUserChat.java | 150 ++++++++---------- 1 file changed, 66 insertions(+), 84 deletions(-) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java index b06c34bab..747b1469f 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java @@ -27,7 +27,6 @@ import java.util.concurrent.CopyOnWriteArraySet; import java.util.logging.Level; import java.util.logging.Logger; -import org.jivesoftware.smack.AsyncButOrdered; import org.jivesoftware.smack.MessageListener; import org.jivesoftware.smack.PresenceListener; import org.jivesoftware.smack.SmackException; @@ -144,8 +143,6 @@ public class MultiUserChat { private final StanzaListener presenceListener; private final StanzaListener subjectListener; - private static final AsyncButOrdered asyncButOrdered = new AsyncButOrdered<>(); - private static final StanzaFilter DECLINE_FILTER = new AndFilter(MessageTypeFilter.NORMAL, new StanzaExtensionFilter(MUCUser.ELEMENT, MUCUser.NAMESPACE)); private final StanzaListener declinesListener; @@ -168,14 +165,9 @@ public class MultiUserChat { public void processStanza(Stanza packet) throws NotConnectedException { final Message message = (Message) packet; - asyncButOrdered.performAsyncButOrdered(MultiUserChat.this, new Runnable() { - @Override - public void run() { - for (MessageListener listener : messageListeners) { + for (MessageListener listener : messageListeners) { listener.processMessage(message); - } - } - }); + } } }; @@ -188,15 +180,10 @@ public class MultiUserChat { // Update the room subject subject = msg.getSubject(); - asyncButOrdered.performAsyncButOrdered(MultiUserChat.this, new Runnable() { - @Override - public void run() { - // Fire event for subject updated listeners - for (SubjectUpdatedListener listener : subjectUpdatedListeners) { - listener.subjectUpdated(msg.getSubject(), from); - } - } - }); + // Fire event for subject updated listeners + for (SubjectUpdatedListener listener : subjectUpdatedListeners) { + listener.subjectUpdated(msg.getSubject(), from); + } } }; @@ -212,66 +199,61 @@ public class MultiUserChat { final EntityFullJid myRoomJID = myRoomJid; final boolean isUserStatusModification = presence.getFrom().equals(myRoomJID); - asyncButOrdered.performAsyncButOrdered(MultiUserChat.this, new Runnable() { - @Override - public void run() { - switch (presence.getType()) { - case available: - Presence oldPresence = occupantsMap.put(from, presence); - if (oldPresence != null) { - // Get the previous occupant's affiliation & role - MUCUser mucExtension = MUCUser.from(oldPresence); - MUCAffiliation oldAffiliation = mucExtension.getItem().getAffiliation(); - MUCRole oldRole = mucExtension.getItem().getRole(); - // Get the new occupant's affiliation & role - mucExtension = MUCUser.from(packet); - MUCAffiliation newAffiliation = mucExtension.getItem().getAffiliation(); - MUCRole newRole = mucExtension.getItem().getRole(); - // Fire role modification events - checkRoleModifications(oldRole, newRole, isUserStatusModification, from); - // Fire affiliation modification events - checkAffiliationModifications( - oldAffiliation, - newAffiliation, - isUserStatusModification, - from); + switch (presence.getType()) { + case available: + Presence oldPresence = occupantsMap.put(from, presence); + if (oldPresence != null) { + // Get the previous occupant's affiliation & role + MUCUser mucExtension = MUCUser.from(oldPresence); + MUCAffiliation oldAffiliation = mucExtension.getItem().getAffiliation(); + MUCRole oldRole = mucExtension.getItem().getRole(); + // Get the new occupant's affiliation & role + mucExtension = MUCUser.from(packet); + MUCAffiliation newAffiliation = mucExtension.getItem().getAffiliation(); + MUCRole newRole = mucExtension.getItem().getRole(); + // Fire role modification events + checkRoleModifications(oldRole, newRole, isUserStatusModification, from); + // Fire affiliation modification events + checkAffiliationModifications( + oldAffiliation, + newAffiliation, + isUserStatusModification, + from); + } + else { + // A new occupant has joined the room + if (!isUserStatusModification) { + for (ParticipantStatusListener listener : participantStatusListeners) { + listener.joined(from); } - else { - // A new occupant has joined the room - if (!isUserStatusModification) { - for (ParticipantStatusListener listener : participantStatusListeners) { - listener.joined(from); - } - } - } - break; - case unavailable: - occupantsMap.remove(from); - MUCUser mucUser = MUCUser.from(packet); - if (mucUser != null && mucUser.hasStatus()) { - // Fire events according to the received presence code - checkPresenceCode( - mucUser.getStatus(), - presence.getFrom().equals(myRoomJID), - mucUser, - from); - } else { - // An occupant has left the room - if (!isUserStatusModification) { - for (ParticipantStatusListener listener : participantStatusListeners) { - listener.left(from); - } - } - } - break; - default: - break; - } - for (PresenceListener listener : presenceListeners) { - listener.processPresence(presence); } } - }); + break; + case unavailable: + occupantsMap.remove(from); + MUCUser mucUser = MUCUser.from(packet); + if (mucUser != null && mucUser.hasStatus()) { + // Fire events according to the received presence code + checkPresenceCode( + mucUser.getStatus(), + presence.getFrom().equals(myRoomJID), + mucUser, + from); + } else { + // An occupant has left the room + if (!isUserStatusModification) { + for (ParticipantStatusListener listener : participantStatusListeners) { + listener.left(from); + } + } + } + break; + default: + break; + } + for (PresenceListener listener : presenceListeners) { + listener.processPresence(presence); + } } }; @@ -341,13 +323,13 @@ public class MultiUserChat { Presence joinPresence = conf.getJoinPresence(this); // Setup the messageListeners and presenceListeners *before* the join presence is send. - connection.addSyncStanzaListener(messageListener, fromRoomGroupchatFilter); + connection.addStanzaListener(messageListener, fromRoomGroupchatFilter); StanzaFilter presenceFromRoomFilter = new AndFilter(fromRoomFilter, StanzaTypeFilter.PRESENCE, PossibleFromTypeFilter.ENTITY_FULL_JID); - connection.addSyncStanzaListener(presenceListener, presenceFromRoomFilter); + connection.addStanzaListener(presenceListener, presenceFromRoomFilter); // @formatter:off - connection.addSyncStanzaListener(subjectListener, + connection.addStanzaListener(subjectListener, new AndFilter(fromRoomFilter, MessageWithSubjectFilter.INSTANCE, new NotFilter(MessageTypeFilter.ERROR), @@ -357,7 +339,7 @@ public class MultiUserChat { new NotFilter(MessageWithThreadFilter.INSTANCE)) ); // @formatter:on - connection.addSyncStanzaListener(declinesListener, new AndFilter(fromRoomFilter, DECLINE_FILTER)); + connection.addStanzaListener(declinesListener, new AndFilter(fromRoomFilter, DECLINE_FILTER)); connection.addStanzaSendingListener(presenceInterceptor, new AndFilter(ToMatchesFilter.create(room), StanzaTypeFilter.PRESENCE)); messageCollector = connection.createStanzaCollector(fromRoomGroupchatFilter); @@ -2118,10 +2100,10 @@ public class MultiUserChat { * connection. */ private void removeConnectionCallbacks() { - connection.removeSyncStanzaListener(messageListener); - connection.removeSyncStanzaListener(presenceListener); - connection.removeSyncStanzaListener(subjectListener); - connection.removeSyncStanzaListener(declinesListener); + connection.removeStanzaListener(messageListener); + connection.removeStanzaListener(presenceListener); + connection.removeStanzaListener(subjectListener); + connection.removeStanzaListener(declinesListener); connection.removeStanzaSendingListener(presenceInterceptor); if (messageCollector != null) { messageCollector.cancel(); From 9d626bf787dc3e0e0a4399cef429285b22744d73 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Fri, 8 Nov 2019 10:14:21 +0100 Subject: [PATCH 16/16] core: improve AsyncButOrdered Instead of marking the handle as not running by setting the handler's value in the map to false, we now remove simply the key if there is no handler running. This also means we no longer need to use a weak hash map for this. Also reduce the size of the synchronized blocks, mainly by scheduling the handler outside of the synchronized(threadActiveMap) block. Make some code better readable and add some more comments. Also do start a new handler thread if the task threw. --- .../jivesoftware/smack/AsyncButOrdered.java | 63 ++++++++++++------- 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/AsyncButOrdered.java b/smack-core/src/main/java/org/jivesoftware/smack/AsyncButOrdered.java index 6fb6244ab..526e3cd2e 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/AsyncButOrdered.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/AsyncButOrdered.java @@ -1,6 +1,6 @@ /** * - * Copyright 2018 Florian Schmaus + * Copyright 2018-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,6 +16,7 @@ */ package org.jivesoftware.smack; +import java.util.HashMap; import java.util.Map; import java.util.Queue; import java.util.WeakHashMap; @@ -51,9 +52,17 @@ import java.util.concurrent.Executor; */ public class AsyncButOrdered { + /** + * A map with the currently pending runnables for a given key. Note that this is a weak hash map so we do not have + * to take care of removing the keys ourselfs from the map. + */ private final Map> pendingRunnables = new WeakHashMap<>(); - private final Map threadActiveMap = new WeakHashMap<>(); + /** + * A marker map if there is an active thread for the given key. Holds the responsible handler thread if one is + * active, otherwise the key is non-existend in the map. + */ + private final Map threadActiveMap = new HashMap<>(); private final Executor executor; @@ -65,6 +74,14 @@ public class AsyncButOrdered { this.executor = executor; } + private void scheduleHandler(Handler handler) { + if (executor == null) { + AbstractXMPPConnection.asyncGo(handler); + } else { + executor.execute(handler); + } + } + /** * Invoke the given {@link Runnable} asynchronous but ordered in respect to the given key. * @@ -73,6 +90,7 @@ public class AsyncButOrdered { * @return true if a new thread was created */ public boolean performAsyncButOrdered(K key, Runnable runnable) { + // First check if a key queue already exists, create one if not. Queue keyQueue; synchronized (pendingRunnables) { keyQueue = pendingRunnables.get(key); @@ -82,29 +100,27 @@ public class AsyncButOrdered { } } + // Then add the task to the queue. keyQueue.add(runnable); - boolean newHandler; + // Finally check if there is already a handler working on that queue, create one if not. + Handler newlyCreatedHandler = null; synchronized (threadActiveMap) { - Boolean threadActive = threadActiveMap.get(key); - if (threadActive == null) { - threadActive = false; - threadActiveMap.put(key, threadActive); - } + if (!threadActiveMap.containsKey(key)) { + newlyCreatedHandler = new Handler(keyQueue, key); - newHandler = !threadActive; - if (newHandler) { - Handler handler = new Handler(keyQueue, key); - threadActiveMap.put(key, true); - if (executor == null) { - AbstractXMPPConnection.asyncGo(handler); - } else { - executor.execute(handler); - } + // Mark that there is thread active for the given key. Note that this has to be done before scheduling + // the handler thread. + threadActiveMap.put(key, newlyCreatedHandler); } } - return newHandler; + if (newlyCreatedHandler != null) { + scheduleHandler(newlyCreatedHandler); + return true; + } + + return false; } public Executor asExecutorFor(final K key) { @@ -134,11 +150,14 @@ public class AsyncButOrdered { try { runnable.run(); } catch (Throwable t) { - // The run() method threw, this handler thread is going to terminate because of that. Ensure we note - // that in the map. + // The run() method threw, this handler thread is going to terminate because of that. We create + // a new handler to continue working on the queue while throwing the throwable so that the + // executor can handle it. + Handler newlyCreatedHandler = new Handler(keyQueue, key); synchronized (threadActiveMap) { - threadActiveMap.put(key, false); + threadActiveMap.put(key, newlyCreatedHandler); } + scheduleHandler(newlyCreatedHandler); throw t; } } @@ -146,7 +165,7 @@ public class AsyncButOrdered { synchronized (threadActiveMap) { // If the queue is empty, stop this handler, otherwise continue looping. if (keyQueue.isEmpty()) { - threadActiveMap.put(key, false); + threadActiveMap.remove(key); break mainloop; } }