From bd6828db38e63cde6209355e985f644afb5ca2a2 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Tue, 11 Mar 2014 09:20:55 +0100 Subject: [PATCH] Make EntityCapsManager's node version configurable Also some cleanup of caps code. --- .../smackx/caps/EntityCapsManager.java | 87 ++++++++++--------- .../smackx/caps/packet/CapsExtension.java | 24 +---- 2 files changed, 51 insertions(+), 60 deletions(-) diff --git a/extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java b/extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java index dc5f376ec..42c38b42b 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java @@ -16,9 +16,9 @@ */ package org.jivesoftware.smackx.caps; +import org.jivesoftware.smack.AbstractConnectionListener; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.ConnectionCreationListener; -import org.jivesoftware.smack.ConnectionListener; import org.jivesoftware.smack.Manager; import org.jivesoftware.smack.PacketInterceptor; import org.jivesoftware.smack.PacketListener; @@ -66,14 +66,15 @@ import java.security.NoSuchAlgorithmException; * Keeps track of entity capabilities. * * @author Florian Schmaus + * @see XEP-0115: Entity Capabilities */ public class EntityCapsManager extends Manager { public static final String NAMESPACE = "http://jabber.org/protocol/caps"; public static final String ELEMENT = "c"; - private static final String ENTITY_NODE = "http://www.igniterealtime.org/projects/smack"; private static final Map SUPPORTED_HASHES = new HashMap(); + private static String DEFAULT_ENTITY_NODE = "http://www.igniterealtime.org/projects/smack"; protected static EntityCapsPersistentCache persistentCache; @@ -82,6 +83,12 @@ public class EntityCapsManager extends Manager { private static Map instances = Collections .synchronizedMap(new WeakHashMap()); + private static final PacketFilter PRESENCES_WITH_CAPS = new AndFilter(new PacketTypeFilter(Presence.class), new PacketExtensionFilter( + ELEMENT, NAMESPACE)); + private static final PacketFilter PRESENCES_WITHOUT_CAPS = new AndFilter(new PacketTypeFilter(Presence.class), new NotFilter(new PacketExtensionFilter( + ELEMENT, NAMESPACE))); + private static final PacketFilter PRESENCES = new PacketTypeFilter(Presence.class); + /** * Map of (node + '#" + hash algorithm) to DiscoverInfo data */ @@ -110,11 +117,14 @@ public class EntityCapsManager extends Manager { } } - private ServiceDiscoveryManager sdm; - private boolean entityCapsEnabled; - private String currentCapsVersion; - private boolean presenceSend = false; - private Queue lastLocalCapsVersions = new ConcurrentLinkedQueue(); + /** + * Set the default entity node that will be used for new EntityCapsManagers + * + * @param entityNode + */ + public static void setDefaultEntityNode(String entityNode) { + DEFAULT_ENTITY_NODE = entityNode; + } /** * Add DiscoverInfo to the database. @@ -219,31 +229,31 @@ public class EntityCapsManager extends Manager { ((Cache) caps).setMaxCacheSize(maxCacheSize); } + private ServiceDiscoveryManager sdm; + private boolean entityCapsEnabled; + private String currentCapsVersion; + private boolean presenceSend = false; + private Queue lastLocalCapsVersions = new ConcurrentLinkedQueue(); + + /** + * The entity node String used by this EntityCapsManager instance. + */ + private String entityNode = DEFAULT_ENTITY_NODE; + private EntityCapsManager(XMPPConnection connection) { super(connection); this.sdm = ServiceDiscoveryManager.getInstanceFor(connection); instances.put(connection, this); - connection.addConnectionListener(new ConnectionListener() { + connection.addConnectionListener(new AbstractConnectionListener() { + @Override public void connectionClosed() { presenceSend = false; } - + @Override public void connectionClosedOnError(Exception e) { presenceSend = false; } - - public void reconnectionFailed(Exception e) { - // ignore - } - - public void reconnectingIn(int seconds) { - // ignore - } - - public void reconnectionSuccessful() { - // ignore - } }); // This calculates the local entity caps version @@ -252,8 +262,6 @@ public class EntityCapsManager extends Manager { if (autoEnableEntityCaps) enableEntityCaps(); - PacketFilter packetFilter = new AndFilter(new PacketTypeFilter(Presence.class), new PacketExtensionFilter( - ELEMENT, NAMESPACE)); connection.addPacketListener(new PacketListener() { // Listen for remote presence stanzas with the caps extension // If we receive such a stanza, record the JID and nodeVer @@ -276,10 +284,8 @@ public class EntityCapsManager extends Manager { jidCaps.put(from, new NodeVerHash(node, ver, hash)); } - }, packetFilter); + }, PRESENCES_WITH_CAPS); - packetFilter = new AndFilter(new PacketTypeFilter(Presence.class), new NotFilter(new PacketExtensionFilter( - ELEMENT, NAMESPACE))); connection.addPacketListener(new PacketListener() { @Override public void processPacket(Packet packet) { @@ -288,30 +294,28 @@ public class EntityCapsManager extends Manager { String from = packet.getFrom(); jidCaps.remove(from); } - }, packetFilter); + }, PRESENCES_WITHOUT_CAPS); - packetFilter = new PacketTypeFilter(Presence.class); connection.addPacketSendingListener(new PacketListener() { @Override public void processPacket(Packet packet) { presenceSend = true; } - }, packetFilter); + }, PRESENCES); // Intercept presence packages and add caps data when intended. // XEP-0115 specifies that a client SHOULD include entity capabilities // with every presence notification it sends. - PacketFilter capsPacketFilter = new PacketTypeFilter(Presence.class); PacketInterceptor packetInterceptor = new PacketInterceptor() { public void interceptPacket(Packet packet) { if (!entityCapsEnabled) return; - CapsExtension caps = new CapsExtension(ENTITY_NODE, getCapsVersion(), "sha-1"); + CapsExtension caps = new CapsExtension(entityNode, getCapsVersion(), "sha-1"); packet.addExtension(caps); } }; - connection.addPacketInterceptor(packetInterceptor, capsPacketFilter); + connection.addPacketInterceptor(packetInterceptor, PRESENCES); // It's important to do this as last action. Since it changes the // behavior of the SDM in some ways sdm.setEntityCapsManager(this); @@ -330,14 +334,14 @@ public class EntityCapsManager extends Manager { return entityCapsManager; } - public void enableEntityCaps() { + public synchronized void enableEntityCaps() { // Add Entity Capabilities (XEP-0115) feature node. sdm.addFeature(NAMESPACE); updateLocalEntityCaps(); entityCapsEnabled = true; } - public void disableEntityCaps() { + public synchronized void disableEntityCaps() { entityCapsEnabled = false; sdm.removeFeature(NAMESPACE); } @@ -346,6 +350,11 @@ public class EntityCapsManager extends Manager { return entityCapsEnabled; } + public void setEntityNode(String entityNode) { + this.entityNode = entityNode; + updateLocalEntityCaps(); + } + /** * Remove a record telling what entity caps node a user has. * @@ -374,7 +383,7 @@ public class EntityCapsManager extends Manager { * @return the local NodeVer */ public String getLocalNodeVer() { - return ENTITY_NODE + '#' + getCapsVersion(); + return entityNode + '#' + getCapsVersion(); } /** @@ -414,19 +423,19 @@ public class EntityCapsManager extends Manager { sdm.addDiscoverInfoTo(discoverInfo); currentCapsVersion = generateVerificationString(discoverInfo, "sha-1"); - addDiscoverInfoByNode(ENTITY_NODE + '#' + currentCapsVersion, discoverInfo); + addDiscoverInfoByNode(entityNode + '#' + currentCapsVersion, discoverInfo); if (lastLocalCapsVersions.size() > 10) { String oldCapsVersion = lastLocalCapsVersions.poll(); - sdm.removeNodeInformationProvider(ENTITY_NODE + '#' + oldCapsVersion); + sdm.removeNodeInformationProvider(entityNode + '#' + oldCapsVersion); } lastLocalCapsVersions.add(currentCapsVersion); caps.put(currentCapsVersion, discoverInfo); if (connection != null) - jidCaps.put(connection.getUser(), new NodeVerHash(ENTITY_NODE, currentCapsVersion, "sha-1")); + jidCaps.put(connection.getUser(), new NodeVerHash(entityNode, currentCapsVersion, "sha-1")); final List identities = new LinkedList(ServiceDiscoveryManager.getInstanceFor(connection).getIdentities()); - sdm.setNodeInformationProvider(ENTITY_NODE + '#' + currentCapsVersion, new NodeInformationProvider() { + sdm.setNodeInformationProvider(entityNode + '#' + currentCapsVersion, new NodeInformationProvider() { List features = sdm.getFeaturesList(); List packetExtensions = sdm.getExtendedInfoAsList(); diff --git a/extensions/src/main/java/org/jivesoftware/smackx/caps/packet/CapsExtension.java b/extensions/src/main/java/org/jivesoftware/smackx/caps/packet/CapsExtension.java index 5dbdb5dc4..ef93a60aa 100644 --- a/extensions/src/main/java/org/jivesoftware/smackx/caps/packet/CapsExtension.java +++ b/extensions/src/main/java/org/jivesoftware/smackx/caps/packet/CapsExtension.java @@ -1,6 +1,6 @@ /** * - * Copyright © 2009 Jonas Ådahl, 2011-2013 Florian Schmaus + * Copyright © 2009 Jonas Ådahl, 2011-2014 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.jivesoftware.smackx.caps.packet; import org.jivesoftware.smack.packet.PacketExtension; @@ -22,10 +21,7 @@ import org.jivesoftware.smackx.caps.EntityCapsManager; public class CapsExtension implements PacketExtension { - private String node, ver, hash; - - public CapsExtension() { - } + private final String node, ver, hash; public CapsExtension(String node, String version, String hash) { this.node = node; @@ -45,26 +41,14 @@ public class CapsExtension implements PacketExtension { return node; } - public void setNode(String node) { - this.node = node; - } - public String getVer() { return ver; } - public void setVer(String ver) { - this.ver = ver; - } - public String getHash() { return hash; } - public void setHash(String hash) { - this.hash = hash; - } - /* * "; - - return xml; } }