First bits of a XEP-0115 implementation based on Jonas Adahl's smack fork.

cusax-fix
Emil Ivov 16 years ago
parent 1dc815b6be
commit 5b6da1b68d

@ -6,28 +6,17 @@
*/
package net.java.sip.communicator.impl.protocol.jabber.extensions.caps;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.filter.AndFilter;
import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.filter.PacketExtensionFilter;
import org.jivesoftware.smack.provider.ProviderManager;
import org.jivesoftware.smack.util.Base64;
import org.jivesoftware.smack.*;
import org.jivesoftware.smack.packet.*;
import org.jivesoftware.smack.filter.*;
import org.jivesoftware.smack.provider.*;
import org.jivesoftware.smack.util.*;
import org.jivesoftware.smackx.*;
import org.jivesoftware.smackx.packet.*;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.concurrent.*;
import java.security.*;
/**
* Keeps track of entity capabilities.
@ -38,12 +27,12 @@ public class EntityCapsManager
{
/**
* The has method we use for generating the ver string.
* The hash method we use for generating the ver string.
*/
public static final String HASH_METHOD = "sha-1";
//public static final String HASH_METHOD = "sha-1";
/**
* The has method we use for generating the ver string.
* The hash method we use for generating the ver string.
*/
public static final String HASH_METHOD_CAPS = "SHA-1";
@ -69,23 +58,27 @@ public class EntityCapsManager
/**
* CapsVerListeners gets notified when the version string is changed.
*/
private Set<CapsVerListener> capsVerListeners = new CopyOnWriteArraySet<CapsVerListener>();
private Set<CapsVerListener> capsVerListeners
= new CopyOnWriteArraySet<CapsVerListener>();
private String currentCapsVersion = null;
/**
* The current hash of our version and supported features.
*/
private String currentCapsVersion = null;
static
{
ProviderManager.getInstance().addExtensionProvider(
CapsExtension.NODE_NAME, CapsExtension.XMLNS,
new CapsExtensionProvider());
CapsPacketExtension.ELEMENT_NAME, CapsPacketExtension.NAMESPACE,
new CapsProvider());
}
/**
* Add DiscoverInfo to the database.
* Add {@link DiscoverInfo} to the our caps database.
*
* @param node The node name. Could be for example
* "http://psi-im.org#q07IKJEyjvHSyhy//CH0CxmKi8w=".
* @param info DiscoverInfo for the specified node.
* "http://sip-communicator.org#q07IKJEyjvHSyhy//CH0CxmKi8w=".
* @param info {@link DiscoverInfo} for the specified node.
*/
public static void addDiscoverInfoByNode(String node, DiscoverInfo info)
{
@ -188,6 +181,11 @@ public static DiscoverInfo getDiscoverInfoByNode(String node)
return caps.get(node);
}
/**
* Removes from, to and packet-id from <tt>info</tt>.
*
* @param info the {@link DiscoverInfo} that we'd like to cleanup.
*/
private static void cleanupDicsoverInfo(DiscoverInfo info)
{
info.setFrom(null);
@ -195,30 +193,72 @@ private static void cleanupDicsoverInfo(DiscoverInfo info)
info.setPacketID(null);
}
public void addPacketListener(Connection connection)
/**
* Registers this Manager's listener with <tt>connection</tt>.
*
* @param connection the connection that we'd like this manager to register
* with.
*/
public void addPacketListener(XMPPConnection connection)
{
PacketFilter f = new AndFilter(new PacketTypeFilter(Presence.class),
new PacketExtensionFilter(CapsExtension.NODE_NAME,
CapsExtension.XMLNS));
connection.addPacketListener(new CapsPacketListener(), f);
PacketFilter filter
= new AndFilter(new PacketTypeFilter(Presence.class),
new PacketExtensionFilter(CapsPacketExtension.ELEMENT_NAME,
CapsPacketExtension.NAMESPACE));
connection.addPacketListener(new CapsPacketListener(), filter);
}
/**
* Adds <tt>listener</tt> to the list of {@link CapsVerListener}s that we
* notify when new features occur and the version hash needs to be
* regenerated. The method would also notify <tt>listener</tt> if our
* current caps version has been generated and is different than
* <tt>null</tt>.
*
* @param listener the {@link CapsVerListener} we'd like to register.
*/
public void addCapsVerListener(CapsVerListener listener)
{
capsVerListeners.add(listener);
synchronized (capsVerListeners)
{
if (capsVerListeners.contains(listener))
return;
if (currentCapsVersion != null)
listener.capsVerUpdated(currentCapsVersion);
capsVerListeners.add(listener);
if (currentCapsVersion != null)
listener.capsVerUpdated(currentCapsVersion);
}
}
/**
* Removes <tt>listener</tt> from the list of currently registered
* {@link CapsVerListener}s.
*
* @param listener the {@link CapsVerListener} we'd like to unregister.
*/
public void removeCapsVerListener(CapsVerListener listener)
{
capsVerListeners.remove(listener);
synchronized(capsVerListeners)
{
capsVerListeners.remove(listener);
}
}
private void notifyCapsVerListeners()
/**
* Notifies all currently registered {@link CapsVerListener}s that the
* version hash has changed.
*/
private void fireCapsVerChanged()
{
for (CapsVerListener listener : capsVerListeners)
List<CapsVerListener> listenersCopy = null;
synchronized(capsVerListeners)
{
listenersCopy = new ArrayList<CapsVerListener>(capsVerListeners);
}
for (CapsVerListener listener : listenersCopy)
{
listener.capsVerUpdated(currentCapsVersion);
}
@ -238,6 +278,14 @@ private void notifyCapsVerListeners()
// Calculate Entity Caps Version String
// /////////
/**
* Computes and returns the SHA-1 hash of the specified <tt>capsString</tt>.
*
* @param capsString
*
* @return the SHA-1 hash of <tt>capsString</tt> or <tt>null</tt> if
* generating the hash has failed.
*/
private static String capsToHash(String capsString)
{
try
@ -245,7 +293,8 @@ private static String capsToHash(String capsString)
MessageDigest md = MessageDigest.getInstance(HASH_METHOD_CAPS);
byte[] digest = md.digest(capsString.getBytes());
return Base64.encodeBytes(digest);
} catch (NoSuchAlgorithmException nsae)
}
catch (NoSuchAlgorithmException nsae)
{
return null;
}
@ -349,7 +398,7 @@ public void setCurrentCapsVersion(DiscoverInfo discoverInfo,
{
currentCapsVersion = capsVersion;
addDiscoverInfoByNode(getNode() + "#" + capsVersion, discoverInfo);
notifyCapsVerListeners();
fireCapsVerChanged();
}
class CapsPacketListener implements PacketListener
@ -357,8 +406,9 @@ class CapsPacketListener implements PacketListener
public void processPacket(Packet packet)
{
CapsExtension ext = (CapsExtension) packet.getExtension(
CapsExtension.NODE_NAME, CapsExtension.XMLNS);
CapsPacketExtension ext = (CapsPacketExtension) packet.getExtension(
CapsPacketExtension.ELEMENT_NAME,
CapsPacketExtension.NAMESPACE);
String nodeVer = ext.getNode() + "#" + ext.getVersion();
String user = packet.getFrom();

Loading…
Cancel
Save