mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-11-22 12:02:05 +01:00
Make EntityCapsManager's node version configurable
Also some cleanup of caps code.
This commit is contained in:
parent
4fb5b85806
commit
bd6828db38
2 changed files with 51 additions and 60 deletions
|
@ -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 <a href="http://www.xmpp.org/extensions/xep-0115.html">XEP-0115: Entity Capabilities</a>
|
||||
*/
|
||||
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<String, MessageDigest> SUPPORTED_HASHES = new HashMap<String, MessageDigest>();
|
||||
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<XMPPConnection, EntityCapsManager> instances = Collections
|
||||
.synchronizedMap(new WeakHashMap<XMPPConnection, EntityCapsManager>());
|
||||
|
||||
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<String> lastLocalCapsVersions = new ConcurrentLinkedQueue<String>();
|
||||
/**
|
||||
* 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<String> lastLocalCapsVersions = new ConcurrentLinkedQueue<String>();
|
||||
|
||||
/**
|
||||
* 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<Identity> identities = new LinkedList<Identity>(ServiceDiscoveryManager.getInstanceFor(connection).getIdentities());
|
||||
sdm.setNodeInformationProvider(ENTITY_NODE + '#' + currentCapsVersion, new NodeInformationProvider() {
|
||||
sdm.setNodeInformationProvider(entityNode + '#' + currentCapsVersion, new NodeInformationProvider() {
|
||||
List<String> features = sdm.getFeaturesList();
|
||||
List<PacketExtension> packetExtensions = sdm.getExtendedInfoAsList();
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
* <c xmlns='http://jabber.org/protocol/caps'
|
||||
* hash='sha-1'
|
||||
|
@ -73,11 +57,9 @@ public class CapsExtension implements PacketExtension {
|
|||
*
|
||||
*/
|
||||
public String toXML() {
|
||||
String xml = "<" + EntityCapsManager.ELEMENT + " xmlns=\"" + EntityCapsManager.NAMESPACE + "\" " +
|
||||
return "<" + EntityCapsManager.ELEMENT + " xmlns=\"" + EntityCapsManager.NAMESPACE + "\" " +
|
||||
"hash=\"" + hash + "\" " +
|
||||
"node=\"" + node + "\" " +
|
||||
"ver=\"" + ver + "\"/>";
|
||||
|
||||
return xml;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue