Implements a more robust contact resource status update mechanism.

Manages resource add, remove and status change in the chat dialog. Adds
the resource in the tooltip of the chat contact when in an active chat
session.
cusax-fix
yanas 13 years ago
parent d1356a9e39
commit b0b59cdf7b

@ -63,6 +63,13 @@ public interface ChatSessionRenderer
*/
public void updateChatTransportStatus(ChatTransport chatTransport);
/**
* Sets the given <tt>chatTransport</tt> to be the selected chat transport.
*
* @param chatTransport the <tt>ChatTransport</tt> to select
*/
public void setSelectedChatTransport(ChatTransport chatTransport);
/**
* Updates the status of the given chat contact.
*

@ -12,10 +12,12 @@
import javax.swing.*;
import org.jitsi.util.*;
import net.java.sip.communicator.impl.gui.*;
import net.java.sip.communicator.impl.gui.utils.*;
import net.java.sip.communicator.plugin.desktoputil.*;
import net.java.sip.communicator.util.*;
import net.java.sip.communicator.util.Logger;
import net.java.sip.communicator.util.skin.*;
/**
@ -89,11 +91,16 @@ public ChatTransportSelectorBox(ChatPanel chatPanel,
while (chatTransports.hasNext())
this.addChatTransport(chatTransports.next());
if (this.menu.getItemCount() > 0 &&
(selectedChatTransport.allowsInstantMessage()
|| selectedChatTransport.allowsSmsMessage()))
if (this.menu.getItemCount() > 0)
{
this.setSelected(selectedChatTransport);
if (selectedChatTransport != null
&& (selectedChatTransport.allowsInstantMessage()
|| selectedChatTransport.allowsSmsMessage()))
{
this.setSelected(selectedChatTransport);
}
else
setSelected(menu.getItem(0));
}
}
@ -236,16 +243,15 @@ public void updateTransportStatus(ChatTransport chatTransport)
&& !chatTransport.getStatus().isOnline())
{
ChatTransport newChatTransport
= chatSession.getCurrentChatTransport();
= getParentContactTransport(chatTransport);
if(newChatTransport.getStatus().isOnline())
this.setSelected(newChatTransport);
}
ChatTransport onlineTransport = getOnlineTransport();
if (!containsOtherOnlineContacts(chatTransport)
&& chatTransport.getStatus().isOnline())
{
this.setSelected(chatTransport);
if(newChatTransport != null
&& newChatTransport.getStatus().isOnline())
setSelected(newChatTransport);
else if (onlineTransport != null)
setSelected(onlineTransport);
}
menuItem = transportMenuItems.get(chatTransport);
@ -346,15 +352,34 @@ public SIPCommMenu getMenu()
* @return TRUE if the send via combo box contains online contacts,
* otherwise returns FALSE.
*/
private boolean containsOtherOnlineContacts(ChatTransport chatTransport)
private ChatTransport getParentContactTransport(ChatTransport chatTransport)
{
for (ChatTransport comboChatTransport : transportMenuItems.keySet())
{
if(comboChatTransport.getDescriptor()
.equals(chatTransport.getDescriptor())
&& StringUtils.isNullOrEmpty(
comboChatTransport.getResourceName()))
return comboChatTransport;
}
return null;
}
/**
* Searches online contacts in the send via combo box.
*
* @param chatTransport the chat transport to check
* @return TRUE if the send via combo box contains online contacts,
* otherwise returns FALSE.
*/
private ChatTransport getOnlineTransport()
{
for (ChatTransport comboChatTransport : transportMenuItems.keySet())
{
if(!comboChatTransport.equals(chatTransport)
&& comboChatTransport.getStatus().isOnline())
return true;
if(comboChatTransport.getStatus().isOnline())
return comboChatTransport;
}
return false;
return null;
}
/**

@ -1035,8 +1035,22 @@ public void run()
*
* @param chatTransport the transport to add
*/
public void addChatTransport(ChatTransport chatTransport)
public void addChatTransport(final ChatTransport chatTransport)
{
// We need to be sure that the following code is executed in the event
// dispatch thread.
if (!SwingUtilities.isEventDispatchThread())
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
addChatTransport(chatTransport);
}
});
return;
}
if (transportSelectorBox != null)
{
transportSelectorBox.addChatTransport(chatTransport);
@ -1045,7 +1059,7 @@ public void addChatTransport(ChatTransport chatTransport)
// provider
if(!transportSelectorBox.isVisible()
&& ConfigurationUtils
.isHideAccountSelectionWhenPossibleEnabled()
.isHideAccountSelectionWhenPossibleEnabled()
&& transportSelectorBox.getMenu().getItemCount() > 1)
{
transportSelectorBox.setVisible(true);
@ -1058,8 +1072,22 @@ public void addChatTransport(ChatTransport chatTransport)
* box and notifies the user for the status change.
* @param chatTransport the <tt>chatTransport</tt> to update
*/
public void updateChatTransportStatus(ChatTransport chatTransport)
public void updateChatTransportStatus(final ChatTransport chatTransport)
{
// We need to be sure that the following code is executed in the event
// dispatch thread.
if (!SwingUtilities.isEventDispatchThread())
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
updateChatTransportStatus(chatTransport);
}
});
return;
}
if (transportSelectorBox != null)
transportSelectorBox.updateTransportStatus(chatTransport);
}
@ -1079,8 +1107,22 @@ public void openChatTransportSelectorBox()
*
* @param chatTransport the transport to remove
*/
public void removeChatTransport(ChatTransport chatTransport)
public void removeChatTransport(final ChatTransport chatTransport)
{
// We need to be sure that the following code is executed in the event
// dispatch thread.
if (!SwingUtilities.isEventDispatchThread())
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
removeChatTransport(chatTransport);
}
});
return;
}
if (transportSelectorBox != null)
transportSelectorBox.removeChatTransport(chatTransport);

@ -30,7 +30,8 @@
*/
public class MetaContactChatSession
extends ChatSession
implements MetaContactListListener
implements MetaContactListListener,
ContactResourceListener
{
private final MetaContact metaContact;
@ -77,6 +78,7 @@ public MetaContactChatSession( ChatSessionRenderer sessionRenderer,
if (metaContactListService != null)
metaContactListService.addMetaContactListListener(this);
}
/**
@ -316,50 +318,12 @@ private void initChatTransports(Contact protocolContact,
{
Contact contact = protocolContacts.next();
MetaContactChatTransport chatTransport = null;
if (contact.supportResources() && contact.getResources() != null)
{
if (contact.getResources().size() > 1)
{
chatTransport = new MetaContactChatTransport(this, contact);
chatTransports.add(chatTransport);
}
Iterator<ContactResource> resourcesIter
= contact.getResources().iterator();
while (resourcesIter.hasNext())
{
ContactResource resource = resourcesIter.next();
MetaContactChatTransport resourceTransport
= new MetaContactChatTransport(
this,
contact,
resource,
(contact.getResources().size() > 1)
? true : false);
if (chatTransport == null
|| (contactResource != null
&& contactResource.equals(resource)))
{
chatTransport = resourceTransport;
}
chatTransports.add(resourceTransport);
}
}
else
{
chatTransport = new MetaContactChatTransport(this, contact);
chatTransports.add(chatTransport);
}
if (contact.equals(protocolContact))
currentChatTransport = chatTransport;
addChatTransports( contact,
(contactResource != null)
? contactResource.getResourceName()
: null,
(protocolContact != null
&& contact.equals(protocolContact)));
}
}
@ -444,7 +408,7 @@ public void protoContactAdded(ProtoContactEvent evt)
{
if (evt.getNewParent().equals(metaContact))
{
addChatTransport(evt.getProtoContact());
addChatTransports(evt.getProtoContact(), null, false);
}
}
@ -482,7 +446,7 @@ public void protoContactRemoved(ProtoContactEvent evt)
if(((MetaContactChatTransport) chatTransport).getContact()
.equals(protoContact))
{
sessionRenderer.removeChatTransport(chatTransport);
removeChatTransport(chatTransport);
}
}
}
@ -534,7 +498,12 @@ public void dispose()
metaContactListService.removeMetaContactListListener(this);
for (ChatTransport chatTransport : chatTransports)
{
((Contact) chatTransport.getDescriptor())
.removeResourceListener(this);
chatTransport.dispose();
}
}
/**
@ -653,44 +622,234 @@ public void removeChatTransportChangeListener(ChatSessionChangeListener l)
* Adds all chat transports for the given <tt>contact</tt>.
*
* @param contact the <tt>Contact</tt>, which transports to add
* @param resourceName the resource to be pre-selected
*/
private void addChatTransport(Contact contact)
private void addChatTransports( Contact contact,
String resourceName,
boolean isSelectedContact)
{
MetaContactChatTransport chatTransport = null;
if (contact.supportResources() && contact.getResources() != null)
Collection<ContactResource> contactResources = contact.getResources();
if (contact.supportResources()
&& contactResources != null
&& contactResources.size() > 0)
{
if (contact.getResources().size() > 1)
if (contactResources.size() > 1)
{
chatTransport = new MetaContactChatTransport(this, contact);
chatTransports.add(chatTransport);
sessionRenderer.addChatTransport(chatTransport);
addChatTransport(chatTransport);
}
Iterator<ContactResource> resourcesIter
= contact.getResources().iterator();
= contactResources.iterator();
while (resourcesIter.hasNext())
{
chatTransport
ContactResource resource = resourcesIter.next();
MetaContactChatTransport resourceTransport
= new MetaContactChatTransport(
this,
contact,
resourcesIter.next(),
resource,
(contact.getResources().size() > 1)
? true : false);
chatTransports.add(chatTransport);
sessionRenderer.addChatTransport(chatTransport);
addChatTransport(resourceTransport);
if ((resourceName != null
&& resource.getResourceName().equals(resourceName))
|| contactResources.size() == 1)
{
chatTransport = resourceTransport;
}
}
}
else
{
chatTransport = new MetaContactChatTransport(this, contact);
addChatTransport(chatTransport);
}
// If this is the selected contact we set it as a selected transport.
if (isSelectedContact)
{
currentChatTransport = chatTransport;
sessionRenderer.setSelectedChatTransport(chatTransport);
}
// If no current transport is set we choose the first one in the list.
if (currentChatTransport == null)
{
currentChatTransport = chatTransports.get(0);
sessionRenderer.setSelectedChatTransport(currentChatTransport);
}
if (contact.supportResources())
{
contact.addResourceListener(this);
}
}
private void addChatTransport(ChatTransport chatTransport)
{
synchronized (chatTransports)
{
chatTransports.add(chatTransport);
sessionRenderer.addChatTransport(chatTransport);
}
sessionRenderer.addChatTransport(chatTransport);
}
/**
* Removes the given <tt>ChatTransport</tt>.
*
* @param chatTransport the <tt>ChatTransport</tt>.
*/
private void removeChatTransport(ChatTransport chatTransport)
{
synchronized (chatTransports)
{
chatTransports.remove(chatTransport);
}
sessionRenderer.removeChatTransport(chatTransport);
}
/**
* Removes the given <tt>ChatTransport</tt>.
*
* @param contact the <tt>ChatTransport</tt>.
*/
private void removeChatTransports(Contact contact)
{
List<ChatTransport> transports;
synchronized (chatTransports)
{
transports = new ArrayList<ChatTransport>(chatTransports);
}
Iterator<ChatTransport> transportsIter = transports.iterator();
while (transportsIter.hasNext())
{
MetaContactChatTransport metaTransport
= (MetaContactChatTransport) transportsIter.next();
if (metaTransport.getContact().equals(contact))
removeChatTransport(metaTransport);
}
contact.removeResourceListener(this);
}
/**
* Updates the chat transports for the given contact.
*
* @param contact the contact, which related transports to update
*/
private void updateChatTransports(Contact contact)
{
MetaContactChatTransport currentTransport
= (MetaContactChatTransport) getCurrentChatTransport();
boolean isSelectedContact
= currentTransport.getContact().equals(contact);
boolean isResourceSelected
= isSelectedContact
&& currentTransport.getResourceName() != null;
String resourceName
= currentTransport.getResourceName();
removeChatTransports(contact);
if (isResourceSelected)
addChatTransports( contact,
resourceName,
true);
else
addChatTransports(contact, null, isSelectedContact);
}
/**
* Called when a new <tt>ContactResource</tt> has been added to the list
* of available <tt>Contact</tt> resources.
*
* @param event the <tt>ContactResourceEvent</tt> that notified us
*/
public void contactResourceAdded(ContactResourceEvent event)
{
Contact contact = event.getContact();
if (metaContact.containsContact(contact))
{
updateChatTransports(contact);
}
}
/**
* Called when a <tt>ContactResource</tt> has been removed to the list
* of available <tt>Contact</tt> resources.
*
* @param event the <tt>ContactResourceEvent</tt> that notified us
*/
public void contactResourceRemoved(ContactResourceEvent event)
{
Contact contact = event.getContact();
if (metaContact.containsContact(contact))
{
updateChatTransports(contact);
}
}
/**
* Called when a <tt>ContactResource</tt> in the list of available
* <tt>Contact</tt> resources has been modified.
*
* @param event the <tt>ContactResourceEvent</tt> that notified us
*/
public void contactResourceModified(ContactResourceEvent event)
{
Contact contact = event.getContact();
if (metaContact.containsContact(contact))
{
ChatTransport transport
= findChatTransportForResource(event.getContactResource());
if (transport != null)
sessionRenderer.updateChatTransportStatus(transport);
}
}
/**
* Finds the <tt>ChatTransport</tt> corresponding to the given contact
* <tt>resource</tt>.
*
* @param resource the <tt>ContactResource</tt>, which corresponding
* transport we're looking for
* @return the <tt>ChatTransport</tt> corresponding to the given contact
* <tt>resource</tt>
*/
private ChatTransport findChatTransportForResource(ContactResource resource)
{
List<ChatTransport> transports;
synchronized (chatTransports)
{
transports = new ArrayList<ChatTransport>(chatTransports);
}
Iterator<ChatTransport> transportsIter = transports.iterator();
while (transportsIter.hasNext())
{
ChatTransport chatTransport = transportsIter.next();
if (chatTransport.getDescriptor().equals(resource.getContact())
&& chatTransport.getResourceName() != null
&& chatTransport.getResourceName()
.equals(resource.getResourceName()))
return chatTransport;
}
return null;
}
}

@ -35,7 +35,7 @@ public class MetaContactChatTransport
/**
* The parent <tt>ChatSession</tt>, where this transport is available.
*/
private final ChatSession parentChatSession;
private final MetaContactChatSession parentChatSession;
/**
* The associated protocol <tt>Contact</tt>.
@ -75,7 +75,7 @@ public class MetaContactChatTransport
* @param chatSession the parent <tt>ChatSession</tt>
* @param contact the <tt>Contact</tt> associated with this transport
*/
public MetaContactChatTransport(ChatSession chatSession,
public MetaContactChatTransport(MetaContactChatSession chatSession,
Contact contact)
{
this(chatSession, contact, null, false);
@ -93,7 +93,7 @@ public MetaContactChatTransport(ChatSession chatSession,
* @param isDisplayResourceOnly indicates if only the resource name should
* be displayed
*/
public MetaContactChatTransport(ChatSession chatSession,
public MetaContactChatTransport(MetaContactChatSession chatSession,
Contact contact,
ContactResource contactResource,
boolean isDisplayResourceOnly)
@ -685,27 +685,22 @@ public void removeInstantMessageListener(MessageListener l)
public void contactPresenceStatusChanged(
ContactPresenceStatusChangeEvent evt)
{
Contact sourceContact = evt.getSourceContact();
if (sourceContact.equals(contact)
&& (evt.getOldStatus() != evt.getNewStatus()))
if (evt.getSourceContact().equals(contact)
&& !evt.getOldStatus().equals(evt.getNewStatus()))
{
this.updateContactStatus(evt.getNewStatus());
this.updateContactStatus();
}
}
/**
* Updates the status of this contact with the new given status.
* @param newStatus The new status.
*/
private void updateContactStatus(PresenceStatus newStatus)
private void updateContactStatus()
{
// Update the status of the given contact in the "send via" selector
// box.
parentChatSession.getChatSessionRenderer()
.updateChatTransportStatus(this);
//TODO: Update the status of the chat session.
}
/**

@ -334,8 +334,13 @@ else if(eventType == MessageReceivedEvent.SMS_MESSAGE_RECEIVED)
messageType = Chat.SMS_MESSAGE;
}
String contactAddress = (contactResource != null)
? protocolContact.getAddress()
+ " (" + contactResource.getResourceName() + ")"
: protocolContact.getAddress();
chatPanel.addMessage(
protocolContact.getAddress(),
contactAddress,
protocolContact.getDisplayName(),
timestamp,
messageType,

@ -330,26 +330,4 @@ public void setResolved(boolean resolved)
return (OperationSetPersistentPresenceDictImpl) parentProvider
.getOperationSet(OperationSetPersistentPresence.class);
}
/**
* Indicates if this contact supports resources.
*
* @return <tt>false</tt> to indicate that this contact doesn't support
* resources
*/
public boolean supportResources()
{
return false;
}
/**
* Returns a collection of resources supported by this contact or null
* if it doesn't support resources.
*
* @return null, as this contact doesn't support resources
*/
public Collection<ContactResource> getResources()
{
return null;
}
}

@ -280,26 +280,4 @@ public void setResolved(boolean resolved)
return (OperationSetPersistentPresenceGibberishImpl)parentProvider
.getOperationSet(OperationSetPersistentPresence.class);
}
/**
* Indicates if this contact supports resources.
*
* @return <tt>false</tt> to indicate that this contact doesn't support
* resources
*/
public boolean supportResources()
{
return false;
}
/**
* Returns a collection of resources supported by this contact or null
* if it doesn't support resources.
*
* @return null, as this contact doesn't support resources
*/
public Collection<ContactResource> getResources()
{
return null;
}
}

@ -331,26 +331,4 @@ protected void setStatusMessage(String statusMessage)
{
this.statusMessage = statusMessage;
}
/**
* Indicates if this contact supports resources.
*
* @return <tt>false</tt> to indicate that this contact doesn't support
* resources
*/
public boolean supportResources()
{
return false;
}
/**
* Returns a collection of resources supported by this contact or null
* if it doesn't support resources.
*
* @return null, as this contact doesn't support resources
*/
public Collection<ContactResource> getResources()
{
return null;
}
}

@ -7,8 +7,10 @@
package net.java.sip.communicator.impl.protocol.jabber;
import java.util.*;
import java.util.concurrent.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.service.protocol.jabberconstants.*;
import org.jivesoftware.smack.*;
@ -22,7 +24,7 @@
* @author Lubomir Marinov
*/
public class ContactJabberImpl
implements Contact
extends AbstractContact
{
/**
* The jid of the user entry in roster.
@ -75,7 +77,7 @@ public class ContactJabberImpl
/**
* The contact resources list.
*/
private List<ContactResource> resources = null;
private Map<String, ContactResourceJabberImpl> resources = null;
/**
* Creates an JabberContactImpl
@ -479,8 +481,7 @@ public boolean supportResources()
public Collection<ContactResource> getResources()
{
if (resources != null)
return Collections.unmodifiableCollection(resources);
return new ArrayList<ContactResource>(resources.values());
return null;
}
@ -490,22 +491,9 @@ public Collection<ContactResource> getResources()
* @param jid the jid for which we're looking for a resource
* @return the <tt>ContactResource</tt> corresponding to the given jid.
*/
ContactResource findResourceFromJid(String jid)
ContactResource getResourceFromJid(String jid)
{
Iterator<ContactResource> resourceIter = resources.iterator();
while (resourceIter.hasNext())
{
ContactResourceJabberImpl jabberResource
= (ContactResourceJabberImpl) resourceIter.next();
if (jabberResource.getFullJid().equals(jid))
{
return jabberResource;
}
}
return null;
return resources.get(jid);
}
/**
@ -516,7 +504,9 @@ void updateResources()
if (jid == null)
return;
resources = new LinkedList<ContactResource>();
if (resources == null)
resources
= new ConcurrentHashMap<String, ContactResourceJabberImpl>();
Iterator<Presence> it
= ((ProtocolProviderServiceJabberImpl) getProtocolProvider())
@ -533,17 +523,67 @@ void updateResources()
if (resource != null && resource.length() > 0)
{
resources.add(new ContactResourceJabberImpl(
presence.getFrom(),
this,
resource,
OperationSetPersistentPresenceJabberImpl
String fullJid = presence.getFrom();
ContactResourceJabberImpl contactResource
= resources.get(fullJid);
PresenceStatus newPresenceStatus
= OperationSetPersistentPresenceJabberImpl
.jabberStatusToPresenceStatus(
presence,
(ProtocolProviderServiceJabberImpl)
getProtocolProvider()),
presence.getPriority()));
getProtocolProvider());
if (contactResource == null)
{
contactResource = new ContactResourceJabberImpl(
fullJid,
this,
resource,
newPresenceStatus,
presence.getPriority());
resources.put(fullJid, contactResource);
fireContactResourceEvent(
new ContactResourceEvent(this, contactResource,
ContactResourceEvent.RESOURCE_ADDED));
}
else
{
if (contactResource.getPresenceStatus().getStatus()
!= newPresenceStatus.getStatus())
{
contactResource.setPresenceStatus(newPresenceStatus);
fireContactResourceEvent(
new ContactResourceEvent(this, contactResource,
ContactResourceEvent.RESOURCE_MODIFIED));
}
}
}
}
Iterator<String> resourceIter = resources.keySet().iterator();
while (resourceIter.hasNext())
{
String fullJid = resourceIter.next();
if(!((ProtocolProviderServiceJabberImpl) getProtocolProvider())
.getConnection().getRoster().getPresenceResource(fullJid)
.isAvailable())
{
ContactResource removedResource = resources.get(fullJid);
if (resources.containsKey(fullJid))
{
resources.remove(fullJid);
fireContactResourceEvent(
new ContactResourceEvent(this, removedResource,
ContactResourceEvent.RESOURCE_REMOVED));
}
}
}
}
}
}

@ -51,4 +51,14 @@ public String getFullJid()
{
return fullJid;
}
/**
* Sets the new <tt>PresenceStatus</tt> of this resource.
*
* @param newStatus the new <tt>PresenceStatus</tt> to set
*/
protected void setPresenceStatus(PresenceStatus newStatus)
{
this.presenceStatus = newStatus;
}
}

@ -802,7 +802,7 @@ public void processPacket(Packet packet)
}
ContactResource resource = ((ContactJabberImpl) sourceContact)
.findResourceFromJid(msg.getFrom());
.getResourceFromJid(msg.getFrom());
MessageReceivedEvent msgReceivedEvt
= new MessageReceivedEvent( newMessage,

@ -1102,8 +1102,8 @@ public int compare(Presence o1, Presence o2)
// when old and new status are the same do nothing
// no change
// if(oldStatus.equals(newStatus))
// return;
if(oldStatus.equals(newStatus))
return;
sourceContact.updatePresenceStatus(newStatus);

@ -18,7 +18,7 @@
* @author Emil Ivov
*/
public class MockContact
implements Contact
extends AbstractContact
{
private String contactID = null;
private boolean isPersistent = true;

@ -6,8 +6,6 @@
*/
package net.java.sip.communicator.impl.protocol.msn;
import java.util.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.msnconstants.*;
import net.sf.jml.*;
@ -281,26 +279,4 @@ public void setStatusMessage(String newStatusMessage)
{
this.statusMessage = newStatusMessage;
}
/**
* Indicates if this contact supports resources.
*
* @return <tt>false</tt> to indicate that this contact doesn't support
* resources
*/
public boolean supportResources()
{
return false;
}
/**
* Returns a collection of resources supported by this contact or null
* if it doesn't support resources.
*
* @return null, as this contact doesn't support resources
*/
public Collection<ContactResource> getResources()
{
return null;
}
}

@ -433,26 +433,4 @@ public String getStatusMessage()
{
return null;
}
/**
* Indicates if this contact supports resources.
*
* @return <tt>false</tt> to indicate that this contact doesn't support
* resources
*/
public boolean supportResources()
{
return false;
}
/**
* Returns a collection of resources supported by this contact or null
* if it doesn't support resources.
*
* @return null, as this contact doesn't support resources
*/
public Collection<ContactResource> getResources()
{
return null;
}
}

@ -26,7 +26,7 @@
* @author Grigorii Balutsel
*/
public class ContactSipImpl
implements Contact
extends AbstractContact
{
/**
* Property used for store in persistent data indicating that contact

@ -906,26 +906,4 @@ public String getStatusMessage()
{
return presenceStatus.getStatusName();
}
/**
* Indicates if this contact supports resources.
*
* @return <tt>false</tt> to indicate that this contact doesn't support
* resources
*/
public boolean supportResources()
{
return false;
}
/**
* Returns a collection of resources supported by this contact or null
* if it doesn't support resources.
*
* @return null, as this contact doesn't support resources
*/
public Collection<ContactResource> getResources()
{
return null;
}
}

@ -6,8 +6,6 @@
*/
package net.java.sip.communicator.impl.protocol.yahoo;
import java.util.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.yahooconstants.*;
import net.java.sip.communicator.util.*;
@ -384,26 +382,4 @@ protected void setStatusMessage(String statusMessage)
{
this.statusMessage = statusMessage;
}
/**
* Indicates if this contact supports resources.
*
* @return <tt>false</tt> to indicate that this contact doesn't support
* resources
*/
public boolean supportResources()
{
return false;
}
/**
* Returns a collection of resources supported by this contact or null
* if it doesn't support resources.
*
* @return null, as this contact doesn't support resources
*/
public Collection<ContactResource> getResources()
{
return null;
}
}

@ -454,26 +454,4 @@ public String getStatusMessage()
{
return null;
}
/**
* Indicates if this contact supports resources.
*
* @return <tt>false</tt> to indicate that this contact doesn't support
* resources
*/
public boolean supportResources()
{
return false;
}
/**
* Returns a collection of resources supported by this contact or null
* if it doesn't support resources.
*
* @return null, as this contact doesn't support resources
*/
public Collection<ContactResource> getResources()
{
return null;
}
}

@ -6,6 +6,10 @@
*/
package net.java.sip.communicator.service.protocol;
import java.util.*;
import net.java.sip.communicator.service.protocol.event.*;
/**
* An abstract base implementation of the {@link Contact} interface which is to
* aid implementers.
@ -15,6 +19,12 @@
public abstract class AbstractContact
implements Contact
{
/**
* The list of <tt>ContactResourceListener</tt>-s registered in this
* contact.
*/
private Collection<ContactResourceListener> resourceListeners;
@Override
public boolean equals(Object obj)
{
@ -66,4 +76,97 @@ public int hashCode()
return hashCode;
}
/**
* Indicates if this contact supports resources.
* <p>
* This default implementation indicates no support for contact resources.
*
* @return <tt>true</tt> if this contact supports resources, <tt>false</tt>
* otherwise
*/
public boolean supportResources()
{
return false;
}
/**
* Returns a collection of resources supported by this contact or null
* if it doesn't support resources.
* <p>
* This default implementation indicates no support for contact resources.
*
* @return a collection of resources supported by this contact or null
* if it doesn't support resources
*/
public Collection<ContactResource> getResources()
{
return null;
}
/**
* Adds the given <tt>ContactResourceListener</tt> to listen for events
* related to contact resources changes.
*
* @param l the <tt>ContactResourceListener</tt> to add
*/
public void addResourceListener(ContactResourceListener l)
{
if (resourceListeners == null)
resourceListeners = new ArrayList<ContactResourceListener>();
synchronized (resourceListeners)
{
resourceListeners.add(l);
}
}
/**
* Removes the given <tt>ContactResourceListener</tt> listening for events
* related to contact resources changes.
*
* @param l the <tt>ContactResourceListener</tt> to remove
*/
public void removeResourceListener(ContactResourceListener l)
{
if (resourceListeners == null)
return;
synchronized (resourceListeners)
{
resourceListeners.remove(l);
}
}
/**
* Notifies all registered <tt>ContactResourceListener</tt>s that an event
* has occurred.
*
* @param event the <tt>ContactResourceEvent</tt> to fire notification for
*/
protected void fireContactResourceEvent(ContactResourceEvent event)
{
if (resourceListeners == null)
return;
Collection<ContactResourceListener> listeners;
synchronized (resourceListeners)
{
listeners
= new ArrayList<ContactResourceListener>(resourceListeners);
}
Iterator<ContactResourceListener> listenersIter = listeners.iterator();
while (listenersIter.hasNext())
{
if (event.getEventType() == ContactResourceEvent.RESOURCE_ADDED)
listenersIter.next().contactResourceAdded(event);
else if (event.getEventType()
== ContactResourceEvent.RESOURCE_REMOVED)
listenersIter.next().contactResourceRemoved(event);
else if (event.getEventType()
== ContactResourceEvent.RESOURCE_MODIFIED)
listenersIter.next().contactResourceModified(event);
}
}
}

@ -8,6 +8,8 @@
import java.util.*;
import net.java.sip.communicator.service.protocol.event.*;
/**
* This class represents the notion of a Contact or Buddy, that is widely used
* in instant messaging today. From a protocol point of view, a contact is
@ -133,4 +135,20 @@ public interface Contact
* if it doesn't support resources
*/
public Collection<ContactResource> getResources();
/**
* Adds the given <tt>ContactResourceListener</tt> to listen for events
* related to contact resources changes.
*
* @param l the <tt>ContactResourceListener</tt> to add
*/
public void addResourceListener(ContactResourceListener l);
/**
* Removes the given <tt>ContactResourceListener</tt> listening for events
* related to contact resources changes.
*
* @param l the <tt>ContactResourceListener</tt> to rmove
*/
public void removeResourceListener(ContactResourceListener l);
}

@ -36,7 +36,7 @@ public class ContactResource
/**
* The presence status of this contact resource.
*/
private PresenceStatus presenceStatus;
protected PresenceStatus presenceStatus;
/**
* The priority of this contact source.

@ -0,0 +1,105 @@
/*
* Jitsi, 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.protocol.event;
import java.util.*;
import net.java.sip.communicator.service.protocol.*;
/**
* The <tt>ContactResourceEvent</tt> is the event that notifies for any changes
* in the <tt>ContactResource</tt>-s for a certain <tt>Contact</tt>.
*
* @author Yana Stamcheva
*/
public class ContactResourceEvent
extends EventObject
{
/**
* The <tt>ContactResource</tt> that is concerned by the change.
*/
private final ContactResource contactResource;
/**
* One of the event types defined in this class: RESOURCE_ADDED,
* RESOURCE_REMOVED, RESOURCE_MODIFIED.
*/
private final int eventType;
/**
* Indicates that the <tt>ContactResourceEvent</tt> instance was triggered
* by the add of a <tt>ContactResource</tt>.
*/
public static final int RESOURCE_ADDED = 0;
/**
* Indicates that the <tt>ContactResourceEvent</tt> instance was triggered
* by the removal of a <tt>ContactResource</tt>.
*/
public static final int RESOURCE_REMOVED = 1;
/**
* Indicates that the <tt>ContactResourceEvent</tt> instance was triggered
* by the modification of a <tt>ContactResource</tt>.
*/
public static final int RESOURCE_MODIFIED = 2;
/**
* Creates an instance of <tt>ContactResourceEvent</tt> by specifying the
* source, where this event occurred and the concerned
* <tt>ContactSource</tt>.
*
* @param source the source where this event occurred
* @param contactResource the <tt>ContactResource</tt> that is concerned by
* the change
* @param eventType an integer representing the type of this event. One of
* the types defined in this class: RESOURCE_ADDED, RESOURCE_REMOVED,
* RESOURCE_MODIFIED.
*/
public ContactResourceEvent(Contact source,
ContactResource contactResource,
int eventType)
{
super(source);
this.contactResource = contactResource;
this.eventType = eventType;
}
/**
* Returns the <tt>Contact</tt>, which is the source of this event.
*
* @return the <tt>Contact</tt>, which is the source of this event
*/
public Contact getContact()
{
return (Contact) getSource();
}
/**
* Returns the <tt>ContactResource</tt> that is concerned by the change.
*
* @return the <tt>ContactResource</tt> that is concerned by the change
*/
public ContactResource getContactResource()
{
return contactResource;
}
/**
* Returns the type of the event.
* <p>
* One of the event types defined in this class: RESOURCE_ADDED,
* RESOURCE_REMOVED, RESOURCE_MODIFIED.
*
* @return an int representing the type of the event
*/
public int getEventType()
{
return eventType;
}
}

@ -0,0 +1,41 @@
/*
* Jitsi, 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.protocol.event;
/**
* The <tt>ContactResourceListener</tt> listens for events related to
* <tt>ContactResource</tt>-s. It is notified each time a
* <tt>ContactResource</tt> has been added, removed or modified.
*
* @author Yana Stamcheva
*/
public interface ContactResourceListener
{
/**
* Called when a new <tt>ContactResource</tt> has been added to the list
* of available <tt>Contact</tt> resources.
*
* @param event the <tt>ContactResourceEvent</tt> that notified us
*/
public void contactResourceAdded(ContactResourceEvent event);
/**
* Called when a <tt>ContactResource</tt> has been removed to the list
* of available <tt>Contact</tt> resources.
*
* @param event the <tt>ContactResourceEvent</tt> that notified us
*/
public void contactResourceRemoved(ContactResourceEvent event);
/**
* Called when a <tt>ContactResource</tt> in the list of available
* <tt>Contact</tt> resources has been modified.
*
* @param event the <tt>ContactResourceEvent</tt> that notified us
*/
public void contactResourceModified(ContactResourceEvent event);
}
Loading…
Cancel
Save