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