Home | History | Annotate | Download | only in packet
      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.packet;
     22 
     23 import org.jivesoftware.smack.Roster;
     24 import org.jivesoftware.smack.RosterEntry;
     25 import org.jivesoftware.smack.RosterGroup;
     26 import org.jivesoftware.smack.packet.PacketExtension;
     27 import org.jivesoftware.smackx.RemoteRosterEntry;
     28 
     29 import java.util.ArrayList;
     30 import java.util.Collections;
     31 import java.util.Iterator;
     32 import java.util.List;
     33 
     34 /**
     35  * Represents XMPP Roster Item Exchange packets.<p>
     36  *
     37  * The 'jabber:x:roster' namespace (which is not to be confused with the 'jabber:iq:roster'
     38  * namespace) is used to send roster items from one client to another. A roster item is sent by
     39  * adding to the &lt;message/&gt; element an &lt;x/&gt; child scoped by the 'jabber:x:roster' namespace. This
     40  * &lt;x/&gt; element may contain one or more &lt;item/&gt; children (one for each roster item to be sent).<p>
     41  *
     42  * Each &lt;item/&gt; element may possess the following attributes:<p>
     43  *
     44  * &lt;jid/&gt; -- The id of the contact being sent. This attribute is required.<br>
     45  * &lt;name/&gt; -- A natural-language nickname for the contact. This attribute is optional.<p>
     46  *
     47  * Each &lt;item/&gt; element may also contain one or more &lt;group/&gt; children specifying the
     48  * natural-language name of a user-specified group, for the purpose of categorizing this contact
     49  * into one or more roster groups.
     50  *
     51  * @author Gaston Dombiak
     52  */
     53 public class RosterExchange implements PacketExtension {
     54 
     55     private List<RemoteRosterEntry> remoteRosterEntries = new ArrayList<RemoteRosterEntry>();
     56 
     57     /**
     58      * Creates a new empty roster exchange package.
     59      *
     60      */
     61     public RosterExchange() {
     62         super();
     63     }
     64 
     65     /**
     66      * Creates a new roster exchange package with the entries specified in roster.
     67      *
     68      * @param roster the roster to send to other XMPP entity.
     69      */
     70     public RosterExchange(Roster roster) {
     71         // Add all the roster entries to the new RosterExchange
     72         for (RosterEntry rosterEntry : roster.getEntries()) {
     73             this.addRosterEntry(rosterEntry);
     74         }
     75     }
     76 
     77     /**
     78      * Adds a roster entry to the packet.
     79      *
     80      * @param rosterEntry a roster entry to add.
     81      */
     82     public void addRosterEntry(RosterEntry rosterEntry) {
     83 		// Obtain a String[] from the roster entry groups name
     84 		List<String> groupNamesList = new ArrayList<String>();
     85 		String[] groupNames;
     86 		for (RosterGroup group : rosterEntry.getGroups()) {
     87 			groupNamesList.add(group.getName());
     88 		}
     89 		groupNames = groupNamesList.toArray(new String[groupNamesList.size()]);
     90 
     91         // Create a new Entry based on the rosterEntry and add it to the packet
     92         RemoteRosterEntry remoteRosterEntry = new RemoteRosterEntry(rosterEntry.getUser(),
     93                 rosterEntry.getName(), groupNames);
     94 
     95         addRosterEntry(remoteRosterEntry);
     96     }
     97 
     98     /**
     99      * Adds a remote roster entry to the packet.
    100      *
    101      * @param remoteRosterEntry a remote roster entry to add.
    102      */
    103     public void addRosterEntry(RemoteRosterEntry remoteRosterEntry) {
    104         synchronized (remoteRosterEntries) {
    105             remoteRosterEntries.add(remoteRosterEntry);
    106         }
    107     }
    108 
    109     /**
    110     * Returns the XML element name of the extension sub-packet root element.
    111     * Always returns "x"
    112     *
    113     * @return the XML element name of the packet extension.
    114     */
    115     public String getElementName() {
    116         return "x";
    117     }
    118 
    119     /**
    120      * Returns the XML namespace of the extension sub-packet root element.
    121      * According the specification the namespace is always "jabber:x:roster"
    122      * (which is not to be confused with the 'jabber:iq:roster' namespace
    123      *
    124      * @return the XML namespace of the packet extension.
    125      */
    126     public String getNamespace() {
    127         return "jabber:x:roster";
    128     }
    129 
    130     /**
    131      * Returns an Iterator for the roster entries in the packet.
    132      *
    133      * @return an Iterator for the roster entries in the packet.
    134      */
    135     public Iterator<RemoteRosterEntry> getRosterEntries() {
    136         synchronized (remoteRosterEntries) {
    137             List<RemoteRosterEntry> entries = Collections.unmodifiableList(new ArrayList<RemoteRosterEntry>(remoteRosterEntries));
    138             return entries.iterator();
    139         }
    140     }
    141 
    142     /**
    143      * Returns a count of the entries in the roster exchange.
    144      *
    145      * @return the number of entries in the roster exchange.
    146      */
    147     public int getEntryCount() {
    148         return remoteRosterEntries.size();
    149     }
    150 
    151     /**
    152      * Returns the XML representation of a Roster Item Exchange according the specification.
    153      *
    154      * Usually the XML representation will be inside of a Message XML representation like
    155      * in the following example:
    156      * <pre>
    157      * &lt;message id="MlIpV-4" to="gato1 (at) gato.home" from="gato3 (at) gato.home/Smack"&gt;
    158      *     &lt;subject&gt;Any subject you want&lt;/subject&gt;
    159      *     &lt;body&gt;This message contains roster items.&lt;/body&gt;
    160      *     &lt;x xmlns="jabber:x:roster"&gt;
    161      *         &lt;item jid="gato1 (at) gato.home"/&gt;
    162      *         &lt;item jid="gato2 (at) gato.home"/&gt;
    163      *     &lt;/x&gt;
    164      * &lt;/message&gt;
    165      * </pre>
    166      *
    167      */
    168     public String toXML() {
    169         StringBuilder buf = new StringBuilder();
    170         buf.append("<").append(getElementName()).append(" xmlns=\"").append(getNamespace()).append(
    171             "\">");
    172         // Loop through all roster entries and append them to the string buffer
    173         for (Iterator<RemoteRosterEntry> i = getRosterEntries(); i.hasNext();) {
    174             RemoteRosterEntry remoteRosterEntry = i.next();
    175             buf.append(remoteRosterEntry.toXML());
    176         }
    177         buf.append("</").append(getElementName()).append(">");
    178         return buf.toString();
    179     }
    180 
    181 }
    182