Home | History | Annotate | Download | only in packet
      1 /**
      2  * $RCSfile$
      3  * $Revision: 7071 $
      4  * $Date: 2007-02-12 08:59:05 +0800 (Mon, 12 Feb 2007) $
      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.packet.IQ;
     24 import org.jivesoftware.smack.util.StringUtils;
     25 
     26 import java.util.Collection;
     27 import java.util.Collections;
     28 import java.util.Iterator;
     29 import java.util.List;
     30 import java.util.concurrent.CopyOnWriteArrayList;
     31 
     32 /**
     33  * A DiscoverItems IQ packet, which is used by XMPP clients to request and receive items
     34  * associated with XMPP entities.<p>
     35  *
     36  * The items could also be queried in order to discover if they contain items inside. Some items
     37  * may be addressable by its JID and others may require to be addressed by a JID and a node name.
     38  *
     39  * @author Gaston Dombiak
     40  */
     41 public class DiscoverItems extends IQ {
     42 
     43     public static final String NAMESPACE = "http://jabber.org/protocol/disco#items";
     44 
     45     private final List<Item> items = new CopyOnWriteArrayList<Item>();
     46     private String node;
     47 
     48     /**
     49      * Adds a new item to the discovered information.
     50      *
     51      * @param item the discovered entity's item
     52      */
     53     public void addItem(Item item) {
     54         synchronized (items) {
     55             items.add(item);
     56         }
     57     }
     58 
     59     /**
     60      * Adds a collection of items to the discovered information. Does nothing if itemsToAdd is null
     61      *
     62      * @param itemsToAdd
     63      */
     64     public void addItems(Collection<Item> itemsToAdd) {
     65         if (itemsToAdd == null) return;
     66         for (Item i : itemsToAdd) {
     67             addItem(i);
     68         }
     69     }
     70 
     71     /**
     72      * Returns the discovered items of the queried XMPP entity.
     73      *
     74      * @return an Iterator on the discovered entity's items
     75      */
     76     public Iterator<DiscoverItems.Item> getItems() {
     77         synchronized (items) {
     78             return Collections.unmodifiableList(items).iterator();
     79         }
     80     }
     81 
     82     /**
     83      * Returns the node attribute that supplements the 'jid' attribute. A node is merely
     84      * something that is associated with a JID and for which the JID can provide information.<p>
     85      *
     86      * Node attributes SHOULD be used only when trying to provide or query information which
     87      * is not directly addressable.
     88      *
     89      * @return the node attribute that supplements the 'jid' attribute
     90      */
     91     public String getNode() {
     92         return node;
     93     }
     94 
     95     /**
     96      * Sets the node attribute that supplements the 'jid' attribute. A node is merely
     97      * something that is associated with a JID and for which the JID can provide information.<p>
     98      *
     99      * Node attributes SHOULD be used only when trying to provide or query information which
    100      * is not directly addressable.
    101      *
    102      * @param node the node attribute that supplements the 'jid' attribute
    103      */
    104     public void setNode(String node) {
    105         this.node = node;
    106     }
    107 
    108     public String getChildElementXML() {
    109         StringBuilder buf = new StringBuilder();
    110         buf.append("<query xmlns=\"" + NAMESPACE + "\"");
    111         if (getNode() != null) {
    112             buf.append(" node=\"");
    113             buf.append(StringUtils.escapeForXML(getNode()));
    114             buf.append("\"");
    115         }
    116         buf.append(">");
    117         synchronized (items) {
    118             for (Item item : items) {
    119                 buf.append(item.toXML());
    120             }
    121         }
    122         buf.append("</query>");
    123         return buf.toString();
    124     }
    125 
    126     /**
    127      * An item is associated with an XMPP Entity, usually thought of a children of the parent
    128      * entity and normally are addressable as a JID.<p>
    129      *
    130      * An item associated with an entity may not be addressable as a JID. In order to handle
    131      * such items, Service Discovery uses an optional 'node' attribute that supplements the
    132      * 'jid' attribute.
    133      */
    134     public static class Item {
    135 
    136         /**
    137          * Request to create or update the item.
    138          */
    139         public static final String UPDATE_ACTION = "update";
    140 
    141         /**
    142          * Request to remove the item.
    143          */
    144         public static final String REMOVE_ACTION = "remove";
    145 
    146         private String entityID;
    147         private String name;
    148         private String node;
    149         private String action;
    150 
    151         /**
    152          * Create a new Item associated with a given entity.
    153          *
    154          * @param entityID the id of the entity that contains the item
    155          */
    156         public Item(String entityID) {
    157             this.entityID = entityID;
    158         }
    159 
    160         /**
    161          * Returns the entity's ID.
    162          *
    163          * @return the entity's ID.
    164          */
    165         public String getEntityID() {
    166             return entityID;
    167         }
    168 
    169         /**
    170          * Returns the entity's name.
    171          *
    172          * @return the entity's name.
    173          */
    174         public String getName() {
    175             return name;
    176         }
    177 
    178         /**
    179          * Sets the entity's name.
    180          *
    181          * @param name the entity's name.
    182          */
    183         public void setName(String name) {
    184             this.name = name;
    185         }
    186 
    187         /**
    188          * Returns the node attribute that supplements the 'jid' attribute. A node is merely
    189          * something that is associated with a JID and for which the JID can provide information.<p>
    190          *
    191          * Node attributes SHOULD be used only when trying to provide or query information which
    192          * is not directly addressable.
    193          *
    194          * @return the node attribute that supplements the 'jid' attribute
    195          */
    196         public String getNode() {
    197             return node;
    198         }
    199 
    200         /**
    201          * Sets the node attribute that supplements the 'jid' attribute. A node is merely
    202          * something that is associated with a JID and for which the JID can provide information.<p>
    203          *
    204          * Node attributes SHOULD be used only when trying to provide or query information which
    205          * is not directly addressable.
    206          *
    207          * @param node the node attribute that supplements the 'jid' attribute
    208          */
    209         public void setNode(String node) {
    210             this.node = node;
    211         }
    212 
    213         /**
    214          * Returns the action that specifies the action being taken for this item. Possible action
    215          * values are: "update" and "remove". Update should either create a new entry if the node
    216          * and jid combination does not already exist, or simply update an existing entry. If
    217          * "remove" is used as the action, the item should be removed from persistent storage.
    218          *
    219          * @return the action being taken for this item
    220          */
    221         public String getAction() {
    222             return action;
    223         }
    224 
    225         /**
    226          * Sets the action that specifies the action being taken for this item. Possible action
    227          * values are: "update" and "remove". Update should either create a new entry if the node
    228          * and jid combination does not already exist, or simply update an existing entry. If
    229          * "remove" is used as the action, the item should be removed from persistent storage.
    230          *
    231          * @param action the action being taken for this item
    232          */
    233         public void setAction(String action) {
    234             this.action = action;
    235         }
    236 
    237         public String toXML() {
    238             StringBuilder buf = new StringBuilder();
    239             buf.append("<item jid=\"").append(entityID).append("\"");
    240             if (name != null) {
    241                 buf.append(" name=\"").append(StringUtils.escapeForXML(name)).append("\"");
    242             }
    243             if (node != null) {
    244                 buf.append(" node=\"").append(StringUtils.escapeForXML(node)).append("\"");
    245             }
    246             if (action != null) {
    247                 buf.append(" action=\"").append(StringUtils.escapeForXML(action)).append("\"");
    248             }
    249             buf.append("/>");
    250             return buf.toString();
    251         }
    252     }
    253 }
    254