1d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 2d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * $RCSfile$ 3d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * $Revision$ 4d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * $Date$ 5d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 6d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Copyright 2003-2007 Jive Software. 7d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 8d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); 9d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * you may not use this file except in compliance with the License. 10d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * You may obtain a copy of the License at 11d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 12d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * http://www.apache.org/licenses/LICENSE-2.0 13d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 14d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Unless required by applicable law or agreed to in writing, software 15d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * distributed under the License is distributed on an "AS IS" BASIS, 16d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * See the License for the specific language governing permissions and 18d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * limitations under the License. 19d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 20d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 21d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpackage org.jivesoftware.smack; 22d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 23d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.filter.PacketIDFilter; 24d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.packet.IQ; 25d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.packet.RosterPacket; 26d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.jivesoftware.smack.util.StringUtils; 27d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 28d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.ArrayList; 29d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.Collection; 30d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.Collections; 31d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.List; 32d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 33d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 34d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * A group of roster entries. 35d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 36d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @see Roster#getGroup(String) 37d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @author Matt Tucker 38d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 39d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic class RosterGroup { 40d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 41d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private String name; 42d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private Connection connection; 43d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private final List<RosterEntry> entries; 44d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 45d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 46d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Creates a new roster group instance. 47d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 48d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param name the name of the group. 49d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param connection the connection the group belongs to. 50d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 51d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen RosterGroup(String name, Connection connection) { 52d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.name = name; 53d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.connection = connection; 54d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen entries = new ArrayList<RosterEntry>(); 55d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 56d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 57d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 58d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the name of the group. 59d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 60d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the name of the group. 61d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 62d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public String getName() { 63d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return name; 64d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 65d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 66d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 67d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Sets the name of the group. Changing the group's name is like moving all the group entries 68d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * of the group to a new group specified by the new name. Since this group won't have entries 69d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * it will be removed from the roster. This means that all the references to this object will 70d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * be invalid and will need to be updated to the new group specified by the new name. 71d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 72d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param name the name of the group. 73d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 74d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void setName(String name) { 75d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen synchronized (entries) { 76d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (RosterEntry entry : entries) { 77d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen RosterPacket packet = new RosterPacket(); 78d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen packet.setType(IQ.Type.SET); 79d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen RosterPacket.Item item = RosterEntry.toRosterItem(entry); 80d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen item.removeGroupName(this.name); 81d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen item.addGroupName(name); 82d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen packet.addRosterItem(item); 83d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen connection.sendPacket(packet); 84d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 85d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 86d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 87d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 88d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 89d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the number of entries in the group. 90d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 91d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the number of entries in the group. 92d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 93d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public int getEntryCount() { 94d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen synchronized (entries) { 95d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return entries.size(); 96d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 97d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 98d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 99d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 100d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns an unmodifiable collection of all entries in the group. 101d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 102d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return all entries in the group. 103d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 104d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public Collection<RosterEntry> getEntries() { 105d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen synchronized (entries) { 106d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return Collections.unmodifiableList(new ArrayList<RosterEntry>(entries)); 107d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 108d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 109d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 110d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 111d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the roster entry associated with the given XMPP address or 112d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * <tt>null</tt> if the user is not an entry in the group. 113d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 114d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param user the XMPP address of the user (eg "jsmith@example.com"). 115d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return the roster entry or <tt>null</tt> if it does not exist in the group. 116d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 117d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public RosterEntry getEntry(String user) { 118d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (user == null) { 119d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return null; 120d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 121d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Roster entries never include a resource so remove the resource 122d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // if it's a part of the XMPP address. 123d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen user = StringUtils.parseBareAddress(user); 124d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen String userLowerCase = user.toLowerCase(); 125d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen synchronized (entries) { 126d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (RosterEntry entry : entries) { 127d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (entry.getUser().equals(userLowerCase)) { 128d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return entry; 129d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 130d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 131d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 132d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return null; 133d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 134d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 135d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 136d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns true if the specified entry is part of this group. 137d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 138d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param entry a roster entry. 139d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return true if the entry is part of this group. 140d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 141d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public boolean contains(RosterEntry entry) { 142d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen synchronized (entries) { 143d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return entries.contains(entry); 144d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 145d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 146d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 147d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 148d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns true if the specified XMPP address is an entry in this group. 149d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 150d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param user the XMPP address of the user. 151d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return true if the XMPP address is an entry in this group. 152d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 153d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public boolean contains(String user) { 154d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return getEntry(user) != null; 155d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 156d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 157d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 158d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Adds a roster entry to this group. If the entry was unfiled then it will be removed from 159d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * the unfiled list and will be added to this group. 160d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Note that this is an asynchronous call -- Smack must wait for the server 161d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * to receive the updated roster. 162d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 163d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param entry a roster entry. 164d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws XMPPException if an error occured while trying to add the entry to the group. 165d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 166d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void addEntry(RosterEntry entry) throws XMPPException { 167d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen PacketCollector collector = null; 168d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Only add the entry if it isn't already in the list. 169d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen synchronized (entries) { 170d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (!entries.contains(entry)) { 171d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen RosterPacket packet = new RosterPacket(); 172d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen packet.setType(IQ.Type.SET); 173d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen RosterPacket.Item item = RosterEntry.toRosterItem(entry); 174d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen item.addGroupName(getName()); 175d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen packet.addRosterItem(item); 176d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Wait up to a certain number of seconds for a reply from the server. 177d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen collector = connection 178d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen .createPacketCollector(new PacketIDFilter(packet.getPacketID())); 179d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen connection.sendPacket(packet); 180d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 181d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 182d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (collector != null) { 183d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen IQ response = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout()); 184d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen collector.cancel(); 185d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (response == null) { 186d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new XMPPException("No response from the server."); 187d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 188d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // If the server replied with an error, throw an exception. 189d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen else if (response.getType() == IQ.Type.ERROR) { 190d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new XMPPException(response.getError()); 191d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 192d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 193d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 194d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 195d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 196d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Removes a roster entry from this group. If the entry does not belong to any other group 197d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * then it will be considered as unfiled, therefore it will be added to the list of unfiled 198d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * entries. 199d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Note that this is an asynchronous call -- Smack must wait for the server 200d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * to receive the updated roster. 201d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 202d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param entry a roster entry. 203d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws XMPPException if an error occured while trying to remove the entry from the group. 204d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 205d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void removeEntry(RosterEntry entry) throws XMPPException { 206d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen PacketCollector collector = null; 207d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Only remove the entry if it's in the entry list. 208d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Remove the entry locally, if we wait for RosterPacketListenerprocess>>Packet(Packet) 209d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // to take place the entry will exist in the group until a packet is received from the 210d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // server. 211d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen synchronized (entries) { 212d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (entries.contains(entry)) { 213d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen RosterPacket packet = new RosterPacket(); 214d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen packet.setType(IQ.Type.SET); 215d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen RosterPacket.Item item = RosterEntry.toRosterItem(entry); 216d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen item.removeGroupName(this.getName()); 217d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen packet.addRosterItem(item); 218d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Wait up to a certain number of seconds for a reply from the server. 219d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen collector = connection 220d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen .createPacketCollector(new PacketIDFilter(packet.getPacketID())); 221d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen connection.sendPacket(packet); 222d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 223d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 224d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (collector != null) { 225d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen IQ response = (IQ) collector.nextResult(SmackConfiguration.getPacketReplyTimeout()); 226d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen collector.cancel(); 227d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (response == null) { 228d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new XMPPException("No response from the server."); 229d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 230d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // If the server replied with an error, throw an exception. 231d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen else if (response.getType() == IQ.Type.ERROR) { 232d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new XMPPException(response.getError()); 233d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 234d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 235d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 236d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 237d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public void addEntryLocal(RosterEntry entry) { 238d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Only add the entry if it isn't already in the list. 239d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen synchronized (entries) { 240d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen entries.remove(entry); 241d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen entries.add(entry); 242d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 243d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 244d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 245d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen void removeEntryLocal(RosterEntry entry) { 246d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // Only remove the entry if it's in the entry list. 247d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen synchronized (entries) { 248d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (entries.contains(entry)) { 249d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen entries.remove(entry); 250d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 251d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 252d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 253d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen}