/** * $RCSfile$ * $Revision$ * $Date$ * * Copyright 2003-2007 Jive Software. * * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jivesoftware.smack; import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.RosterPacket; import java.util.*; /** * Each user in your roster is represented by a roster entry, which contains the user's * JID and a name or nickname you assign. * * @author Matt Tucker */ public class RosterEntry { private String user; private String name; private RosterPacket.ItemType type; private RosterPacket.ItemStatus status; final private Roster roster; final private Connection connection; /** * Creates a new roster entry. * * @param user the user. * @param name the nickname for the entry. * @param type the subscription type. * @param status the subscription status (related to subscriptions pending to be approbed). * @param connection a connection to the XMPP server. */ RosterEntry(String user, String name, RosterPacket.ItemType type, RosterPacket.ItemStatus status, Roster roster, Connection connection) { this.user = user; this.name = name; this.type = type; this.status = status; this.roster = roster; this.connection = connection; } /** * Returns the JID of the user associated with this entry. * * @return the user associated with this entry. */ public String getUser() { return user; } /** * Returns the name associated with this entry. * * @return the name. */ public String getName() { return name; } /** * Sets the name associated with this entry. * * @param name the name. */ public void setName(String name) { // Do nothing if the name hasn't changed. if (name != null && name.equals(this.name)) { return; } this.name = name; RosterPacket packet = new RosterPacket(); packet.setType(IQ.Type.SET); packet.addRosterItem(toRosterItem(this)); connection.sendPacket(packet); } /** * Updates the state of the entry with the new values. * * @param name the nickname for the entry. * @param type the subscription type. * @param status the subscription status (related to subscriptions pending to be approbed). */ void updateState(String name, RosterPacket.ItemType type, RosterPacket.ItemStatus status) { this.name = name; this.type = type; this.status = status; } /** * Returns an unmodifiable collection of the roster groups that this entry belongs to. * * @return an iterator for the groups this entry belongs to. */ public Collection<RosterGroup> getGroups() { List<RosterGroup> results = new ArrayList<RosterGroup>(); // Loop through all roster groups and find the ones that contain this // entry. This algorithm should be fine for (RosterGroup group: roster.getGroups()) { if (group.contains(this)) { results.add(group); } } return Collections.unmodifiableCollection(results); } /** * Returns the roster subscription type of the entry. When the type is * RosterPacket.ItemType.none or RosterPacket.ItemType.from, * refer to {@link RosterEntry getStatus()} to see if a subscription request * is pending. * * @return the type. */ public RosterPacket.ItemType getType() { return type; } /** * Returns the roster subscription status of the entry. When the status is * RosterPacket.ItemStatus.SUBSCRIPTION_PENDING, the contact has to answer the * subscription request. * * @return the status. */ public RosterPacket.ItemStatus getStatus() { return status; } public String toString() { StringBuilder buf = new StringBuilder(); if (name != null) { buf.append(name).append(": "); } buf.append(user); Collection<RosterGroup> groups = getGroups(); if (!groups.isEmpty()) { buf.append(" ["); Iterator<RosterGroup> iter = groups.iterator(); RosterGroup group = iter.next(); buf.append(group.getName()); while (iter.hasNext()) { buf.append(", "); group = iter.next(); buf.append(group.getName()); } buf.append("]"); } return buf.toString(); } public boolean equals(Object object) { if (this == object) { return true; } if (object != null && object instanceof RosterEntry) { return user.equals(((RosterEntry)object).getUser()); } else { return false; } } @Override public int hashCode() { return this.user.hashCode(); } /** * Indicates whether some other object is "equal to" this by comparing all members. * <p> * The {@link #equals(Object)} method returns <code>true</code> if the user JIDs are equal. * * @param obj the reference object with which to compare. * @return <code>true</code> if this object is the same as the obj argument; <code>false</code> * otherwise. */ public boolean equalsDeep(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; RosterEntry other = (RosterEntry) obj; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; if (status == null) { if (other.status != null) return false; } else if (!status.equals(other.status)) return false; if (type == null) { if (other.type != null) return false; } else if (!type.equals(other.type)) return false; if (user == null) { if (other.user != null) return false; } else if (!user.equals(other.user)) return false; return true; } static RosterPacket.Item toRosterItem(RosterEntry entry) { RosterPacket.Item item = new RosterPacket.Item(entry.getUser(), entry.getName()); item.setItemType(entry.getType()); item.setItemStatus(entry.getStatus()); // Set the correct group names for the item. for (RosterGroup group : entry.getGroups()) { item.addGroupName(group.getName()); } return item; } }