Home | History | Annotate | Download | only in pubsub
      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