• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
3  * you may not use this file except in compliance with the License.
4  * You may obtain a copy of the License at
5  *
6  *     http://www.apache.org/licenses/LICENSE-2.0
7  *
8  * Unless required by applicable law or agreed to in writing, software
9  * distributed under the License is distributed on an "AS IS" BASIS,
10  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11  * See the License for the specific language governing permissions and
12  * limitations under the License.
13  */
14 package org.jivesoftware.smackx.pubsub;
15 
16 import java.util.ArrayList;
17 import java.util.Collection;
18 import java.util.List;
19 
20 import org.jivesoftware.smack.Connection;
21 import org.jivesoftware.smack.XMPPException;
22 import org.jivesoftware.smack.packet.IQ.Type;
23 import org.jivesoftware.smackx.packet.DiscoverItems;
24 import org.jivesoftware.smackx.pubsub.packet.PubSub;
25 import org.jivesoftware.smackx.pubsub.packet.SyncPacketSend;
26 
27 /**
28  * The main class for the majority of pubsub functionality.  In general
29  * almost all pubsub capabilities are related to the concept of a node.
30  * All items are published to a node, and typically subscribed to by other
31  * users.  These users then retrieve events based on this subscription.
32  *
33  * @author Robin Collier
34  */
35 public class LeafNode extends Node
36 {
LeafNode(Connection connection, String nodeName)37 	LeafNode(Connection connection, String nodeName)
38 	{
39 		super(connection, nodeName);
40 	}
41 
42 	/**
43 	 * Get information on the items in the node in standard
44 	 * {@link DiscoverItems} format.
45 	 *
46 	 * @return The item details in {@link DiscoverItems} format
47 	 *
48 	 * @throws XMPPException
49 	 */
discoverItems()50 	public DiscoverItems discoverItems()
51 		throws XMPPException
52 	{
53 		DiscoverItems items = new DiscoverItems();
54 		items.setTo(to);
55 		items.setNode(getId());
56 		return (DiscoverItems)SyncPacketSend.getReply(con, items);
57 	}
58 
59 	/**
60 	 * Get the current items stored in the node.
61 	 *
62 	 * @return List of {@link Item} in the node
63 	 *
64 	 * @throws XMPPException
65 	 */
getItems()66 	public <T extends Item> List<T> getItems()
67 		throws XMPPException
68 	{
69 		PubSub request = createPubsubPacket(Type.GET, new GetItemsRequest(getId()));
70 
71 		PubSub result = (PubSub)SyncPacketSend.getReply(con, request);
72 		ItemsExtension itemsElem = (ItemsExtension)result.getExtension(PubSubElementType.ITEMS);
73 		return (List<T>)itemsElem.getItems();
74 	}
75 
76 	/**
77 	 * Get the current items stored in the node based
78 	 * on the subscription associated with the provided
79 	 * subscription id.
80 	 *
81 	 * @param subscriptionId -  The subscription id for the
82 	 * associated subscription.
83 	 * @return List of {@link Item} in the node
84 	 *
85 	 * @throws XMPPException
86 	 */
getItems(String subscriptionId)87 	public <T extends Item> List<T> getItems(String subscriptionId)
88 		throws XMPPException
89 	{
90 		PubSub request = createPubsubPacket(Type.GET, new GetItemsRequest(getId(), subscriptionId));
91 
92 		PubSub result = (PubSub)SyncPacketSend.getReply(con, request);
93 		ItemsExtension itemsElem = (ItemsExtension)result.getExtension(PubSubElementType.ITEMS);
94 		return (List<T>)itemsElem.getItems();
95 	}
96 
97 	/**
98 	 * Get the items specified from the node.  This would typically be
99 	 * used when the server does not return the payload due to size
100 	 * constraints.  The user would be required to retrieve the payload
101 	 * after the items have been retrieved via {@link #getItems()} or an
102 	 * event, that did not include the payload.
103 	 *
104 	 * @param ids Item ids of the items to retrieve
105 	 *
106 	 * @return The list of {@link Item} with payload
107 	 *
108 	 * @throws XMPPException
109 	 */
getItems(Collection<String> ids)110 	public <T extends Item> List<T> getItems(Collection<String> ids)
111 		throws XMPPException
112 	{
113 		List<Item> itemList = new ArrayList<Item>(ids.size());
114 
115 		for (String id : ids)
116 		{
117 			itemList.add(new Item(id));
118 		}
119 		PubSub request = createPubsubPacket(Type.GET, new ItemsExtension(ItemsExtension.ItemsElementType.items, getId(), itemList));
120 
121 		PubSub result = (PubSub)SyncPacketSend.getReply(con, request);
122 		ItemsExtension itemsElem = (ItemsExtension)result.getExtension(PubSubElementType.ITEMS);
123 		return (List<T>)itemsElem.getItems();
124 	}
125 
126 	/**
127 	 * Get items persisted on the node, limited to the specified number.
128 	 *
129 	 * @param maxItems Maximum number of items to return
130 	 *
131 	 * @return List of {@link Item}
132 	 *
133 	 * @throws XMPPException
134 	 */
getItems(int maxItems)135 	public <T extends Item> List<T> getItems(int maxItems)
136 		throws XMPPException
137 	{
138 		PubSub request = createPubsubPacket(Type.GET, new GetItemsRequest(getId(), maxItems));
139 
140 		PubSub result = (PubSub)SyncPacketSend.getReply(con, request);
141 		ItemsExtension itemsElem = (ItemsExtension)result.getExtension(PubSubElementType.ITEMS);
142 		return (List<T>)itemsElem.getItems();
143 	}
144 
145 	/**
146 	 * Get items persisted on the node, limited to the specified number
147 	 * based on the subscription associated with the provided subscriptionId.
148 	 *
149 	 * @param maxItems Maximum number of items to return
150 	 * @param subscriptionId The subscription which the retrieval is based
151 	 * on.
152 	 *
153 	 * @return List of {@link Item}
154 	 *
155 	 * @throws XMPPException
156 	 */
getItems(int maxItems, String subscriptionId)157 	public <T extends Item> List<T> getItems(int maxItems, String subscriptionId)
158 		throws XMPPException
159 	{
160 		PubSub request = createPubsubPacket(Type.GET, new GetItemsRequest(getId(), subscriptionId, maxItems));
161 
162 		PubSub result = (PubSub)SyncPacketSend.getReply(con, request);
163 		ItemsExtension itemsElem = (ItemsExtension)result.getExtension(PubSubElementType.ITEMS);
164 		return (List<T>)itemsElem.getItems();
165 	}
166 
167 	/**
168 	 * Publishes an event to the node.  This is an empty event
169 	 * with no item.
170 	 *
171 	 * This is only acceptable for nodes with {@link ConfigureForm#isPersistItems()}=false
172 	 * and {@link ConfigureForm#isDeliverPayloads()}=false.
173 	 *
174 	 * This is an asynchronous call which returns as soon as the
175 	 * packet has been sent.
176 	 *
177 	 * For synchronous calls use {@link #send() send()}.
178 	 */
publish()179 	public void publish()
180 	{
181 		PubSub packet = createPubsubPacket(Type.SET, new NodeExtension(PubSubElementType.PUBLISH, getId()));
182 
183 		con.sendPacket(packet);
184 	}
185 
186 	/**
187 	 * Publishes an event to the node.  This is a simple item
188 	 * with no payload.
189 	 *
190 	 * If the id is null, an empty item (one without an id) will be sent.
191 	 * Please note that this is not the same as {@link #send()}, which
192 	 * publishes an event with NO item.
193 	 *
194 	 * This is an asynchronous call which returns as soon as the
195 	 * packet has been sent.
196 	 *
197 	 * For synchronous calls use {@link #send(Item) send(Item))}.
198 	 *
199 	 * @param item - The item being sent
200 	 */
publish(T item)201 	public <T extends Item> void publish(T item)
202 	{
203 		Collection<T> items = new ArrayList<T>(1);
204 		items.add((T)(item == null ? new Item() : item));
205 		publish(items);
206 	}
207 
208 	/**
209 	 * Publishes multiple events to the node.  Same rules apply as in {@link #publish(Item)}.
210 	 *
211 	 * In addition, if {@link ConfigureForm#isPersistItems()}=false, only the last item in the input
212 	 * list will get stored on the node, assuming it stores the last sent item.
213 	 *
214 	 * This is an asynchronous call which returns as soon as the
215 	 * packet has been sent.
216 	 *
217 	 * For synchronous calls use {@link #send(Collection) send(Collection))}.
218 	 *
219 	 * @param items - The collection of items being sent
220 	 */
publish(Collection<T> items)221 	public <T extends Item> void publish(Collection<T> items)
222 	{
223 		PubSub packet = createPubsubPacket(Type.SET, new PublishItem<T>(getId(), items));
224 
225 		con.sendPacket(packet);
226 	}
227 
228 	/**
229 	 * Publishes an event to the node.  This is an empty event
230 	 * with no item.
231 	 *
232 	 * This is only acceptable for nodes with {@link ConfigureForm#isPersistItems()}=false
233 	 * and {@link ConfigureForm#isDeliverPayloads()}=false.
234 	 *
235 	 * This is a synchronous call which will throw an exception
236 	 * on failure.
237 	 *
238 	 * For asynchronous calls, use {@link #publish() publish()}.
239 	 *
240 	 * @throws XMPPException
241 	 */
send()242 	public void send()
243 		throws XMPPException
244 	{
245 		PubSub packet = createPubsubPacket(Type.SET, new NodeExtension(PubSubElementType.PUBLISH, getId()));
246 
247 		SyncPacketSend.getReply(con, packet);
248 	}
249 
250 	/**
251 	 * Publishes an event to the node.  This can be either a simple item
252 	 * with no payload, or one with it.  This is determined by the Node
253 	 * configuration.
254 	 *
255 	 * If the node has <b>deliver_payload=false</b>, the Item must not
256 	 * have a payload.
257 	 *
258 	 * If the id is null, an empty item (one without an id) will be sent.
259 	 * Please note that this is not the same as {@link #send()}, which
260 	 * publishes an event with NO item.
261 	 *
262 	 * This is a synchronous call which will throw an exception
263 	 * on failure.
264 	 *
265 	 * For asynchronous calls, use {@link #publish(Item) publish(Item)}.
266 	 *
267 	 * @param item - The item being sent
268 	 *
269 	 * @throws XMPPException
270 	 */
send(T item)271 	public <T extends Item> void send(T item)
272 		throws XMPPException
273 	{
274 		Collection<T> items = new ArrayList<T>(1);
275 		items.add((item == null ? (T)new Item() : item));
276 		send(items);
277 	}
278 
279 	/**
280 	 * Publishes multiple events to the node.  Same rules apply as in {@link #send(Item)}.
281 	 *
282 	 * In addition, if {@link ConfigureForm#isPersistItems()}=false, only the last item in the input
283 	 * list will get stored on the node, assuming it stores the last sent item.
284 	 *
285 	 * This is a synchronous call which will throw an exception
286 	 * on failure.
287 	 *
288 	 * For asynchronous calls, use {@link #publish(Collection) publish(Collection))}.
289 	 *
290 	 * @param items - The collection of {@link Item} objects being sent
291 	 *
292 	 * @throws XMPPException
293 	 */
send(Collection<T> items)294 	public <T extends Item> void send(Collection<T> items)
295 		throws XMPPException
296 	{
297 		PubSub packet = createPubsubPacket(Type.SET, new PublishItem<T>(getId(), items));
298 
299 		SyncPacketSend.getReply(con, packet);
300 	}
301 
302 	/**
303 	 * Purges the node of all items.
304 	 *
305 	 * <p>Note: Some implementations may keep the last item
306 	 * sent.
307 	 *
308 	 * @throws XMPPException
309 	 */
deleteAllItems()310 	public void deleteAllItems()
311 		throws XMPPException
312 	{
313 		PubSub request = createPubsubPacket(Type.SET, new NodeExtension(PubSubElementType.PURGE_OWNER, getId()), PubSubElementType.PURGE_OWNER.getNamespace());
314 
315 		SyncPacketSend.getReply(con, request);
316 	}
317 
318 	/**
319 	 * Delete the item with the specified id from the node.
320 	 *
321 	 * @param itemId The id of the item
322 	 *
323 	 * @throws XMPPException
324 	 */
deleteItem(String itemId)325 	public void deleteItem(String itemId)
326 		throws XMPPException
327 	{
328 		Collection<String> items = new ArrayList<String>(1);
329 		items.add(itemId);
330 		deleteItem(items);
331 	}
332 
333 	/**
334 	 * Delete the items with the specified id's from the node.
335 	 *
336 	 * @param itemIds The list of id's of items to delete
337 	 *
338 	 * @throws XMPPException
339 	 */
deleteItem(Collection<String> itemIds)340 	public void deleteItem(Collection<String> itemIds)
341 		throws XMPPException
342 	{
343 		List<Item> items = new ArrayList<Item>(itemIds.size());
344 
345 		for (String id : itemIds)
346 		{
347 			items.add(new Item(id));
348 		}
349 		PubSub request = createPubsubPacket(Type.SET, new ItemsExtension(ItemsExtension.ItemsElementType.retract, getId(), items));
350 		SyncPacketSend.getReply(con, request);
351 	}
352 }
353