RosterExchange.java

  1. /**
  2.  *
  3.  * Copyright 2003-2007 Jive Software.
  4.  *
  5.  * Licensed under the Apache License, Version 2.0 (the "License");
  6.  * you may not use this file except in compliance with the License.
  7.  * You may obtain a copy of the License at
  8.  *
  9.  *     http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */

  17. package org.jivesoftware.smackx.xroster.packet;

  18. import org.jivesoftware.smack.packet.ExtensionElement;
  19. import org.jivesoftware.smack.roster.Roster;
  20. import org.jivesoftware.smack.roster.RosterEntry;
  21. import org.jivesoftware.smack.roster.RosterGroup;
  22. import org.jivesoftware.smackx.xroster.RemoteRosterEntry;
  23. import org.jivesoftware.smackx.xroster.RosterExchangeManager;

  24. import java.util.ArrayList;
  25. import java.util.Collections;
  26. import java.util.Iterator;
  27. import java.util.List;

  28. /**
  29.  * Represents XMPP Roster Item Exchange packets.<p>
  30.  *
  31.  * The 'jabber:x:roster' namespace (which is not to be confused with the 'jabber:iq:roster'
  32.  * namespace) is used to send roster items from one client to another. A roster item is sent by
  33.  * adding to the &lt;message/&gt; element an &lt;x/&gt; child scoped by the 'jabber:x:roster' namespace. This
  34.  * &lt;x/&gt; element may contain one or more &lt;item/&gt; children (one for each roster item to be sent).<p>
  35.  *
  36.  * Each &lt;item/&gt; element may possess the following attributes:<p>
  37.  *
  38.  * &lt;jid/&gt; -- The id of the contact being sent. This attribute is required.<br>
  39.  * &lt;name/&gt; -- A natural-language nickname for the contact. This attribute is optional.<p>
  40.  *
  41.  * Each &lt;item/&gt; element may also contain one or more &lt;group/&gt; children specifying the
  42.  * natural-language name of a user-specified group, for the purpose of categorizing this contact
  43.  * into one or more roster groups.
  44.  *
  45.  * @author Gaston Dombiak
  46.  */
  47. public class RosterExchange implements ExtensionElement {

  48.     private List<RemoteRosterEntry> remoteRosterEntries = new ArrayList<RemoteRosterEntry>();

  49.     /**
  50.      * Creates a new empty roster exchange package.
  51.      *
  52.      */
  53.     public RosterExchange() {
  54.         super();
  55.     }

  56.     /**
  57.      * Creates a new roster exchange package with the entries specified in roster.
  58.      *
  59.      * @param roster the roster to send to other XMPP entity.
  60.      */
  61.     public RosterExchange(Roster roster) {
  62.         // Add all the roster entries to the new RosterExchange
  63.         for (RosterEntry rosterEntry : roster.getEntries()) {
  64.             this.addRosterEntry(rosterEntry);
  65.         }
  66.     }

  67.     /**
  68.      * Adds a roster entry to the packet.
  69.      *
  70.      * @param rosterEntry a roster entry to add.
  71.      */
  72.     public void addRosterEntry(RosterEntry rosterEntry) {
  73.         // Obtain a String[] from the roster entry groups name
  74.         List<String> groupNamesList = new ArrayList<String>();
  75.         String[] groupNames;
  76.         for (RosterGroup group : rosterEntry.getGroups()) {
  77.             groupNamesList.add(group.getName());
  78.         }
  79.         groupNames = groupNamesList.toArray(new String[groupNamesList.size()]);

  80.         // Create a new Entry based on the rosterEntry and add it to the packet
  81.         RemoteRosterEntry remoteRosterEntry = new RemoteRosterEntry(rosterEntry.getUser(),
  82.                 rosterEntry.getName(), groupNames);
  83.        
  84.         addRosterEntry(remoteRosterEntry);
  85.     }

  86.     /**
  87.      * Adds a remote roster entry to the packet.
  88.      *
  89.      * @param remoteRosterEntry a remote roster entry to add.
  90.      */
  91.     public void addRosterEntry(RemoteRosterEntry remoteRosterEntry) {
  92.         synchronized (remoteRosterEntries) {
  93.             remoteRosterEntries.add(remoteRosterEntry);
  94.         }
  95.     }
  96.    
  97.     /**
  98.     * Returns the XML element name of the extension sub-packet root element.
  99.     * Always returns "x"
  100.     *
  101.     * @return the XML element name of the packet extension.
  102.     */
  103.     public String getElementName() {
  104.         return RosterExchangeManager.ELEMENT;
  105.     }

  106.     /**
  107.      * Returns the XML namespace of the extension sub-packet root element.
  108.      * According the specification the namespace is always "jabber:x:roster"
  109.      * (which is not to be confused with the 'jabber:iq:roster' namespace
  110.      *
  111.      * @return the XML namespace of the packet extension.
  112.      */
  113.     public String getNamespace() {
  114.         return RosterExchangeManager.NAMESPACE;
  115.     }

  116.     /**
  117.      * Returns an Iterator for the roster entries in the packet.
  118.      *
  119.      * @return an Iterator for the roster entries in the packet.
  120.      */
  121.     public Iterator<RemoteRosterEntry> getRosterEntries() {
  122.         synchronized (remoteRosterEntries) {
  123.             List<RemoteRosterEntry> entries = Collections.unmodifiableList(new ArrayList<RemoteRosterEntry>(remoteRosterEntries));
  124.             return entries.iterator();
  125.         }
  126.     }

  127.     /**
  128.      * Returns a count of the entries in the roster exchange.
  129.      *
  130.      * @return the number of entries in the roster exchange.
  131.      */
  132.     public int getEntryCount() {
  133.         return remoteRosterEntries.size();
  134.     }

  135.     /**
  136.      * Returns the XML representation of a Roster Item Exchange according the specification.
  137.      *
  138.      * Usually the XML representation will be inside of a Message XML representation like
  139.      * in the following example:
  140.      * <pre>
  141.      * &lt;message id="MlIpV-4" to="gato1@gato.home" from="gato3@gato.home/Smack"&gt;
  142.      *     &lt;subject&gt;Any subject you want&lt;/subject&gt;
  143.      *     &lt;body&gt;This message contains roster items.&lt;/body&gt;
  144.      *     &lt;x xmlns="jabber:x:roster"&gt;
  145.      *         &lt;item jid="gato1@gato.home"/&gt;
  146.      *         &lt;item jid="gato2@gato.home"/&gt;
  147.      *     &lt;/x&gt;
  148.      * &lt;/message&gt;
  149.      * </pre>
  150.      *
  151.      */
  152.     public String toXML() {
  153.         StringBuilder buf = new StringBuilder();
  154.         buf.append("<").append(getElementName()).append(" xmlns=\"").append(getNamespace()).append(
  155.             "\">");
  156.         // Loop through all roster entries and append them to the string buffer
  157.         for (Iterator<RemoteRosterEntry> i = getRosterEntries(); i.hasNext();) {
  158.             RemoteRosterEntry remoteRosterEntry = i.next();
  159.             buf.append(remoteRosterEntry.toXML());
  160.         }
  161.         buf.append("</").append(getElementName()).append(">");
  162.         return buf.toString();
  163.     }

  164. }