From b8d9c38a39a6e9f1556658c14e227b078e8e9e2f Mon Sep 17 00:00:00 2001
From: Florian Schmaus
From 67cc513b2e45996ea4eef1564a36010ac1f91471 Mon Sep 17 00:00:00 2001
From: Florian Schmaus
Thank you for downloading Smack! This version of Smack is compatible
-with JVMs @targetCompatibility@ or higher. If you dont' use a
+with JVMs @targetCompatibility@ or higher. Using a build system which
+is able to consume Maven artifacts, like gradle or Maven, is highly
+recommended when using Smack.
+
+ This is not the real README. Please visit
+
+If you dont' use a
dependency resolution system, like gradle or maven, then you will need
to download at least
the Xml
Pull Parser 3rd Edition (XPP3) library or any other library that
implements the XmlPullParser interface
-(like kXML).
+(like kXML) and the set of
+jXMPP libraries.
@@ -174,21 +189,14 @@ Smack Readme
Smack Readme
online forum.
About the Distribution
- -The smack-core.jar file in the main distribution folder. The optional -smack-extensions.jar contains the Smack extensions -while smack-debug.jar contains an enhanced debugger.-
Changelog and Upgrading
View the changelog for a list of changes since the last release. -If you are upgrading from Smack 3 to Smack 4, then please consult the Smack 4 Readme and Upgrade Guide
License Agreements
Copyright 2002-2008 Jive Software. From 125f858b453afb2907e8923012875da726ee074b Mon Sep 17 00:00:00 2001 From: ramabitDate: Fri, 29 Jul 2016 16:46:48 -0300 Subject: [PATCH 11/18] add mam documentation --- documentation/extensions/mam.md | 192 ++++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 documentation/extensions/mam.md diff --git a/documentation/extensions/mam.md b/documentation/extensions/mam.md new file mode 100644 index 0000000000..ed0de6b03c --- /dev/null +++ b/documentation/extensions/mam.md @@ -0,0 +1,192 @@ +Message Archive Management +========================== + +Query and control an archive of messages stored on a server. + + * Check MAM support + * Query archive + * Paging + * Get form fields + * Get preferences + * Update preferences + + +**XEP related:** [XEP-0313](http://xmpp.org/extensions/xep-0313.html) + + +Get an instance of Message Archive Management Manager +----------------------------------------------------- + +``` +MamManager mamManager = MamManager.getInstanceFor(connection); +``` + + +Check MAM support +----------------- + +``` +boolean isSupported = mamManager.isSupportedByServer(); +``` + + +Query archive +------------- + +``` +MamQueryResult mamQueryResult = mamManager.queryArchive(max); +``` +*max* is an `Integer` + +or + +``` +MamQueryResult mamQueryResult = mamManager.queryArchive(withJid); +``` +*withJid* is a `Jid` + +or + +``` +MamQueryResult mamQueryResult = mamManager.queryArchive(start, end); +``` +*start* is a `Date` + +*end* is a `Date` + +or + +``` +MamQueryResult mamQueryResult = mamManager.queryArchive(additionalFields); +``` +*additionalFields* is a `List ` + +or + +``` +MamQueryResult mamQueryResult = mamManager.queryArchiveWithStartDate(start); +``` +*start* is a `Date` + +or + +``` +MamQueryResult mamQueryResult = mamManager.queryArchiveWithEndDate(end); +``` +*end* is a `Date` + +or + +``` +MamQueryResult mamQueryResult = mamManager.queryArchive(max, start, end, withJid, additionalFields); +``` +*max* is an `Integer` + +*start* is a `Date` + +*end* is a `Date` + +*withJid* is a `Jid` + +*additionalFields* is a `List ` + + +**Get data from mamQueryResult object** + +``` +// Get forwarded messages +List forwardedMessages = mamQueryResult.forwardedMessages; + +// Get fin IQ +MamFinIQ mamFinIQ = mamQueryResult.mamFinIQ; +``` + + +Paging +------ + +**Get a page** + +``` +MamQueryResult mamQueryResult = mamManager.page(dataForm, rsmSet); +``` +*dataForm* is a `DataForm` + +*rsmSet* is a `RSMSet` + + +**Get the next page** + +``` +MamQueryResult mamQueryResult = mamManager.pageNext(previousMamQueryResult, count); +``` +*previousMamQueryResult* is a `MamQueryResult` + +*count* is an `int` + + +**Get page before the first message saved (specific chat)** + +``` +MamQueryResult mamQueryResult = mamManager.pageBefore(chatJid, firstMessageId, max); +``` +*chatJid* is a `Jid` + +*firstMessageId* is a `String` + +*max* is an `int` + + +**Get page after the last message saved (specific chat)** + +``` +MamQueryResult mamQueryResult = mamManager.pageAfter(chatJid, lastMessageId, max); +``` +*chatJid* is a `Jid` + +*lastMessageId* is a `String` + +*max* is an `int` + + +Get form fields +--------------- + +``` +List formFields = mamManager.retrieveFormFields(); +``` + + +Get preferences +--------------- + +``` +MamPrefsResult mamPrefsResult = mamManager.retrieveArchivingPreferences(); + +// Get preferences IQ +MamPrefsIQ mamPrefs = mamPrefsResult.mamPrefs; + +// Obtain always and never list +List alwaysJids = mamPrefs.getAlwaysJids(); +List neverJids = mamPrefs.getNeverJids(); + +// Obtain default behaviour (can be 'always', 'never' or 'roster') +DefaultBehavior defaultBehavior = mamPrefs.getDefault(); + +// Get the data form +DataForm dataForm = mamPrefs.form; +``` + + +Update preferences +------------------ + +``` +MamPrefsResult mamPrefsResult = mamManager.updateArchivingPreferences(alwaysJids, neverJids, defaultBehavior); +``` +*alwaysJids* is a `List ` + +*neverJids* is a `List ` + +*defaultBehavior* is a `DefaultBehavior` + From 656914dcb0a9747f852e748c5f31dc16371ff729 Mon Sep 17 00:00:00 2001 From: ramabit Date: Fri, 29 Jul 2016 17:55:10 -0300 Subject: [PATCH 12/18] add mam.md in index.md --- documentation/extensions/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/extensions/index.md b/documentation/extensions/index.md index 274951a344..6ab64d5de6 100644 --- a/documentation/extensions/index.md +++ b/documentation/extensions/index.md @@ -85,7 +85,7 @@ Experimental Smack Extensions and currently supported XEPs of smack-experimental | [Internet of Things - Discovery](iot.md) | [XEP-0347](http://xmpp.org/extensions/xep-0347.html) | Describes how Things can be installed and discovered by their owners. | | Google GCM JSON payload | n/a | Semantically the same as XEP-0335: JSON Containers | | Client State Indication | [XEP-0352](http://xmpp.org/extensions/xep-0352.html) | A way for the client to indicate its active/inactive state. | -| Message Archive Management | [XEP-0313](http://xmpp.org/extensions/xep-0313.html) | Query and control an archive of messages stored on a server. | +| [Message Archive Management](mam.md) | [XEP-0313](http://xmpp.org/extensions/xep-0313.html) | Query and control an archive of messages stored on a server. | Legacy Smack Extensions and currently supported XEPs of smack-legacy From a87007fb7795b52f067f907af628afed5e52fda5 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sat, 30 Jul 2016 10:29:30 +0200 Subject: [PATCH 13/18] Smack 4.1.8 --- resources/releasedocs/changelog.html | 15 +++++++++++++++ version.gradle | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/resources/releasedocs/changelog.html b/resources/releasedocs/changelog.html index b844e1e00b..01c8a003ba 100644 --- a/resources/releasedocs/changelog.html +++ b/resources/releasedocs/changelog.html @@ -141,6 +141,21 @@ Smack Changelog
+4.1.8 -- 2016-07-30
+ +Bug +
++
+- [SMACK-722] - SASL X-OAUTH2 implementation incorrectly performs Base64 encoding twice +
+- [SMACK-724] - Do not re-use the Socket after connect() failed. +
+- [SMACK-725] - ReconnectionManager should handle AlreadyConnectedException and AlreadyLoggedInException not as failure +
+- [SMACK-726] - 'purge' and 'remove' IQ of XEP-0013 must be of type 'set' +
+4.1.7 -- 2016-04-14
Bug diff --git a/version.gradle b/version.gradle index d19cd230ac..41a5580b64 100644 --- a/version.gradle +++ b/version.gradle @@ -1,7 +1,7 @@ allprojects { ext { shortVersion = '4.1.8' - isSnapshot = true + isSnapshot = false jxmppVersion = '0.4.2' smackMinAndroidSdk = 8 } From 252f1b690cf66fa2012ab044890d515bc23976a4 Mon Sep 17 00:00:00 2001 From: Florian Schmaus
Date: Sat, 30 Jul 2016 11:00:06 +0200 Subject: [PATCH 14/18] Smack 4.2.0-beta2 --- version.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.gradle b/version.gradle index e74f1891ad..2337ae3609 100644 --- a/version.gradle +++ b/version.gradle @@ -1,7 +1,7 @@ allprojects { ext { shortVersion = '4.2.0-beta2' - isSnapshot = true + isSnapshot = false jxmppVersion = '0.5.0-alpha7' smackMinAndroidSdk = 8 } From 632acbe33f208de9740922daa78e8d571aa75ba9 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sat, 30 Jul 2016 11:11:54 +0200 Subject: [PATCH 15/18] Smack 4.2.0-beta3-SNAPSHOT --- version.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.gradle b/version.gradle index 2337ae3609..16b0168971 100644 --- a/version.gradle +++ b/version.gradle @@ -1,7 +1,7 @@ allprojects { ext { - shortVersion = '4.2.0-beta2' - isSnapshot = false + shortVersion = '4.2.0-beta3' + isSnapshot = true jxmppVersion = '0.5.0-alpha7' smackMinAndroidSdk = 8 } From 8810f17460e7e5faea6431148c7297e9d1d2e9df Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 31 Jul 2016 12:09:06 +0200 Subject: [PATCH 16/18] Allow empty username/passwords in integration test --- .../org/igniterealtime/smack/inttest/Configuration.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java index 9f36a4c99c..abc9a4fd22 100644 --- a/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java +++ b/smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java @@ -266,7 +266,11 @@ public static Configuration newConfiguration() throws IOException { String accountTwoPassword = properties.getProperty("accountTwoPassword"); String accountThreeUsername = properties.getProperty("accountThreeUsername"); String accountThreePassword = properties.getProperty("accountThreePassword"); - builder.setUsernamesAndPassword(accountOneUsername, accountOnePassword, accountTwoUsername, accountTwoPassword, accountThreeUsername, accountThreePassword); + if (accountOneUsername != null || accountOnePassword != null || accountTwoUsername != null + || accountTwoPassword != null || accountThreeUsername != null || accountThreePassword != null) { + builder.setUsernamesAndPassword(accountOneUsername, accountOnePassword, accountTwoUsername, + accountTwoPassword, accountThreeUsername, accountThreePassword); + } builder.setDebug(properties.getProperty("debug")); builder.setEnabledTests(properties.getProperty("enabledTests")); From 5b137616bbdd5e0ec21d09e3b271f50612f226bd Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 31 Jul 2016 14:30:23 +0200 Subject: [PATCH 17/18] Fix NPE in IoTDiscoveryManager --- .../smackx/iot/discovery/IoTDiscoveryManager.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/IoTDiscoveryManager.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/IoTDiscoveryManager.java index 8851f84e1e..f1ce9c3625 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/IoTDiscoveryManager.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/IoTDiscoveryManager.java @@ -36,6 +36,7 @@ import org.jivesoftware.smack.iqrequest.AbstractIqRequestHandler; import org.jivesoftware.smack.iqrequest.IQRequestHandler.Mode; import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smack.util.Objects; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.packet.DiscoverInfo; import org.jivesoftware.smackx.iot.Thing; @@ -202,7 +203,7 @@ public IQ handleIQRequest(IQ iqRequest) { /** * Try to find an XMPP IoT registry. * - * @return the JID of a Thing Registry if one could be found. + * @return the JID of a Thing Registry if one could be found, null
otherwise. * @throws InterruptedException * @throws NotConnectedException * @throws XMPPErrorException @@ -373,9 +374,11 @@ public void disownThing(Jid registry, Jid thing, NodeInfo nodeInfo) // Registry utility methods public boolean isRegistry(BareJid jid) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { + Objects.requireNonNull(jid, "JID argument must not be null"); // At some point 'usedRegistries' will also contain the registry returned by findRegistry(), but since this is // not the case from the beginning, we perform findRegistry().equals(jid) too. - if (findRegistry().equals(jid)) { + Jid registry = findRegistry(); + if (jid.equals(registry)) { return true; } if (usedRegistries.contains(jid)) { From f1e24e227367f3ec6723d2fd2c1a855c9b287017 Mon Sep 17 00:00:00 2001 From: Florian SchmausDate: Sun, 31 Jul 2016 14:30:31 +0200 Subject: [PATCH 18/18] Rework Roster's SubscribeListener allow multiple of them to be installed, instead of at most one. Fixes deadlock in LowLevelRosterIntegration test because IoTProvisioningManager's SubscribeListener would not come up with a decission. --- .../provisioning/IoTProvisioningManager.java | 2 +- .../org/jivesoftware/smack/roster/Roster.java | 47 ++++++++++++++----- .../smack/roster/RosterIntegrationTest.java | 22 ++++++--- 3 files changed, 50 insertions(+), 21 deletions(-) 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 077a068827..d9264dfca1 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 @@ -151,7 +151,7 @@ public IQ handleIQRequest(IQ iqRequest) { }); roster = Roster.getInstanceFor(connection); - roster.setSubscribeListener(new SubscribeListener() { + roster.addSubscribeListener(new SubscribeListener() { @Override public SubscribeAnswer processSubscribe(Jid from, Presence subscribeRequest) { // First check if the subscription request comes from a known registry and accept the request if so. 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 59513f454c..52a18dad29 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 @@ -199,7 +199,9 @@ private enum RosterState { private SubscriptionMode subscriptionMode = getDefaultSubscriptionMode(); - private SubscribeListener subscribeListener; + private final Set subscribeListeners = new CopyOnWriteArraySet<>(); + + private SubscriptionMode previousSubscriptionMode; /** * Returns the default subscription processing mode to use when a new Roster is created. The @@ -249,11 +251,12 @@ public void processPacket(Stanza stanza) throws NotConnectedException, SubscribeAnswer subscribeAnswer = null; switch (subscriptionMode) { case manual: - final SubscribeListener subscribeListener = Roster.this.subscribeListener; - if (subscribeListener == null) { - return; + for (SubscribeListener subscribeListener : subscribeListeners) { + subscribeAnswer = subscribeListener.processSubscribe(from, presence); + if (subscribeAnswer != null) { + break; + } } - subscribeAnswer = subscribeListener.processSubscribe(from, presence); if (subscribeAnswer == null) { return; } @@ -666,19 +669,37 @@ public void sendSubscriptionRequest(BareJid jid) throws NotLoggedInException, No } /** - * Set the subscribe listener, which is invoked on incoming subscription requests and if - * {@link SubscriptionMode} is set to {@link SubscriptionMode#manual}. If - * subscribeListener
is notnull
, then this also sets subscription + * Add a subscribe listener, which is invoked on incoming subscription requests and if + * {@link SubscriptionMode} is set to {@link SubscriptionMode#manual}. This also sets subscription * mode to {@link SubscriptionMode#manual}. * - * @param subscribeListener the subscribe listener to set. + * @param subscribeListener the subscribe listener to add. + * @returntrue
if the listener was not already added. + * @since 4.2 + */ + public boolean addSubscribeListener(SubscribeListener subscribeListener) { + Objects.requireNonNull(subscribeListener, "SubscribeListener argument must not be null"); + if (subscriptionMode != SubscriptionMode.manual) { + previousSubscriptionMode = subscriptionMode; + } + return subscribeListeners.add(subscribeListener); + } + + /** + * Remove a subscribe listener. Also restores the previous subscription mode + * state, if the last listener got removed. + * + * @param subscribeListener + * the subscribe listener to remove. + * @returntrue
if the listener registered and got removed. * @since 4.2 */ - public void setSubscribeListener(SubscribeListener subscribeListener) { - if (subscribeListener != null) { - setSubscriptionMode(SubscriptionMode.manual); + public boolean removeSubscribeListener(SubscribeListener subscribeListener) { + boolean removed = subscribeListeners.remove(subscribeListener); + if (removed && subscribeListeners.isEmpty()) { + setSubscriptionMode(previousSubscriptionMode); } - this.subscribeListener = subscribeListener; + return removed; } /** diff --git a/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/RosterIntegrationTest.java b/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/RosterIntegrationTest.java index d5a6394d30..8691bacaca 100644 --- a/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/RosterIntegrationTest.java +++ b/smack-integration-test/src/main/java/org/jivesoftware/smack/roster/RosterIntegrationTest.java @@ -50,7 +50,7 @@ public RosterIntegrationTest(SmackIntegrationTestEnvironment environment) { public void subscribeRequestListenerTest() throws TimeoutException, Exception { ensureBothAccountsAreNotInEachOthersRoster(conOne, conTwo); - rosterTwo.setSubscribeListener(new SubscribeListener() { + final SubscribeListener subscribeListener = new SubscribeListener() { @Override public SubscribeAnswer processSubscribe(Jid from, Presence subscribeRequest) { if (from.equals(conOne.getUser().asBareJid())) { @@ -58,7 +58,8 @@ public SubscribeAnswer processSubscribe(Jid from, Presence subscribeRequest) { } return SubscribeAnswer.Deny; } - }); + }; + rosterTwo.addSubscribeListener(subscribeListener); final String conTwosRosterName = "ConTwo " + testRunId; final SimpleResultSyncPoint addedAndSubscribed = new SimpleResultSyncPoint(); @@ -88,9 +89,15 @@ private void checkIfAddedAndSubscribed(Collectionaddresses) { } } }); - rosterOne.createEntry(conTwo.getUser().asBareJid(), conTwosRosterName, null); - assertTrue(addedAndSubscribed.waitForResult(2 * connection.getPacketReplyTimeout())); + try { + rosterOne.createEntry(conTwo.getUser().asBareJid(), conTwosRosterName, null); + + assertTrue(addedAndSubscribed.waitForResult(2 * connection.getPacketReplyTimeout())); + } + finally { + rosterTwo.removeSubscribeListener(subscribeListener); + } } public static void ensureBothAccountsAreNotInEachOthersRoster(XMPPConnection conOne, XMPPConnection conTwo) throws NotLoggedInException, @@ -124,7 +131,7 @@ private static void ensureSubscribedTo(final XMPPConnection conOne, final XMPPCo return; } - rosterOne.setSubscribeListener(new SubscribeListener() { + final SubscribeListener subscribeListener = new SubscribeListener() { @Override public SubscribeAnswer processSubscribe(Jid from, Presence subscribeRequest) { if (from.equals(conTwo.getUser().asBareJid())) { @@ -132,7 +139,8 @@ public SubscribeAnswer processSubscribe(Jid from, Presence subscribeRequest) { } return SubscribeAnswer.Deny; } - }); + }; + rosterOne.addSubscribeListener(subscribeListener); final SimpleResultSyncPoint syncPoint = new SimpleResultSyncPoint(); rosterTwo.addPresenceEventListener(new AbstractPresenceEventListener() { @@ -149,7 +157,7 @@ public void presenceSubscribed(BareJid address, Presence subscribedPresence) { try { syncPoint.waitForResult(timeout); } finally { - rosterOne.setSubscribeListener(null); + rosterOne.removeSubscribeListener(subscribeListener); } } }