diff --git a/src/net/java/sip/communicator/impl/contactlist/MclStorageManager.java b/src/net/java/sip/communicator/impl/contactlist/MclStorageManager.java
index e685d3af0..8becadeb4 100644
--- a/src/net/java/sip/communicator/impl/contactlist/MclStorageManager.java
+++ b/src/net/java/sip/communicator/impl/contactlist/MclStorageManager.java
@@ -2071,18 +2071,4 @@ public void metaContactAvatarUpdated(MetaContactAvatarUpdateEvent evt)
{
// TODO Store MetaContact avatar.
}
-
- /**
- * Indicates that the capabilities of a given MetaContact have
- * changed.
- * @param evt the MetaContactCapabilitiesEvent that notified us
- */
- public void metaContactCapabilitiesChanged(MetaContactCapabilitiesEvent evt)
- {
- /*
- * The OperationSet capabilities of MetaContact are not pesistent so
- * MclStorageManager has nothing to do in response to
- * MetaContactCapabilitiesEvent.
- */
- }
}
diff --git a/src/net/java/sip/communicator/impl/contactlist/MetaContactImpl.java b/src/net/java/sip/communicator/impl/contactlist/MetaContactImpl.java
index c1ee86e95..f82765bff 100644
--- a/src/net/java/sip/communicator/impl/contactlist/MetaContactImpl.java
+++ b/src/net/java/sip/communicator/impl/contactlist/MetaContactImpl.java
@@ -36,6 +36,12 @@ public class MetaContactImpl
*/
private final List protoContacts = new Vector();
+ /**
+ * The list of capabilities of the meta contact.
+ */
+ private final Map> capabilities
+ = new HashMap>();
+
/**
* The number of contacts online in this meta contact.
*/
@@ -204,8 +210,24 @@ public List getContactsForOperationSet(
for (Contact contact : protoContacts)
{
- if(contact.getProtocolProvider()
- .getOperationSet(opSetClass) != null)
+ ProtocolProviderService contactProvider
+ = contact.getProtocolProvider();
+
+ // First try to ask the capabilities operation set if such is
+ // available.
+ OperationSetContactCapabilities capOpSet = contactProvider
+ .getOperationSet(OperationSetContactCapabilities.class);
+
+ if (capOpSet != null)
+ {
+ List capContacts
+ = capabilities.get(opSetClass.getName());
+ if (capContacts != null && capContacts.contains(contact))
+ {
+ opSetContacts.add( contact );
+ }
+ }
+ else if (contactProvider.getOperationSet(opSetClass) != null)
opSetContacts.add( contact );
}
@@ -381,9 +403,13 @@ public Contact getDefaultContact(Class extends OperationSet> operationSet)
if (capOpSet != null)
{
- if (capOpSet.getOperationSet(defaultContact, operationSet)
- != null)
+ List capContacts
+ = capabilities.get(operationSet.getName());
+
+ if (capContacts != null && capContacts.contains(defaultContact))
+ {
defaultOpSetContact = defaultContact;
+ }
}
else if (contactProvider.getOperationSet(operationSet) != null)
defaultOpSetContact = defaultContact;
@@ -407,9 +433,14 @@ else if (contactProvider.getOperationSet(operationSet) != null)
// the needed opset.
if (capOpSet != null)
{
- if (capOpSet.getOperationSet(defaultContact, operationSet)
- == null)
+ List capContacts
+ = capabilities.get(operationSet.getName());
+
+ if (capContacts == null
+ || !capContacts.contains(defaultContact))
+ {
continue;
+ }
}
else if (contactProvider.getOperationSet(operationSet) == null)
continue;
@@ -1252,6 +1283,109 @@ else if (value == null)
data[index + 1] = value;
}
+ /**
+ * Loads the capabilities of this MetaContact.
+ *
+ * @param protocolProvider the ProtocolProviderService, for which
+ * we're loading the capabilities
+ * @param capOpSet the OperationSetContactCapabilities
+ * through which we obtain the capability information
+ */
+ public void loadCapabilities(
+ ProtocolProviderService protocolProvider,
+ OperationSetContactCapabilities capOpSet)
+ {
+ Iterator contactIter = getContactsForProvider(protocolProvider);
+
+ while (contactIter.hasNext())
+ {
+ Contact contact = contactIter.next();
+
+ addCapabilities(contact,
+ capOpSet.getSupportedOperationSets(contact));
+ }
+ }
+
+ /**
+ * Updates the capabilities for the given contact.
+ *
+ * @param contact the Contact, which capabilities have changed
+ * @param opSets the new updated set of operation sets
+ */
+ public void updateCapabilities( Contact contact,
+ Map opSets)
+ {
+ OperationSetContactCapabilities capOpSet
+ = contact.getProtocolProvider().getOperationSet(
+ OperationSetContactCapabilities.class);
+
+ // This should not happen, because this method is called explicitly for
+ // events coming from the capabilities operation set.
+ if (capOpSet == null)
+ return;
+
+ removeCapabilities(contact, opSets);
+ addCapabilities(contact, opSets);
+ }
+
+ private void removeCapabilities(Contact contact,
+ Map opSets)
+ {
+ Iterator caps = this.capabilities.keySet().iterator();
+
+ Set contactNewCaps = opSets.keySet();
+
+ while (caps.hasNext())
+ {
+ String opSetName = caps.next();
+ List contactsForCap = capabilities.get(opSetName);
+
+ if (contactsForCap.contains(contact)
+ && !contactNewCaps.contains(opSetName))
+ {
+ contactsForCap.remove(contact);
+
+ if (contactsForCap.size() == 0)
+ capabilities.remove(opSetName);
+ }
+ }
+ }
+
+ /**
+ * Adds the capabilities of the given contact.
+ *
+ * @param contact the Contact, which capabilities we add
+ * @param opSets the map of operation sets supported by the contact
+ */
+ private void addCapabilities( Contact contact,
+ Map opSets)
+ {
+ Iterator contactNewCaps = opSets.keySet().iterator();
+
+ while (contactNewCaps.hasNext())
+ {
+ String newCap = contactNewCaps.next();
+
+ List capContacts = null;
+ if (!capabilities.containsKey(newCap))
+ {
+ capContacts = new LinkedList();
+ capContacts.add(contact);
+
+ capabilities.put(newCap, capContacts);
+ }
+ else
+ {
+ capContacts = capabilities.get(newCap);
+
+ if (!capContacts.contains(contact))
+ {
+ capContacts.add(contact);
+ }
+ }
+ }
+ }
+
/**
* Determines the index in #data of a specific key.
*
diff --git a/src/net/java/sip/communicator/impl/contactlist/MetaContactListServiceImpl.java b/src/net/java/sip/communicator/impl/contactlist/MetaContactListServiceImpl.java
index bdda5f95a..e28cb3739 100644
--- a/src/net/java/sip/communicator/impl/contactlist/MetaContactListServiceImpl.java
+++ b/src/net/java/sip/communicator/impl/contactlist/MetaContactListServiceImpl.java
@@ -1542,6 +1542,51 @@ private void synchronizeOpSetWithLocalContactList(
.addServerStoredGroupChangeListener(clGroupEventHandler);
}
+ /**
+ * Goes through the MetaContacts in the given group and
+ * loads contact capabilities for contained protocol contacts through the
+ * given capabilities operation set.
+ */
+ private class LoadCapabilitiesThread extends Thread
+ {
+ private ProtocolProviderService protocolProvider;
+
+ private OperationSetContactCapabilities capabilitiesOpSet;
+
+ public LoadCapabilitiesThread(
+ ProtocolProviderService protocolProvider,
+ OperationSetContactCapabilities capabilitiesOpSet)
+ {
+ this.protocolProvider = protocolProvider;
+ this.capabilitiesOpSet = capabilitiesOpSet;
+ }
+
+ public void run()
+ {
+ loadCapabilities(rootMetaGroup);
+ }
+
+ private void loadCapabilities(MetaContactGroup group)
+ {
+ Iterator metaContactIter = group.getChildContacts();
+
+ while (metaContactIter.hasNext())
+ {
+ MetaContact metaContact = metaContactIter.next();
+
+ ((MetaContactImpl) metaContact)
+ .loadCapabilities(protocolProvider, capabilitiesOpSet);
+ }
+
+ Iterator subGroupIter = group.getSubgroups();
+
+ while (subGroupIter.hasNext())
+ {
+ loadCapabilities(subGroupIter.next());
+ }
+ }
+ }
+
/**
* Creates meta contacts and meta contact groups for all children of the
* specified contactGroup and adds them to metaGroup
@@ -1689,7 +1734,10 @@ private synchronized void handleProviderAdded(
= provider.getOperationSet(OperationSetContactCapabilities.class);
if (capOpSet != null)
+ {
+ new LoadCapabilitiesThread(provider, capOpSet).start();
capOpSet.addContactCapabilitiesListener(this);
+ }
}
/**
@@ -3234,57 +3282,13 @@ public void supportedOperationSetsChanged(ContactCapabilitiesEvent event)
if(metaContactImpl == null)
return;
- fireCapabilitiesEvent(metaContactImpl,
- MetaContactCapabilitiesEvent.SUPPORTED_OPERATION_SETS_CHANGED);
- }
-
- /**
- * Fires a new MetaContactCapabilitiesEvent to notify the
- * registered MetaContactCapabilitiesListeners that this
- * MetaContact has changed its list of OperationSet
- * capabilities.
- *
- * @param metaContact the source MetaContact, which capabilities
- * has changed
- * @param eventID the ID of the event to be fired which indicates the
- * specifics of the change of the list of OperationSet capabilities
- * of the specified sourceContact and the details of the event
- */
- private void fireCapabilitiesEvent(MetaContact metaContact, int eventID)
- {
- MetaContactListListener[] listeners;
+ Contact contact = event.getSourceContact();
- synchronized (metaContactListListeners)
- {
- listeners
- = metaContactListListeners.toArray(
- new MetaContactListListener[
- metaContactListListeners.size()]);
- }
- if (listeners.length != 0)
- {
- MetaContactCapabilitiesEvent event
- = new MetaContactCapabilitiesEvent(metaContact, eventID);
+ metaContactImpl.updateCapabilities(contact, event.getOperationSets());
- for (MetaContactListListener listener : listeners)
- {
- switch (eventID)
- {
- case MetaContactCapabilitiesEvent
- .SUPPORTED_OPERATION_SETS_CHANGED:
- listener.metaContactCapabilitiesChanged(event);
- break;
- default:
- if (logger.isDebugEnabled())
- {
- logger.debug(
- "Cannot fire MetaContactCapabilitiesEvent with"
- + " unsupported eventID: "
- + eventID);
- }
- throw new IllegalArgumentException("eventID");
- }
- }
- }
+ fireProtoContactEvent( contact,
+ ProtoContactEvent.PROTO_CONTACT_MODIFIED,
+ metaContactImpl,
+ metaContactImpl);
}
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/MetaContactChatSession.java b/src/net/java/sip/communicator/impl/gui/main/chat/MetaContactChatSession.java
index 9c497b12b..6c5405e37 100644
--- a/src/net/java/sip/communicator/impl/gui/main/chat/MetaContactChatSession.java
+++ b/src/net/java/sip/communicator/impl/gui/main/chat/MetaContactChatSession.java
@@ -372,9 +372,6 @@ public void metaContactRemoved(MetaContactEvent evt)
public void metaContactAvatarUpdated(MetaContactAvatarUpdateEvent evt) {}
- public void metaContactCapabilitiesChanged(MetaContactCapabilitiesEvent evt)
- {}
-
/**
* Implements MetaContactListListener.metaContactRenamed method.
* When a meta contact is renamed, updates all related labels in this
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactList.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactList.java
index 774a5b82c..c713ad62f 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactList.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactList.java
@@ -219,9 +219,6 @@ public void metaContactMoved(MetaContactMovedEvent evt)
public void metaContactAvatarUpdated(MetaContactAvatarUpdateEvent evt) {}
- public void metaContactCapabilitiesChanged(
- MetaContactCapabilitiesEvent evt) {}
-
/**
* Handles the MetaContactGroupEvent. Refreshes the list model
* when a new meta contact group has been added.
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/TreeContactList.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/TreeContactList.java
index 4bb670d72..4067dc346 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/TreeContactList.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/TreeContactList.java
@@ -446,7 +446,25 @@ public void protoContactAdded(ProtoContactEvent evt)
}
}
- public void protoContactModified(ProtoContactEvent evt) {}
+ /**
+ * Notifies the UI representation of the parent MetaContact that
+ * this contact has been modified.
+ *
+ * @param evt the ProtoContactEvent that notified us
+ */
+ public void protoContactModified(ProtoContactEvent evt)
+ {
+ UIContact uiContact = MetaContactListSource
+ .getUIContact(evt.getNewParent());
+
+ if (uiContact != null)
+ {
+ ContactNode contactNode = uiContact.getContactNode();
+
+ if (contactNode != null)
+ treeModel.nodeChanged(contactNode);
+ }
+ }
/**
* Adds the new MetaContact parent and removes the old one if the
@@ -596,29 +614,6 @@ public void metaGroupReceived(MetaGroupQueryEvent event)
MetaContactListSource.createUIGroup(event.getMetaGroup()), true);
}
- /**
- * Updates the corresponding node when the list of the OperationSet
- * capabilities of a MetaContact has changed.
- * @param evt a ContactCapabilitiesEvent with ID
- * {@link MetaContactCapabilitiesEvent#SUPPORTED_OPERATION_SETS_CHANGED}
- * which specifies the Contact whose list of OperationSet
- * capabilities has changed
- */
- public void metaContactCapabilitiesChanged(MetaContactCapabilitiesEvent evt)
- {
- UIContact uiContact = MetaContactListSource
- .getUIContact(evt.getSourceContact());
-
- if (uiContact != null && evt.getEventID()
- == MetaContactCapabilitiesEvent.SUPPORTED_OPERATION_SETS_CHANGED)
- {
- ContactNode contactNode = uiContact.getContactNode();
-
- if (contactNode != null)
- treeModel.nodeChanged(contactNode);
- }
- }
-
/**
* Indicates that the status of a query has changed.
* @param event the ContactQueryStatusEvent that notified us
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetContactCapabilitiesJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetContactCapabilitiesJabberImpl.java
index c7eca99aa..051a017fe 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetContactCapabilitiesJabberImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetContactCapabilitiesJabberImpl.java
@@ -23,10 +23,12 @@
* Jabber Contact in question.
*
* @author Lubomir Marinov
+ * @author Yana Stamcheva
*/
public class OperationSetContactCapabilitiesJabberImpl
extends AbstractOperationSetContactCapabilities
- implements UserCapsNodeListener
+ implements UserCapsNodeListener,
+ ContactPresenceStatusListener
{
/**
* The Logger used by the
@@ -66,6 +68,15 @@ public class OperationSetContactCapabilitiesJabberImpl
ProtocolProviderServiceJabberImpl.URN_XMPP_JINGLE_RTP,
ProtocolProviderServiceJabberImpl.URN_XMPP_JINGLE_RTP_AUDIO
});
+
+ OPERATION_SETS_TO_FEATURES.put(
+ OperationSetVideoTelephony.class,
+ new String[]
+ {
+ ProtocolProviderServiceJabberImpl.URN_XMPP_JINGLE,
+ ProtocolProviderServiceJabberImpl.URN_XMPP_JINGLE_RTP,
+ ProtocolProviderServiceJabberImpl.URN_XMPP_JINGLE_RTP_VIDEO
+ });
}
/**
@@ -86,6 +97,12 @@ public OperationSetContactCapabilitiesJabberImpl(
ProtocolProviderServiceJabberImpl parentProvider)
{
super(parentProvider);
+
+ OperationSetPresence presenceOpSet
+ = parentProvider.getOperationSet(OperationSetPresence.class);
+
+ if (presenceOpSet != null)
+ presenceOpSet.addContactPresenceStatusListener(this);
}
/**
@@ -120,47 +137,11 @@ protected U getOperationSet(
Class opsetClass,
boolean online)
{
- U opset = parentProvider.getOperationSet(opsetClass);
-
- if (opset == null)
- return null;
-
- /*
- * If the specified contact is offline, don't query its features (they
- * should fail anyway).
- */
- if (!online)
- {
- if (OFFLINE_OPERATION_SETS.contains(opsetClass))
- return opset;
- else
- return null;
- }
-
- /*
- * If we know the features required for the support of opsetClass, check
- * whether the contact supports them. Otherwise, presume the contact
- * possesses the opsetClass capability in light of the fact that we miss
- * any knowledge of the opsetClass whatsoever.
- */
- if (OPERATION_SETS_TO_FEATURES.containsKey(opsetClass))
- {
- String[] features = OPERATION_SETS_TO_FEATURES.get(opsetClass);
+ String jid = parentProvider.getFullJid(contact);
+ if (jid == null)
+ jid = contact.getAddress();
- /*
- * Either we've completely disabled the opsetClass capability by
- * mapping it to the null list of features or we've mapped it to an
- * actual list of features which are to be checked whether the
- * contact supports them.
- */
- if ((features == null)
- || ((features.length != 0)
- && !parentProvider.isFeatureListSupported(
- parentProvider.getFullJid(contact),
- features)))
- opset = null;
- }
- return opset;
+ return getOperationSet(jid, opsetClass, online);
}
/**
@@ -183,13 +164,43 @@ protected U getOperationSet(
* Contact)
*/
@Override
- @SuppressWarnings("unchecked")
protected Map getSupportedOperationSets(
Contact contact,
boolean online)
+ {
+ String jid = parentProvider.getFullJid(contact);
+ if (jid == null)
+ jid = contact.getAddress();
+
+ return getSupportedOperationSets(jid, online);
+ }
+
+ /**
+ * Gets the OperationSets supported by a specific Contact.
+ * The returned OperationSets are considered by the associated
+ * protocol provider to capabilities possessed by the specified
+ * contact.
+ *
+ * @param jid the Contact for which the supported
+ * OperationSet capabilities are to be retrieved
+ * @param online true if contact is online; otherwise,
+ * false
+ * @return a Map listing the OperationSets considered by
+ * the associated protocol provider to be supported by the specified
+ * contact (i.e. to be possessed as capabilities). Each supported
+ * OperationSet capability is represented by a Map.Entry
+ * with key equal to the OperationSet class name and value equal to
+ * the respective OperationSet instance
+ * @see AbstractOperationSetContactCapabilities#getSupportedOperationSets(
+ * Contact)
+ */
+ @SuppressWarnings("unchecked")
+ private Map getSupportedOperationSets(String jid,
+ boolean online)
{
Map supportedOperationSets
- = super.getSupportedOperationSets(contact, online);
+ = parentProvider.getSupportedOperationSets();
+
int supportedOperationSetCount = supportedOperationSets.size();
Map contactSupportedOperationSets
= new HashMap(supportedOperationSetCount);
@@ -204,7 +215,6 @@ protected Map getSupportedOperationSets(
try
{
-
opsetClass
= (Class extends OperationSet>)
Class.forName(opsetClassName);
@@ -220,7 +230,7 @@ protected Map getSupportedOperationSets(
if (opsetClass != null)
{
OperationSet opset
- = getOperationSet(contact, opsetClass, online);
+ = getOperationSet(jid, opsetClass, online);
if (opset != null)
{
@@ -234,6 +244,79 @@ protected Map getSupportedOperationSets(
return contactSupportedOperationSets;
}
+ /**
+ * Gets the OperationSet corresponding to the specified
+ * Class and supported by the specified Contact. If the
+ * returned value is non-null, it indicates that the
+ * Contact is considered by the associated protocol provider to
+ * possess the opsetClass capability. Otherwise, the associated
+ * protocol provider considers contact to not have the
+ * opsetClass capability.
+ *
+ * @param the type extending OperationSet for which the
+ * specified contact is to be checked whether it possesses it as a
+ * capability
+ * @param jid the Jabber id for which we're checking supported operation
+ * sets
+ * @param opsetClass the OperationSet Class for which the
+ * specified contact is to be checked whether it possesses it as a
+ * capability
+ * @param online true if contact is online; otherwise,
+ * false
+ * @return the OperationSet corresponding to the specified
+ * opsetClass which is considered by the associated protocol
+ * provider to be possessed as a capability by the specified
+ * contact; otherwise, null
+ * @see AbstractOperationSetContactCapabilities#getOperationSet(Contact,
+ * Class)
+ */
+ private U getOperationSet(String jid,
+ Class opsetClass,
+ boolean online)
+ {
+ U opset = parentProvider.getOperationSet(opsetClass);
+
+ if (opset == null)
+ return null;
+
+ /*
+ * If the specified contact is offline, don't query its features (they
+ * should fail anyway).
+ */
+ if (!online)
+ {
+ if (OFFLINE_OPERATION_SETS.contains(opsetClass))
+ return opset;
+ else
+ return null;
+ }
+
+ /*
+ * If we know the features required for the support of opsetClass, check
+ * whether the contact supports them. Otherwise, presume the contact
+ * possesses the opsetClass capability in light of the fact that we miss
+ * any knowledge of the opsetClass whatsoever.
+ */
+ if (OPERATION_SETS_TO_FEATURES.containsKey(opsetClass))
+ {
+ String[] features = OPERATION_SETS_TO_FEATURES.get(opsetClass);
+
+ /*
+ * Either we've completely disabled the opsetClass capability by
+ * mapping it to the null list of features or we've mapped it to an
+ * actual list of features which are to be checked whether the
+ * contact supports them.
+ */
+ if ((features == null)
+ || ((features.length != 0)
+ && !parentProvider.isFeatureListSupported(
+ jid,
+ features)))
+ opset = null;
+ }
+ return opset;
+ }
+
/**
* Sets the EntityCapsManager which is associated with the
* discoveryManager of {@link #parentProvider}.
@@ -276,15 +359,16 @@ void setDiscoveryManager(ScServiceDiscoveryManager discoveryManager)
*
* @param user the user (full JID)
* @param node the entity caps node#ver
- * @see UserCapsNodeListener#userCapsNodeAdded(String, String)
+ * @param online indicates if the user is currently online
+ * @see UserCapsNodeListener#userCapsNodeAdded(String, String, boolean)
*/
- public void userCapsNodeAdded(String user, String node)
+ public void userCapsNodeAdded(String user, String node, boolean online)
{
/*
* It doesn't matter to us whether a caps node has been added or removed
* for the specified user because we report all changes.
*/
- userCapsNodeRemoved(user, node);
+ userCapsNodeRemoved(user, node, online);
}
/**
@@ -293,9 +377,10 @@ public void userCapsNodeAdded(String user, String node)
*
* @param user the user (full JID)
* @param node the entity caps node#ver
- * @see UserCapsNodeListener#userCapsNodeRemoved(String, String)
+ * @param online indicates if the given user is online
+ * @see UserCapsNodeListener#userCapsNodeRemoved(String, String, boolean)
*/
- public void userCapsNodeRemoved(String user, String node)
+ public void userCapsNodeRemoved(String user, String node, boolean online)
{
OperationSetPresence opsetPresence
= parentProvider.getOperationSet(OperationSetPresence.class);
@@ -305,12 +390,30 @@ public void userCapsNodeRemoved(String user, String node)
String jid = StringUtils.parseBareAddress(user);
Contact contact = opsetPresence.findContactByID(jid);
- if (contact != null)
+ // If the contact isn't null and is online we try to discover the
+ // new set of operation sets and to notify interested parties.
+ // Otherwise we ignore the event.
+ if (contact != null && online)
{
fireContactCapabilitiesEvent(
contact,
- ContactCapabilitiesEvent.SUPPORTED_OPERATION_SETS_CHANGED);
+ ContactCapabilitiesEvent.SUPPORTED_OPERATION_SETS_CHANGED,
+ getSupportedOperationSets(user, online));
}
}
}
+
+ /**
+ * Removes the capabilities when the user goes offline.
+ *
+ * @param evt the ContactPresenceStatusChangeEvent that notified
+ * us
+ */
+ public void contactPresenceStatusChanged(
+ ContactPresenceStatusChangeEvent evt)
+ {
+ // If the user goes offline we ensure to remove the caps node.
+ if (evt.getNewStatus().getStatus() < PresenceStatus.ONLINE_THRESHOLD)
+ capsManager.removeUserCapsNode(evt.getSourceContact().getAddress());
+ }
}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java
index b4acd7df5..373b4d0c5 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/ProtocolProviderServiceJabberImpl.java
@@ -1523,13 +1523,19 @@ public boolean isFeatureSupported(String jid, String feature)
}
/**
- * Returns the full jabber id (jid) corresponding to the given contact.
+ * Returns the full jabber id (jid) corresponding to the given contact. If
+ * the provider is not connected returns null.
*
* @param contact the contact, for which we're looking for a jid
- * @return the jid of the specified contact;
+ * @return the jid of the specified contact or null if the provider is not
+ * yet connected;
*/
public String getFullJid(Contact contact)
{
+ XMPPConnection connection = getConnection();
+ if (connection == null)
+ return null;
+
Roster roster = getConnection().getRoster();
Presence presence = roster.getPresence(contact.getAddress());
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/caps/EntityCapsManager.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/caps/EntityCapsManager.java
index 3a399ecca..9fc5f5681 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/caps/EntityCapsManager.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/caps/EntityCapsManager.java
@@ -179,10 +179,13 @@ private static String getCapsPropertyName(Caps caps)
* @param node the node (of the caps packet extension)
* @param hash the hashing algorithm used to calculate ver
* @param ver the version (of the caps packet extension)
+ * @param online indicates if the user is online
*/
- private void addUserCapsNode(
- String user,
- String node, String hash, String ver)
+ private void addUserCapsNode( String user,
+ String node,
+ String hash,
+ String ver,
+ boolean online)
{
if ((user != null) && (node != null) && (hash != null) && (ver != null))
{
@@ -194,6 +197,7 @@ private void addUserCapsNode(
|| !caps.ver.equals(ver))
{
caps = new Caps(node, hash, ver);
+
userCaps.put(user, caps);
}
else
@@ -213,7 +217,7 @@ private void addUserCapsNode(
String nodeVer = caps.getNodeVer();
for (UserCapsNodeListener listener : listeners)
- listener.userCapsNodeAdded(user, nodeVer);
+ listener.userCapsNodeAdded(user, nodeVer, online);
}
}
}
@@ -264,7 +268,7 @@ public void removeUserCapsNode(String user)
String nodeVer = caps.getNodeVer();
for (UserCapsNodeListener listener : listeners)
- listener.userCapsNodeRemoved(user, nodeVer);
+ listener.userCapsNodeRemoved(user, nodeVer, false);
}
}
}
@@ -829,9 +833,16 @@ public void processPacket(Packet packet)
if (hash != null)
{
+ // Check it the packet indicates that the user is online. We
+ // will use this information to decide if we're going to send
+ // the discover info request.
+ boolean online = false;
+ if (packet instanceof Presence)
+ online = ((Presence) packet).isAvailable();
+
addUserCapsNode(
packet.getFrom(),
- ext.getNode(), hash, ext.getVersion());
+ ext.getNode(), hash, ext.getVersion(), online);
}
}
}
diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/caps/UserCapsNodeListener.java b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/caps/UserCapsNodeListener.java
index e520410a4..c9aca3bfb 100644
--- a/src/net/java/sip/communicator/impl/protocol/jabber/extensions/caps/UserCapsNodeListener.java
+++ b/src/net/java/sip/communicator/impl/protocol/jabber/extensions/caps/UserCapsNodeListener.java
@@ -20,8 +20,9 @@ public interface UserCapsNodeListener
*
* @param user the user (full JID)
* @param node the entity caps node#ver
+ * @param online indicates if the user for which we're notified is online
*/
- public void userCapsNodeAdded(String user, String node);
+ public void userCapsNodeAdded(String user, String node, boolean online);
/**
* Notifies this listener that an EntityCapsManager has removed a
@@ -29,6 +30,7 @@ public interface UserCapsNodeListener
*
* @param user the user (full JID)
* @param node the entity caps node#ver
+ * @param online indicates if the user for which we're notified is online
*/
- public void userCapsNodeRemoved(String user, String node);
+ public void userCapsNodeRemoved(String user, String node, boolean online);
}
diff --git a/src/net/java/sip/communicator/service/contactlist/event/MetaContactCapabilitiesEvent.java b/src/net/java/sip/communicator/service/contactlist/event/MetaContactCapabilitiesEvent.java
deleted file mode 100644
index 37e99e544..000000000
--- a/src/net/java/sip/communicator/service/contactlist/event/MetaContactCapabilitiesEvent.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
- *
- * Distributable under LGPL license.
- * See terms of license at gnu.org.
- */
-package net.java.sip.communicator.service.contactlist.event;
-
-import java.util.*;
-
-import net.java.sip.communicator.service.contactlist.*;
-
-/**
- * Represents an event/EventObject fired by
- * OperationSetClientCapabilities in order to notify about changes in
- * the list of the OperationSet capabilities of a Contact.
- *
- * @author Yana Stamcheva
- */
-public class MetaContactCapabilitiesEvent
- extends EventObject
-{
- /**
- * Serial version UID.
- */
- private static final long serialVersionUID = 0L;
-
- /**ContactList.java
- * The ID of the MetaContactCapabilitiesEvent which notifies about
- * changes in the list of the OperationSet capabilities of a
- * MetaContact.
- */
- public static final int SUPPORTED_OPERATION_SETS_CHANGED = 1;
-
- /**
- * The ID of this event which indicates the specifics of the change in the
- * list of OperationSet capabilities of the associated
- * Contact and the details this event carries.
- */
- private final int eventID;
-
- /**
- * Initializes a new ContactCapabilitiesEvent instance which is to
- * notify about a specific change in the list of OperationSet
- * capabilities of a specific Contact.
- *
- * @param sourceContact the MetaContact which is to be considered
- * the source/cause of the new event
- * @param eventID the ID of the new event which indicates the specifics of
- * the change in the list of OperationSet capabilities of the
- * specified sourceContact and the details to be carried by the new
- * event
- */
- public MetaContactCapabilitiesEvent(MetaContact sourceContact, int eventID)
- {
- super(sourceContact);
-
- this.eventID = eventID;
- }
-
- /**
- * Gets the ID of this event which indicates the specifics of the change in
- * the list of OperationSet capabilities of the associated
- * sourceContact and the details it carries.
- *
- * @return the ID of this event which indicates the specifics of the change
- * in the list of OperationSet capabilities of the associated
- * sourceContact and the details it carries
- */
- public int getEventID()
- {
- return eventID;
- }
-
- /**
- * Gets the MetaContact which is the source/cause of this event i.e.
- * which has changed its list of OperationSet capabilities.
- *
- * @return the MetaContact which is the source/cause of this event
- */
- public MetaContact getSourceContact()
- {
- return (MetaContact) getSource();
- }
-}
\ No newline at end of file
diff --git a/src/net/java/sip/communicator/service/contactlist/event/MetaContactListListener.java b/src/net/java/sip/communicator/service/contactlist/event/MetaContactListListener.java
index 31c81e7ed..84720e076 100644
--- a/src/net/java/sip/communicator/service/contactlist/event/MetaContactListListener.java
+++ b/src/net/java/sip/communicator/service/contactlist/event/MetaContactListListener.java
@@ -126,15 +126,4 @@ public interface MetaContactListListener
* of this event
*/
public void metaContactAvatarUpdated(MetaContactAvatarUpdateEvent evt);
-
- /**
- * Notifies this listener that the list of the OperationSet
- * capabilities of a MetaContact has changed.
- *
- * @param evt a MetaContactCapabilitiesEvent with ID
- * {@link MetaContactCapabilitiesEvent#SUPPORTED_OPERATION_SETS_CHANGED}
- * which specifies the MetaContact whose list of
- * OperationSet capabilities has changed
- */
- public void metaContactCapabilitiesChanged(MetaContactCapabilitiesEvent evt);
}
diff --git a/src/net/java/sip/communicator/service/protocol/AbstractOperationSetContactCapabilities.java b/src/net/java/sip/communicator/service/protocol/AbstractOperationSetContactCapabilities.java
index 15ded1375..1aadc9f6f 100644
--- a/src/net/java/sip/communicator/service/protocol/AbstractOperationSetContactCapabilities.java
+++ b/src/net/java/sip/communicator/service/protocol/AbstractOperationSetContactCapabilities.java
@@ -98,10 +98,12 @@ public void addContactCapabilitiesListener(
* @param eventID the ID of the event to be fired which indicates the
* specifics of the change of the list of OperationSet capabilities
* of the specified sourceContact and the details of the event
+ * @param opSets the new set of operation sets for the given source contact
*/
protected void fireContactCapabilitiesEvent(
Contact sourceContact,
- int eventID)
+ int eventID,
+ Map opSets)
{
ContactCapabilitiesListener[] listeners;
@@ -115,7 +117,7 @@ protected void fireContactCapabilitiesEvent(
if (listeners.length != 0)
{
ContactCapabilitiesEvent event
- = new ContactCapabilitiesEvent(sourceContact, eventID);
+ = new ContactCapabilitiesEvent(sourceContact, eventID, opSets);
for (ContactCapabilitiesListener listener : listeners)
{
diff --git a/src/net/java/sip/communicator/service/protocol/event/ContactCapabilitiesEvent.java b/src/net/java/sip/communicator/service/protocol/event/ContactCapabilitiesEvent.java
index da12de339..cd77656e2 100644
--- a/src/net/java/sip/communicator/service/protocol/event/ContactCapabilitiesEvent.java
+++ b/src/net/java/sip/communicator/service/protocol/event/ContactCapabilitiesEvent.java
@@ -16,6 +16,7 @@
* the list of the OperationSet capabilities of a Contact.
*
* @author Lubomir Marinov
+ * @author Yana Stamcheva
*/
public class ContactCapabilitiesEvent
extends EventObject
@@ -39,6 +40,11 @@ public class ContactCapabilitiesEvent
*/
private final int eventID;
+ /**
+ * The new set of supported OperationSets.
+ */
+ private final Map opSets;
+
/**
* Initializes a new ContactCapabilitiesEvent instance which is to
* notify about a specific change in the list of OperationSet
@@ -50,12 +56,17 @@ public class ContactCapabilitiesEvent
* the change in the list of OperationSet capabilities of the
* specified sourceContact and the details to be carried by the new
* event
+ * @param opSets the new set of operation sets this event is about
*/
- public ContactCapabilitiesEvent(Contact sourceContact, int eventID)
+ public ContactCapabilitiesEvent(
+ Contact sourceContact,
+ int eventID,
+ Map opSets)
{
super(sourceContact);
this.eventID = eventID;
+ this.opSets = opSets;
}
/**
@@ -82,4 +93,14 @@ public Contact getSourceContact()
{
return (Contact) getSource();
}
+
+ /**
+ * Returns the new set of OperationSet-s this event is about
+ *
+ * @return the new set of OperationSet-s
+ */
+ public Map getOperationSets()
+ {
+ return opSets;
+ }
}
diff --git a/test/net/java/sip/communicator/slick/contactlist/TestMetaContactList.java b/test/net/java/sip/communicator/slick/contactlist/TestMetaContactList.java
index 31efffa40..987aef801 100644
--- a/test/net/java/sip/communicator/slick/contactlist/TestMetaContactList.java
+++ b/test/net/java/sip/communicator/slick/contactlist/TestMetaContactList.java
@@ -1245,16 +1245,5 @@ public void metaContactAvatarUpdated(MetaContactAvatarUpdateEvent evt)
{
collectedMetaContactGroupEvents.add(evt);
}
-
- /**
- * Indicates that a MetaContact capabilities have changed.
- * @param evt the MetaContactCapabilitiesEvent that notified
- * us
- */
- public void metaContactCapabilitiesChanged(
- MetaContactCapabilitiesEvent evt)
- {
- collectedMetaContactEvents.add(evt);
- }
}
}