diff options
10 files changed, 318 insertions, 48 deletions
diff --git a/src/net/java/sip/communicator/impl/contactlist/MclStorageManager.java b/src/net/java/sip/communicator/impl/contactlist/MclStorageManager.java index ef3c3e7..1a18747 100644 --- a/src/net/java/sip/communicator/impl/contactlist/MclStorageManager.java +++ b/src/net/java/sip/communicator/impl/contactlist/MclStorageManager.java @@ -2071,4 +2071,14 @@ public class MclStorageManager { // TODO: Store meta contact avatar. } + + /** + * Indicates that the capabilities of a given <tt>MetaContact</tt> have + * changed. + * @param evt the <tt>MetaContactCapabilitiesEvent</tt> that notified us + */ + public void metaContactCapabilitiesChanged(MetaContactCapabilitiesEvent evt) + { + // TODO Auto-generated method stub + } } diff --git a/src/net/java/sip/communicator/impl/contactlist/MetaContactImpl.java b/src/net/java/sip/communicator/impl/contactlist/MetaContactImpl.java index af7dc90..c6a72f2 100644 --- a/src/net/java/sip/communicator/impl/contactlist/MetaContactImpl.java +++ b/src/net/java/sip/communicator/impl/contactlist/MetaContactImpl.java @@ -364,41 +364,68 @@ public class MetaContactImpl // if the current default contact supports the requested operationSet // we use it - if (defaultContact != null - && defaultContact.getProtocolProvider() - .getOperationSet(operationSet) != null) + if (defaultContact != null) { - defaultOpSetContact = defaultContact; + ProtocolProviderService contactProvider + = defaultContact.getProtocolProvider(); + + // First try to ask the capabilities operation set if such is + // available. + OperationSetContactCapabilities capOpSet = contactProvider + .getOperationSet(OperationSetContactCapabilities.class); + + if (capOpSet != null) + { + if (capOpSet.getOperationSet(defaultContact, operationSet) + != null) + defaultOpSetContact = defaultContact; + } + else if (contactProvider.getOperationSet(operationSet) != null) + defaultOpSetContact = defaultContact; } - else + + if (defaultOpSetContact == null) { PresenceStatus currentStatus = null; for (Contact protoContact : protoContacts) { - // we filter to care only about contact which support + ProtocolProviderService contactProvider + = protoContact.getProtocolProvider(); + + // First try to ask the capabilities operation set if such is + // available. + OperationSetContactCapabilities capOpSet = contactProvider + .getOperationSet(OperationSetContactCapabilities.class); + + // We filter to care only about contact which support // the needed opset. - if (protoContact.getProtocolProvider() - .getOperationSet(operationSet) != null) + if (capOpSet != null) { - PresenceStatus contactStatus - = protoContact.getPresenceStatus(); + if (capOpSet.getOperationSet(defaultContact, operationSet) + == null) + continue; + } + else if (contactProvider.getOperationSet(operationSet) == null) + continue; - if (currentStatus != null) - { - if (currentStatus.getStatus() - < contactStatus.getStatus()) - { - currentStatus = contactStatus; - defaultOpSetContact = protoContact; - } - } - else + PresenceStatus contactStatus + = protoContact.getPresenceStatus(); + + if (currentStatus != null) + { + if (currentStatus.getStatus() + < contactStatus.getStatus()) { currentStatus = contactStatus; defaultOpSetContact = protoContact; } } + else + { + currentStatus = contactStatus; + defaultOpSetContact = protoContact; + } } } return defaultOpSetContact; diff --git a/src/net/java/sip/communicator/impl/contactlist/MetaContactListServiceImpl.java b/src/net/java/sip/communicator/impl/contactlist/MetaContactListServiceImpl.java index e27710c..7ae214c 100644 --- a/src/net/java/sip/communicator/impl/contactlist/MetaContactListServiceImpl.java +++ b/src/net/java/sip/communicator/impl/contactlist/MetaContactListServiceImpl.java @@ -29,7 +29,8 @@ import net.java.sip.communicator.util.xml.*; public class MetaContactListServiceImpl implements MetaContactListService, ServiceListener, - ContactPresenceStatusListener + ContactPresenceStatusListener, + ContactCapabilitiesListener { private static final Logger logger = Logger.getLogger(MetaContactListServiceImpl.class); @@ -1673,6 +1674,15 @@ public class MetaContactListServiceImpl //events for all contacts that we have already extracted if(opSetPersPresence != null) opSetPersPresence.addContactPresenceStatusListener(this); + + // Check if the capabilities operation set is available for this + // contact and add a listener to it in order to track capabilities' + // changes for all contained protocol contacts. + OperationSetContactCapabilities capOpSet + = provider.getOperationSet(OperationSetContactCapabilities.class); + + if (capOpSet != null) + capOpSet.addContactCapabilitiesListener(this); } /** @@ -1697,37 +1707,48 @@ public class MetaContactListServiceImpl provider.getOperationSet(OperationSetPersistentPresence.class); //ignore if persistent presence is not supported. - if(persPresOpSet == null) - return; + if(persPresOpSet != null) + { + //we don't gare about subscription and presence status events here any + //longer + persPresOpSet.removeContactPresenceStatusListener(this); + persPresOpSet.removeSubscriptionListener( + clSubscriptionEventHandler); + persPresOpSet.removeServerStoredGroupChangeListener( + clGroupEventHandler); - //we don't gare about subscription and presence status events here any - //longer - persPresOpSet.removeContactPresenceStatusListener(this); - persPresOpSet.removeSubscriptionListener(clSubscriptionEventHandler); - persPresOpSet.removeServerStoredGroupChangeListener(clGroupEventHandler); + ContactGroup rootGroup + = persPresOpSet.getServerStoredContactListRoot(); - ContactGroup rootGroup - = persPresOpSet.getServerStoredContactListRoot(); + //iterate all sub groups and remove them one by one + //(we dont simply remove the root group because the mcl storage + // manager is stupid (i wrote it) and doesn't know root groups exist. + // that's why it needs to hear an event for every single group.) + Iterator<ContactGroup> subgroups = rootGroup.subgroups(); - //iterate all sub groups and remove them one by one - //(we dont simply remove the root group because the mcl storage manager - //is stupid (i wrote it) and doesn't know root groups exist. that's why - //it needs to hear an event for every single group.) - Iterator<ContactGroup> subgroups = rootGroup.subgroups(); + while(subgroups.hasNext()) + { + ContactGroup group = subgroups.next(); + //remove the group + this.removeContactGroupFromMetaContactGroup( + (MetaContactGroupImpl) findMetaContactGroupByContactGroup( + group), + group, + provider); + } - while(subgroups.hasNext()) - { - ContactGroup group = subgroups.next(); - //remove the group + //remove the root group this.removeContactGroupFromMetaContactGroup( - (MetaContactGroupImpl)findMetaContactGroupByContactGroup(group), - group, - provider); + this.rootMetaGroup, rootGroup, provider); } - //remove the root group - this.removeContactGroupFromMetaContactGroup( - this.rootMetaGroup, rootGroup, provider); + // Check if the capabilities operation set is available for this + // contact and remove previously added listeners. + OperationSetContactCapabilities capOpSet + = provider.getOperationSet(OperationSetContactCapabilities.class); + + if (capOpSet != null) + capOpSet.removeContactCapabilitiesListener(this); } /** @@ -3146,4 +3167,79 @@ public class MetaContactListServiceImpl } } } + + /** + * Notifies this listener that the list of the <tt>OperationSet</tt> + * capabilities of a <tt>Contact</tt> has changed. + * + * @param event a <tt>ContactCapabilitiesEvent</tt> with ID + * {@link ContactCapabilitiesEvent#SUPPORTED_OPERATION_SETS_CHANGED} which + * specifies the <tt>Contact</tt> whose list of <tt>OperationSet</tt> + * capabilities has changed + */ + public void supportedOperationSetsChanged(ContactCapabilitiesEvent event) + { + // If the source contact isn't contained in this meta contact we have + // nothing more to do here. + MetaContactImpl metaContactImpl + = (MetaContactImpl) findMetaContactByContact( + event.getSourceContact()); + + //ignore if we have no meta contact. + if(metaContactImpl == null) + return; + + fireCapabilitiesEvent(metaContactImpl, + MetaContactCapabilitiesEvent.SUPPORTED_OPERATION_SETS_CHANGED); + } + + /** + * Fires a new <tt>MetaContactCapabilitiesEvent</tt> to notify the + * registered <tt>MetaContactCapabilitiesListener</tt>s that this + * <tt>MetaContact</tt> has changed its list of <tt>OperationSet</tt> + * capabilities. + * + * @param metaContact the source <tt>MetaContact</tt>, 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 <tt>OperationSet</tt> capabilities + * of the specified <tt>sourceContact</tt> and the details of the event + */ + private void fireCapabilitiesEvent(MetaContact metaContact, int eventID) + { + MetaContactListListener[] listeners; + + synchronized (metaContactListListeners) + { + listeners + = metaContactListListeners.toArray( + new MetaContactListListener[ + metaContactListListeners.size()]); + } + if (listeners.length != 0) + { + MetaContactCapabilitiesEvent event + = new MetaContactCapabilitiesEvent(metaContact, eventID); + + 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"); + } + } + } + } } 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 b4ef61e..4b3a74e 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,6 +372,9 @@ public class MetaContactChatSession public void metaContactAvatarUpdated(MetaContactAvatarUpdateEvent evt) {} + public void metaContactCapabilitiesChanged(MetaContactCapabilitiesEvent evt) + {} + /** * Implements <tt>MetaContactListListener.metaContactRenamed</tt> 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 c713ad6..774a5b8 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,6 +219,9 @@ public class ContactList public void metaContactAvatarUpdated(MetaContactAvatarUpdateEvent evt) {} + public void metaContactCapabilitiesChanged( + MetaContactCapabilitiesEvent evt) {} + /** * Handles the <tt>MetaContactGroupEvent</tt>. 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 d6a2db1..88f2bb0 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 @@ -513,7 +513,12 @@ public class TreeContactList = MetaContactListSource.getUIContact(oldParent); if (oldUIContact != null) - removeContact(oldUIContact); + { + ContactNode contactNode = oldUIContact.getContactNode(); + + if (contactNode != null) + treeModel.nodeChanged(contactNode); + } } /** @@ -589,6 +594,29 @@ public class TreeContactList } /** + * Updates the corresponding node when the list of the <tt>OperationSet</tt> + * capabilities of a <tt>MetaContact</tt> has changed. + * @param evt a <tt>ContactCapabilitiesEvent</tt> with ID + * {@link MetaContactCapabilitiesEvent#SUPPORTED_OPERATION_SETS_CHANGED} + * which specifies the <tt>Contact</tt> whose list of <tt>OperationSet</tt> + * 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 <tt>ContactQueryStatusEvent</tt> that notified us */ diff --git a/src/net/java/sip/communicator/service/contactlist/MetaContact.java b/src/net/java/sip/communicator/service/contactlist/MetaContact.java index e4ec40c..b999e50 100644 --- a/src/net/java/sip/communicator/service/contactlist/MetaContact.java +++ b/src/net/java/sip/communicator/service/contactlist/MetaContact.java @@ -11,7 +11,7 @@ import java.util.*; import net.java.sip.communicator.service.protocol.*; /** - * A MetaContact is an abstraction used for merging mutltiple Contacts (most + * A MetaContact is an abstraction used for merging multiple Contacts (most * often) belonging to different <tt>ProtocolProvider</tt>s. * <p> * Instances of a MetaContact are read-only objects that cannot be modified diff --git a/src/net/java/sip/communicator/service/contactlist/event/MetaContactCapabilitiesEvent.java b/src/net/java/sip/communicator/service/contactlist/event/MetaContactCapabilitiesEvent.java new file mode 100644 index 0000000..9ae391c --- /dev/null +++ b/src/net/java/sip/communicator/service/contactlist/event/MetaContactCapabilitiesEvent.java @@ -0,0 +1,80 @@ +/* + * 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/<tt>EventObject</tt> fired by + * <tt>OperationSetClientCapabilities</tt> in order to notify about changes in + * the list of the <tt>OperationSet</tt> capabilities of a <tt>Contact</tt>. + * + * @author Yana Stamcheva + */ +public class MetaContactCapabilitiesEvent + extends EventObject +{ + /**ContactList.java + * The ID of the <tt>MetaContactCapabilitiesEvent</tt> which notifies about + * changes in the list of the <tt>OperationSet</tt> capabilities of a + * <tt>MetaContact</tt>. + */ + 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 <tt>OperationSet</tt> capabilities of the associated + * <tt>Contact</tt> and the details this event carries. + */ + private final int eventID; + + /** + * Initializes a new <tt>ContactCapabilitiesEvent</tt> instance which is to + * notify about a specific change in the list of <tt>OperationSet</tt> + * capabilities of a specific <tt>Contact</tt>. + * + * @param sourceContact the <tt>MetaContact</tt> 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 <tt>OperationSet</tt> capabilities of the + * specified <tt>sourceContact</tt> 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 <tt>OperationSet</tt> capabilities of the associated + * <tt>sourceContact</tt> and the details it carries. + * + * @return the ID of this event which indicates the specifics of the change + * in the list of <tt>OperationSet</tt> capabilities of the associated + * <tt>sourceContact</tt> and the details it carries + */ + public int getEventID() + { + return eventID; + } + + /** + * Gets the <tt>MetaContact</tt> which is the source/cause of this event i.e. + * which has changed its list of <tt>OperationSet</tt> capabilities. + * + * @return the <tt>MetaContact</tt> 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 f2b7602..0ac41c3 100644 --- a/src/net/java/sip/communicator/service/contactlist/event/MetaContactListListener.java +++ b/src/net/java/sip/communicator/service/contactlist/event/MetaContactListListener.java @@ -115,7 +115,8 @@ public interface MetaContactListListener /** * Indicates that a MetaContact has been modified. - * @param evt the MetaContactModifiedEvent containing the corresponding contact + * @param evt the MetaContactModifiedEvent containing the corresponding + * contact */ public void metaContactModified(MetaContactModifiedEvent evt); @@ -125,4 +126,15 @@ public interface MetaContactListListener * of this event */ public void metaContactAvatarUpdated(MetaContactAvatarUpdateEvent evt); + + /** + * Notifies this listener that the list of the <tt>OperationSet</tt> + * capabilities of a <tt>MetaContact</tt> has changed. + * + * @param evt a <tt>ContactCapabilitiesEvent</tt> with ID + * {@link MetaContactCapabilitiesEvent#SUPPORTED_OPERATION_SETS_CHANGED} + * which specifies the <tt>Contact</tt> whose list of <tt>OperationSet</tt> + * capabilities has changed + */ + public void metaContactCapabilitiesChanged(MetaContactCapabilitiesEvent evt); } diff --git a/test/net/java/sip/communicator/slick/contactlist/TestMetaContactList.java b/test/net/java/sip/communicator/slick/contactlist/TestMetaContactList.java index 987aef8..31efffa 100644 --- a/test/net/java/sip/communicator/slick/contactlist/TestMetaContactList.java +++ b/test/net/java/sip/communicator/slick/contactlist/TestMetaContactList.java @@ -1245,5 +1245,16 @@ public class TestMetaContactList { collectedMetaContactGroupEvents.add(evt); } + + /** + * Indicates that a <tt>MetaContact</tt> capabilities have changed. + * @param evt the <tt>MetaContactCapabilitiesEvent</tt> that notified + * us + */ + public void metaContactCapabilitiesChanged( + MetaContactCapabilitiesEvent evt) + { + collectedMetaContactEvents.add(evt); + } } } |