From 717090d272ba54a2e0b8bc1be3feb7bed4621c9a Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 5 Jan 2015 21:42:35 +0100 Subject: [PATCH] Rework incoming packet listeners and Roster Differentiate between asynchronous and synchronous ones. Asynchronous are the ones where the invocation order may not be the same as the order in which the stanzas arrived. Since it's no longer guaranteed that when a unit test calls processPacket(stanza) the stanza will be completely processed when the call returns, it was necessary to extend the unit tests (mostly Roster and ChatManager) with a packet listener that waits for his invocation. Since we now also use LinkedHashMaps as Map for the packet listeners (SMACK-531, SMACK-424), adding a packet listeners as last also means that it will be called as last. We exploit this behavior change now in the unit tests. Rename 'recvListeners' to 'syncRecvListeners' in AbstractXMPPConnection. Rename 'rosterInitialized' to 'loaded' in Roster. Add Roster.isLoaded(). Reset 'loaded' to false in Roster.setOfflinePresencesAndResetLoaded() (was setOfflinePresences()). Fixes SMACK-583, SMACK-532, SMACK-424 --- .../smack/bosh/XMPPBOSHConnection.java | 2 +- .../jivesoftware/smack/PacketReaderTest.java | 14 +- .../smack/AbstractXMPPConnection.java | 111 +++++----- .../org/jivesoftware/smack/ChatManager.java | 2 +- .../jivesoftware/smack/PacketListener.java | 2 +- .../java/org/jivesoftware/smack/Roster.java | 79 +++++-- .../jivesoftware/smack/XMPPConnection.java | 59 +++++- .../smack/ChatConnectionTest.java | 193 +++++++----------- .../jivesoftware/smack/DummyConnection.java | 15 +- .../org/jivesoftware/smack/RosterTest.java | 75 ++++--- .../smack/RosterVersioningTest.java | 29 ++- .../test/util/WaitForPacketListener.java | 60 ++++++ .../smackx/debugger/EnhancedDebugger.java | 2 +- .../smackx/debugger/LiteDebugger.java | 2 +- .../smackx/packet/MessageEventTest.java | 2 +- .../smackx/packet/XHTMLExtensionTest.java | 2 +- .../ibb/InBandBytestreamManager.java | 12 +- .../ibb/InBandBytestreamSession.java | 4 +- .../socks5/Socks5BytestreamManager.java | 4 +- .../smackx/caps/EntityCapsManager.java | 4 +- .../smackx/disco/ServiceDiscoveryManager.java | 4 +- .../smackx/iqlast/LastActivityManager.java | 2 +- .../smackx/iqversion/VersionManager.java | 2 +- .../smackx/muc/MultiUserChat.java | 14 +- .../jivesoftware/smackx/pep/PEPManager.java | 4 +- .../jivesoftware/smackx/ping/PingManager.java | 2 +- .../smackx/privacy/PrivacyListManager.java | 2 +- .../org/jivesoftware/smackx/pubsub/Node.java | 12 +- .../receipts/DeliveryReceiptManager.java | 2 +- .../smackx/time/EntityTimeManager.java | 2 +- .../smackx/jingle/JingleManagerTest.java | 2 +- .../smackx/jingleold/JingleManager.java | 2 +- .../smackx/jingleold/JingleSession.java | 10 +- .../smackx/workgroup/agent/AgentRoster.java | 4 +- .../smackx/workgroup/agent/AgentSession.java | 4 +- .../smackx/workgroup/user/Workgroup.java | 2 +- .../smackx/xevent/MessageEventManager.java | 2 +- .../smackx/xroster/RosterExchangeManager.java | 2 +- .../smack/tcp/XMPPTCPConnection.java | 2 +- 39 files changed, 443 insertions(+), 306 deletions(-) create mode 100644 smack-core/src/test/java/org/jivesoftware/smack/test/util/WaitForPacketListener.java 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 edd2d4800..1dd20c3d0 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 @@ -169,7 +169,7 @@ public class XMPPBOSHConnection extends AbstractXMPPConnection { initDebugger(); if (isFirstInitialization) { if (debugger.getReaderListener() != null) { - addPacketListener(debugger.getReaderListener(), null); + addAsyncPacketListener(debugger.getReaderListener(), null); } if (debugger.getWriterListener() != null) { addPacketSendingListener(debugger.getWriterListener(), null); diff --git a/smack-core/src/integration-test/java/org/jivesoftware/smack/PacketReaderTest.java b/smack-core/src/integration-test/java/org/jivesoftware/smack/PacketReaderTest.java index 4a667a27f..d2b36bf28 100644 --- a/smack-core/src/integration-test/java/org/jivesoftware/smack/PacketReaderTest.java +++ b/smack-core/src/integration-test/java/org/jivesoftware/smack/PacketReaderTest.java @@ -107,7 +107,7 @@ public class PacketReaderTest extends SmackTestCase { // Keep number of current listeners int listenersSize = getConnection(0).getPacketListeners().size(); // Add a new listener - getConnection(0).addPacketListener(listener, new MockPacketFilter(true)); + getConnection(0).addAsyncPacketListener(listener, new MockPacketFilter(true)); // Check that the listener was added assertEquals("Listener was not added", listenersSize + 1, getConnection(0).getPacketListeners().size()); @@ -117,7 +117,7 @@ public class PacketReaderTest extends SmackTestCase { getConnection(1).sendPacket(msg); // Remove the listener - getConnection(0).removePacketListener(listener); + getConnection(0).removeAsyncPacketListener(listener); // Check that the number of listeners is correct (i.e. the listener was removed) assertEquals("Listener was not removed", listenersSize, getConnection(0).getPacketListeners().size()); @@ -134,7 +134,7 @@ public class PacketReaderTest extends SmackTestCase { packet.setBody("aloha"); // User1 will always reply to user0 when a message is received - getConnection(1).addPacketListener(new PacketListener() { + getConnection(1).addAsyncPacketListener(new PacketListener() { public void processPacket(Packet packet) { System.out.println(new Date() + " " + packet); @@ -203,8 +203,8 @@ public class PacketReaderTest extends SmackTestCase { } }; - getConnection(0).addPacketListener(listener0, pf0); - getConnection(1).addPacketListener(listener1, pf1); + getConnection(0).addAsyncPacketListener(listener0, pf0); + getConnection(1).addAsyncPacketListener(listener1, pf1); // Check that the listener was added @@ -225,8 +225,8 @@ public class PacketReaderTest extends SmackTestCase { } // Remove the listener - getConnection(0).removePacketListener(listener0); - getConnection(1).removePacketListener(listener1); + getConnection(0).removeAsyncPacketListener(listener0); + getConnection(1).removeAsyncPacketListener(listener1); try { Thread.sleep(300); 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 1633e5526..b8694d255 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/AbstractXMPPConnection.java @@ -22,6 +22,7 @@ import java.io.Writer; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -126,12 +127,14 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { private final Collection collectors = new ConcurrentLinkedQueue(); /** - * List of PacketListeners that will be notified when a new packet was received. + * List of PacketListeners that will be notified synchronously when a new packet was received. */ - private final Map recvListeners = - new HashMap(); + private final Map syncRecvListeners = new LinkedHashMap<>(); - private final Map asyncRecvListeners = new HashMap<>(); + /** + * List of PacketListeners that will be notified asynchronously when a new packet was received. + */ + private final Map asyncRecvListeners = new LinkedHashMap<>(); /** * List of PacketListeners that will be notified when a new packet was sent. @@ -245,6 +248,14 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { // @formatter:on ); + /** + * A executor service used to invoke the callbacks of synchronous packet listeners. We use a executor service to + * decouple incoming stanza processing from callback invocation. It is important that order of callback invocation + * is the same as the order of the incoming stanzas. Therefore we use a single threaded executor service. + */ + private final ExecutorService singleThreadedExecutorService = Executors.newSingleThreadExecutor(new SmackExecutorThreadFactory( + getConnectionCounter(), "Sync PacketListener Callback")); + private Roster roster; /** @@ -593,27 +604,10 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { // changes to the roster. Note: because of this waiting logic, internal // Smack code should be wary about calling the getRoster method, and may need to // access the roster object directly. - // Also only check for rosterInitalized is isRosterLoadedAtLogin is set, otherwise the user + // Also only check for rosterIsLoaded is isRosterLoadedAtLogin is set, otherwise the user // has to manually call Roster.reload() before he can expect a initialized roster. - if (!roster.rosterInitialized && config.isRosterLoadedAtLogin()) { - try { - synchronized (roster) { - long waitTime = getPacketReplyTimeout(); - long start = System.currentTimeMillis(); - while (!roster.rosterInitialized) { - if (waitTime <= 0) { - break; - } - roster.wait(waitTime); - long now = System.currentTimeMillis(); - waitTime -= now - start; - start = now; - } - } - } - catch (InterruptedException ie) { - // Ignore. - } + if (!roster.isLoaded() && config.isRosterLoadedAtLogin()) { + roster.waitUntilLoaded(); } return roster; } @@ -727,19 +721,29 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { @Override public void addPacketListener(PacketListener packetListener, PacketFilter packetFilter) { - if (packetListener == null) { - throw new NullPointerException("Packet listener is null."); - } - ListenerWrapper wrapper = new ListenerWrapper(packetListener, packetFilter); - synchronized (recvListeners) { - recvListeners.put(packetListener, wrapper); - } + addAsyncPacketListener(packetListener, packetFilter); } @Override public boolean removePacketListener(PacketListener packetListener) { - synchronized (recvListeners) { - return recvListeners.remove(packetListener) != null; + return removeAsyncPacketListener(packetListener); + } + + @Override + public void addSyncPacketListener(PacketListener packetListener, PacketFilter packetFilter) { + if (packetListener == null) { + throw new NullPointerException("Packet listener is null."); + } + ListenerWrapper wrapper = new ListenerWrapper(packetListener, packetFilter); + synchronized (syncRecvListeners) { + syncRecvListeners.put(packetListener, wrapper); + } + } + + @Override + public boolean removeSyncPacketListener(PacketListener packetListener) { + synchronized (syncRecvListeners) { + return syncRecvListeners.remove(packetListener) != null; } } @@ -961,7 +965,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { // First handle the async recv listeners. Note that this code is very similar to what follows a few lines below, // the only difference is that asyncRecvListeners is used here and that the packet listeners are started in // their own thread. - Collection listenersToNotify = new LinkedList(); + final Collection listenersToNotify = new LinkedList(); synchronized (asyncRecvListeners) { for (ListenerWrapper listenerWrapper : asyncRecvListeners.values()) { if (listenerWrapper.filterMatches(packet)) { @@ -989,25 +993,33 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { } // Notify the receive listeners interested in the packet - listenersToNotify = new LinkedList(); - synchronized (recvListeners) { - for (ListenerWrapper listenerWrapper : recvListeners.values()) { + listenersToNotify.clear(); + synchronized (syncRecvListeners) { + for (ListenerWrapper listenerWrapper : syncRecvListeners.values()) { if (listenerWrapper.filterMatches(packet)) { listenersToNotify.add(listenerWrapper.getListener()); } } } - for (PacketListener listener : listenersToNotify) { - try { - listener.processPacket(packet); - } catch(NotConnectedException e) { - LOGGER.log(Level.WARNING, "Got not connected exception, aborting", e); - break; - } catch (Exception e) { - LOGGER.log(Level.SEVERE, "Exception in packet listener", e); + // Decouple incoming stanza processing from listener invocation. Unlike async listeners, this uses a single + // threaded executor service and therefore keeps the order. + singleThreadedExecutorService.execute(new Runnable() { + @Override + public void run() { + for (PacketListener listener : listenersToNotify) { + try { + listener.processPacket(packet); + } catch(NotConnectedException e) { + LOGGER.log(Level.WARNING, "Got not connected exception, aborting", e); + break; + } catch (Exception e) { + LOGGER.log(Level.SEVERE, "Exception in packet listener", e); + } + } } - } + }); + } /** @@ -1145,6 +1157,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { executorService.shutdownNow(); cachedExecutorService.shutdown(); removeCallbacksService.shutdownNow(); + singleThreadedExecutorService.shutdownNow(); } catch (Throwable t) { LOGGER.log(Level.WARNING, "finalize() threw trhowable", t); } @@ -1302,14 +1315,14 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { } } finally { - removePacketListener(this); + removeAsyncPacketListener(this); } } }; removeCallbacksService.schedule(new Runnable() { @Override public void run() { - boolean removed = removePacketListener(packetListener); + boolean removed = removeAsyncPacketListener(packetListener); // If the packetListener got removed, then it was never run and // we never received a response, inform the exception callback if (removed && exceptionCallback != null) { @@ -1317,7 +1330,7 @@ public abstract class AbstractXMPPConnection implements XMPPConnection { } } }, timeout, TimeUnit.MILLISECONDS); - addPacketListener(packetListener, replyFilter); + addAsyncPacketListener(packetListener, replyFilter); sendPacket(stanza); } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/ChatManager.java b/smack-core/src/main/java/org/jivesoftware/smack/ChatManager.java index fddfb7b5d..47696ca74 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/ChatManager.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/ChatManager.java @@ -137,7 +137,7 @@ public class ChatManager extends Manager{ // Add a listener for all message packets so that we can deliver // messages to the best Chat instance available. - connection.addPacketListener(new PacketListener() { + connection.addSyncPacketListener(new PacketListener() { public void processPacket(Packet packet) { Message message = (Message) packet; Chat chat; diff --git a/smack-core/src/main/java/org/jivesoftware/smack/PacketListener.java b/smack-core/src/main/java/org/jivesoftware/smack/PacketListener.java index 22c2471e0..190913791 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/PacketListener.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/PacketListener.java @@ -33,7 +33,7 @@ import org.jivesoftware.smack.packet.Packet; * org.jivesoftware.smack.filter.PacketFilter)} *

* - * @see XMPPConnection#addPacketListener(PacketListener, org.jivesoftware.smack.filter.PacketFilter) + * @see XMPPConnection#addAsyncPacketListener(PacketListener, org.jivesoftware.smack.filter.PacketFilter) * @author Matt Tucker */ public interface PacketListener { diff --git a/smack-core/src/main/java/org/jivesoftware/smack/Roster.java b/smack-core/src/main/java/org/jivesoftware/smack/Roster.java index 308e86c48..b01fe0a0a 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/Roster.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/Roster.java @@ -85,9 +85,11 @@ public class Roster { private final List unfiledEntries = new CopyOnWriteArrayList(); private final List rosterListeners = new CopyOnWriteArrayList(); private final Map> presenceMap = new ConcurrentHashMap>(); + // The roster is marked as initialized when at least a single roster packet // has been received and processed. - boolean rosterInitialized = false; + private boolean loaded = false; + private final PresencePacketListener presencePacketListener = new PresencePacketListener(); private SubscriptionMode subscriptionMode = getDefaultSubscriptionMode(); @@ -124,10 +126,13 @@ public class Roster { Roster(final XMPPConnection connection) { this.connection = connection; rosterStore = connection.getRosterStore(); + + // Note that we use sync packet listeners because RosterListeners should be invoked in the same order as the + // roster stanzas arrive. // Listen for any roster packets. - connection.addPacketListener(new RosterPushListener(), ROSTER_PUSH_FILTER); + connection.addSyncPacketListener(new RosterPushListener(), ROSTER_PUSH_FILTER); // Listen for any presence packets. - connection.addPacketListener(presencePacketListener, PRESENCE_PACKET_FILTER); + connection.addSyncPacketListener(presencePacketListener, PRESENCE_PACKET_FILTER); // Listen for connection events connection.addConnectionListener(new AbstractConnectionListener() { @@ -151,22 +156,12 @@ public class Roster { public void connectionClosed() { // Changes the presence available contacts to unavailable - try { - setOfflinePresences(); - } - catch (NotConnectedException e) { - LOGGER.log(Level.SEVERE, "Not connected exception" ,e); - } + setOfflinePresencesAndResetLoaded(); } public void connectionClosedOnError(Exception e) { // Changes the presence available contacts to unavailable - try { - setOfflinePresences(); - } - catch (NotConnectedException e1) { - LOGGER.log(Level.SEVERE, "Not connected exception" ,e); - } + setOfflinePresencesAndResetLoaded(); } }); @@ -238,6 +233,40 @@ public class Roster { }); } + protected boolean waitUntilLoaded() { + long waitTime = connection.getPacketReplyTimeout(); + long start = System.currentTimeMillis(); + while (!loaded) { + if (waitTime <= 0) { + break; + } + try { + synchronized (this) { + if (!loaded) { + wait(waitTime); + } + } + } + catch (InterruptedException e) { + LOGGER.log(Level.FINE, "spurious interrupt", e); + } + long now = System.currentTimeMillis(); + waitTime -= now - start; + start = now; + } + return isLoaded(); + } + + /** + * Check if the roster is loaded. + * + * @return true if the roster is loaded. + * @since 4.1 + */ + public boolean isLoaded() { + return loaded; + } + /** * Adds a listener to this roster. The listener will be fired anytime one or more * changes to the roster are pushed from the server. @@ -696,7 +725,7 @@ public class Roster { * to offline. * @throws NotConnectedException */ - private void setOfflinePresences() throws NotConnectedException { + private void setOfflinePresencesAndResetLoaded() { Presence packetUnavailable; for (String user : presenceMap.keySet()) { Map resources = presenceMap.get(user); @@ -704,10 +733,18 @@ public class Roster { for (String resource : resources.keySet()) { packetUnavailable = new Presence(Presence.Type.unavailable); packetUnavailable.setFrom(user + "/" + resource); - presencePacketListener.processPacket(packetUnavailable); + try { + presencePacketListener.processPacket(packetUnavailable); + } + catch (NotConnectedException e) { + throw new IllegalStateException( + "presencePakcetListener should never throw a NotConnectedException when processPacket is called with a presence of type unavailable", + e); + } } } } + loaded = false; } /** @@ -719,8 +756,8 @@ public class Roster { * @param updatedEntries the collection of address of the updated contacts. * @param deletedEntries the collection of address of the deleted contacts. */ - private void fireRosterChangedEvent(Collection addedEntries, Collection updatedEntries, - Collection deletedEntries) { + private void fireRosterChangedEvent(final Collection addedEntries, final Collection updatedEntries, + final Collection deletedEntries) { for (RosterListener listener : rosterListeners) { if (!addedEntries.isEmpty()) { listener.entriesAdded(addedEntries); @@ -739,7 +776,7 @@ public class Roster { * * @param presence the presence change. */ - private void fireRosterPresenceEvent(Presence presence) { + private void fireRosterPresenceEvent(final Presence presence) { for (RosterListener listener : rosterListeners) { listener.presenceChanged(presence); } @@ -1068,7 +1105,7 @@ public class Roster { } } - rosterInitialized = true; + loaded = true; synchronized (Roster.this) { Roster.this.notifyAll(); } diff --git a/smack-core/src/main/java/org/jivesoftware/smack/XMPPConnection.java b/smack-core/src/main/java/org/jivesoftware/smack/XMPPConnection.java index 5a3eb9d12..a8daeccd8 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/XMPPConnection.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/XMPPConnection.java @@ -246,16 +246,20 @@ public interface XMPPConnection { public void removePacketCollector(PacketCollector collector); /** - * Registers a packet listener with this connection. A packet listener will be invoked only - * when an incoming packet is received. A packet filter determines - * which packets will be delivered to the listener. If the same packet listener - * is added again with a different filter, only the new filter will be used. - * - * NOTE: If you want get a similar callback for outgoing packets, see {@link #addPacketInterceptor(PacketListener, PacketFilter)}. - * + * Registers a packet listener with this connection. + *

+ * This method has been deprecated. It is important to differentiate between using an asynchronous packet listener + * (preferred where possible) and a synchronous packet lister. Refer + * {@link #addAsyncPacketListener(PacketListener, PacketFilter)} and + * {@link #addSyncPacketListener(PacketListener, PacketFilter)} for more information. + *

+ * * @param packetListener the packet listener to notify of new received packets. - * @param packetFilter the packet filter to use. + * @param packetFilter the packet filter to use. + * @deprecated use {@link #addAsyncPacketListener(PacketListener, PacketFilter)} or + * {@link #addSyncPacketListener(PacketListener, PacketFilter)}. */ + @Deprecated public void addPacketListener(PacketListener packetListener, PacketFilter packetFilter); /** @@ -263,22 +267,54 @@ public interface XMPPConnection { * * @param packetListener the packet listener to remove. * @return true if the packet listener was removed + * @deprecated use {@link #removeAsyncPacketListener(PacketListener)} or {@link #removeSyncPacketListener(PacketListener)}. */ + @Deprecated public boolean removePacketListener(PacketListener packetListener); + /** + * Registers a synchronous packet listener with this connection. A packet listener will be invoked only when + * an incoming packet is received. A packet filter determines which packets will be delivered to the listener. If + * the same packet listener is added again with a different filter, only the new filter will be used. + *

+ * Important: This packet listeners will be called in the same single thread that processes all + * incoming stanzas. Only use this kind of packet filter if it does not perform any XMPP activity that waits for a + * response. Consider using {@link #addAsyncPacketListener(PacketListener, PacketFilter)} when possible, i.e. when + * the invocation order doesn't have to be the same as the order of the arriving packets. If the order of the + * arriving packets, consider using a {@link PacketCollector} when possible. + *

+ * + * @param packetListener the packet listener to notify of new received packets. + * @param packetFilter the packet filter to use. + * @see {@link #addPacketInterceptor(PacketListener, PacketFilter)} for a similar callback for outgoing stanzas. + * @since 4.1 + */ + public void addSyncPacketListener(PacketListener packetListener, PacketFilter packetFilter); + + /** + * Removes a packet listener for received packets from this connection. + * + * @param packetListener the packet listener to remove. + * @return true if the packet listener was removed + * @since 4.1 + */ + public boolean removeSyncPacketListener(PacketListener packetListener); + /** * Registers an asynchronous packet listener with this connection. A packet listener will be invoked only * when an incoming packet is received. A packet filter determines which packets will be delivered to the listener. * If the same packet listener is added again with a different filter, only the new filter will be used. *

- * Unlike {@link #addPacketListener(PacketListener, PacketFilter)} packet listeners added with this method will be + * Unlike {@link #addAsyncPacketListener(PacketListener, PacketFilter)} packet listeners added with this method will be * invoked asynchronously in their own thread. Use this method if the order of the packet listeners must not depend * on the order how the stanzas where received. *

* * @param packetListener the packet listener to notify of new received packets. * @param packetFilter the packet filter to use. - */ + * @see {@link #addPacketInterceptor(PacketListener, PacketFilter)} for a similar callback for outgoing stanzas. + * @since 4.1 + */ public void addAsyncPacketListener(PacketListener packetListener, PacketFilter packetFilter); /** @@ -286,6 +322,7 @@ public interface XMPPConnection { * * @param packetListener the packet listener to remove. * @return true if the packet listener was removed + * @since 4.1 */ public boolean removeAsyncPacketListener(PacketListener packetListener); @@ -316,7 +353,7 @@ public interface XMPPConnection { * will be delivered to the interceptor. * *

- * NOTE: For a similar functionality on incoming packets, see {@link #addPacketListener(PacketListener, PacketFilter)}. + * NOTE: For a similar functionality on incoming packets, see {@link #addAsyncPacketListener(PacketListener, PacketFilter)}. * * @param packetInterceptor the packet interceptor to notify of packets about to be sent. * @param packetFilter the packet filter to use. diff --git a/smack-core/src/test/java/org/jivesoftware/smack/ChatConnectionTest.java b/smack-core/src/test/java/org/jivesoftware/smack/ChatConnectionTest.java index 9ade29490..6f8658ebf 100644 --- a/smack-core/src/test/java/org/jivesoftware/smack/ChatConnectionTest.java +++ b/smack-core/src/test/java/org/jivesoftware/smack/ChatConnectionTest.java @@ -27,102 +27,108 @@ import org.jivesoftware.smack.ChatManager.MatchMode; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Message.Type; import org.jivesoftware.smack.packet.Packet; +import org.jivesoftware.smack.test.util.WaitForPacketListener; import org.junit.After; import org.junit.Before; import org.junit.Test; public class ChatConnectionTest { - private DummyConnection connection; + private DummyConnection dc; + private ChatManager cm; + private TestChatManagerListener listener; + private WaitForPacketListener waitListener; @Before public void setUp() throws Exception { - connection = getConnection(); + // Defaults + ChatManager.setDefaultIsNormalIncluded(true); + ChatManager.setDefaultMatchMode(MatchMode.BARE_JID); + + dc = DummyConnection.newConnectedDummyConnection(); + cm = ChatManager.getInstanceFor(dc); + listener = new TestChatManagerListener(); + cm.addChatListener(listener); + waitListener = new WaitForPacketListener(); + dc.addSyncPacketListener(waitListener, null); } @After public void tearDown() throws Exception { - if (connection != null) - connection.disconnect(); + if (dc != null) { + dc.disconnect(); + } } @Test - public void validateDefaultSetNormalIncluded() { + public void validateDefaultSetNormalIncludedFalse() { ChatManager.setDefaultIsNormalIncluded(false); - assertFalse(ChatManager.getInstanceFor(getConnection()).isNormalIncluded()); - + assertFalse(ChatManager.getInstanceFor(new DummyConnection()).isNormalIncluded()); + } + + @Test + public void validateDefaultSetNormalIncludedTrue() { ChatManager.setDefaultIsNormalIncluded(true); - assertTrue(ChatManager.getInstanceFor(getConnection()).isNormalIncluded()); + assertTrue(ChatManager.getInstanceFor(new DummyConnection()).isNormalIncluded()); } - + @Test - public void validateDefaultSetMatchMode() { + public void validateDefaultSetMatchModeNone() { ChatManager.setDefaultMatchMode(MatchMode.NONE); - assertEquals(MatchMode.NONE, ChatManager.getInstanceFor(getConnection()).getMatchMode()); - + assertEquals(MatchMode.NONE, ChatManager.getInstanceFor(new DummyConnection()).getMatchMode()); + } + + @Test + public void validateDefaultSetMatchModeBareJid() { ChatManager.setDefaultMatchMode(MatchMode.BARE_JID); - assertEquals(MatchMode.BARE_JID, ChatManager.getInstanceFor(getConnection()).getMatchMode()); + assertEquals(MatchMode.BARE_JID, ChatManager.getInstanceFor(new DummyConnection()).getMatchMode()); } @Test - public void validateMessageTypeWithDefaults() { - DummyConnection dc = getConnection(); - ChatManager cm = ChatManager.getInstanceFor(dc); - TestChatManagerListener listener = new TestChatManagerListener(); - cm.addChatListener(listener); + public void validateMessageTypeWithDefaults1() { Message incomingChat = createChatPacket("134", true); incomingChat.setType(Type.chat); - processServerMessage(incomingChat, dc); + processServerMessage(incomingChat); assertNotNull(listener.getNewChat()); + } - dc = getConnection(); - cm = ChatManager.getInstanceFor(dc); - listener = new TestChatManagerListener(); - cm.addChatListener(listener); - incomingChat = createChatPacket("134", true); + @Test + public void validateMessageTypeWithDefaults2() { + Message incomingChat = createChatPacket("134", true); incomingChat.setType(Type.normal); - processServerMessage(incomingChat, dc); + processServerMessage(incomingChat); assertNotNull(listener.getNewChat()); - - dc = getConnection(); - cm = ChatManager.getInstanceFor(dc); - listener = new TestChatManagerListener(); - cm.addChatListener(listener); - incomingChat = createChatPacket("134", true); + } + @Test + public void validateMessageTypeWithDefaults3() { + Message incomingChat = createChatPacket("134", true); incomingChat.setType(Type.groupchat); - processServerMessage(incomingChat, dc); - assertNull(listener.getNewChat()); - - dc = getConnection(); - cm = ChatManager.getInstanceFor(dc); - listener = new TestChatManagerListener(); - cm.addChatListener(listener); - incomingChat = createChatPacket("134", true); - incomingChat.setType(Type.headline); - processServerMessage(incomingChat, dc); + processServerMessage(incomingChat); assertNull(listener.getNewChat()); } - + @Test - public void validateMessageTypeWithNoNormal() { - DummyConnection dc = getConnection(); - ChatManager cm = ChatManager.getInstanceFor(dc); + public void validateMessageTypeWithDefaults4() { + Message incomingChat = createChatPacket("134", true); + incomingChat.setType(Type.headline); + assertNull(listener.getNewChat()); + } + + @Test + public void validateMessageTypeWithNoNormal1() { cm.setNormalIncluded(false); - TestChatManagerListener listener = new TestChatManagerListener(); - cm.addChatListener(listener); Message incomingChat = createChatPacket("134", true); incomingChat.setType(Type.chat); - processServerMessage(incomingChat, dc); + processServerMessage(incomingChat); assertNotNull(listener.getNewChat()); + } - dc = getConnection(); - cm = ChatManager.getInstanceFor(dc); + @Test + public void validateMessageTypeWithNoNormal2() { cm.setNormalIncluded(false); - listener = new TestChatManagerListener(); - cm.addChatListener(listener); - incomingChat = createChatPacket("134", true); + Message incomingChat = createChatPacket("134", true); incomingChat.setType(Type.normal); - processServerMessage(incomingChat, dc); + processServerMessage(incomingChat); assertNull(listener.getNewChat()); } @@ -130,65 +136,59 @@ public class ChatConnectionTest { @Test public void chatMatchedOnJIDWhenNoThreadBareMode() { // MatchMode.BARE_JID is the default, so setting required. - DummyConnection con = getConnection(); TestMessageListener msgListener = new TestMessageListener(); TestChatManagerListener listener = new TestChatManagerListener(msgListener); - ChatManager cm = ChatManager.getInstanceFor(con); cm.addChatListener(listener); Packet incomingChat = createChatPacket(null, true); - processServerMessage(incomingChat, con); + processServerMessage(incomingChat); Chat newChat = listener.getNewChat(); assertNotNull(newChat); // Should match on chat with full jid incomingChat = createChatPacket(null, true); - processServerMessage(incomingChat, con); + processServerMessage(incomingChat); assertEquals(2, msgListener.getNumMessages()); // Should match on chat with bare jid incomingChat = createChatPacket(null, false); - processServerMessage(incomingChat, con); + processServerMessage(incomingChat); assertEquals(3, msgListener.getNumMessages()); } @Test public void chatMatchedOnJIDWhenNoThreadJidMode() { - DummyConnection con = getConnection(); TestMessageListener msgListener = new TestMessageListener(); TestChatManagerListener listener = new TestChatManagerListener(msgListener); - ChatManager cm = ChatManager.getInstanceFor(con); cm.setMatchMode(MatchMode.SUPPLIED_JID); cm.addChatListener(listener); Packet incomingChat = createChatPacket(null, true); - processServerMessage(incomingChat, con); + processServerMessage(incomingChat); Chat newChat = listener.getNewChat(); assertNotNull(newChat); cm.removeChatListener(listener); // Should match on chat with full jid incomingChat = createChatPacket(null, true); - processServerMessage(incomingChat, con); + processServerMessage(incomingChat); assertEquals(2, msgListener.getNumMessages()); // Should not match on chat with bare jid TestChatManagerListener listener2 = new TestChatManagerListener(); cm.addChatListener(listener2); incomingChat = createChatPacket(null, false); - processServerMessage(incomingChat, con); + processServerMessage(incomingChat); assertEquals(2, msgListener.getNumMessages()); assertNotNull(listener2.getNewChat()); } @Test public void chatMatchedOnJIDWhenNoThreadNoneMode() { - DummyConnection con = getConnection(); TestMessageListener msgListener = new TestMessageListener(); TestChatManagerListener listener = new TestChatManagerListener(msgListener); - ChatManager cm = ChatManager.getInstanceFor(con); cm.setMatchMode(MatchMode.NONE); cm.addChatListener(listener); Packet incomingChat = createChatPacket(null, true); - processServerMessage(incomingChat, con); + processServerMessage(incomingChat); Chat newChat = listener.getNewChat(); assertNotNull(newChat); assertEquals(1, msgListener.getNumMessages()); @@ -198,7 +198,7 @@ public class ChatConnectionTest { TestChatManagerListener listener2 = new TestChatManagerListener(); cm.addChatListener(listener2); incomingChat = createChatPacket(null, true); - processServerMessage(incomingChat, con); + processServerMessage(incomingChat); assertEquals(1, msgListener.getNumMessages()); assertNotNull(newChat); cm.removeChatListener(listener2); @@ -207,7 +207,7 @@ public class ChatConnectionTest { TestChatManagerListener listener3 = new TestChatManagerListener(); cm.addChatListener(listener3); incomingChat = createChatPacket(null, false); - processServerMessage(incomingChat, con); + processServerMessage(incomingChat); assertEquals(1, msgListener.getNumMessages()); assertNotNull(listener3.getNewChat()); } @@ -218,9 +218,6 @@ public class ChatConnectionTest { */ @Test public void chatFoundWhenNoThreadFullJid() { - TestChatManagerListener listener = new TestChatManagerListener(); - ChatManager cm = ChatManager.getInstanceFor(connection); - cm.addChatListener(listener); Chat outgoing = cm.createChat("you@testserver", null); Packet incomingChat = createChatPacket(null, true); @@ -237,9 +234,6 @@ public class ChatConnectionTest { */ @Test public void chatFoundWhenNoThreadBaseJid() { - TestChatManagerListener listener = new TestChatManagerListener(); - ChatManager cm = ChatManager.getInstanceFor(connection); - cm.addChatListener(listener); Chat outgoing = cm.createChat("you@testserver", null); Packet incomingChat = createChatPacket(null, false); @@ -256,9 +250,6 @@ public class ChatConnectionTest { */ @Test public void chatFoundWithSameThreadFullJid() { - TestChatManagerListener listener = new TestChatManagerListener(); - ChatManager cm = ChatManager.getInstanceFor(connection); - cm.addChatListener(listener); Chat outgoing = cm.createChat("you@testserver", null); Packet incomingChat = createChatPacket(outgoing.getThreadID(), true); @@ -275,9 +266,6 @@ public class ChatConnectionTest { */ @Test public void chatFoundWithSameThreadBaseJid() { - TestChatManagerListener listener = new TestChatManagerListener(); - ChatManager cm = ChatManager.getInstanceFor(connection); - cm.addChatListener(listener); Chat outgoing = cm.createChat("you@testserver", null); Packet incomingChat = createChatPacket(outgoing.getThreadID(), false); @@ -294,9 +282,6 @@ public class ChatConnectionTest { */ @Test public void chatNotFoundWithDiffThreadBaseJid() { - TestChatManagerListener listener = new TestChatManagerListener(); - ChatManager cm = ChatManager.getInstanceFor(connection); - cm.addChatListener(listener); Chat outgoing = cm.createChat("you@testserver", null); Packet incomingChat = createChatPacket(outgoing.getThreadID() + "ff", false); @@ -313,9 +298,6 @@ public class ChatConnectionTest { */ @Test public void chatNotFoundWithDiffThreadFullJid() { - TestChatManagerListener listener = new TestChatManagerListener(); - ChatManager cm = ChatManager.getInstanceFor(connection); - cm.addChatListener(listener); Chat outgoing = cm.createChat("you@testserver", null); Packet incomingChat = createChatPacket(outgoing.getThreadID() + "ff", true); @@ -328,11 +310,7 @@ public class ChatConnectionTest { @Test public void chatNotMatchedWithTypeNormal() { - TestChatManagerListener listener = new TestChatManagerListener(); - DummyConnection con = getConnection(); - ChatManager cm = ChatManager.getInstanceFor(con); cm.setNormalIncluded(false); - cm.addChatListener(listener); Message incomingChat = createChatPacket(null, false); incomingChat.setType(Type.normal); @@ -341,50 +319,26 @@ public class ChatConnectionTest { assertNull(listener.getNewChat()); } - @SuppressWarnings("unused") - private ChatManager getChatManager(boolean includeNormal, MatchMode mode) { - ChatManager cm = ChatManager.getInstanceFor(getConnection()); - cm.setMatchMode(mode); - cm.setNormalIncluded(includeNormal); - return cm; - } - - private DummyConnection getConnection() { - DummyConnection con = new DummyConnection(); - - try { - con.connect(); - con.login(); - } catch (Exception e) { - // No need for handling in a dummy connection. - } - return con; - } private Message createChatPacket(final String threadId, final boolean isFullJid) { Message chatMsg = new Message("me@testserver", Message.Type.chat); chatMsg.setBody("the body message - " + System.currentTimeMillis()); chatMsg.setFrom("you@testserver" + (isFullJid ? "/resource" : "")); - - if (threadId != null) - chatMsg.setThread(threadId); + chatMsg.setThread(threadId); return chatMsg; } private void processServerMessage(Packet incomingChat) { - processServerMessage(incomingChat, connection); - } - - private void processServerMessage(Packet incomingChat, DummyConnection con) { - TestChatServer chatServer = new TestChatServer(incomingChat, con); + TestChatServer chatServer = new TestChatServer(incomingChat, dc); chatServer.start(); try { chatServer.join(); } catch (InterruptedException e) { fail(); } + waitListener.waitAndReset(); } - class TestChatManagerListener implements ChatManagerListener { + class TestChatManagerListener extends WaitForPacketListener implements ChatManagerListener { private Chat newChat; private ChatMessageListener listener; @@ -401,6 +355,7 @@ public class ChatConnectionTest { if (listener != null) newChat.addMessageListener(listener); + reportInvoked(); } public Chat getNewChat() { diff --git a/smack-core/src/test/java/org/jivesoftware/smack/DummyConnection.java b/smack-core/src/test/java/org/jivesoftware/smack/DummyConnection.java index 8a8503b30..eebeeeb34 100644 --- a/smack-core/src/test/java/org/jivesoftware/smack/DummyConnection.java +++ b/smack-core/src/test/java/org/jivesoftware/smack/DummyConnection.java @@ -17,6 +17,7 @@ package org.jivesoftware.smack; +import java.io.IOException; import java.util.Date; import java.util.Random; import java.util.concurrent.BlockingQueue; @@ -189,7 +190,7 @@ public class DummyConnection extends AbstractXMPPConnection { */ @SuppressWarnings("unchecked") public

P getSentPacket() throws InterruptedException { - return (P) queue.poll(); + return (P) queue.poll(5, TimeUnit.MINUTES); } /** @@ -221,6 +222,18 @@ public class DummyConnection extends AbstractXMPPConnection { invokePacketCollectorsAndNotifyRecvListeners(packet); } + public static DummyConnection newConnectedDummyConnection() { + DummyConnection dummyConnection = new DummyConnection(); + try { + dummyConnection.connect(); + dummyConnection.login(); + } + catch (SmackException | IOException | XMPPException e) { + throw new IllegalStateException(e); + } + return dummyConnection; + } + public static class DummyConnectionConfiguration extends ConnectionConfiguration { protected DummyConnectionConfiguration(Builder builder) { super(builder); diff --git a/smack-core/src/test/java/org/jivesoftware/smack/RosterTest.java b/smack-core/src/test/java/org/jivesoftware/smack/RosterTest.java index a3b1b7dc1..613a0dddc 100644 --- a/smack-core/src/test/java/org/jivesoftware/smack/RosterTest.java +++ b/smack-core/src/test/java/org/jivesoftware/smack/RosterTest.java @@ -26,6 +26,7 @@ import static org.junit.Assert.fail; import java.util.Collection; import java.util.Collections; +import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import org.jivesoftware.smack.packet.IQ; @@ -36,6 +37,7 @@ import org.jivesoftware.smack.packet.IQ.Type; import org.jivesoftware.smack.packet.RosterPacket.Item; import org.jivesoftware.smack.packet.RosterPacket.ItemType; import org.jivesoftware.smack.test.util.TestUtils; +import org.jivesoftware.smack.test.util.WaitForPacketListener; import org.jivesoftware.smack.util.PacketParserUtils; import org.junit.After; import org.junit.Before; @@ -52,6 +54,7 @@ import org.xmlpull.v1.XmlPullParser; public class RosterTest { private DummyConnection connection; + private Roster roster; private TestRosterListener rosterListener; @Before @@ -63,7 +66,9 @@ public class RosterTest { connection.connect(); connection.login(); rosterListener = new TestRosterListener(); - connection.getRoster().addRosterListener(rosterListener); + roster = connection.getRoster(); + roster.addRosterListener(rosterListener); + connection.setPacketReplyTimeout(1000 * 60 * 5); } @After @@ -83,19 +88,17 @@ public class RosterTest { * RFC3921: Retrieving One's Roster on Login. */ - @Test(timeout=5000) + @Test public void testSimpleRosterInitialization() throws Exception { - // Setup - final Roster roster = connection.getRoster(); assertNotNull("Can't get the roster from the provided connection!", roster); - assertFalse("Roster shouldn't be already initialized!", - roster.rosterInitialized); + assertFalse("Roster shouldn't be already loaded!", + roster.isLoaded()); // Perform roster initialization - initRoster(connection, roster); + initRoster(); // Verify roster - assertTrue("Roster can't be initialized!", roster.rosterInitialized); + assertTrue("Roster can't be loaded!", roster.waitUntilLoaded()); verifyRomeosEntry(roster.getEntry("romeo@example.net")); verifyMercutiosEntry(roster.getEntry("mercutio@example.com")); verifyBenvoliosEntry(roster.getEntry("benvolio@example.net")); @@ -121,7 +124,7 @@ public class RosterTest { * RFC3921: Adding a Roster Item. */ - @Test(timeout=5000) + @Test public void testAddRosterItem() throws Throwable { // Constants for the new contact final String contactJID = "nurse@example.com"; @@ -129,9 +132,8 @@ public class RosterTest { final String[] contactGroup = {"Servants"}; // Setup - final Roster roster = connection.getRoster(); assertNotNull("Can't get the roster from the provided connection!", roster); - initRoster(connection, roster); + initRoster(); rosterListener.reset(); // Adding the new roster item @@ -161,6 +163,7 @@ public class RosterTest { if (exception != null) { throw exception; } + rosterListener.waitUntilInvocationOrTimeout(); // Verify the roster entry of the new contact final RosterEntry addedEntry = roster.getEntry(contactJID); @@ -192,7 +195,7 @@ public class RosterTest { * RFC3921: Updating a Roster Item. */ - @Test(timeout=5000) + @Test public void testUpdateRosterItem() throws Throwable { // Constants for the updated contact final String contactJID = "romeo@example.net"; @@ -200,9 +203,8 @@ public class RosterTest { final String[] contactGroups = {"Friends", "Lovers"}; // Setup - final Roster roster = connection.getRoster(); assertNotNull("Can't get the roster from the provided connection!", roster); - initRoster(connection, roster); + initRoster(); rosterListener.reset(); // Updating the roster item @@ -235,6 +237,7 @@ public class RosterTest { if (exception != null) { throw exception; } + rosterListener.waitUntilInvocationOrTimeout(); // Verify the roster entry of the updated contact final RosterEntry addedEntry = roster.getEntry(contactJID); @@ -267,15 +270,14 @@ public class RosterTest { * RFC3921: Deleting a Roster Item. */ - @Test(timeout=5000) + @Test public void testDeleteRosterItem() throws Throwable { // The contact which should be deleted final String contactJID = "romeo@example.net"; // Setup - final Roster roster = connection.getRoster(); assertNotNull("Can't get the roster from the provided connection!", roster); - initRoster(connection, roster); + initRoster(); rosterListener.reset(); // Delete a roster item @@ -296,6 +298,7 @@ public class RosterTest { if (exception != null) { throw exception; } + rosterListener.waitUntilInvocationOrTimeout(); // Verify final RosterEntry deletedEntry = roster.getEntry(contactJID); @@ -314,10 +317,9 @@ public class RosterTest { * RFC3921bis-03: Roster Push. */ - @Test(timeout=5000) + @Test public void testSimpleRosterPush() throws Throwable { final String contactJID = "nurse@example.com"; - final Roster roster = connection.getRoster(); assertNotNull("Can't get the roster from the provided connection!", roster); final StringBuilder sb = new StringBuilder(); sb.append(""); final XmlPullParser parser = TestUtils.getIQParser(sb.toString()); final IQ rosterPush = PacketParserUtils.parse(parser, connection); - initRoster(connection, roster); + initRoster(); rosterListener.reset(); // Simulate receiving the roster push connection.processPacket(rosterPush); + rosterListener.waitUntilInvocationOrTimeout(); // Verify the roster entry of the new contact final RosterEntry addedEntry = roster.getEntry(contactJID); @@ -358,7 +361,7 @@ public class RosterTest { * * @see RFC 6121, Section 2.1.6 */ - @Test(timeout=5000) + @Test public void testIgnoreInvalidFrom() { RosterPacket packet = new RosterPacket(); packet.setType(Type.set); @@ -366,8 +369,11 @@ public class RosterTest { packet.setFrom("mallory@example.com"); packet.addRosterItem(new Item("spam@example.com", "Cool products!")); + WaitForPacketListener waitForPacketListener = new WaitForPacketListener(); + connection.addAsyncPacketListener(waitForPacketListener, null); // Simulate receiving the roster push connection.processPacket(packet); + waitForPacketListener.waitUntilInvocationOrTimeout(); assertNull("Contact was added to roster", connection.getRoster().getEntry("spam@example.com")); } @@ -386,9 +392,8 @@ public class RosterTest { final String[] contactGroup = {""}; // Setup - final Roster roster = connection.getRoster(); assertNotNull("Can't get the roster from the provided connection!", roster); - initRoster(connection, roster); + initRoster(); rosterListener.reset(); // Adding the new roster item @@ -416,6 +421,7 @@ public class RosterTest { if (exception != null) { throw exception; } + rosterListener.waitUntilInvocationOrTimeout(); // Verify the roster entry of the new contact final RosterEntry addedEntry = roster.getEntry(contactJID); @@ -445,10 +451,9 @@ public class RosterTest { * * @see SMACK-294 */ - @Test(timeout=5000) + @Test public void testEmptyGroupRosterPush() throws Throwable { final String contactJID = "nurse@example.com"; - final Roster roster = connection.getRoster(); assertNotNull("Can't get the roster from the provided connection!", roster); final StringBuilder sb = new StringBuilder(); sb.append(""); final XmlPullParser parser = TestUtils.getIQParser(sb.toString()); final IQ rosterPush = PacketParserUtils.parse(parser, connection); - initRoster(connection, roster); + initRoster(); rosterListener.reset(); // Simulate receiving the roster push connection.processPacket(rosterPush); + rosterListener.waitUntilInvocationOrTimeout(); // Verify the roster entry of the new contact final RosterEntry addedEntry = roster.getEntry(contactJID); @@ -520,7 +526,7 @@ public class RosterTest { * @param roster the roster (or buddy list) which should be initialized. * @throws SmackException */ - public static void initRoster(DummyConnection connection, Roster roster) throws InterruptedException, XMPPException, SmackException { + private void initRoster() throws InterruptedException, XMPPException, SmackException { roster.reload(); while (true) { final Packet sentPacket = connection.getSentPacket(); @@ -558,6 +564,8 @@ public class RosterTest { break; } } + roster.waitUntilLoaded(); + rosterListener.waitUntilInvocationOrTimeout(); } /** @@ -687,10 +695,10 @@ public class RosterTest { /** * This class can be used to check if the RosterListener was invoked. */ - public static class TestRosterListener implements RosterListener { - private CopyOnWriteArrayList addressesAdded = new CopyOnWriteArrayList(); - private CopyOnWriteArrayList addressesDeleted = new CopyOnWriteArrayList(); - private CopyOnWriteArrayList addressesUpdated = new CopyOnWriteArrayList(); + public static class TestRosterListener extends WaitForPacketListener implements RosterListener { + private final List addressesAdded = new CopyOnWriteArrayList<>(); + private final List addressesDeleted = new CopyOnWriteArrayList<>(); + private final List addressesUpdated = new CopyOnWriteArrayList<>(); public synchronized void entriesAdded(Collection addresses) { addressesAdded.addAll(addresses); @@ -699,6 +707,7 @@ public class RosterTest { System.out.println("Roster entry for " + address + " added."); } } + reportInvoked(); } public synchronized void entriesDeleted(Collection addresses) { @@ -708,6 +717,7 @@ public class RosterTest { System.out.println("Roster entry for " + address + " deleted."); } } + reportInvoked(); } public synchronized void entriesUpdated(Collection addresses) { @@ -717,12 +727,14 @@ public class RosterTest { System.out.println("Roster entry for " + address + " updated."); } } + reportInvoked(); } public void presenceChanged(Presence presence) { if (SmackConfiguration.DEBUG_ENABLED) { System.out.println("Roster presence changed: " + presence.toXML()); } + reportInvoked(); } /** @@ -756,6 +768,7 @@ public class RosterTest { * Reset the lists of added, deleted or updated items. */ public synchronized void reset() { + super.reset(); addressesAdded.clear(); addressesDeleted.clear(); addressesUpdated.clear(); diff --git a/smack-core/src/test/java/org/jivesoftware/smack/RosterVersioningTest.java b/smack-core/src/test/java/org/jivesoftware/smack/RosterVersioningTest.java index dd9e9dae2..2b12e08cf 100644 --- a/smack-core/src/test/java/org/jivesoftware/smack/RosterVersioningTest.java +++ b/smack-core/src/test/java/org/jivesoftware/smack/RosterVersioningTest.java @@ -27,6 +27,7 @@ import java.util.Collection; import java.util.HashSet; import org.jivesoftware.smack.ConnectionConfiguration.Builder; +import org.jivesoftware.smack.RosterTest.TestRosterListener; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IQ.Type; import org.jivesoftware.smack.packet.Packet; @@ -53,15 +54,14 @@ import org.junit.rules.TemporaryFolder; public class RosterVersioningTest { private DummyConnection connection; + private Roster roster; + private TestRosterListener rosterListener; @Rule public TemporaryFolder tmpFolder = new TemporaryFolder(); @Before public void setUp() throws Exception { - // Uncomment this to enable debug output - //XMPPConnection.DEBUG_ENABLED = true; - DirectoryRosterStore store = DirectoryRosterStore.init(tmpFolder.newFolder("store")); populateStore(store); @@ -69,13 +69,20 @@ public class RosterVersioningTest { builder.setRosterStore(store); connection = new DummyConnection(builder.build()); connection.connect(); - connection.login(); + rosterListener = new TestRosterListener(); + roster = connection.getRoster(); + roster.addRosterListener(rosterListener); + roster.reload(); } @After public void tearDown() throws Exception { if (connection != null) { + if (rosterListener != null && roster != null) { + roster.removeRosterListener(rosterListener); + rosterListener = null; + } connection.disconnect(); connection = null; } @@ -89,10 +96,9 @@ public class RosterVersioningTest { */ @Test(timeout = 5000) public void testEqualVersionStored() throws InterruptedException, IOException, XMPPException, SmackException { - connection.getRoster().reload(); answerWithEmptyRosterResult(); + roster.waitUntilLoaded(); - Roster roster = connection.getRoster(); Collection entries = roster.getEntries(); assertSame("Size of the roster", 3, entries.size()); @@ -124,8 +130,6 @@ public class RosterVersioningTest { */ @Test(timeout = 5000) public void testOtherVersionStored() throws InterruptedException, XMPPException, SmackException { - connection.getRoster().reload(); - Item vaglafItem = vaglafItem(); // We expect that the roster request is the only packet sent. This is not part of the specification, @@ -141,7 +145,9 @@ public class RosterVersioningTest { answer.setVersion("newVersion"); answer.addRosterItem(vaglafItem); + rosterListener.reset(); connection.processPacket(answer); + rosterListener.waitUntilInvocationOrTimeout(); } else { assertTrue("Expected to get a RosterPacket ", false); } @@ -164,11 +170,10 @@ public class RosterVersioningTest { */ @Test(timeout = 5000) public void testRosterVersioningWithCachedRosterAndPushes() throws Throwable { - connection.getRoster().reload(); answerWithEmptyRosterResult(); + rosterListener.waitAndReset(); RosterStore store = connection.getConfiguration().getRosterStore(); - Roster roster = connection.getRoster(); // Simulate a roster push adding vaglaf { @@ -179,7 +184,9 @@ public class RosterVersioningTest { Item pushedItem = vaglafItem(); rosterPush.addRosterItem(pushedItem); + rosterListener.reset(); connection.processPacket(rosterPush); + rosterListener.waitAndReset(); assertEquals("Expect store version after push", "v97", store.getRosterVersion()); @@ -204,7 +211,9 @@ public class RosterVersioningTest { Item item = new Item("vaglaf@example.com", "vaglaf the only"); item.setItemType(ItemType.remove); rosterPush.addRosterItem(item); + rosterListener.reset(); connection.processPacket(rosterPush); + rosterListener.waitAndReset(); assertNull("Store doses not contain vaglaf", store.getEntry("vaglaf@example.com")); assertEquals("Expect store version after push", "v98", store.getRosterVersion()); diff --git a/smack-core/src/test/java/org/jivesoftware/smack/test/util/WaitForPacketListener.java b/smack-core/src/test/java/org/jivesoftware/smack/test/util/WaitForPacketListener.java new file mode 100644 index 000000000..16c906570 --- /dev/null +++ b/smack-core/src/test/java/org/jivesoftware/smack/test/util/WaitForPacketListener.java @@ -0,0 +1,60 @@ +/** + * + * 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.test.util; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import org.jivesoftware.smack.PacketListener; +import org.jivesoftware.smack.SmackException.NotConnectedException; +import org.jivesoftware.smack.packet.Packet; + +public class WaitForPacketListener implements PacketListener { + + private CountDownLatch latch = new CountDownLatch(1); + + @Override + public void processPacket(Packet packet) throws NotConnectedException { + reportInvoked(); + } + + protected void reportInvoked() { + latch.countDown(); + } + + public void waitAndReset() { + waitUntilInvocationOrTimeout(); + reset(); + } + + public void waitUntilInvocationOrTimeout() { + try { + boolean res = latch.await(30, TimeUnit.SECONDS); + if (!res) { + throw new IllegalStateException("Latch timed out before it reached zero"); + } + } + catch (InterruptedException e) { + // TODO better handling of spurious interrupts + throw new IllegalStateException(e); + } + } + + public void reset() { + latch = new CountDownLatch(1); + } +} diff --git a/smack-debug/src/main/java/org/jivesoftware/smackx/debugger/EnhancedDebugger.java b/smack-debug/src/main/java/org/jivesoftware/smackx/debugger/EnhancedDebugger.java index 212ce6467..28b078a59 100644 --- a/smack-debug/src/main/java/org/jivesoftware/smackx/debugger/EnhancedDebugger.java +++ b/smack-debug/src/main/java/org/jivesoftware/smackx/debugger/EnhancedDebugger.java @@ -956,7 +956,7 @@ public class EnhancedDebugger implements SmackDebugger { */ void cancel() { connection.removeConnectionListener(connListener); - connection.removePacketListener(packetReaderListener); + connection.removeAsyncPacketListener(packetReaderListener); connection.removePacketSendingListener(packetWriterListener); ((ObservableReader) reader).removeReaderListener(readerListener); ((ObservableWriter) writer).removeWriterListener(writerListener); diff --git a/smack-debug/src/main/java/org/jivesoftware/smackx/debugger/LiteDebugger.java b/smack-debug/src/main/java/org/jivesoftware/smackx/debugger/LiteDebugger.java index 1584ac859..d31035ee6 100644 --- a/smack-debug/src/main/java/org/jivesoftware/smackx/debugger/LiteDebugger.java +++ b/smack-debug/src/main/java/org/jivesoftware/smackx/debugger/LiteDebugger.java @@ -278,7 +278,7 @@ public class LiteDebugger implements SmackDebugger { * @param evt the event that indicates that the root window is closing */ public void rootWindowClosing(WindowEvent evt) { - connection.removePacketListener(listener); + connection.removeAsyncPacketListener(listener); ((ObservableReader)reader).removeReaderListener(readerListener); ((ObservableWriter)writer).removeWriterListener(writerListener); } diff --git a/smack-extensions/src/integration-test/java/org/jivesoftware/smackx/packet/MessageEventTest.java b/smack-extensions/src/integration-test/java/org/jivesoftware/smackx/packet/MessageEventTest.java index 6d56b9cfe..24e3ca810 100644 --- a/smack-extensions/src/integration-test/java/org/jivesoftware/smackx/packet/MessageEventTest.java +++ b/smack-extensions/src/integration-test/java/org/jivesoftware/smackx/packet/MessageEventTest.java @@ -101,7 +101,7 @@ public class MessageEventTest extends SmackTestCase { } } }; - getConnection(0).addPacketListener(packetListener, packetFilter); + getConnection(0).addAsyncPacketListener(packetListener, packetFilter); // Create the message to send with the roster Message msg = new Message(); diff --git a/smack-extensions/src/integration-test/java/org/jivesoftware/smackx/packet/XHTMLExtensionTest.java b/smack-extensions/src/integration-test/java/org/jivesoftware/smackx/packet/XHTMLExtensionTest.java index 4045dd658..af16f4eeb 100644 --- a/smack-extensions/src/integration-test/java/org/jivesoftware/smackx/packet/XHTMLExtensionTest.java +++ b/smack-extensions/src/integration-test/java/org/jivesoftware/smackx/packet/XHTMLExtensionTest.java @@ -150,7 +150,7 @@ public class XHTMLExtensionTest extends SmackTestCase { } }; - getConnection(1).addPacketListener(packetListener, packetFilter); + getConnection(1).addAsyncPacketListener(packetListener, packetFilter); // User1 creates a message to send to user2 Message msg = new Message(); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamManager.java index b419e1e3a..4c82cf892 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamManager.java @@ -215,16 +215,16 @@ public class InBandBytestreamManager implements BytestreamManager { // register bytestream open packet listener this.initiationListener = new InitiationListener(this); - this.connection.addPacketListener(this.initiationListener, + this.connection.addAsyncPacketListener(this.initiationListener, this.initiationListener.getFilter()); // register bytestream data packet listener this.dataListener = new DataListener(this); - this.connection.addPacketListener(this.dataListener, this.dataListener.getFilter()); + this.connection.addSyncPacketListener(this.dataListener, this.dataListener.getFilter()); // register bytestream close packet listener this.closeListener = new CloseListener(this); - this.connection.addPacketListener(this.closeListener, this.closeListener.getFilter()); + this.connection.addSyncPacketListener(this.closeListener, this.closeListener.getFilter()); } @@ -548,9 +548,9 @@ public class InBandBytestreamManager implements BytestreamManager { managers.remove(connection); // remove all listeners registered by this manager - this.connection.removePacketListener(this.initiationListener); - this.connection.removePacketListener(this.dataListener); - this.connection.removePacketListener(this.closeListener); + this.connection.removeAsyncPacketListener(this.initiationListener); + this.connection.removeSyncPacketListener(this.dataListener); + this.connection.removeSyncPacketListener(this.closeListener); // shutdown threads this.initiationListener.shutdown(); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSession.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSession.java index 6771dda13..109ea5833 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSession.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamSession.java @@ -264,7 +264,7 @@ public class InBandBytestreamSession implements BytestreamSession { public IBBInputStream() { // add data packet listener to connection this.dataPacketListener = getDataPacketListener(); - connection.addPacketListener(this.dataPacketListener, getDataPacketFilter()); + connection.addSyncPacketListener(this.dataPacketListener, getDataPacketFilter()); } /** @@ -431,7 +431,7 @@ public class InBandBytestreamSession implements BytestreamSession { * Invoked if the session is closed. */ private void cleanup() { - connection.removePacketListener(this.dataPacketListener); + connection.removeSyncPacketListener(this.dataPacketListener); } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java index 820359402..3607c91ab 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java @@ -289,7 +289,7 @@ public final class Socks5BytestreamManager implements BytestreamManager { public synchronized void disableService() { // remove initiation packet listener - this.connection.removePacketListener(this.initiationListener); + this.connection.removeAsyncPacketListener(this.initiationListener); // shutdown threads this.initiationListener.shutdown(); @@ -718,7 +718,7 @@ public final class Socks5BytestreamManager implements BytestreamManager { */ private void activate() { // register bytestream initiation packet listener - this.connection.addPacketListener(this.initiationListener, + this.connection.addAsyncPacketListener(this.initiationListener, this.initiationListener.getFilter()); // enable SOCKS5 feature diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java index 13957cf43..97b8f6946 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java @@ -315,7 +315,7 @@ public class EntityCapsManager extends Manager { if (autoEnableEntityCaps) enableEntityCaps(); - connection.addPacketListener(new PacketListener() { + connection.addAsyncPacketListener(new PacketListener() { // Listen for remote presence stanzas with the caps extension // If we receive such a stanza, record the JID and nodeVer @Override @@ -330,7 +330,7 @@ public class EntityCapsManager extends Manager { }, PRESENCES_WITH_CAPS); - connection.addPacketListener(new PacketListener() { + connection.addAsyncPacketListener(new PacketListener() { @Override public void processPacket(Packet packet) { // always remove the JID from the map, even if entityCaps are diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java index 59cb67acf..96c372c72 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/ServiceDiscoveryManager.java @@ -148,7 +148,7 @@ public class ServiceDiscoveryManager extends Manager { connection().sendPacket(response); } }; - connection.addPacketListener(packetListener, GET_DISCOVER_ITEMS); + connection.addAsyncPacketListener(packetListener, GET_DISCOVER_ITEMS); // Listen for disco#info requests and answer the client's supported features // To add a new feature as supported use the #addFeature message @@ -187,7 +187,7 @@ public class ServiceDiscoveryManager extends Manager { connection().sendPacket(response); } }; - connection.addPacketListener(packetListener, GET_DISCOVER_INFO); + connection.addAsyncPacketListener(packetListener, GET_DISCOVER_INFO); } /** diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqlast/LastActivityManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqlast/LastActivityManager.java index 42445f24c..dc29ae08f 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqlast/LastActivityManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqlast/LastActivityManager.java @@ -160,7 +160,7 @@ public class LastActivityManager extends Manager { }, PacketTypeFilter.MESSAGE); // Register a listener for a last activity query - connection.addPacketListener(new PacketListener() { + connection.addAsyncPacketListener(new PacketListener() { public void processPacket(Packet packet) throws NotConnectedException { if (!enabled) return; diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqversion/VersionManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqversion/VersionManager.java index fc33e39be..68ecd50f2 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/iqversion/VersionManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/iqversion/VersionManager.java @@ -86,7 +86,7 @@ public class VersionManager extends Manager { ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(connection); sdm.addFeature(Version.NAMESPACE); - connection.addPacketListener(new PacketListener() { + connection.addAsyncPacketListener(new PacketListener() { /** * Sends a Version reply on request * @throws NotConnectedException diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java index e85d4100f..020906879 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/muc/MultiUserChat.java @@ -292,12 +292,12 @@ public class MultiUserChat { + nickname), new PacketTypeFilter(Presence.class)); // Setup the messageListeners and presenceListeners *before* the join presence is send. - connection.addPacketListener(messageListener, fromRoomGroupchatFilter); - connection.addPacketListener(presenceListener, new AndFilter(fromRoomFilter, + connection.addSyncPacketListener(messageListener, fromRoomGroupchatFilter); + connection.addSyncPacketListener(presenceListener, new AndFilter(fromRoomFilter, PacketTypeFilter.PRESENCE)); - connection.addPacketListener(subjectListener, new AndFilter(fromRoomFilter, + connection.addSyncPacketListener(subjectListener, new AndFilter(fromRoomFilter, MessageWithSubjectFilter.INSTANCE)); - connection.addPacketListener(declinesListener, new AndFilter(new PacketExtensionFilter(MUCUser.ELEMENT, + connection.addSyncPacketListener(declinesListener, new AndFilter(new PacketExtensionFilter(MUCUser.ELEMENT, MUCUser.NAMESPACE), new NotFilter(MessageTypeFilter.ERROR))); connection.addPacketInterceptor(presenceInterceptor, new AndFilter(new ToFilter(room), PacketTypeFilter.PRESENCE)); @@ -1702,9 +1702,9 @@ public class MultiUserChat { * connection. */ private void removeConnectionCallbacks() { - connection.removePacketListener(messageListener); - connection.removePacketListener(presenceListener); - connection.removePacketListener(declinesListener); + connection.removeSyncPacketListener(messageListener); + connection.removeSyncPacketListener(presenceListener); + connection.removeSyncPacketListener(declinesListener); connection.removePacketInterceptor(presenceInterceptor); if (messageCollector != null) { messageCollector.cancel(); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pep/PEPManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pep/PEPManager.java index 60f2afa9e..f1f00a8a4 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pep/PEPManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pep/PEPManager.java @@ -142,12 +142,12 @@ public class PEPManager { firePEPListeners(message.getFrom(), event); } }; - connection.addPacketListener(packetListener, packetFilter); + connection.addSyncPacketListener(packetListener, packetFilter); } public void destroy() { if (connection != null) - connection.removePacketListener(packetListener); + connection.removeSyncPacketListener(packetListener); } protected void finalize() throws Throwable { diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/PingManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/PingManager.java index 18bde0166..69c7c04c5 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/PingManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/ping/PingManager.java @@ -127,7 +127,7 @@ public class PingManager extends Manager { ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(connection); sdm.addFeature(Ping.NAMESPACE); - connection.addPacketListener(new PacketListener() { + connection.addAsyncPacketListener(new PacketListener() { // Send a Pong for every Ping @Override public void processPacket(Packet packet) throws NotConnectedException { diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/PrivacyListManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/PrivacyListManager.java index fbbeed8b3..ea351f02a 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/PrivacyListManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/privacy/PrivacyListManager.java @@ -85,7 +85,7 @@ public class PrivacyListManager extends Manager { private PrivacyListManager(final XMPPConnection connection) { super(connection); - connection.addPacketListener(new PacketListener() { + connection.addSyncPacketListener(new PacketListener() { @Override public void processPacket(Packet packet) throws NotConnectedException { Privacy privacy = (Privacy) packet; diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/Node.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/Node.java index 88224e23f..f11219f58 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/Node.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/Node.java @@ -399,7 +399,7 @@ abstract public class Node { PacketListener conListener = new ItemEventTranslator(listener); itemEventToListenerMap.put(listener, conListener); - con.addPacketListener(conListener, new EventContentFilter(EventElementType.items.toString(), "item")); + con.addSyncPacketListener(conListener, new EventContentFilter(EventElementType.items.toString(), "item")); } /** @@ -412,7 +412,7 @@ abstract public class Node PacketListener conListener = itemEventToListenerMap.remove(listener); if (conListener != null) - con.removePacketListener(conListener); + con.removeSyncPacketListener(conListener); } /** @@ -425,7 +425,7 @@ abstract public class Node { PacketListener conListener = new NodeConfigTranslator(listener); configEventToListenerMap.put(listener, conListener); - con.addPacketListener(conListener, new EventContentFilter(EventElementType.configuration.toString())); + con.addSyncPacketListener(conListener, new EventContentFilter(EventElementType.configuration.toString())); } /** @@ -438,7 +438,7 @@ abstract public class Node PacketListener conListener = configEventToListenerMap .remove(listener); if (conListener != null) - con.removePacketListener(conListener); + con.removeSyncPacketListener(conListener); } /** @@ -454,7 +454,7 @@ abstract public class Node EventContentFilter deleteItem = new EventContentFilter(EventElementType.items.toString(), "retract"); EventContentFilter purge = new EventContentFilter(EventElementType.purge.toString()); - con.addPacketListener(delListener, new OrFilter(deleteItem, purge)); + con.addSyncPacketListener(delListener, new OrFilter(deleteItem, purge)); } /** @@ -467,7 +467,7 @@ abstract public class Node PacketListener conListener = itemDeleteToListenerMap .remove(listener); if (conListener != null) - con.removePacketListener(conListener); + con.removeSyncPacketListener(conListener); } @Override diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceiptManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceiptManager.java index 93f088b8a..1ec315df1 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceiptManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceiptManager.java @@ -62,7 +62,7 @@ public class DeliveryReceiptManager extends Manager implements PacketListener { sdm.addFeature(DeliveryReceipt.NAMESPACE); // register listener for delivery receipts and requests - connection.addPacketListener(this, new PacketExtensionFilter(DeliveryReceipt.NAMESPACE)); + connection.addAsyncPacketListener(this, new PacketExtensionFilter(DeliveryReceipt.NAMESPACE)); } /** diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/time/EntityTimeManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/time/EntityTimeManager.java index 815391524..73f6488b2 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/time/EntityTimeManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/time/EntityTimeManager.java @@ -72,7 +72,7 @@ public class EntityTimeManager extends Manager { if (autoEnable) enable(); - connection.addPacketListener(new PacketListener() { + connection.addAsyncPacketListener(new PacketListener() { @Override public void processPacket(Packet packet) throws NotConnectedException { if (!enabled) diff --git a/smack-jingle-old/src/integration-test/java/org/jivesoftware/smackx/jingle/JingleManagerTest.java b/smack-jingle-old/src/integration-test/java/org/jivesoftware/smackx/jingle/JingleManagerTest.java index 1f855f505..a31b6a4c7 100644 --- a/smack-jingle-old/src/integration-test/java/org/jivesoftware/smackx/jingle/JingleManagerTest.java +++ b/smack-jingle-old/src/integration-test/java/org/jivesoftware/smackx/jingle/JingleManagerTest.java @@ -159,7 +159,7 @@ public class JingleManagerTest extends SmackTestCase { }; // Start a packet listener for session initiation requests - getConnection(0).addPacketListener(new PacketListener() { + getConnection(0).addAsyncPacketListener(new PacketListener() { public void processPacket(final Packet packet) { System.out.println("Packet detected... "); incCounter(); diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/JingleManager.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/JingleManager.java index d69a729bd..275cf2591 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/JingleManager.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/JingleManager.java @@ -461,7 +461,7 @@ public class JingleManager implements JingleSessionListener { jingleSessionRequestListeners = new ArrayList(); // Start a packet listener for session initiation requests - connection.addPacketListener(new PacketListener() { + connection.addAsyncPacketListener(new PacketListener() { public void processPacket(Packet packet) { triggerSessionRequested((Jingle) packet); } diff --git a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/JingleSession.java b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/JingleSession.java index 4b48a5680..73af7edde 100644 --- a/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/JingleSession.java +++ b/smack-jingle-old/src/main/java/org/jivesoftware/smackx/jingleold/JingleSession.java @@ -654,9 +654,9 @@ public class JingleSession extends JingleNegotiator implements MediaReceivedList /** * Remove the packet listener used for processing packet. */ - protected void removePacketListener() { + protected void removeAsyncPacketListener() { if (packetListener != null) { - getConnection().removePacketListener(packetListener); + getConnection().removeAsyncPacketListener(packetListener); LOGGER.fine("JINGLE SESSION: REMOVE PACKET LISTENER"); } @@ -667,7 +667,7 @@ public class JingleSession extends JingleNegotiator implements MediaReceivedList * to any packet that we receive... */ protected void updatePacketListener() { - removePacketListener(); + removeAsyncPacketListener(); LOGGER.fine("UpdatePacketListener"); @@ -728,7 +728,7 @@ public class JingleSession extends JingleNegotiator implements MediaReceivedList } }; - getConnection().addPacketListener(packetListener, packetFilter); + getConnection().addAsyncPacketListener(packetListener, packetFilter); } // Listeners @@ -1002,7 +1002,7 @@ public class JingleSession extends JingleNegotiator implements MediaReceivedList contentNegotiator.close(); } - removePacketListener(); + removeAsyncPacketListener(); removeConnectionListener(); getConnection().removeConnectionListener(connectionListener); LOGGER.fine("Negotiation Closed: " + getConnection().getUser() + " " + sid); diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentRoster.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentRoster.java index f0bbc8caa..694dcd038 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentRoster.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentRoster.java @@ -74,9 +74,9 @@ public class AgentRoster { presenceMap = new HashMap>(); // Listen for any roster packets. PacketFilter rosterFilter = new PacketTypeFilter(AgentStatusRequest.class); - connection.addPacketListener(new AgentStatusListener(), rosterFilter); + connection.addAsyncPacketListener(new AgentStatusListener(), rosterFilter); // Listen for any presence packets. - connection.addPacketListener(new PresencePacketListener(), + connection.addAsyncPacketListener(new PresencePacketListener(), new PacketTypeFilter(Presence.class)); // Send request for roster. diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java index ac9b952a1..5d18bbcf4 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/agent/AgentSession.java @@ -157,7 +157,7 @@ public class AgentSession { } } }; - connection.addPacketListener(packetListener, filter); + connection.addAsyncPacketListener(packetListener, filter); // Create the agent associated to this session agent = new Agent(connection, workgroupJID); } @@ -167,7 +167,7 @@ public class AgentSession { * packet listeners that were added by this agent session will be removed. */ public void close() { - connection.removePacketListener(packetListener); + connection.removeAsyncPacketListener(packetListener); } /** diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/user/Workgroup.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/user/Workgroup.java index 2bba746a1..4fa29e65f 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/user/Workgroup.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/workgroup/user/Workgroup.java @@ -142,7 +142,7 @@ public class Workgroup { // Register a packet listener for all the messages sent to this client. PacketFilter typeFilter = new PacketTypeFilter(Message.class); - connection.addPacketListener(new PacketListener() { + connection.addAsyncPacketListener(new PacketListener() { public void processPacket(Packet packet) { handlePacket(packet); } diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/xevent/MessageEventManager.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/xevent/MessageEventManager.java index 14f8b9d13..213c5203e 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/xevent/MessageEventManager.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/xevent/MessageEventManager.java @@ -75,7 +75,7 @@ public class MessageEventManager extends Manager { private MessageEventManager(XMPPConnection connection) { super(connection); // Listens for all message event packets and fire the proper message event listeners. - connection.addPacketListener(new PacketListener() { + connection.addAsyncPacketListener(new PacketListener() { public void processPacket(Packet packet) { Message message = (Message) packet; MessageEvent messageEvent = diff --git a/smack-legacy/src/main/java/org/jivesoftware/smackx/xroster/RosterExchangeManager.java b/smack-legacy/src/main/java/org/jivesoftware/smackx/xroster/RosterExchangeManager.java index b4daaf764..42d5abeb0 100644 --- a/smack-legacy/src/main/java/org/jivesoftware/smackx/xroster/RosterExchangeManager.java +++ b/smack-legacy/src/main/java/org/jivesoftware/smackx/xroster/RosterExchangeManager.java @@ -85,7 +85,7 @@ public class RosterExchangeManager { fireRosterExchangeListeners(message.getFrom(), rosterExchange.getRosterEntries()); } }; - connection.addPacketListener(packetListener, PACKET_FILTER); + connection.addAsyncPacketListener(packetListener, PACKET_FILTER); } /** 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 ed2150af3..c4c25be31 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 @@ -568,7 +568,7 @@ public class XMPPTCPConnection extends AbstractXMPPConnection { // If debugging is enabled, we should start the thread that will listen for // all packets and then log them. if (config.isDebuggerEnabled()) { - addPacketListener(debugger.getReaderListener(), null); + addAsyncPacketListener(debugger.getReaderListener(), null); if (debugger.getWriterListener() != null) { addPacketSendingListener(debugger.getWriterListener(), null); }