diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/VCardManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/VCardManager.java index 82dded328..bc7bf47eb 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/VCardManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/VCardManager.java @@ -16,27 +16,51 @@ */ package org.jivesoftware.smackx.vcardtemp; +import java.util.Map; +import java.util.WeakHashMap; + import org.jivesoftware.smack.ConnectionCreationListener; +import org.jivesoftware.smack.Manager; import org.jivesoftware.smack.SmackException.NoResponseException; import org.jivesoftware.smack.SmackException.NotConnectedException; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPConnectionRegistry; import org.jivesoftware.smack.XMPPException.XMPPErrorException; +import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; +import org.jivesoftware.smackx.vcardtemp.packet.VCard; -public class VCardManager { - public static final String NAMESPACE = "vcard-temp"; - public static final String ELEMENT = "vCard"; +public class VCardManager extends Manager { + public static final String NAMESPACE = VCard.NAMESPACE; + public static final String ELEMENT = VCard.ELEMENT; + + private static final Map INSTANCES = new WeakHashMap<>(); static { XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() { @Override public void connectionCreated(XMPPConnection connection) { - ServiceDiscoveryManager.getInstanceFor(connection).addFeature(NAMESPACE); + getInstanceFor(connection); } }); } + /** + * Retrieves a {@link VCardManager} for the specified {@link XMPPConnection}, creating one if it doesn't already + * exist. + * + * @param connection the connection the manager is attached to. + * @return The new or existing manager. + */ + public static synchronized VCardManager getInstanceFor(XMPPConnection connection) { + VCardManager vcardManager = INSTANCES.get(connection); + if (vcardManager == null) { + vcardManager = new VCardManager(connection); + INSTANCES.put(connection, vcardManager); + } + return vcardManager; + } + /** * Returns true if the given entity understands the vCard-XML format and allows the exchange of such. * @@ -45,9 +69,67 @@ public class VCardManager { * @return true if the given entity understands the vCard-XML format and exchange. * @throws XMPPErrorException * @throws NoResponseException + * @throws NotConnectedException + * @deprecated use {@link #isSupported(String)} instead. + */ + @Deprecated + public static boolean isSupported(String jid, XMPPConnection connection) throws NoResponseException, XMPPErrorException, NotConnectedException { + return VCardManager.getInstanceFor(connection).isSupported(jid); + } + + private VCardManager(XMPPConnection connection) { + super(connection); + ServiceDiscoveryManager.getInstanceFor(connection).addFeature(NAMESPACE); + } + + /** + * Save this vCard for the user connected by 'connection'. XMPPConnection should be authenticated + * and not anonymous. + * + * @throws XMPPErrorException thrown if there was an issue setting the VCard in the server. + * @throws NoResponseException if there was no response from the server. * @throws NotConnectedException */ - public static boolean isSupported(String jid, XMPPConnection connection) throws NoResponseException, XMPPErrorException, NotConnectedException { - return ServiceDiscoveryManager.getInstanceFor(connection).supportsFeature(jid, NAMESPACE); + public void saveVCard(VCard vcard) throws NoResponseException, XMPPErrorException, NotConnectedException { + vcard.setType(IQ.Type.set); + connection().createPacketCollectorAndSend(vcard).nextResultOrThrow(); + } + + /** + * Load the VCard of the current user. + * + * @throws XMPPErrorException + * @throws NoResponseException + * @throws NotConnectedException + */ + public VCard loadVCard() throws NoResponseException, XMPPErrorException, NotConnectedException { + return loadVCard(null); + } + + /** + * Load VCard information for a given user. + * + * @throws XMPPErrorException + * @throws NoResponseException if there was no response from the server. + * @throws NotConnectedException + */ + public VCard loadVCard(String bareJid) throws NoResponseException, XMPPErrorException, NotConnectedException { + VCard vcardRequest = new VCard(); + vcardRequest.setTo(bareJid); + VCard result = connection().createPacketCollectorAndSend(vcardRequest).nextResultOrThrow(); + return result; + } + + /** + * Returns true if the given entity understands the vCard-XML format and allows the exchange of such. + * + * @param jid + * @return true if the given entity understands the vCard-XML format and exchange. + * @throws XMPPErrorException + * @throws NoResponseException + * @throws NotConnectedException + */ + public boolean isSupported(String jid) throws NoResponseException, XMPPErrorException, NotConnectedException { + return ServiceDiscoveryManager.getInstanceFor(connection()).supportsFeature(jid, NAMESPACE); } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/packet/VCard.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/packet/VCard.java index e2dd78fad..303510031 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/packet/VCard.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/vcardtemp/packet/VCard.java @@ -39,6 +39,7 @@ import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smack.util.stringencoder.Base64; +import org.jivesoftware.smackx.vcardtemp.VCardManager; /** * A VCard class for use with the @@ -398,6 +399,7 @@ public class VCard extends IQ { * @param encodedAvatar the encoded avatar string. * @deprecated Use {@link #setAvatar(String, String)} instead. */ + @Deprecated public void setEncodedImage(String encodedAvatar) { setAvatar(encodedAvatar, DEFAULT_MIME_TYPE); } @@ -515,21 +517,17 @@ public class VCard extends IQ { /** * Save this vCard for the user connected by 'connection'. XMPPConnection should be authenticated - * and not anonymous.

- *

- * NOTE: the method is asynchronous and does not wait for the returned value. + * and not anonymous. * * @param connection the XMPPConnection to use. * @throws XMPPErrorException thrown if there was an issue setting the VCard in the server. * @throws NoResponseException if there was no response from the server. * @throws NotConnectedException + * @deprecated use {@link VCardManager#saveVCard(VCard)} instead. */ + @Deprecated public void save(XMPPConnection connection) throws NoResponseException, XMPPErrorException, NotConnectedException { - checkAuthenticated(connection, true); - - setType(IQ.Type.set); - setFrom(connection.getUser()); - connection.createPacketCollectorAndSend(this).nextResultOrThrow(); + VCardManager.getInstanceFor(connection).saveVCard(this); } /** @@ -538,12 +536,11 @@ public class VCard extends IQ { * @throws XMPPErrorException * @throws NoResponseException * @throws NotConnectedException + * @deprecated use {@link VCardManager#loadVCard()} instead. */ + @Deprecated public void load(XMPPConnection connection) throws NoResponseException, XMPPErrorException, NotConnectedException { - checkAuthenticated(connection, true); - - setFrom(connection.getUser()); - doLoad(connection, connection.getUser()); + load(connection, null); } /** @@ -551,17 +548,11 @@ public class VCard extends IQ { * @throws XMPPErrorException * @throws NoResponseException if there was no response from the server. * @throws NotConnectedException + * @deprecated use {@link VCardManager#loadVCard(String)} instead. */ + @Deprecated public void load(XMPPConnection connection, String user) throws NoResponseException, XMPPErrorException, NotConnectedException { - checkAuthenticated(connection, false); - - setTo(user); - doLoad(connection, user); - } - - private void doLoad(XMPPConnection connection, String user) throws NoResponseException, XMPPErrorException, NotConnectedException { - setType(Type.get); - VCard result = (VCard) connection.createPacketCollectorAndSend(this).nextResultOrThrow(); + VCard result = VCardManager.getInstanceFor(connection).loadVCard(user); copyFieldsFrom(result); } @@ -664,18 +655,6 @@ public class VCard extends IQ { } } - private void checkAuthenticated(XMPPConnection connection, boolean checkForAnonymous) { - if (connection == null) { - throw new IllegalArgumentException("No connection was provided"); - } - if (!connection.isAuthenticated()) { - throw new IllegalArgumentException("XMPPConnection is not authenticated"); - } - if (checkForAnonymous && connection.isAnonymous()) { - throw new IllegalArgumentException("XMPPConnection cannot be anonymous"); - } - } - private boolean hasContent() { //noinspection OverlyComplexBooleanExpression return hasNameField()