diff --git a/experimental/source/org/jivesoftware/smackx/carbons/CarbonManager.java b/experimental/source/org/jivesoftware/smackx/carbons/CarbonManager.java index bdc00a31e..dc2159925 100644 --- a/experimental/source/org/jivesoftware/smackx/carbons/CarbonManager.java +++ b/experimental/source/org/jivesoftware/smackx/carbons/CarbonManager.java @@ -16,6 +16,7 @@ package org.jivesoftware.smackx.carbons; +import java.lang.ref.WeakReference; import java.util.Collections; import java.util.Map; import java.util.WeakHashMap; @@ -56,13 +57,13 @@ public class CarbonManager { }); } - private Connection connection; + private WeakReference weakRefConnection; private volatile boolean enabled_state = false; private CarbonManager(Connection connection) { ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(connection); sdm.addFeature(Carbon.NAMESPACE); - this.connection = connection; + weakRefConnection = new WeakReference(connection); instances.put(connection, this); } @@ -99,6 +100,7 @@ public class CarbonManager { * @return true if supported */ public boolean isSupportedByServer() { + Connection connection = weakRefConnection.get(); try { DiscoverInfo result = ServiceDiscoveryManager .getInstanceFor(connection).discoverInfo(connection.getServiceName()); @@ -118,6 +120,7 @@ public class CarbonManager { * @param new_state whether carbons should be enabled or disabled */ public void sendCarbonsEnabled(final boolean new_state) { + final Connection connection = weakRefConnection.get(); IQ setIQ = carbonsEnabledIQ(new_state); connection.addPacketListener(new PacketListener() { @@ -148,6 +151,7 @@ public class CarbonManager { if (enabled_state == new_state) return true; + Connection connection = weakRefConnection.get(); IQ setIQ = carbonsEnabledIQ(new_state); PacketCollector collector = diff --git a/source/org/jivesoftware/smack/keepalive/KeepAliveManager.java b/source/org/jivesoftware/smack/keepalive/KeepAliveManager.java index 254a0419b..3560bc1c3 100644 --- a/source/org/jivesoftware/smack/keepalive/KeepAliveManager.java +++ b/source/org/jivesoftware/smack/keepalive/KeepAliveManager.java @@ -16,12 +16,12 @@ package org.jivesoftware.smack.keepalive; +import java.lang.ref.WeakReference; import java.util.Collections; -import java.util.Date; -import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.WeakHashMap; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledThreadPoolExecutor; @@ -52,7 +52,7 @@ import org.jivesoftware.smack.ping.packet.Ping; * @author Florian Schmaus */ public class KeepAliveManager { - private static Map instances = new HashMap(); + private static Map instances = Collections.synchronizedMap(new WeakHashMap()); private static volatile ScheduledExecutorService periodicPingExecutorService; static { @@ -65,7 +65,7 @@ public class KeepAliveManager { } } - private Connection connection; + private WeakReference weakRefConnection; private long pingInterval = SmackConfiguration.getKeepAliveInterval(); private Set pingFailedListeners = Collections.synchronizedSet(new HashSet()); private volatile ScheduledFuture periodicPingTask; @@ -120,40 +120,21 @@ public class KeepAliveManager { } private KeepAliveManager(Connection connection) { - this.connection = connection; - init(); - handleConnect(); - } + weakRefConnection = new WeakReference(connection); - /* - * Call after every connection to add the packet listener. - */ - private void handleConnect() { - // Listen for all incoming packets and reset the scheduled ping whenever - // one arrives. - connection.addPacketListener(new PacketListener() { - - @Override - public void processPacket(Packet packet) { - // reschedule the ping based on this last server contact - lastSuccessfulContact = System.currentTimeMillis(); - schedulePingServerTask(); - } - }, null); - } - - private void init() { connection.addConnectionListener(new ConnectionListener() { @Override public void connectionClosed() { stopPingServerTask(); + Connection connection = weakRefConnection.get(); handleDisconnect(connection); } @Override public void connectionClosedOnError(Exception arg0) { stopPingServerTask(); + Connection connection = weakRefConnection.get(); handleDisconnect(connection); } @@ -174,6 +155,25 @@ public class KeepAliveManager { instances.put(connection, this); schedulePingServerTask(); + handleConnect(); + } + + /* + * Call after every connection to add the packet listener. + */ + private void handleConnect() { + Connection connection = weakRefConnection.get(); + // Listen for all incoming packets and reset the scheduled ping whenever + // one arrives. + connection.addPacketListener(new PacketListener() { + + @Override + public void processPacket(Packet packet) { + // reschedule the ping based on this last server contact + lastSuccessfulContact = System.currentTimeMillis(); + schedulePingServerTask(); + } + }, null); } /** @@ -276,6 +276,7 @@ public class KeepAliveManager { public void run() { Ping ping = new Ping(); PacketFilter responseFilter = new PacketIDFilter(ping.getPacketID()); + Connection connection = weakRefConnection.get(); final PacketCollector response = pingFailedListeners.isEmpty() ? null : connection.createPacketCollector(responseFilter); connection.sendPacket(ping); diff --git a/source/org/jivesoftware/smackx/MessageEventManager.java b/source/org/jivesoftware/smackx/MessageEventManager.java index 900914b3d..7ad7adfeb 100644 --- a/source/org/jivesoftware/smackx/MessageEventManager.java +++ b/source/org/jivesoftware/smackx/MessageEventManager.java @@ -20,7 +20,6 @@ package org.jivesoftware.smackx; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Iterator; diff --git a/source/org/jivesoftware/smackx/ping/PingManager.java b/source/org/jivesoftware/smackx/ping/PingManager.java index 068206698..4c34f9223 100644 --- a/source/org/jivesoftware/smackx/ping/PingManager.java +++ b/source/org/jivesoftware/smackx/ping/PingManager.java @@ -16,6 +16,7 @@ package org.jivesoftware.smackx.ping; +import java.lang.ref.WeakReference; import java.util.Collections; import java.util.Map; import java.util.WeakHashMap; @@ -65,7 +66,7 @@ public class PingManager { }); } - private Connection connection; + private WeakReference weakRefConnection; /** * Retrieves a {@link PingManager} for the specified {@link Connection}, creating one if it doesn't already @@ -84,8 +85,8 @@ public class PingManager { return pingManager; } - private PingManager(Connection con) { - this.connection = con; + private PingManager(Connection connection) { + weakRefConnection = new WeakReference(connection); ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(connection); // The ServiceDiscoveryManager was not pre-initialized @@ -101,6 +102,7 @@ public class PingManager { * Sends a Pong for every Ping */ public void processPacket(Packet packet) { + Connection connection = weakRefConnection.get(); IQ pong = IQ.createResultIQ((Ping) packet); connection.sendPacket(pong); } @@ -121,7 +123,7 @@ public class PingManager { */ public boolean ping(String jid, long pingTimeout) { Ping ping = new Ping(jid); - + Connection connection = weakRefConnection.get(); try { SyncPacketSend.getReply(connection, ping); } @@ -151,6 +153,7 @@ public class PingManager { * @throws XMPPException An XMPP related error occurred during the request */ public boolean isPingSupported(String jid) throws XMPPException { + Connection connection = weakRefConnection.get(); DiscoverInfo result = ServiceDiscoveryManager.getInstanceFor(connection).discoverInfo(jid); return result.containsFeature(Ping.NAMESPACE); } @@ -165,6 +168,7 @@ public class PingManager { * @return true if a reply was received from the server, false otherwise. */ public boolean pingMyServer() { + Connection connection = weakRefConnection.get(); return ping(connection.getServiceName()); } } diff --git a/source/org/jivesoftware/smackx/receipts/DeliveryReceiptManager.java b/source/org/jivesoftware/smackx/receipts/DeliveryReceiptManager.java index 0b4a6aae6..e628b20e5 100644 --- a/source/org/jivesoftware/smackx/receipts/DeliveryReceiptManager.java +++ b/source/org/jivesoftware/smackx/receipts/DeliveryReceiptManager.java @@ -16,6 +16,7 @@ package org.jivesoftware.smackx.receipts; +import java.lang.ref.WeakReference; import java.util.Collections; import java.util.HashSet; import java.util.Map; @@ -52,7 +53,7 @@ public class DeliveryReceiptManager implements PacketListener { }); } - private Connection connection; + private WeakReference weakRefConnection; private boolean auto_receipts_enabled = false; private Set receiptReceivedListeners = Collections .synchronizedSet(new HashSet()); @@ -60,7 +61,7 @@ public class DeliveryReceiptManager implements PacketListener { private DeliveryReceiptManager(Connection connection) { ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(connection); sdm.addFeature(DeliveryReceipt.NAMESPACE); - this.connection = connection; + weakRefConnection = new WeakReference(connection); instances.put(connection, this); // register listener for delivery receipts and requests @@ -91,6 +92,7 @@ public class DeliveryReceiptManager implements PacketListener { * @return true if supported */ public boolean isSupported(String jid) { + Connection connection = weakRefConnection.get(); try { DiscoverInfo result = ServiceDiscoveryManager.getInstanceFor(connection).discoverInfo(jid); @@ -119,6 +121,7 @@ public class DeliveryReceiptManager implements PacketListener { DeliveryReceiptRequest drr = (DeliveryReceiptRequest)packet.getExtension( DeliveryReceiptRequest.ELEMENT, DeliveryReceipt.NAMESPACE); if (drr != null) { + Connection connection = weakRefConnection.get(); Message ack = new Message(packet.getFrom(), Message.Type.normal); ack.addExtension(new DeliveryReceipt(packet.getPacketID())); connection.sendPacket(ack);