Improve jabber image retreiving

cusax-fix
Damian Minkov 19 years ago
parent 188b8adb05
commit 0dac2cc68c

@ -7,7 +7,6 @@
package net.java.sip.communicator.impl.protocol.jabber;
import org.jivesoftware.smack.*;
import org.jivesoftware.smackx.packet.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.util.*;
import net.java.sip.communicator.service.protocol.jabberconstants.*;
@ -89,13 +88,24 @@ public boolean isLocal()
return isLocal;
}
/**
* Returns the image of the contact or null if absent
*/
public byte[] getImage()
{
if(image == null)
image = getAvatar();
ssclCallback.addContactForImageUpdate(this);
return image;
}
/**
* Set the image of the contact
*/
void setImage(byte[] imgBytes)
{
this.image = imgBytes;
}
/**
* Returns a hashCode for this contact. The returned hashcode is actually
@ -292,31 +302,4 @@ RosterEntry getSourceEntry()
{
return rosterEntry;
}
private byte[] getAvatar()
{
try
{
XMPPConnection connection =
ssclCallback.getParentProvider().getConnection();
if(connection == null || !connection.isAuthenticated())
return null;
VCard card = new VCard();
card.load(
connection,
getAddress());
return card.getAvatar();
}
catch (Exception exc)
{
logger.error("Cannot load image for contact "
+ this + " : " + exc.getMessage()
, exc);
}
return null;
}
}

@ -998,6 +998,46 @@ private void fireContactPresenceStatusChangeEvent(
listener.contactPresenceStatusChanged(evt);
}
}
/**
* Notify all subscription listeners of the corresponding contact property
* change event.
*
* @param eventID the String ID of the event to dispatch
* @param sourceContact the ContactJabberImpl instance that this event is
* pertaining to.
* @param oldValue the value that the changed property had before the change
* occurred.
* @param newValue the value that the changed property currently has (after
* the change has occurred).
*/
void fireContactPropertyChangeEvent( String eventID,
ContactJabberImpl sourceContact,
Object oldValue,
Object newValue)
{
ContactPropertyChangeEvent evt =
new ContactPropertyChangeEvent(sourceContact, eventID
, oldValue, newValue);
logger.debug("Dispatching a Contact Property Change Event to"
+subscriptionListeners.size() + " listeners. Evt="+evt);
Iterator listeners = null;
synchronized (subscriptionListeners)
{
listeners = new ArrayList(subscriptionListeners).iterator();
}
while (listeners.hasNext())
{
SubscriptionListener listener
= (SubscriptionListener) listeners.next();
listener.contactModified(evt);
}
}
/**
*

@ -298,11 +298,7 @@ private void connectAndLogin(SecurityAuthority authority)
{
logger.error("Failed to establish a Jabber connection for "
+ getAccountID().getAccountUniqueID(), exc);
fireRegistrationStateChanged(
getRegistrationState()
, RegistrationState.CONNECTION_FAILED
, OperationFailedException.NETWORK_FAILURE
, null);
throw new OperationFailedException(
"Failed to establish a Jabber connection for "
+ getAccountID().getAccountUniqueID()

@ -10,6 +10,7 @@
import org.jivesoftware.smack.*;
import org.jivesoftware.smack.packet.*;
import org.jivesoftware.smackx.packet.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.event.*;
import net.java.sip.communicator.util.*;
@ -58,6 +59,11 @@ public class ServerStoredContactListJabberImpl
* names or other properties, removal or creation of groups.
*/
private Vector serverStoredGroupListeners = new Vector();
/**
* Thread retreiving images for contacts
*/
private ImageRetriever imageRetriever = null;
/**
* Creates a ServerStoredContactList wrapper for the specified BuddyList.
@ -746,6 +752,23 @@ void fireContactResolved( ContactGroupJabberImpl parentGroup,
parentOperationSet.fireSubscriptionEvent(
SubscriptionEvent.SUBSCRIPTION_RESOLVED, contact, parentGroup);
}
/**
* when there is no image for contact we must retreive it
* add contacts for image update
*
* @param c ContactJabberImpl
*/
protected void addContactForImageUpdate(ContactJabberImpl c)
{
if(imageRetriever == null)
{
imageRetriever = new ImageRetriever();
imageRetriever.start();
}
imageRetriever.addContact(c);
}
private class ChangeListener
implements RosterListener
@ -938,4 +961,95 @@ else if(group instanceof RootContactGroupJabberImpl)
public void presenceChanged(Presence presence)
{}
}
}
private class ImageRetriever
extends Thread
{
/**
* list with the accounts with missing image
*/
private Vector contactsForUpdate = new Vector();
public void run()
{
try
{
Collection copyContactsForUpdate = null;
while (true)
{
synchronized(contactsForUpdate){
if(contactsForUpdate.isEmpty())
contactsForUpdate.wait();
copyContactsForUpdate = new Vector(contactsForUpdate);
contactsForUpdate.clear();
}
Iterator iter = copyContactsForUpdate.iterator();
while (iter.hasNext())
{
ContactJabberImpl contact = (ContactJabberImpl) iter.next();
byte[] imgBytes = getAvatar(contact);
if(imgBytes != null)
{
contact.setImage(imgBytes);
parentOperationSet.fireContactPropertyChangeEvent(
ContactPropertyChangeEvent.PROPERTY_IMAGE,
contact, null, imgBytes);
}
}
}
}
catch (InterruptedException ex)
{
logger.error("NickRetriever error waiting will stop now!", ex);
}
}
/**
* Add contact for retreiving
* if the provider is register notify the retreiver to get the nicks
* if we are not registered add a listener to wiat for registering
*
* @param contact ContactJabberImpl
*/
synchronized void addContact(ContactJabberImpl contact)
{
synchronized(contactsForUpdate){
if (!contactsForUpdate.contains(contact))
{
contactsForUpdate.add(contact);
contactsForUpdate.notifyAll();
}
}
}
private byte[] getAvatar(ContactJabberImpl contact)
{
try
{
XMPPConnection connection = jabberProvider.getConnection();
if(connection == null || !connection.isAuthenticated())
return null;
VCard card = new VCard();
card.load(connection, contact.getAddress());
return card.getAvatar();
}
catch (Exception exc)
{
logger.error("Cannot load image for contact "
+ this + " : " + exc.getMessage()
, exc);
}
return null;
}
}
}

@ -17,6 +17,12 @@ public class ContactPropertyChangeEvent
* contact.
*/
public static final String PROPERTY_DISPLAY_NAME = "DisplayName";
/**
* Indicates that a change has occurred in the image of the source
* contact.
*/
public static final String PROPERTY_IMAGE = "Image";
/**
* Creates a ContactPropertyChangeEvent indicating that a change has

Loading…
Cancel
Save