blob: 4ac84be92b89724979f55466c387c9ba77a00528 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2007 Remy Suen
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Remy Suen <remy.suen@gmail.com> - initial API and implementation
******************************************************************************/
package org.eclipse.ecf.protocol.msn;
import java.net.URLDecoder;
import java.util.*;
import org.eclipse.ecf.protocol.msn.events.IContactListener;
import org.eclipse.ecf.protocol.msn.internal.encode.StringUtils;
/**
* <p>
* This class represents a contact that a user has on his or her MSN list.
* </p>
*
* <p>
* <b>Note:</b> This class/interface is part of an interim API that is still
* under development and expected to change significantly before reaching
* stability. It is being made available at this early stage to solicit feedback
* from pioneering adopters on the understanding that any code that uses this
* API will almost certainly be broken (repeatedly) as the API evolves.
* </p>
*/
public final class Contact {
/**
* The list of listeners that is attached to this.
*/
private final ArrayList listeners;
/**
* The list of groups that this contact is in.
*/
private final ArrayList groups;
/**
* The email address that is associated with this contact.
*/
private final String email;
/**
* The guid of this contact.
*/
private final String guid;
/**
* The displayed name of this contact, this is typically different from
* their {@link #email}.
*/
private String name;
/**
* The personal message that the contact is currently displaying.
*/
private String personalMessage;
/**
* The current status of this user.
*
* @see Status#ONLINE Status.ONLINE and others
*/
private Status status;
/**
* Creates a new Contact with the given name and email address.
* @param email
* the user's email address
* @param name
* the contact's MSN nickname in raw format, the name will be URL
* decoded accordingly
*/
Contact(String email, String name) {
this(email, name, null);
}
Contact(String email, String name, String guid) {
this.name = URLDecoder.decode(name);
this.email = email;
this.guid = guid;
this.status = Status.OFFLINE;
listeners = new ArrayList();
groups = new ArrayList();
}
/**
* Invokes the {@link IContactListener#statusChanged(Status)} method on
* every listener within {@link #listeners}. This method is automatically
* invoked when {@link #setStatus(Status)} is called.
*
* @param newStatus
* the status that this contact has now switched to
*/
private void fireStatusChanged(Status newStatus) {
synchronized (listeners) {
for (int i = 0; i < listeners.size(); i++) {
((IContactListener) listeners.get(i)).statusChanged(newStatus);
}
}
}
/**
* Invokes the {@link IContactListener#nameChanged(String)} method on every
* listener within {@link #listeners}. This method is automatically invoked
* when {@link #setDisplayName(String)} is called.
*
* @param newName
* the new name of this contact
*/
private void fireNameChanged(String newName) {
synchronized (listeners) {
for (int i = 0; i < listeners.size(); i++) {
((IContactListener) listeners.get(i)).nameChanged(newName);
}
}
}
private void firePersonalMessageChanged(String message) {
synchronized (listeners) {
for (int i = 0; i < listeners.size(); i++) {
((IContactListener) listeners.get(i)).personalMessageChanged(message);
}
}
}
void add(Group group) {
groups.add(group);
}
void remove() {
for (int i = 0; i < groups.size(); i++) {
((Group) groups.get(i)).remove(this);
}
groups.clear();
}
/**
* Retrieves the groups that this contact is a part of.
*
* @return a collection of the groups that this contact is a member of
*/
public Collection getGroups() {
return Collections.unmodifiableCollection(groups);
}
/**
* Sets this contact's status to the given status. Developers are highly
* discouraged from calling this method since if the user's status actually
* did change, the {@link IContactListener#nameChanged(String)} method will
* be invoked on all the listeners attached to this contact.
*
* @param status
* the status that this contact is now in
*/
void setStatus(Status status) {
if (this.status != status) {
this.status = status;
fireStatusChanged(status);
}
}
/**
* Retrieves the current status of this contact.
*
* @return the status that this contact currently is in
*/
public Status getStatus() {
return status;
}
/**
* Sets the user name of this contact with the given name. Developers are
* highly discouraged from calling this method since if the value of
* <code>newName</code> differs from the current name, the
* {@link IContactListener#nameChanged(String)} method will be invoked on
* all the listeners attached to this contact.
*
* @param newName
* the new user name of this Contact
*/
void setDisplayName(String newName) {
newName = URLDecoder.decode(newName);
if (!newName.equals(name)) {
this.name = newName;
fireNameChanged(newName);
}
}
/**
* Gets the displayed name of this contact.
*
* @return the name that this contact uses
*/
public String getDisplayName() {
return name;
}
/**
* Changes the contact's personal message to the provided message if the two
* messages differ.
*
* @param message
* the message the contact may have set to
*/
void setPersonalMessage(String message) {
message = StringUtils.xmlDecode(message);
if (!message.equals(personalMessage)) {
personalMessage = message;
firePersonalMessageChanged(message);
}
}
/**
* Returns the personal message that this contact is currently using.
*
* @return the personal message in use
*/
public String getPersonalMessage() {
return personalMessage;
}
/**
* Returns the email address of the user.
*
* @return the user's email address
*/
public String getEmail() {
return email;
}
String getGuid() {
return guid;
}
/**
* Adds a IContactListener to this contact.
*
* @param listener
* the listener to be added
*/
public void addContactListener(IContactListener listener) {
if (listener != null) {
synchronized (listeners) {
if (!listeners.contains(listener)) {
listeners.add(listener);
}
}
}
}
/**
* Removes a IContactListener from this contact.
*
* @param listener
* the listener to be removed
*/
public void removeContactListener(IContactListener listener) {
if (listener != null) {
synchronized (listeners) {
listeners.remove(listener);
}
}
}
/**
* Returns this contact's email address that's being used for identification
* purposes in MSN.
*
* @return the contact's email address
*/
public String toString() {
return email;
}
/**
* Returns whether the specified object is equal to this. An object is equal
* to this if it is also a <tt>Contact</tt> and its email addresses is
* equal to this contact's email address.
* @param obj
*
* @return <code>true</code> if the argument is a <tt>Contact</tt> and
* also has the same email address as this
*/
public boolean equals(Object obj) {
if (this == obj) {
return true;
} else if (obj instanceof Contact) {
return email.equals(((Contact) obj).email);
} else {
return false;
}
}
/**
* Returns a unique integer hash code for this contact.
*
* @return a integer hash code that represents this contact
*/
public int hashCode() {
return 31 * -1 + email.hashCode();
}
}