Home | History | Annotate | Download | only in smackx
      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