From a0d3314b26b994c7bc31307c40abebf7f413ca81 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 15 Feb 2015 21:13:48 +0100 Subject: [PATCH 01/18] Smack 4.1.0-rc2-SNAPSHOT --- version.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version.gradle b/version.gradle index 42291c08c..af5396e11 100644 --- a/version.gradle +++ b/version.gradle @@ -1,7 +1,7 @@ allprojects { ext { - shortVersion = '4.1.0-rc1' - isSnapshot = false + shortVersion = '4.1.0-rc2' + isSnapshot = true jxmppVersion = '0.4.2-beta1' smackMinAndroidSdk = 8 } From 1577fa1fcada9523d03a0d9fffad43e9649938f4 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 16 Feb 2015 13:29:14 +0100 Subject: [PATCH 02/18] Fix duplicate presence in XMPPBOSHConnection.shutdown() --- .../smack/bosh/XMPPBOSHConnection.java | 14 -------------- 1 file changed, 14 deletions(-) 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 e4f203698..1bc1e1492 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 @@ -39,7 +39,6 @@ import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.packet.PlainStreamElement; import org.jivesoftware.smack.packet.Presence; -import org.jivesoftware.smack.packet.Presence.Type; import org.jivesoftware.smack.sasl.packet.SaslStreamElements.SASLFailure; import org.jivesoftware.smack.sasl.packet.SaslStreamElements.Success; import org.jivesoftware.smack.util.PacketParserUtils; @@ -288,19 +287,6 @@ public class XMPPBOSHConnection extends AbstractXMPPConnection { connected = false; isFirstInitialization = false; - Presence unavailablePresence = new Presence(Type.unavailable); - try { - client.disconnect(ComposableBody.builder() - .setNamespaceDefinition("xmpp", XMPP_BOSH_NS) - .setPayloadXML(unavailablePresence.toXML().toString()) - .build()); - // Wait 150 ms for processes to clean-up, then shutdown. - Thread.sleep(150); - } - catch (Exception e) { - // Ignore. - } - // Close down the readers and writers. if (readerPipe != null) { try { From b910d026cd3fac6484548c97922e0b6691ab5344 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 16 Feb 2015 14:51:37 +0100 Subject: [PATCH 03/18] Remove toString form XMPPException subclasses and getMessage(), to use the implementations in Exception instead. --- .../org/jivesoftware/smack/XMPPException.java | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/XMPPException.java b/smack-core/src/main/java/org/jivesoftware/smack/XMPPException.java index 2656c6890..774ca76ad 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/XMPPException.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/XMPPException.java @@ -129,11 +129,6 @@ public abstract class XMPPException extends Exception { } } - @Override - public String toString() { - return getMessage(); - } - public static void ifHasErrorThenThrow(Stanza packet) throws XMPPErrorException { XMPPError xmppError = packet.getError(); if (xmppError != null) { @@ -157,7 +152,7 @@ public abstract class XMPPException extends Exception { * @param streamError the root cause of the exception. */ public StreamErrorException(StreamError streamError) { - super(); + super(streamError.toString()); this.streamError = streamError; } @@ -171,14 +166,5 @@ public abstract class XMPPException extends Exception { return streamError; } - @Override - public String getMessage() { - return streamError.toString(); - } - - @Override - public String toString() { - return getMessage(); - } } } From 98cfad6cc689394089b74997e110360ea3a777fe Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Tue, 17 Feb 2015 15:24:33 +0100 Subject: [PATCH 04/18] Add RosterLoadedListener --- .../org/jivesoftware/smack/roster/Roster.java | 49 +++++++++++++++++++ .../smack/roster/RosterLoadedListener.java | 38 ++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 smack-im/src/main/java/org/jivesoftware/smack/roster/RosterLoadedListener.java 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 cad183c6b..ec87ec67c 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 @@ -134,6 +134,11 @@ public class Roster extends Manager { private final Set rosterListeners = new LinkedHashSet<>(); private final Map> presenceMap = new ConcurrentHashMap>(); + /** + * Listeners called when the Roster was loaded. + */ + private final Set rosterLoadedListeners = new LinkedHashSet<>(); + /** * Mutually exclude roster listener invocation and changing the {@link entries} map. Also used * to synchronize access to either the roster listeners or the entries map. @@ -387,6 +392,34 @@ public class Roster extends Manager { } } + /** + * Add a roster loaded listener. + * + * @param rosterLoadedListener the listener to add. + * @return true if the listener was not already added. + * @see RosterLoadedListener + * @since 4.1 + */ + public boolean addRosterLoadedListener(RosterLoadedListener rosterLoadedListener) { + synchronized (rosterLoadedListener) { + return rosterLoadedListeners.add(rosterLoadedListener); + } + } + + /** + * Remove a roster loaded listener. + * + * @param rosterLoadedListener the listener to remove. + * @return true if the listener was active and got removed. + * @see RosterLoadedListener + * @since 4.1 + */ + public boolean removeRosterLoadedListener(RosterLoadedListener rosterLoadedListener) { + synchronized (rosterLoadedListener) { + return rosterLoadedListeners.remove(rosterLoadedListener); + } + } + /** * Creates a new group.

*

@@ -1309,6 +1342,22 @@ public class Roster extends Manager { } // Fire event for roster listeners. fireRosterChangedEvent(addedEntries, updatedEntries, deletedEntries); + + // Call the roster loaded listeners after the roster events have been fired. This is + // imporant because the user may call getEntriesAndAddListener() in onRosterLoaded(), + // and if the order would be the other way around, the roster listener added by + // getEntriesAndAddListener() would be invoked with information that was already + // available at the time getEntriesAndAddListenr() was called. + try { + synchronized (rosterLoadedListeners) { + for (RosterLoadedListener rosterLoadedListener : rosterLoadedListeners) { + rosterLoadedListener.onRosterLoaded(Roster.this); + } + } + } + catch (Exception e) { + LOGGER.log(Level.WARNING, "RosterLoadedListener threw exception", e); + } } } diff --git a/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterLoadedListener.java b/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterLoadedListener.java new file mode 100644 index 000000000..94f08f094 --- /dev/null +++ b/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterLoadedListener.java @@ -0,0 +1,38 @@ +/** + * + * Copyright 2015 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.roster; + +/** + * Roster loaded listeners are invoked once the {@link Roster} was successfully loaded. + *

+ * A common approach is to call + * {@link Roster#getEntriesAndAddListener(RosterListener, RosterEntries)} within + * {@link #onRosterLoaded(Roster)}, to initialize or update your UI components with the current + * roster state. + *

+ */ +public interface RosterLoadedListener { + + /** + * Called when the Roster was loaded successfully. + * + * @param roster the Roster that was loaded successfully. + */ + public void onRosterLoaded(Roster roster); + +} From 33cf205bdcfbae9a876a476c09cabaf759e14077 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 18 Feb 2015 09:27:27 +0100 Subject: [PATCH 05/18] Use Objects.requireNonNull() in BytestreamSIDFilter --- .../smackx/filetransfer/Socks5TransferNegotiator.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiator.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiator.java index 4dc0cb39e..efaa9b6e8 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiator.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/Socks5TransferNegotiator.java @@ -32,6 +32,7 @@ import org.jivesoftware.smack.filter.PacketFilter; import org.jivesoftware.smack.filter.PacketTypeFilter; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.Stanza; +import org.jivesoftware.smack.util.Objects; import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamManager; import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamRequest; import org.jivesoftware.smackx.bytestreams.socks5.Socks5BytestreamSession; @@ -127,14 +128,11 @@ public class Socks5TransferNegotiator extends StreamNegotiator { */ private static class BytestreamSIDFilter extends PacketTypeFilter { - private String sessionID; + private final String sessionID; public BytestreamSIDFilter(String sessionID) { super(Bytestream.class); - if (sessionID == null) { - throw new IllegalArgumentException("StreamID cannot be null"); - } - this.sessionID = sessionID; + this.sessionID = Objects.requireNonNull(sessionID, "SessionID cannot be null"); } @Override From 7897fca876788fad7eafd6c3e8264e8a2144564e Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 18 Feb 2015 11:59:45 +0100 Subject: [PATCH 06/18] Add comment about Stream Management's unacked stanzas queue --- .../main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java index be3253191..71d84b3b1 100644 --- a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java +++ b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java @@ -1284,6 +1284,8 @@ public class XMPPTCPConnection extends AbstractXMPPConnection { writer.flush(); } try { + // It is important the we put the stanza in the unacknowledged stanza + // queue before we put it on the wire unacknowledgedStanzas.put(packet); } catch (InterruptedException e) { From aa8daba1cfd3cfa95f01da611473ba0a16a6e00a Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 18 Feb 2015 12:01:55 +0100 Subject: [PATCH 07/18] Add StreamManagemtCounterError to allow graceful connectionClosedOnError() disconnects, since we received a bunch of reports where the counter seems wrong, which is causing a NPE in a thread pool executor, causing the VM or Android App to terminate. Now we throw the StreamManagementCounterError instead. --- .../smack/sm/StreamManagementException.java | 58 +++++++++++++++++++ .../smack/tcp/XMPPTCPConnection.java | 8 ++- 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/smack-tcp/src/main/java/org/jivesoftware/smack/sm/StreamManagementException.java b/smack-tcp/src/main/java/org/jivesoftware/smack/sm/StreamManagementException.java index 95278f3af..43684e299 100644 --- a/smack-tcp/src/main/java/org/jivesoftware/smack/sm/StreamManagementException.java +++ b/smack-tcp/src/main/java/org/jivesoftware/smack/sm/StreamManagementException.java @@ -16,7 +16,11 @@ */ package org.jivesoftware.smack.sm; +import java.util.Collections; +import java.util.List; + import org.jivesoftware.smack.SmackException; +import org.jivesoftware.smack.packet.Stanza; public abstract class StreamManagementException extends SmackException { @@ -52,5 +56,59 @@ public abstract class StreamManagementException extends SmackException { super("Stream IDs do not match. Expected '" + expected + "', but got '" + got + "'"); } } + + public static class StreamManagementCounterError extends StreamManagementException { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private final long handledCount; + private final long previousServerHandledCount; + private final long ackedStanzaCount; + private final int outstandingStanzasCount; + private final List ackedStanzas; + + public StreamManagementCounterError(long handledCount, long previousServerHandlerCount, + long ackedStanzaCount, + List ackedStanzas) { + super( + "There was an error regarding the Stream Mangement counters. Server reported " + + handledCount + + " handled stanzas, which means that the " + + ackedStanzaCount + + " recently send stanzas by client are now acked by the server. But Smack had only " + + ackedStanzas.size() + + " to acknowledge. The stanza id of the last acked outstanding stanza is " + + (ackedStanzas.isEmpty() ? "" + : ackedStanzas.get(ackedStanzas.size() - 1).getStanzaId())); + this.handledCount = handledCount; + this.previousServerHandledCount = previousServerHandlerCount; + this.ackedStanzaCount = ackedStanzaCount; + this.outstandingStanzasCount = ackedStanzas.size(); + this.ackedStanzas = Collections.unmodifiableList(ackedStanzas); + } + + public long getHandledCount() { + return handledCount; + } + + public long getPreviousServerHandledCount() { + return previousServerHandledCount; + } + + public long getAckedStanzaCount() { + return ackedStanzaCount; + } + + public int getOutstandingStanzasCount() { + return outstandingStanzasCount; + } + + public List getAckedStanzas() { + return ackedStanzas; + } + } } diff --git a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java index 71d84b3b1..ae9610d5b 100644 --- a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java +++ b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java @@ -54,6 +54,7 @@ import org.jivesoftware.smack.sasl.packet.SaslStreamElements.Success; import org.jivesoftware.smack.sm.SMUtils; import org.jivesoftware.smack.sm.StreamManagementException; import org.jivesoftware.smack.sm.StreamManagementException.StreamIdDoesNotMatchException; +import org.jivesoftware.smack.sm.StreamManagementException.StreamManagementCounterError; import org.jivesoftware.smack.sm.StreamManagementException.StreamManagementNotEnabledException; import org.jivesoftware.smack.sm.packet.StreamManagement; import org.jivesoftware.smack.sm.packet.StreamManagement.AckAnswer; @@ -1642,7 +1643,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection { return Math.min(clientResumptionTime, serverResumptionTime); } - private void processHandledCount(long handledCount) throws NotConnectedException { + private void processHandledCount(long handledCount) throws NotConnectedException, StreamManagementCounterError { long ackedStanzasCount = SMUtils.calculateDelta(handledCount, serverHandledStanzasCount); final List ackedStanzas = new ArrayList( handledCount <= Integer.MAX_VALUE ? (int) handledCount @@ -1651,7 +1652,10 @@ public class XMPPTCPConnection extends AbstractXMPPConnection { Stanza ackedStanza = unacknowledgedStanzas.poll(); // If the server ack'ed a stanza, then it must be in the // unacknowledged stanza queue. There can be no exception. - assert(ackedStanza != null); + if (ackedStanza == null) { + throw new StreamManagementCounterError(handledCount, serverHandledStanzasCount, + ackedStanzasCount, ackedStanzas); + } ackedStanzas.add(ackedStanza); } From d415661e35546a71605caf56463894536b29d735 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 18 Feb 2015 14:38:56 +0100 Subject: [PATCH 08/18] Add BundleAndDeferCallback to smack-tcp --- .../smack/tcp/BundleAndDefer.java | 39 +++++++++++++ .../smack/tcp/BundleAndDeferCallback.java | 49 ++++++++++++++++ .../smack/tcp/XMPPTCPConnection.java | 56 +++++++++++++++++++ 3 files changed, 144 insertions(+) create mode 100644 smack-tcp/src/main/java/org/jivesoftware/smack/tcp/BundleAndDefer.java create mode 100644 smack-tcp/src/main/java/org/jivesoftware/smack/tcp/BundleAndDeferCallback.java diff --git a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/BundleAndDefer.java b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/BundleAndDefer.java new file mode 100644 index 000000000..ad899f9e5 --- /dev/null +++ b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/BundleAndDefer.java @@ -0,0 +1,39 @@ +/** + * + * Copyright 2015 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.tcp; + +import java.util.concurrent.atomic.AtomicBoolean; + + +public class BundleAndDefer { + + private final AtomicBoolean isStopped; + + BundleAndDefer(AtomicBoolean isStopped) { + this.isStopped = isStopped; + } + + public void stopCurrentBundleAndDefer() { + synchronized (isStopped) { + if (isStopped.get()) { + return; + } + isStopped.set(true); + isStopped.notify(); + } + } +} diff --git a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/BundleAndDeferCallback.java b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/BundleAndDeferCallback.java new file mode 100644 index 000000000..5102b0019 --- /dev/null +++ b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/BundleAndDeferCallback.java @@ -0,0 +1,49 @@ +/** + * + * Copyright 2015 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.tcp; + +/** + * This callback is used to get the current value of the period in which Smack does bundle and defer + * outgoing stanzas. + *

+ * Smack will bundle and defer stanzas if the connection is authenticated, the send queue is empty + * and if a bundle and defer callback is set, either via + * {@link XMPPTCPConnection#setDefaultBundleAndDeferCallback(BundleAndDeferCallback)} or + * {@link XMPPTCPConnection#setBundleandDeferCallback(BundleAndDeferCallback)}, and + * {@link #getBundleAndDeferMillis(BundleAndDefer)} returns a positive value. In a mobile environment, bundling + * and deferring outgoing stanzas may reduce battery consumption. It heavily depends on the + * environment, but recommend values for the bundle and defer period range from 20-60 seconds. But + * keep in mind that longer periods decrease the realtime aspect of Smack. + *

+ *

+ * Smack will invoke the callback when it needs to know the length of the bundle and defer period. + * If {@link #getBundleAndDeferMillis(BundleAndDefer)} returns 0 or a negative value, then the + * stanzas will send immediately. You can also prematurely abort the bundling of stanzas by calling + * {@link BundleAndDefer#stopCurrentBundleAndDefer()}. + *

+ */ +public interface BundleAndDeferCallback { + + /** + * Return the bundle and defer period used by Smack in milliseconds. + * + * @param bundleAndDefer used to premature abort bundle and defer. + * @return the bundle and defer period in milliseconds. + */ + public int getBundleAndDeferMillis(BundleAndDefer bundleAndDefer); + +} diff --git a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java index ae9610d5b..f7d98b6dd 100644 --- a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java +++ b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java @@ -125,6 +125,7 @@ import java.util.concurrent.BlockingQueue; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; import java.util.logging.Logger; @@ -184,6 +185,10 @@ public class XMPPTCPConnection extends AbstractXMPPConnection { private final SynchronizationPoint compressSyncPoint = new SynchronizationPoint( this); + private static BundleAndDeferCallback defaultBundleAndDeferCallback; + + private BundleAndDeferCallback bundleAndDeferCallback = defaultBundleAndDeferCallback; + private static boolean useSmDefault = false; private static boolean useSmResumptionDefault = true; @@ -1269,6 +1274,30 @@ public class XMPPTCPConnection extends AbstractXMPPConnection { if (element == null) { continue; } + + // Get a local version of the bundle and defer callback, in case it's unset + // between the null check and the method invocation + final BundleAndDeferCallback localBundleAndDeferCallback = bundleAndDeferCallback; + // If the preconditions are given (e.g. bundleAndDefer callback is set, queue is + // empty), then we could wait a bit for further stanzas attempting to decrease + // our energy consumption + if (localBundleAndDeferCallback != null && isAuthenticated() && queue.isEmpty()) { + final AtomicBoolean bundlingAndDeferringStopped = new AtomicBoolean(); + final int bundleAndDeferMillis = localBundleAndDeferCallback.getBundleAndDeferMillis(new BundleAndDefer( + bundlingAndDeferringStopped)); + if (bundleAndDeferMillis > 0) { + long remainingWait = bundleAndDeferMillis; + final long waitStart = System.currentTimeMillis(); + synchronized (bundlingAndDeferringStopped) { + while (!bundlingAndDeferringStopped.get() && remainingWait > 0) { + bundlingAndDeferringStopped.wait(remainingWait); + remainingWait = bundleAndDeferMillis + - (System.currentTimeMillis() - waitStart); + } + } + } + } + Stanza packet = null; if (element instanceof Stanza) { packet = (Stanza) element; @@ -1709,4 +1738,31 @@ public class XMPPTCPConnection extends AbstractXMPPConnection { serverHandledStanzasCount = handledCount; } + + /** + * Set the default bundle and defer callback used for new connections. + * + * @param defaultBundleAndDeferCallback + * @see BundleAndDeferCallback + * @since 4.1 + */ + public static void setDefaultBundleAndDeferCallback(BundleAndDeferCallback defaultBundleAndDeferCallback) { + XMPPTCPConnection.defaultBundleAndDeferCallback = defaultBundleAndDeferCallback; + } + + /** + * Set the bundle and defer callback used for this connection. + *

+ * You can use null as argument to reset the callback. Outgoing stanzas will then + * no longer get deferred. + *

+ * + * @param bundleAndDeferCallback the callback or null. + * @see BundleAndDeferCallback + * @since 4.1 + */ + public void setBundleandDeferCallback(BundleAndDeferCallback bundleAndDeferCallback) { + this.bundleAndDeferCallback = bundleAndDeferCallback; + } + } From 887c6114b727d4fb275dfb2c4c5e6158a5de821a Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Thu, 19 Feb 2015 12:11:19 +0100 Subject: [PATCH 09/18] Add filter information to NoResponseException in order to aid debugging errors. This made it necessary to override 'toString()' for all filters in Smack. --- .../smack/AbstractXMPPConnection.java | 4 +- .../jivesoftware/smack/PacketCollector.java | 2 +- .../smack/SASLAuthentication.java | 6 +- .../jivesoftware/smack/SmackException.java | 44 ++++++++++- .../smack/SynchronizationPoint.java | 2 +- .../smack/filter/AbstractListFilter.java | 78 +++++++++++++++++++ .../jivesoftware/smack/filter/AndFilter.java | 34 +------- .../filter/FlexiblePacketTypeFilter.java | 11 ++- .../smack/filter/FromMatchesFilter.java | 2 +- .../smack/filter/IQReplyFilter.java | 8 ++ .../smack/filter/IQResultReplyFilter.java | 7 ++ .../smack/filter/IQTypeFilter.java | 8 +- .../smack/filter/MessageTypeFilter.java | 4 + .../smack/filter/MessageWithBodiesFilter.java | 4 + .../filter/MessageWithSubjectFilter.java | 4 + .../jivesoftware/smack/filter/NotFilter.java | 6 +- .../jivesoftware/smack/filter/OrFilter.java | 35 +-------- .../smack/filter/PacketExtensionFilter.java | 5 ++ .../smack/filter/PacketIDFilter.java | 2 +- .../smack/filter/PacketTypeFilter.java | 3 +- .../smack/filter/PresenceTypeFilter.java | 8 +- .../smack/filter/ThreadFilter.java | 13 +++- .../jivesoftware/smack/filter/ToFilter.java | 4 + .../filetransfer/FaultTolerantNegotiator.java | 7 +- 24 files changed, 210 insertions(+), 91 deletions(-) create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/filter/AbstractListFilter.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 36d570533..e8585ad85 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java @@ -1432,7 +1432,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { } @Override - public void sendStanzaWithResponseCallback(Stanza stanza, PacketFilter replyFilter, + public void sendStanzaWithResponseCallback(Stanza stanza, final PacketFilter replyFilter, final PacketListener callback, final ExceptionCallback exceptionCallback, long timeout) throws NotConnectedException { Objects.requireNonNull(stanza, "stanza must not be null"); @@ -1465,7 +1465,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { // If the packetListener got removed, then it was never run and // we never received a response, inform the exception callback if (removed && exceptionCallback != null) { - exceptionCallback.processException(new NoResponseException(AbstractXMPPConnection.this)); + exceptionCallback.processException(NoResponseException.newWith(AbstractXMPPConnection.this, replyFilter)); } } }, timeout, TimeUnit.MILLISECONDS); diff --git a/smack-core/src/main/java/org/jivesoftware/smack/PacketCollector.java b/smack-core/src/main/java/org/jivesoftware/smack/PacketCollector.java index 0908b35c2..49ce54f64 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/PacketCollector.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/PacketCollector.java @@ -214,7 +214,7 @@ public class PacketCollector { P result = nextResult(timeout); cancel(); if (result == null) { - throw new NoResponseException(connection); + throw NoResponseException.newWith(connection, this); } XMPPErrorException.ifHasErrorThenThrow(result); 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 d15e6c446..dade9ae82 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/SASLAuthentication.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/SASLAuthentication.java @@ -200,7 +200,7 @@ public class SASLAuthentication { maybeThrowException(); if (!authenticationSuccessful) { - throw new NoResponseException(connection); + throw NoResponseException.newWith(connection); } } else { @@ -247,7 +247,7 @@ public class SASLAuthentication { maybeThrowException(); if (!authenticationSuccessful) { - throw new NoResponseException(connection); + throw NoResponseException.newWith(connection); } } else { @@ -286,7 +286,7 @@ public class SASLAuthentication { maybeThrowException(); if (!authenticationSuccessful) { - throw new NoResponseException(connection); + throw NoResponseException.newWith(connection); } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/SmackException.java b/smack-core/src/main/java/org/jivesoftware/smack/SmackException.java index 807f68ef1..789f6a0ff 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/SmackException.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/SmackException.java @@ -19,6 +19,7 @@ package org.jivesoftware.smack; import java.util.ArrayList; import java.util.List; +import org.jivesoftware.smack.filter.PacketFilter; import org.jivesoftware.smack.util.dns.HostAddress; /** @@ -64,10 +65,47 @@ public class SmackException extends Exception { */ private static final long serialVersionUID = -6523363748984543636L; - public NoResponseException(XMPPConnection connection) { - super("No response received within packet reply timeout. Timeout was " + connection.getPacketReplyTimeout() - + "ms (~" + connection.getPacketReplyTimeout() / 1000 + "s)"); + private final PacketFilter filter; + + private NoResponseException(String message, PacketFilter filter) { + super(message); + this.filter = filter; } + + /** + * Get the filter that was used to collect the response. + * + * @return the used filter or null. + */ + public PacketFilter getFilter() { + return filter; + } + + public static NoResponseException newWith(XMPPConnection connection) { + return newWith(connection, (PacketFilter) null); + } + + public static NoResponseException newWith(XMPPConnection connection, + PacketCollector collector) { + return newWith(connection, collector.getPacketFilter()); + } + + public static NoResponseException newWith(XMPPConnection connection, PacketFilter filter) { + final long replyTimeout = connection.getPacketReplyTimeout(); + final StringBuilder sb = new StringBuilder(256); + sb.append("No response received within reply timeout. Timeout was " + + replyTimeout + "ms (~" + + replyTimeout / 1000 + "s). Used filter: "); + if (filter != null) { + sb.append(filter.toString()); + } + else { + sb.append("No filter used or filter was 'null'"); + } + sb.append('.'); + return new NoResponseException(sb.toString(), filter); + } + } public static class NotLoggedInException extends SmackException { diff --git a/smack-core/src/main/java/org/jivesoftware/smack/SynchronizationPoint.java b/smack-core/src/main/java/org/jivesoftware/smack/SynchronizationPoint.java index 7e75a75c1..4cd2070e1 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/SynchronizationPoint.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/SynchronizationPoint.java @@ -189,7 +189,7 @@ public class SynchronizationPoint { case Initial: case NoResponse: case RequestSent: - throw new NoResponseException(connection); + throw NoResponseException.newWith(connection); default: // Do nothing break; diff --git a/smack-core/src/main/java/org/jivesoftware/smack/filter/AbstractListFilter.java b/smack-core/src/main/java/org/jivesoftware/smack/filter/AbstractListFilter.java new file mode 100644 index 000000000..d32fb6eef --- /dev/null +++ b/smack-core/src/main/java/org/jivesoftware/smack/filter/AbstractListFilter.java @@ -0,0 +1,78 @@ +/** + * + * Copyright 2015 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.filter; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.jivesoftware.smack.util.Objects; + +/** + * + */ +public abstract class AbstractListFilter implements PacketFilter { + + /** + * The list of filters. + */ + protected final List filters; + + /** + * Creates an empty filter. + */ + protected AbstractListFilter() { + filters = new ArrayList(); + } + + /** + * Creates an filter using the specified filters. + * + * @param filters the filters to add. + */ + protected AbstractListFilter(PacketFilter... filters) { + Objects.requireNonNull(filters, "Parameter must not be null."); + for(PacketFilter filter : filters) { + Objects.requireNonNull(filter, "Parameter must not be null."); + } + this.filters = new ArrayList(Arrays.asList(filters)); + } + + /** + * Adds a filter to the filter list. A stanza will pass the filter if all of the filters in the + * list accept it. + * + * @param filter a filter to add to the filter list. + */ + public void addFilter(PacketFilter filter) { + Objects.requireNonNull(filter, "Parameter must not be null."); + filters.add(filter); + } + + @Override + public final String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(getClass().getSimpleName()); + sb.append(" ("); + for (PacketFilter filter : filters) { + sb.append(' ' + filter.toString() + ','); + } + sb.append(")"); + return sb.toString(); + } +} diff --git a/smack-core/src/main/java/org/jivesoftware/smack/filter/AndFilter.java b/smack-core/src/main/java/org/jivesoftware/smack/filter/AndFilter.java index 0f7ccb4e0..7006852fe 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/filter/AndFilter.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/filter/AndFilter.java @@ -17,12 +17,7 @@ package org.jivesoftware.smack.filter; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - import org.jivesoftware.smack.packet.Stanza; -import org.jivesoftware.smack.util.Objects; /** * Implements the logical AND operation over two or more packet filters. @@ -30,19 +25,14 @@ import org.jivesoftware.smack.util.Objects; * * @author Matt Tucker */ -public class AndFilter implements PacketFilter { - - /** - * The list of filters. - */ - private final List filters; +public class AndFilter extends AbstractListFilter implements PacketFilter { /** * Creates an empty AND filter. Filters should be added using the * {@link #addFilter(PacketFilter)} method. */ public AndFilter() { - filters = new ArrayList(); + super(); } /** @@ -51,22 +41,7 @@ public class AndFilter implements PacketFilter { * @param filters the filters to add. */ public AndFilter(PacketFilter... filters) { - Objects.requireNonNull(filters, "Parameter must not be null."); - for(PacketFilter filter : filters) { - Objects.requireNonNull(filter, "Parameter must not be null."); - } - this.filters = new ArrayList(Arrays.asList(filters)); - } - - /** - * Adds a filter to the filter list for the AND operation. A packet - * will pass the filter if all of the filters in the list accept it. - * - * @param filter a filter to add to the filter list. - */ - public void addFilter(PacketFilter filter) { - Objects.requireNonNull(filter, "Parameter must not be null."); - filters.add(filter); + super(filters); } public boolean accept(Stanza packet) { @@ -78,7 +53,4 @@ public class AndFilter implements PacketFilter { return true; } - public String toString() { - return filters.toString(); - } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/filter/FlexiblePacketTypeFilter.java b/smack-core/src/main/java/org/jivesoftware/smack/filter/FlexiblePacketTypeFilter.java index 54e49c2fe..454d8caa3 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/filter/FlexiblePacketTypeFilter.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/filter/FlexiblePacketTypeFilter.java @@ -20,6 +20,7 @@ package org.jivesoftware.smack.filter; import java.lang.reflect.ParameterizedType; import org.jivesoftware.smack.packet.Stanza; +import org.jivesoftware.smack.util.Objects; /** * Filters for packets of a particular type and allows a custom method to further filter the packets. @@ -31,7 +32,7 @@ public abstract class FlexiblePacketTypeFilter

implements Pack protected final Class

packetType; public FlexiblePacketTypeFilter(Class

packetType) { - this.packetType = packetType; + this.packetType = Objects.requireNonNull(packetType, "Type must not be null"); } @SuppressWarnings("unchecked") @@ -49,4 +50,12 @@ public abstract class FlexiblePacketTypeFilter

implements Pack } protected abstract boolean acceptSpecific(P packet); + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(getClass().getSimpleName()); + sb.append(" (" + packetType.toString() + ')'); + return sb.toString(); + } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/filter/FromMatchesFilter.java b/smack-core/src/main/java/org/jivesoftware/smack/filter/FromMatchesFilter.java index ee570aa78..3b48d0f13 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/filter/FromMatchesFilter.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/filter/FromMatchesFilter.java @@ -104,6 +104,6 @@ public class FromMatchesFilter implements PacketFilter { public String toString() { String matchMode = matchBareJID ? "bare" : "full"; - return "FromMatchesFilter (" +matchMode + "): " + address; + return getClass().getSimpleName() + " (" + matchMode + "): " + address; } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/filter/IQReplyFilter.java b/smack-core/src/main/java/org/jivesoftware/smack/filter/IQReplyFilter.java index fc0673548..e7b162356 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/filter/IQReplyFilter.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/filter/IQReplyFilter.java @@ -130,4 +130,12 @@ public class IQReplyFilter implements PacketFilter { } } + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(getClass().getSimpleName()); + sb.append(": iqAndIdFilter (").append(iqAndIdFilter.toString()).append("), "); + sb.append(": fromFilter (").append(fromFilter.toString()).append(')'); + return sb.toString(); + } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/filter/IQResultReplyFilter.java b/smack-core/src/main/java/org/jivesoftware/smack/filter/IQResultReplyFilter.java index c77539f56..a8225dcf4 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/filter/IQResultReplyFilter.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/filter/IQResultReplyFilter.java @@ -38,4 +38,11 @@ public class IQResultReplyFilter extends IQReplyFilter { return IQTypeFilter.RESULT.accept(packet); } + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(getClass().getSimpleName()); + sb.append(" (" + super.toString() + ')'); + return sb.toString(); + } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/filter/IQTypeFilter.java b/smack-core/src/main/java/org/jivesoftware/smack/filter/IQTypeFilter.java index f0cccb245..dc2c38b10 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/filter/IQTypeFilter.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/filter/IQTypeFilter.java @@ -18,6 +18,7 @@ package org.jivesoftware.smack.filter; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IQ.Type; +import org.jivesoftware.smack.util.Objects; /** * A filter for IQ packet types. Returns true only if the packet is an IQ packet @@ -38,11 +39,16 @@ public class IQTypeFilter extends FlexiblePacketTypeFilter { private IQTypeFilter(IQ.Type type) { super(IQ.class); - this.type = type; + this.type = Objects.requireNonNull(type, "Type must not be null"); } @Override protected boolean acceptSpecific(IQ iq) { return iq.getType() == type; } + + @Override + public String toString() { + return getClass().getSimpleName() + ": type=" + type; + } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/filter/MessageTypeFilter.java b/smack-core/src/main/java/org/jivesoftware/smack/filter/MessageTypeFilter.java index c7eaa5275..74df7bfed 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/filter/MessageTypeFilter.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/filter/MessageTypeFilter.java @@ -55,4 +55,8 @@ public class MessageTypeFilter extends FlexiblePacketTypeFilter { return message.getType() == type; } + @Override + public String toString() { + return getClass().getSimpleName() + ": type=" + type; + } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/filter/MessageWithBodiesFilter.java b/smack-core/src/main/java/org/jivesoftware/smack/filter/MessageWithBodiesFilter.java index a8f796622..201e5546d 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/filter/MessageWithBodiesFilter.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/filter/MessageWithBodiesFilter.java @@ -36,4 +36,8 @@ public class MessageWithBodiesFilter extends FlexiblePacketTypeFilter { return !message.getBodies().isEmpty(); } + @Override + public String toString() { + return getClass().getSimpleName(); + } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/filter/MessageWithSubjectFilter.java b/smack-core/src/main/java/org/jivesoftware/smack/filter/MessageWithSubjectFilter.java index fa29ec497..c484aa2e8 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/filter/MessageWithSubjectFilter.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/filter/MessageWithSubjectFilter.java @@ -36,4 +36,8 @@ public class MessageWithSubjectFilter extends FlexiblePacketTypeFilter return message.getSubject() != null; } + @Override + public String toString() { + return getClass().getSimpleName(); + } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/filter/NotFilter.java b/smack-core/src/main/java/org/jivesoftware/smack/filter/NotFilter.java index 3dd76a7f0..76d63ce9c 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/filter/NotFilter.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/filter/NotFilter.java @@ -18,6 +18,7 @@ package org.jivesoftware.smack.filter; import org.jivesoftware.smack.packet.Stanza; +import org.jivesoftware.smack.util.Objects; /** * Implements the logical NOT operation on a packet filter. In other words, packets @@ -35,10 +36,7 @@ public class NotFilter implements PacketFilter { * @param filter the filter. */ public NotFilter(PacketFilter filter) { - if (filter == null) { - throw new IllegalArgumentException("Parameter must not be null."); - } - this.filter = filter; + this.filter = Objects.requireNonNull(filter, "Parameter must not be null."); } public boolean accept(Stanza packet) { diff --git a/smack-core/src/main/java/org/jivesoftware/smack/filter/OrFilter.java b/smack-core/src/main/java/org/jivesoftware/smack/filter/OrFilter.java index db583c076..b1d96eeef 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/filter/OrFilter.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/filter/OrFilter.java @@ -17,12 +17,7 @@ package org.jivesoftware.smack.filter; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - import org.jivesoftware.smack.packet.Stanza; -import org.jivesoftware.smack.util.Objects; /** * Implements the logical OR operation over two or more packet filters. In @@ -30,19 +25,14 @@ import org.jivesoftware.smack.util.Objects; * * @author Matt Tucker */ -public class OrFilter implements PacketFilter { - - /** - * The list of filters. - */ - private final List filters; +public class OrFilter extends AbstractListFilter implements PacketFilter { /** * Creates an empty OR filter. Filters should be added using the * {@link #addFilter(PacketFilter)} method. */ public OrFilter() { - filters = new ArrayList(); + super(); } /** @@ -51,24 +41,10 @@ public class OrFilter implements PacketFilter { * @param filters the filters to add. */ public OrFilter(PacketFilter... filters) { - Objects.requireNonNull(filters, "Parameter must not be null."); - for(PacketFilter filter : filters) { - Objects.requireNonNull(filter, "Parameter must not be null."); - } - this.filters = new ArrayList(Arrays.asList(filters)); - } - - /** - * Adds a filter to the filter list for the OR operation. A packet - * will pass the filter if any filter in the list accepts it. - * - * @param filter a filter to add to the filter list. - */ - public void addFilter(PacketFilter filter) { - Objects.requireNonNull(filter, "Parameter must not be null."); - filters.add(filter); + super(filters); } + @Override public boolean accept(Stanza packet) { for (PacketFilter filter : filters) { if (filter.accept(packet)) { @@ -78,7 +54,4 @@ public class OrFilter implements PacketFilter { return false; } - public String toString() { - return filters.toString(); - } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/filter/PacketExtensionFilter.java b/smack-core/src/main/java/org/jivesoftware/smack/filter/PacketExtensionFilter.java index 0ba17386f..c0deb6183 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/filter/PacketExtensionFilter.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/filter/PacketExtensionFilter.java @@ -68,4 +68,9 @@ public class PacketExtensionFilter implements PacketFilter { public boolean accept(Stanza packet) { return packet.hasExtension(elementName, namespace); } + + @Override + public String toString() { + return getClass().getSimpleName() + ": element=" + elementName + " namespace=" + namespace; + } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/filter/PacketIDFilter.java b/smack-core/src/main/java/org/jivesoftware/smack/filter/PacketIDFilter.java index 82a2ea904..a01b247c6 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/filter/PacketIDFilter.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/filter/PacketIDFilter.java @@ -53,6 +53,6 @@ public class PacketIDFilter implements PacketFilter { } public String toString() { - return "PacketIDFilter by id: " + packetID; + return getClass().getSimpleName() + ": id=" + packetID; } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/filter/PacketTypeFilter.java b/smack-core/src/main/java/org/jivesoftware/smack/filter/PacketTypeFilter.java index 6c57a4071..5a32e784c 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/filter/PacketTypeFilter.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/filter/PacketTypeFilter.java @@ -53,7 +53,8 @@ public class PacketTypeFilter implements PacketFilter { return packetType.isInstance(packet); } + @Override public String toString() { - return "PacketTypeFilter: " + packetType.getName(); + return getClass().getSimpleName() + ": " + packetType.getName(); } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/filter/PresenceTypeFilter.java b/smack-core/src/main/java/org/jivesoftware/smack/filter/PresenceTypeFilter.java index 045cd2bf8..d67635609 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/filter/PresenceTypeFilter.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/filter/PresenceTypeFilter.java @@ -18,6 +18,7 @@ package org.jivesoftware.smack.filter; import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smack.packet.Presence.Type; +import org.jivesoftware.smack.util.Objects; /** * A filter for Presence types. Returns true only if the stanza is an Presence packet and it matches the type provided in the @@ -38,11 +39,16 @@ public class PresenceTypeFilter extends FlexiblePacketTypeFilter { private PresenceTypeFilter(Presence.Type type) { super(Presence.class); - this.type = type; + this.type = Objects.requireNonNull(type, "type must not be null"); } @Override protected boolean acceptSpecific(Presence presence) { return presence.getType() == type; } + + @Override + public String toString() { + return getClass().getSimpleName() + ": type=" + type; + } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/filter/ThreadFilter.java b/smack-core/src/main/java/org/jivesoftware/smack/filter/ThreadFilter.java index e053d364b..da1c3d7dd 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/filter/ThreadFilter.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/filter/ThreadFilter.java @@ -17,7 +17,6 @@ package org.jivesoftware.smack.filter; -import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.util.StringUtils; @@ -26,7 +25,7 @@ import org.jivesoftware.smack.util.StringUtils; * * @author Matt Tucker */ -public class ThreadFilter implements PacketFilter { +public class ThreadFilter extends FlexiblePacketTypeFilter implements PacketFilter { private final String thread; @@ -40,7 +39,13 @@ public class ThreadFilter implements PacketFilter { this.thread = thread; } - public boolean accept(Stanza packet) { - return packet instanceof Message && thread.equals(((Message) packet).getThread()); + @Override + protected boolean acceptSpecific(Message message) { + return thread.equals(message.getThread()); + } + + @Override + public String toString() { + return getClass().getSimpleName() + ": thread=" + thread; } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/filter/ToFilter.java b/smack-core/src/main/java/org/jivesoftware/smack/filter/ToFilter.java index cfb0d3ed4..a691537b2 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/filter/ToFilter.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/filter/ToFilter.java @@ -38,4 +38,8 @@ public class ToFilter implements PacketFilter { return packetTo.equals(to); } + @Override + public String toString() { + return getClass().getSimpleName() + ": to=" + to; + } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FaultTolerantNegotiator.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FaultTolerantNegotiator.java index b93850279..25ff808c4 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FaultTolerantNegotiator.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FaultTolerantNegotiator.java @@ -175,11 +175,8 @@ public class FaultTolerantNegotiator extends StreamNegotiator { this.collector = collector; } - public InputStream call() throws XMPPErrorException, InterruptedException, SmackException { - Stanza streamInitiation = collector.nextResult(); - if (streamInitiation == null) { - throw new NoResponseException(connection); - } + public InputStream call() throws XMPPErrorException, InterruptedException, NoResponseException, SmackException { + Stanza streamInitiation = collector.nextResultOrThrow(); StreamNegotiator negotiator = determineNegotiator(streamInitiation); return negotiator.negotiateIncomingStream(streamInitiation); } From 5f4374ec260809f934093bfd26885c370dc3e713 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Thu, 19 Feb 2015 09:23:36 +0100 Subject: [PATCH 10/18] Use host(name) to construct the SSLSocket in XMPPTCPConnection. So that the hostname and not the IP is available to the SSLSocket and the SSLSession, which handed over to HostnameVerifier. This leaves the HostnameVerifier with the - name of the XMPP service (first argument of verify(String, SSLSession) - name of the used host (found in the SSLSession) allowing more complex verification mechanisms performed by the HostnameVerifier. --- .../main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java index f7d98b6dd..501d9d7fa 100644 --- a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java +++ b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java @@ -721,7 +721,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection { Socket plain = socket; // Secure the plain connection socket = context.getSocketFactory().createSocket(plain, - plain.getInetAddress().getHostAddress(), plain.getPort(), true); + host, plain.getPort(), true); // Initialize the reader and writer with the new secured version initReaderAndWriter(); From 2663a62033ef700a62b6074b04a110e5912e8be1 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Thu, 19 Feb 2015 13:20:58 +0100 Subject: [PATCH 11/18] Filter smack-bosh from smack-android dependencies smack-bosh was recently added to androidProjects, but it was not filtered out from the dependencies for smack-android. Since it is an optional dependency, it should not be a dependency of smack-android. --- smack-android/build.gradle | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/smack-android/build.gradle b/smack-android/build.gradle index 84326fb2e..48e9a4785 100644 --- a/smack-android/build.gradle +++ b/smack-android/build.gradle @@ -7,9 +7,10 @@ smack-extensions and smack-experimental.""" // Note that the test dependencies (junit, …) are inferred from the // sourceSet.test of the core subproject dependencies { + // androidProjects lists all projects that are checked to compile against android.jar // Filter out the optional Smack dependencies from androidProjects androidProjects.findAll { - ![':smack-tcp', ':smack-extensions', ':smack-experimental'].contains(it.getPath()) + ![':smack-tcp', ':smack-extensions', ':smack-experimental', ':smack-bosh'].contains(it.getPath()) }.each { project -> compile project } From 2856b8ace6933ee1b28178473d92923ff0847634 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Thu, 19 Feb 2015 14:28:46 +0100 Subject: [PATCH 12/18] Fix dependency version specification Mathematical range syntax was introduced with 31c53f094c9a613821b9e101f9d7f9bfd775b4e1, but unforutantely brackets and parentheses where reversed. --- smack-bosh/build.gradle | 2 +- smack-compression-jzlib/build.gradle | 2 +- smack-debug-slf4j/build.gradle | 2 +- smack-resolver-dnsjava/build.gradle | 2 +- smack-resolver-minidns/build.gradle | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/smack-bosh/build.gradle b/smack-bosh/build.gradle index 8955ed6e4..4ec1ce03a 100644 --- a/smack-bosh/build.gradle +++ b/smack-bosh/build.gradle @@ -4,5 +4,5 @@ This API is considered beta quality.""" dependencies { compile project(':smack-core') - compile 'org.igniterealtime.jbosh:jbosh:(0.8,0.9]' + compile 'org.igniterealtime.jbosh:jbosh:[0.8,0.9)' } diff --git a/smack-compression-jzlib/build.gradle b/smack-compression-jzlib/build.gradle index f90968ddf..9f449f88e 100644 --- a/smack-compression-jzlib/build.gradle +++ b/smack-compression-jzlib/build.gradle @@ -4,5 +4,5 @@ Allow to compress the XMPP stream with help of jzlib.""" dependencies { compile project(path: ':smack-core') - compile 'com.jcraft:jzlib:(1.1,1.2]' + compile 'com.jcraft:jzlib:[1.1,1.2)' } diff --git a/smack-debug-slf4j/build.gradle b/smack-debug-slf4j/build.gradle index 4e5a2a65f..43f430dbb 100644 --- a/smack-debug-slf4j/build.gradle +++ b/smack-debug-slf4j/build.gradle @@ -5,6 +5,6 @@ Connect your favourite slf4j backend of choice to get output inside of it""" dependencies { compile project(':smack-core') - compile 'org.slf4j:slf4j-api:(1.7,1.8]' + compile 'org.slf4j:slf4j-api:[1.7,1.8)' testCompile project(':smack-core').sourceSets.test.runtimeClasspath } diff --git a/smack-resolver-dnsjava/build.gradle b/smack-resolver-dnsjava/build.gradle index 2e46948bc..9de83e1f5 100644 --- a/smack-resolver-dnsjava/build.gradle +++ b/smack-resolver-dnsjava/build.gradle @@ -5,5 +5,5 @@ javax.naming API (e.g. Android).""" dependencies { compile project(path: ':smack-core') - compile 'dnsjava:dnsjava:(2.1,2.2]' + compile 'dnsjava:dnsjava:[2.1,2.2)' } diff --git a/smack-resolver-minidns/build.gradle b/smack-resolver-minidns/build.gradle index 49438ee95..812fe8c4b 100644 --- a/smack-resolver-minidns/build.gradle +++ b/smack-resolver-minidns/build.gradle @@ -5,6 +5,6 @@ javax.naming API (e.g. Android).""" dependencies { compile project(path: ':smack-core') - compile 'de.measite.minidns:minidns:(0.1,0.2]' + compile 'de.measite.minidns:minidns:[0.1,0.2)' compile "org.jxmpp:jxmpp-util-cache:$jxmppVersion" } From 7ebea7ce949a367f0a410018a89c5972d46f31ba Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Thu, 19 Feb 2015 14:59:44 +0100 Subject: [PATCH 13/18] Add StanzaIdFilter, deprecate PacketIDFilter --- build.gradle | 1 + documentation/processing.md | 2 +- .../smack/AbstractXMPPConnection.java | 6 +- .../smack/filter/IQReplyFilter.java | 2 +- .../smack/filter/PacketFilter.java | 2 +- .../smack/filter/PacketIDFilter.java | 6 ++ .../smack/filter/StanzaIdFilter.java | 57 +++++++++++++++++++ .../smackx/iqregister/AccountManager.java | 4 +- .../smackx/iqversion/packet/Version.java | 20 ------- .../java/org/jivesoftware/util/Protocol.java | 2 +- 10 files changed, 73 insertions(+), 29 deletions(-) create mode 100644 smack-core/src/main/java/org/jivesoftware/smack/filter/StanzaIdFilter.java diff --git a/build.gradle b/build.gradle index bcffddd94..0fd69f2e0 100644 --- a/build.gradle +++ b/build.gradle @@ -95,6 +95,7 @@ allprojects { options.addStringOption('Xdoclint:none', '-quiet') } } + } gradle.taskGraph.whenReady { taskGraph -> diff --git a/documentation/processing.md b/documentation/processing.md index 4e4fe1b9b..6d3b41c7e 100644 --- a/documentation/processing.md +++ b/documentation/processing.md @@ -46,7 +46,7 @@ own filters by coding to the `PacketFilter` interface. The default set of filters includes: * `PacketTypeFilter` -- filters for packets that are a particular Class type. - * `PacketIDFilter` -- filters for packets with a particular packet ID. + * `StanzaIdFilter` -- filters for packets with a particular packet ID. * `ThreadFilter` -- filters for message packets with a particular thread ID. * `ToContainsFilter` -- filters for packets that are sent to a particular address. * `FromContainsFilter` -- filters for packets that are sent to a particular address. 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 e8585ad85..5e8b4928a 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java @@ -57,7 +57,7 @@ import org.jivesoftware.smack.compression.XMPPInputOutputStream; import org.jivesoftware.smack.debugger.SmackDebugger; import org.jivesoftware.smack.filter.IQReplyFilter; import org.jivesoftware.smack.filter.PacketFilter; -import org.jivesoftware.smack.filter.PacketIDFilter; +import org.jivesoftware.smack.filter.StanzaIdFilter; import org.jivesoftware.smack.iqrequest.IQRequestHandler; import org.jivesoftware.smack.packet.Bind; import org.jivesoftware.smack.packet.ErrorIQ; @@ -539,7 +539,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { // Note that we can not use IQReplyFilter here, since the users full JID is not yet // available. It will become available right after the resource has been successfully bound. Bind bindResource = Bind.newSet(resource); - PacketCollector packetCollector = createPacketCollectorAndSend(new PacketIDFilter(bindResource), bindResource); + PacketCollector packetCollector = createPacketCollectorAndSend(new StanzaIdFilter(bindResource), bindResource); Bind response = packetCollector.nextResultOrThrow(); // Set the connections user to the result of resource binding. It is important that we don't infer the user // from the login() arguments and the configurations service name, as, for example, when SASL External is used, @@ -552,7 +552,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { // For more information see http://tools.ietf.org/html/draft-cridland-xmpp-session-01 if (sessionFeature != null && !sessionFeature.isOptional() && !getConfiguration().isLegacySessionDisabled()) { Session session = new Session(); - packetCollector = createPacketCollectorAndSend(new PacketIDFilter(session), session); + packetCollector = createPacketCollectorAndSend(new StanzaIdFilter(session), session); packetCollector.nextResultOrThrow(); } } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/filter/IQReplyFilter.java b/smack-core/src/main/java/org/jivesoftware/smack/filter/IQReplyFilter.java index e7b162356..0c3064e65 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/filter/IQReplyFilter.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/filter/IQReplyFilter.java @@ -99,7 +99,7 @@ public class IQReplyFilter implements PacketFilter { packetId = iqPacket.getStanzaId(); PacketFilter iqFilter = new OrFilter(IQTypeFilter.ERROR, IQTypeFilter.RESULT); - PacketFilter idFilter = new PacketIDFilter(iqPacket); + PacketFilter idFilter = new StanzaIdFilter(iqPacket); iqAndIdFilter = new AndFilter(iqFilter, idFilter); fromFilter = new OrFilter(); fromFilter.addFilter(FromMatchesFilter.createFull(to)); diff --git a/smack-core/src/main/java/org/jivesoftware/smack/filter/PacketFilter.java b/smack-core/src/main/java/org/jivesoftware/smack/filter/PacketFilter.java index c71cbe3fe..5aecfa2a2 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/filter/PacketFilter.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/filter/PacketFilter.java @@ -28,7 +28,7 @@ import org.jivesoftware.smack.packet.Stanza; * packet filtering by using the {@link org.jivesoftware.smack.filter.AndFilter AndFilter} and * {@link org.jivesoftware.smack.filter.OrFilter OrFilter} filters. It's also possible to define * your own filters by implementing this interface. The code example below creates a trivial filter - * for packets with a specific ID (real code should use {@link PacketIDFilter} instead). + * for packets with a specific ID (real code should use {@link StanzaIdFilter} instead). * *

  * // Use an anonymous inner class to define a packet filter that returns
diff --git a/smack-core/src/main/java/org/jivesoftware/smack/filter/PacketIDFilter.java b/smack-core/src/main/java/org/jivesoftware/smack/filter/PacketIDFilter.java
index a01b247c6..11796a0ab 100644
--- a/smack-core/src/main/java/org/jivesoftware/smack/filter/PacketIDFilter.java
+++ b/smack-core/src/main/java/org/jivesoftware/smack/filter/PacketIDFilter.java
@@ -24,7 +24,9 @@ import org.jivesoftware.smack.util.StringUtils;
  * Filters for packets with a particular packet ID.
  *
  * @author Matt Tucker
+ * @deprecated use {@link StanzaIdFilter} instead.
  */
+@Deprecated
 public class PacketIDFilter implements PacketFilter {
 
     private final String packetID;
@@ -33,7 +35,9 @@ public class PacketIDFilter implements PacketFilter {
      * Creates a new packet ID filter using the specified packet's ID.
      *
      * @param packet the packet which the ID is taken from.
+     * @deprecated use {@link StanzaIdfilter(Stanza)} instead.
      */
+    @Deprecated
     public PacketIDFilter(Stanza packet) {
         this(packet.getStanzaId());
     }
@@ -42,7 +46,9 @@ public class PacketIDFilter implements PacketFilter {
      * Creates a new packet ID filter using the specified packet ID.
      *
      * @param packetID the packet ID to filter for.
+     * @deprecated use {@link StanzaIdFilter(String)} instead.
      */
+    @Deprecated
     public PacketIDFilter(String packetID) {
         StringUtils.requireNotNullOrEmpty(packetID, "Packet ID must not be null or empty.");
         this.packetID = packetID;
diff --git a/smack-core/src/main/java/org/jivesoftware/smack/filter/StanzaIdFilter.java b/smack-core/src/main/java/org/jivesoftware/smack/filter/StanzaIdFilter.java
new file mode 100644
index 000000000..bf123726b
--- /dev/null
+++ b/smack-core/src/main/java/org/jivesoftware/smack/filter/StanzaIdFilter.java
@@ -0,0 +1,57 @@
+/**
+ *
+ * Copyright 2003-2007 Jive Software.
+ *
+ * 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.filter;
+
+import org.jivesoftware.smack.packet.Stanza;
+import org.jivesoftware.smack.util.StringUtils;
+
+/**
+ * Filters for Stanzas with a particular stanza ID.
+ *
+ * @author Matt Tucker
+ */
+public class StanzaIdFilter implements PacketFilter {
+
+    private final String stanzaId;
+
+    /**
+     * Creates a new stanza ID filter using the specified stanza's ID.
+     *
+     * @param stanza the stanza which the ID is taken from.
+     */
+    public StanzaIdFilter(Stanza stanza) {
+        this(stanza.getStanzaId());
+    }
+
+    /**
+     * Creates a new stanza ID filter using the specified stanza ID.
+     *
+     * @param stanzaID the stanza ID to filter for.
+     */
+    public StanzaIdFilter(String stanzaID) {
+        this.stanzaId = StringUtils.requireNotNullOrEmpty(stanzaID, "Stanza ID must not be null or empty.");
+    }
+
+    public boolean accept(Stanza stanza) {
+        return stanzaId.equals(stanza.getStanzaId());
+    }
+
+    public String toString() {
+        return getClass().getSimpleName() + ": id=" + stanzaId;
+    }
+}
diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/AccountManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/AccountManager.java
index c701e5105..b0ec24d08 100644
--- a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/AccountManager.java
+++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/AccountManager.java
@@ -31,7 +31,7 @@ import org.jivesoftware.smack.XMPPException;
 import org.jivesoftware.smack.SmackException.NoResponseException;
 import org.jivesoftware.smack.SmackException.NotConnectedException;
 import org.jivesoftware.smack.XMPPException.XMPPErrorException;
-import org.jivesoftware.smack.filter.PacketIDFilter;
+import org.jivesoftware.smack.filter.StanzaIdFilter;
 import org.jivesoftware.smack.packet.IQ;
 import org.jivesoftware.smackx.iqregister.packet.Registration;
 import org.jxmpp.util.XmppStringUtils;
@@ -290,7 +290,7 @@ public class AccountManager extends Manager {
     }
 
     private PacketCollector createPacketCollectorAndSend(IQ req) throws NotConnectedException {
-        PacketCollector collector = connection().createPacketCollectorAndSend(new PacketIDFilter(req.getStanzaId()), req);
+        PacketCollector collector = connection().createPacketCollectorAndSend(new StanzaIdFilter(req.getStanzaId()), req);
         return collector;
     }
 }
diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqversion/packet/Version.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqversion/packet/Version.java
index 58e592849..e2bf06ec7 100644
--- a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqversion/packet/Version.java
+++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqversion/packet/Version.java
@@ -26,26 +26,6 @@ import org.jivesoftware.smack.util.StringUtils;
  * A Version IQ packet, which is used by XMPP clients to discover version information
  * about the software running at another entity's JID.

* - * An example to discover the version of the server: - *

- * // Request the version from the server.
- * Version versionRequest = new Version();
- * timeRequest.setType(IQ.Type.get);
- * timeRequest.setTo("example.com");
- *
- * // Create a packet collector to listen for a response.
- * PacketCollector collector = con.createPacketCollector(
- *                new PacketIDFilter(versionRequest.getStanzaId()));
- *
- * con.sendPacket(versionRequest);
- *
- * // Wait up to 5 seconds for a result.
- * IQ result = (IQ)collector.nextResult(5000);
- * if (result != null && result.getType() == IQ.Type.result) {
- *     Version versionResult = (Version)result;
- *     // Do something with result...
- * }

- * * @author Gaston Dombiak */ public class Version extends IQ { diff --git a/smack-extensions/src/test/java/org/jivesoftware/util/Protocol.java b/smack-extensions/src/test/java/org/jivesoftware/util/Protocol.java index 71fdbc33a..75acff249 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/util/Protocol.java +++ b/smack-extensions/src/test/java/org/jivesoftware/util/Protocol.java @@ -51,7 +51,7 @@ import org.jivesoftware.smack.packet.Stanza; * * public void methodToTest() { * Packet packet = new Packet(); // create an XMPP packet - * PacketCollector collector = connection.createPacketCollector(new PacketIDFilter()); + * PacketCollector collector = connection.createPacketCollector(new StanzaIdFilter()); * connection.sendPacket(packet); * Packet reply = collector.nextResult(); * } From bfcb403673f10136b9ceef559ebf21a8bfd51d09 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Thu, 19 Feb 2015 23:01:38 +0100 Subject: [PATCH 14/18] Fix Stream Management ack listner invocation aborting to early, because of a 'return' statement, when 'continue' should be used. Thanks to Daniele Ricci for reporting this bug. --- .../main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java index 501d9d7fa..f8852f1ad 100644 --- a/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java +++ b/smack-tcp/src/main/java/org/jivesoftware/smack/tcp/XMPPTCPConnection.java @@ -1720,7 +1720,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection { } String id = ackedStanza.getStanzaId(); if (StringUtils.isNullOrEmpty(id)) { - return; + continue; } PacketListener listener = stanzaIdAcknowledgedListeners.remove(id); if (listener != null) { From 26d9a95c64180efb650533015a0dd544ea798f10 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Fri, 20 Feb 2015 08:36:04 +0100 Subject: [PATCH 15/18] Add Smack 4.0.7 Changelog Cherry-picked 5cf99508adbd253939b92542784fd7f096ca4113 from 4.0 branch to include the 4.0.7 changelog. Conflicts: version.gradle --- resources/releasedocs/changelog.html | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/resources/releasedocs/changelog.html b/resources/releasedocs/changelog.html index 93b258e2d..eb5830715 100644 --- a/resources/releasedocs/changelog.html +++ b/resources/releasedocs/changelog.html @@ -141,6 +141,17 @@ hr {

+

4.0.7 -- 2015-02-20

+ +

Bug +

+
    +
  • [SMACK-635] - Typo DNSUtil.init() prevents DNS SRV lookups to fail in some cases +
  • +
  • [SMACK-643] - Smack should not set the service name to the vale of the 'from' attribute of the opening stream element received from the service +
  • +
+

4.0.6 -- 2014-11-23

Bug From 19f96d2c401a1777375825f48d5efacc974832a4 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Fri, 20 Feb 2015 12:15:00 +0100 Subject: [PATCH 16/18] Avoid duplicate provider lookup in ItemProvider This also fixes a programming error, since it could be possible that the provider was removed between the lookup and the usage. --- .../jivesoftware/smackx/pubsub/provider/ItemProvider.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/ItemProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/ItemProvider.java index 42d961faa..17a170cb1 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/ItemProvider.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/ItemProvider.java @@ -57,14 +57,15 @@ public class ItemProvider extends PacketExtensionProvider String payloadElemName = parser.getName(); String payloadNS = parser.getNamespace(); - if (ProviderManager.getExtensionProvider(payloadElemName, payloadNS) == null) + final PacketExtensionProvider extensionProvider = ProviderManager.getExtensionProvider(payloadElemName, payloadNS); + if (extensionProvider == null) { CharSequence payloadText = PacketParserUtils.parseElement(parser, true); return new PayloadItem(id, node, new SimplePayload(payloadElemName, payloadNS, payloadText)); } else { - return new PayloadItem(id, node, PacketParserUtils.parsePacketExtension(payloadElemName, payloadNS, parser)); + return new PayloadItem(id, node, extensionProvider.parse(parser)); } } } From 29bda59617ee00724c436b37498a6e01849c0ad7 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sat, 21 Feb 2015 16:55:30 +0100 Subject: [PATCH 17/18] Log warning if account creation over insecure connection Prepare for SMACK-644. --- .../smackx/iqregister/AccountManager.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/AccountManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/AccountManager.java index b0ec24d08..94d42042c 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/AccountManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqregister/AccountManager.java @@ -22,6 +22,7 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.WeakHashMap; +import java.util.logging.Logger; import org.jivesoftware.smack.Manager; import org.jivesoftware.smack.PacketCollector; @@ -42,6 +43,9 @@ import org.jxmpp.util.XmppStringUtils; * @author Matt Tucker */ public class AccountManager extends Manager { + + private static final Logger LOGGER = Logger.getLogger(AccountManager.class.getName()); + private static final Map INSTANCES = new WeakHashMap(); /** @@ -59,6 +63,35 @@ public class AccountManager extends Manager { return accountManager; } + private static boolean allowSensitiveOperationOverInsecureConnectionDefault = false; + + /** + * The default value used by new account managers for allowSensitiveOperationOverInsecureConnection. + * + * @param allow + * @see #sensitiveOperationOverInsecureConnection(boolean) + * @since 4.1 + */ + public static void sensitiveOperationOverInsecureConnectionDefault(boolean allow) { + AccountManager.allowSensitiveOperationOverInsecureConnectionDefault = allow; + } + + private boolean allowSensitiveOperationOverInsecureConnection = allowSensitiveOperationOverInsecureConnectionDefault; + + /** + * Set to true to allow sensitive operation over insecure connection. + *

+ * Set to true to allow sensitive operations like account creation or password changes over an insecure (e.g. + * unencrypted) connections. + *

+ * + * @param allow + * @since 4.1 + */ + public void sensitiveOperationOverInsecureConnection(boolean allow) { + this.allowSensitiveOperationOverInsecureConnection = allow; + } + private Registration info = null; /** @@ -226,6 +259,11 @@ public class AccountManager extends Manager { */ public void createAccount(String username, String password, Map attributes) throws NoResponseException, XMPPErrorException, NotConnectedException { + if (!connection().isSecureConnection() && !allowSensitiveOperationOverInsecureConnection) { + // TODO throw exception in newer Smack versions + LOGGER.warning("Creating account over insecure connection. " + + "This will throw an exception in future versions of Smack if AccountManager.sensitiveOperationOverInsecureConnection(true) is not set"); + } attributes.put("username", username); attributes.put("password", password); Registration reg = new Registration(attributes); @@ -245,6 +283,11 @@ public class AccountManager extends Manager { * @throws NotConnectedException */ public void changePassword(String newPassword) throws NoResponseException, XMPPErrorException, NotConnectedException { + if (!connection().isSecureConnection() && !allowSensitiveOperationOverInsecureConnection) { + // TODO throw exception in newer Smack versions + LOGGER.warning("Changing password over insecure connection. " + + "This will throw an exception in future versions of Smack if AccountManager.sensitiveOperationOverInsecureConnection(true) is not set"); + } Map map = new HashMap(); map.put("username",XmppStringUtils.parseLocalpart(connection().getUser())); map.put("password",newPassword); From 407f555cbf62df4cb100c7348d1a15598a5eeebd Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sat, 21 Feb 2015 16:57:52 +0100 Subject: [PATCH 18/18] Smack 4.1.0-rc2 --- version.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.gradle b/version.gradle index af5396e11..4ad04179b 100644 --- a/version.gradle +++ b/version.gradle @@ -1,7 +1,7 @@ allprojects { ext { shortVersion = '4.1.0-rc2' - isSnapshot = true + isSnapshot = false jxmppVersion = '0.4.2-beta1' smackMinAndroidSdk = 8 }