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 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) 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); - } } }