001/** 002 * 003 * Copyright 2003-2007 Jive Software. 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.jivesoftware.smackx.disco.packet; 018 019import org.jivesoftware.smack.packet.IQ; 020import org.jivesoftware.smack.util.XmlStringBuilder; 021import org.jxmpp.jid.Jid; 022 023import java.util.Collection; 024import java.util.Collections; 025import java.util.LinkedList; 026import java.util.List; 027 028/** 029 * A DiscoverItems IQ packet, which is used by XMPP clients to request and receive items 030 * associated with XMPP entities.<p> 031 * 032 * The items could also be queried in order to discover if they contain items inside. Some items 033 * may be addressable by its JID and others may require to be addressed by a JID and a node name. 034 * 035 * @author Gaston Dombiak 036 */ 037public class DiscoverItems extends IQ { 038 039 public static final String ELEMENT = QUERY_ELEMENT; 040 public static final String NAMESPACE = "http://jabber.org/protocol/disco#items"; 041 042 private final List<Item> items = new LinkedList<Item>(); 043 private String node; 044 045 public DiscoverItems() { 046 super(ELEMENT, NAMESPACE); 047 } 048 049 /** 050 * Adds a new item to the discovered information. 051 * 052 * @param item the discovered entity's item 053 */ 054 public void addItem(Item item) { 055 items.add(item); 056 } 057 058 /** 059 * Adds a collection of items to the discovered information. Does nothing if itemsToAdd is null 060 * 061 * @param itemsToAdd 062 */ 063 public void addItems(Collection<Item> itemsToAdd) { 064 if (itemsToAdd == null) return; 065 for (Item i : itemsToAdd) { 066 addItem(i); 067 } 068 } 069 070 071 /** 072 * Returns the discovered items of the queried XMPP entity. 073 * 074 * @return an unmodifiable list of the discovered entity's items 075 */ 076 public List<DiscoverItems.Item> getItems() { 077 return Collections.unmodifiableList(items); 078 } 079 080 /** 081 * Returns the node attribute that supplements the 'jid' attribute. A node is merely 082 * something that is associated with a JID and for which the JID can provide information.<p> 083 * 084 * Node attributes SHOULD be used only when trying to provide or query information which 085 * is not directly addressable. 086 * 087 * @return the node attribute that supplements the 'jid' attribute 088 */ 089 public String getNode() { 090 return node; 091 } 092 093 /** 094 * Sets the node attribute that supplements the 'jid' attribute. A node is merely 095 * something that is associated with a JID and for which the JID can provide information.<p> 096 * 097 * Node attributes SHOULD be used only when trying to provide or query information which 098 * is not directly addressable. 099 * 100 * @param node the node attribute that supplements the 'jid' attribute 101 */ 102 public void setNode(String node) { 103 this.node = node; 104 } 105 106 @Override 107 protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) { 108 xml.optAttribute("node", getNode()); 109 xml.rightAngleBracket(); 110 111 for (Item item : items) { 112 xml.append(item.toXML()); 113 } 114 115 return xml; 116 } 117 118 /** 119 * An item is associated with an XMPP Entity, usually thought of a children of the parent 120 * entity and normally are addressable as a JID.<p> 121 * 122 * An item associated with an entity may not be addressable as a JID. In order to handle 123 * such items, Service Discovery uses an optional 'node' attribute that supplements the 124 * 'jid' attribute. 125 */ 126 public static class Item { 127 128 /** 129 * Request to create or update the item. 130 */ 131 public static final String UPDATE_ACTION = "update"; 132 133 /** 134 * Request to remove the item. 135 */ 136 public static final String REMOVE_ACTION = "remove"; 137 138 private final Jid entityID; 139 private String name; 140 private String node; 141 private String action; 142 143 /** 144 * Create a new Item associated with a given entity. 145 * 146 * @param entityID the id of the entity that contains the item 147 */ 148 public Item(Jid entityID) { 149 this.entityID = entityID; 150 } 151 152 /** 153 * Returns the entity's ID. 154 * 155 * @return the entity's ID. 156 */ 157 public Jid getEntityID() { 158 return entityID; 159 } 160 161 /** 162 * Returns the entity's name. 163 * 164 * @return the entity's name. 165 */ 166 public String getName() { 167 return name; 168 } 169 170 /** 171 * Sets the entity's name. 172 * 173 * @param name the entity's name. 174 */ 175 public void setName(String name) { 176 this.name = name; 177 } 178 179 /** 180 * Returns the node attribute that supplements the 'jid' attribute. A node is merely 181 * something that is associated with a JID and for which the JID can provide information.<p> 182 * 183 * Node attributes SHOULD be used only when trying to provide or query information which 184 * is not directly addressable. 185 * 186 * @return the node attribute that supplements the 'jid' attribute 187 */ 188 public String getNode() { 189 return node; 190 } 191 192 /** 193 * Sets the node attribute that supplements the 'jid' attribute. A node is merely 194 * something that is associated with a JID and for which the JID can provide information.<p> 195 * 196 * Node attributes SHOULD be used only when trying to provide or query information which 197 * is not directly addressable. 198 * 199 * @param node the node attribute that supplements the 'jid' attribute 200 */ 201 public void setNode(String node) { 202 this.node = node; 203 } 204 205 /** 206 * Returns the action that specifies the action being taken for this item. Possible action 207 * values are: "update" and "remove". Update should either create a new entry if the node 208 * and jid combination does not already exist, or simply update an existing entry. If 209 * "remove" is used as the action, the item should be removed from persistent storage. 210 * 211 * @return the action being taken for this item 212 */ 213 public String getAction() { 214 return action; 215 } 216 217 /** 218 * Sets the action that specifies the action being taken for this item. Possible action 219 * values are: "update" and "remove". Update should either create a new entry if the node 220 * and jid combination does not already exist, or simply update an existing entry. If 221 * "remove" is used as the action, the item should be removed from persistent storage. 222 * 223 * @param action the action being taken for this item 224 */ 225 public void setAction(String action) { 226 this.action = action; 227 } 228 229 public XmlStringBuilder toXML() { 230 XmlStringBuilder xml = new XmlStringBuilder(); 231 xml.halfOpenElement("item"); 232 xml.attribute("jid", entityID); 233 xml.optAttribute("name", name); 234 xml.optAttribute("node", node); 235 xml.optAttribute("action", action); 236 xml.closeEmptyElement(); 237 return xml; 238 } 239 } 240}