1 /** 2 * $RCSfile$ 3 * $Revision$ 4 * $Date$ 5 * 6 * Copyright 2003-2007 Jive Software. 7 * 8 * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 */ 20 21 package org.jivesoftware.smackx; 22 23 import java.util.ArrayList; 24 import java.util.Iterator; 25 import java.util.List; 26 27 import org.jivesoftware.smack.PacketListener; 28 import org.jivesoftware.smack.Roster; 29 import org.jivesoftware.smack.RosterEntry; 30 import org.jivesoftware.smack.RosterGroup; 31 import org.jivesoftware.smack.Connection; 32 import org.jivesoftware.smack.filter.PacketExtensionFilter; 33 import org.jivesoftware.smack.filter.PacketFilter; 34 import org.jivesoftware.smack.packet.Message; 35 import org.jivesoftware.smack.packet.Packet; 36 import org.jivesoftware.smackx.packet.RosterExchange; 37 38 /** 39 * 40 * Manages Roster exchanges. A RosterExchangeManager provides a high level access to send 41 * rosters, roster groups and roster entries to XMPP clients. It also provides an easy way 42 * to hook up custom logic when entries are received from another XMPP client through 43 * RosterExchangeListeners. 44 * 45 * @author Gaston Dombiak 46 */ 47 public class RosterExchangeManager { 48 49 private List<RosterExchangeListener> rosterExchangeListeners = new ArrayList<RosterExchangeListener>(); 50 51 private Connection con; 52 53 private PacketFilter packetFilter = new PacketExtensionFilter("x", "jabber:x:roster"); 54 private PacketListener packetListener; 55 56 /** 57 * Creates a new roster exchange manager. 58 * 59 * @param con a Connection which is used to send and receive messages. 60 */ 61 public RosterExchangeManager(Connection con) { 62 this.con = con; 63 init(); 64 } 65 66 /** 67 * Adds a listener to roster exchanges. The listener will be fired anytime roster entries 68 * are received from remote XMPP clients. 69 * 70 * @param rosterExchangeListener a roster exchange listener. 71 */ 72 public void addRosterListener(RosterExchangeListener rosterExchangeListener) { 73 synchronized (rosterExchangeListeners) { 74 if (!rosterExchangeListeners.contains(rosterExchangeListener)) { 75 rosterExchangeListeners.add(rosterExchangeListener); 76 } 77 } 78 } 79 80 /** 81 * Removes a listener from roster exchanges. The listener will be fired anytime roster 82 * entries are received from remote XMPP clients. 83 * 84 * @param rosterExchangeListener a roster exchange listener.. 85 */ 86 public void removeRosterListener(RosterExchangeListener rosterExchangeListener) { 87 synchronized (rosterExchangeListeners) { 88 rosterExchangeListeners.remove(rosterExchangeListener); 89 } 90 } 91 92 /** 93 * Sends a roster to userID. All the entries of the roster will be sent to the 94 * target user. 95 * 96 * @param roster the roster to send 97 * @param targetUserID the user that will receive the roster entries 98 */ 99 public void send(Roster roster, String targetUserID) { 100 // Create a new message to send the roster 101 Message msg = new Message(targetUserID); 102 // Create a RosterExchange Package and add it to the message 103 RosterExchange rosterExchange = new RosterExchange(roster); 104 msg.addExtension(rosterExchange); 105 106 // Send the message that contains the roster 107 con.sendPacket(msg); 108 } 109 110 /** 111 * Sends a roster entry to userID. 112 * 113 * @param rosterEntry the roster entry to send 114 * @param targetUserID the user that will receive the roster entries 115 */ 116 public void send(RosterEntry rosterEntry, String targetUserID) { 117 // Create a new message to send the roster 118 Message msg = new Message(targetUserID); 119 // Create a RosterExchange Package and add it to the message 120 RosterExchange rosterExchange = new RosterExchange(); 121 rosterExchange.addRosterEntry(rosterEntry); 122 msg.addExtension(rosterExchange); 123 124 // Send the message that contains the roster 125 con.sendPacket(msg); 126 } 127 128 /** 129 * Sends a roster group to userID. All the entries of the group will be sent to the 130 * target user. 131 * 132 * @param rosterGroup the roster group to send 133 * @param targetUserID the user that will receive the roster entries 134 */ 135 public void send(RosterGroup rosterGroup, String targetUserID) { 136 // Create a new message to send the roster 137 Message msg = new Message(targetUserID); 138 // Create a RosterExchange Package and add it to the message 139 RosterExchange rosterExchange = new RosterExchange(); 140 for (RosterEntry entry : rosterGroup.getEntries()) { 141 rosterExchange.addRosterEntry(entry); 142 } 143 msg.addExtension(rosterExchange); 144 145 // Send the message that contains the roster 146 con.sendPacket(msg); 147 } 148 149 /** 150 * Fires roster exchange listeners. 151 */ 152 private void fireRosterExchangeListeners(String from, Iterator<RemoteRosterEntry> remoteRosterEntries) { 153 RosterExchangeListener[] listeners = null; 154 synchronized (rosterExchangeListeners) { 155 listeners = new RosterExchangeListener[rosterExchangeListeners.size()]; 156 rosterExchangeListeners.toArray(listeners); 157 } 158 for (int i = 0; i < listeners.length; i++) { 159 listeners[i].entriesReceived(from, remoteRosterEntries); 160 } 161 } 162 163 private void init() { 164 // Listens for all roster exchange packets and fire the roster exchange listeners. 165 packetListener = new PacketListener() { 166 public void processPacket(Packet packet) { 167 Message message = (Message) packet; 168 RosterExchange rosterExchange = 169 (RosterExchange) message.getExtension("x", "jabber:x:roster"); 170 // Fire event for roster exchange listeners 171 fireRosterExchangeListeners(message.getFrom(), rosterExchange.getRosterEntries()); 172 }; 173 174 }; 175 con.addPacketListener(packetListener, packetFilter); 176 } 177 178 public void destroy() { 179 if (con != null) 180 con.removePacketListener(packetListener); 181 182 } 183 protected void finalize() throws Throwable { 184 destroy(); 185 super.finalize(); 186 } 187 } 188