blob: f6a09414eba21152d60f24dd273c4a113da3f9bc [file] [log] [blame]
Shuyi Chend7955ce2013-05-22 14:51:55 -07001/**
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
21package org.jivesoftware.smackx.packet;
22
23import org.jivesoftware.smack.packet.IQ;
24import org.jivesoftware.smack.util.StringUtils;
25
26import java.util.Collection;
27import java.util.Collections;
28import java.util.Iterator;
29import java.util.List;
30import 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 */
41public 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}