From 0c29fdb769e54e2cc1cb50aca55e5987c28e0bc2 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Fri, 4 Apr 2014 11:55:06 +0200 Subject: [PATCH] Use WeakHashMap in BookmarkManager and PrivateDataManager Also remove the "other user" constructor fo PrivateDataManager, as this feature is not specified by XEP-49. Fixes SMACK-554 --- .../smackx/bookmarks/BookmarkManager.java | 23 +++---- .../smackx/iqprivate/PrivateDataManager.java | 67 +++++-------------- 2 files changed, 29 insertions(+), 61 deletions(-) diff --git a/extensions/src/main/java/org/jivesoftware/smackx/bookmarks/BookmarkManager.java b/extensions/src/main/java/org/jivesoftware/smackx/bookmarks/BookmarkManager.java index b89d9be5a..597b32ebf 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/bookmarks/BookmarkManager.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/bookmarks/BookmarkManager.java @@ -17,6 +17,13 @@ package org.jivesoftware.smackx.bookmarks; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.WeakHashMap; + import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.SmackException.NotConnectedException; @@ -25,7 +32,6 @@ import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smackx.iqprivate.PrivateDataManager; -import java.util.*; /** * Provides methods to manage bookmarks in accordance with JEP-0048. Methods for managing URLs and @@ -38,7 +44,8 @@ import java.util.*; * @author Alexander Wenckus */ public class BookmarkManager { - private static final Map bookmarkManagerMap = new HashMap(); + private static final Map bookmarkManagerMap = new WeakHashMap(); + static { PrivateDataManager.addPrivateDataProvider("storage", "storage:bookmarks", new Bookmarks.Provider()); @@ -60,7 +67,6 @@ public class BookmarkManager { BookmarkManager manager = (BookmarkManager) bookmarkManagerMap.get(connection); if (manager == null) { manager = new BookmarkManager(connection); - bookmarkManagerMap.put(connection, manager); } return manager; } @@ -74,17 +80,10 @@ public class BookmarkManager { * storage:bookmarks namespace. * * @param connection the connection for persisting and retrieving bookmarks. - * @throws SmackException thrown has not been authenticated. - * @throws IllegalArgumentException when the connection is null. */ private BookmarkManager(XMPPConnection connection) throws XMPPException, SmackException { - if (connection == null) { - throw new IllegalArgumentException("connection must not be null."); - } - if (!connection.isAuthenticated()) { - throw new SmackException("connection not authenticated."); - } - this.privateDataManager = new PrivateDataManager(connection); + privateDataManager = PrivateDataManager.getInstanceFor(connection); + bookmarkManagerMap.put(connection, this); } /** diff --git a/extensions/src/main/java/org/jivesoftware/smackx/iqprivate/PrivateDataManager.java b/extensions/src/main/java/org/jivesoftware/smackx/iqprivate/PrivateDataManager.java index afaf4fb49..5e831dd74 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/iqprivate/PrivateDataManager.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/iqprivate/PrivateDataManager.java @@ -17,6 +17,7 @@ package org.jivesoftware.smackx.iqprivate; +import org.jivesoftware.smack.Manager; import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smack.XMPPConnection; @@ -30,6 +31,7 @@ import org.xmlpull.v1.XmlPullParser; import java.util.Hashtable; import java.util.Map; +import java.util.WeakHashMap; /** * Manages private data, which is a mechanism to allow users to store arbitrary XML @@ -53,7 +55,16 @@ import java.util.Map; * * @author Matt Tucker */ -public class PrivateDataManager { +public class PrivateDataManager extends Manager { + private static final Map instances = new WeakHashMap(); + + public static synchronized PrivateDataManager getInstanceFor(XMPPConnection connection) { + PrivateDataManager privateDataManager = instances.get(connection); + if (connection == null) { + privateDataManager = new PrivateDataManager(connection); + } + return privateDataManager; + } /** * Map of provider instances. @@ -113,49 +124,15 @@ public class PrivateDataManager { privateDataProviders.remove(key); } - - private XMPPConnection connection; - /** - * The user to get and set private data for. In most cases, this value should - * be null, as the typical use of private data is to get and set - * your own private data and not others. - */ - private String user; - - /** - * Creates a new private data manager. The connection must have - * undergone a successful login before being used to construct an instance of - * this class. + * Creates a new private data manager. * * @param connection an XMPP connection which must have already undergone a * successful login. */ - public PrivateDataManager(XMPPConnection connection) { - if (!connection.isAuthenticated()) { - throw new IllegalStateException("Must be logged in to XMPP server."); - } - this.connection = connection; - } - - /** - * Creates a new private data manager for a specific user (special case). Most - * servers only support getting and setting private data for the user that - * authenticated via the connection. However, some servers support the ability - * to get and set private data for other users (for example, if you are the - * administrator). The connection must have undergone a successful login before - * being used to construct an instance of this class. - * - * @param connection an XMPP connection which must have already undergone a - * successful login. - * @param user the XMPP address of the user to get and set private data for. - */ - public PrivateDataManager(XMPPConnection connection, String user) { - if (!connection.isAuthenticated()) { - throw new IllegalStateException("Must be logged in to XMPP server."); - } - this.connection = connection; - this.user = user; + private PrivateDataManager(XMPPConnection connection) { + super(connection); + instances.put(connection, this); } /** @@ -186,12 +163,8 @@ public class PrivateDataManager { } }; privateDataGet.setType(IQ.Type.GET); - // Address the packet to the other account if user has been set. - if (user != null) { - privateDataGet.setTo(user); - } - PrivateDataResult response = (PrivateDataResult) connection.createPacketCollectorAndSend( + PrivateDataResult response = (PrivateDataResult) connection().createPacketCollectorAndSend( privateDataGet).nextResultOrThrow(); return response.getPrivateData(); } @@ -218,12 +191,8 @@ public class PrivateDataManager { } }; privateDataSet.setType(IQ.Type.SET); - // Address the packet to the other account if user has been set. - if (user != null) { - privateDataSet.setTo(user); - } - connection.createPacketCollectorAndSend(privateDataSet).nextResultOrThrow(); + connection().createPacketCollectorAndSend(privateDataSet).nextResultOrThrow(); } /**