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 { 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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