Package rocks.xmpp.extensions.pubsub

Source Code of rocks.xmpp.extensions.pubsub.PubSubNode

/*
* The MIT License (MIT)
*
* Copyright (c) 2014 Christian Schudt
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

package rocks.xmpp.extensions.pubsub;

import rocks.xmpp.core.Jid;
import rocks.xmpp.core.XmppException;
import rocks.xmpp.core.session.XmppSession;
import rocks.xmpp.core.stanza.model.client.IQ;
import rocks.xmpp.extensions.data.model.DataForm;
import rocks.xmpp.extensions.disco.ServiceDiscoveryManager;
import rocks.xmpp.extensions.disco.model.info.Identity;
import rocks.xmpp.extensions.disco.model.info.InfoNode;
import rocks.xmpp.extensions.disco.model.items.Item;
import rocks.xmpp.extensions.disco.model.items.ItemNode;
import rocks.xmpp.extensions.pubsub.model.*;
import rocks.xmpp.extensions.pubsub.model.owner.PubSubOwner;

import java.net.URI;
import java.util.*;

/**
* @author Christian Schudt
*/
public final class PubSubNode {

    private final String name;

    private final Type type;

    private final Jid pubSubServiceAddress;

    private final XmppSession xmppSession;

    private final ServiceDiscoveryManager serviceDiscoveryManager;

    private String nodeId;

    PubSubNode(String nodeId, String name, Jid pubSubServiceAddress, XmppSession xmppSession) {
        // If a node is a leaf node rather than a collection node and items have been published to the node, the service MAY return one <item/> element for each published item as described in the Discover Items for a Node section of this document, however such items MUST NOT include a 'node' attribute (since they are published items, not nodes).
        this(nodeId, name, nodeId == null ? Type.LEAF : Type.COLLECTION, pubSubServiceAddress, xmppSession);
    }

    PubSubNode(String nodeId, String name, Type type, Jid pubSubServiceAddress, XmppSession xmppSession) {
        this.nodeId = nodeId;
        this.name = name;
        this.type = type;
        this.pubSubServiceAddress = pubSubServiceAddress;
        this.xmppSession = xmppSession;
        this.serviceDiscoveryManager = xmppSession.getExtensionManager(ServiceDiscoveryManager.class);

    }

    /**
     * Gets node info.
     *
     * @return The node info.
     * @throws rocks.xmpp.core.stanza.model.StanzaException If the entity returned a stanza error.
     * @throws rocks.xmpp.core.session.NoResponseException  If the entity did not respond.
     */
    public NodeInfo getNodeInfo() throws XmppException {
        InfoNode infoNode = serviceDiscoveryManager.discoverInformation(pubSubServiceAddress);
        Identity identity = null;
        Set<PubSubFeature> features = new HashSet<>();
        PubSubMetaDataForm metaDataForm = null;

        if (infoNode != null) {
            Set<Identity> identities = infoNode.getIdentities();
            Iterator<Identity> iterator = identities.iterator();
            if (iterator.hasNext()) {
                identity = iterator.next();
            }
            for (DataForm dataForm : infoNode.getExtensions()) {
                String formType = dataForm.getFormType();
                if (PubSubMetaDataForm.FORM_TYPE.equals(formType)) {
                    metaDataForm = new PubSubMetaDataForm(dataForm);
                    break;
                }
            }
        }

        return new NodeInfo(identity, features, metaDataForm);
    }

    /**
     * Gets the items for this node.
     *
     * @return The items.
     * @throws rocks.xmpp.core.stanza.model.StanzaException If the entity returned a stanza error.
     * @throws rocks.xmpp.core.session.NoResponseException  If the entity did not respond.
     * @see <a href="http://xmpp.org/extensions/xep-0060.html#entity-discoveritems">5.5 Discover Items for a Node</a>
     */
    public List<rocks.xmpp.extensions.pubsub.model.Item> discoverItems() throws XmppException {
        ItemNode itemNode = serviceDiscoveryManager.discoverItems(pubSubServiceAddress, nodeId);
        List<rocks.xmpp.extensions.pubsub.model.Item> result = new ArrayList<>();
        for (Item item : itemNode.getItems()) {
            // The 'name' attribute of each Service Discovery item MUST contain its ItemID
            result.add(new PubSub.ItemElement(item.getName()));
        }
        return result;
    }

    /**
     * Gets the subscriptions for this node.
     *
     * @return The subscriptions for the node.
     * @throws rocks.xmpp.core.stanza.model.StanzaException If the entity returned a stanza error.
     * @throws rocks.xmpp.core.session.NoResponseException  If the entity did not respond.
     * @see <a href="http://xmpp.org/extensions/xep-0060.html#entity-subscriptions">5.6 Retrieve Subscriptions</a>
     */
    public List<Subscription> getSubscriptions() throws XmppException {
        IQ result = xmppSession.query(new IQ(pubSubServiceAddress, IQ.Type.GET, PubSub.withSubscriptions(nodeId)));
        PubSub pubSub = result.getExtension(PubSub.class);
        return pubSub.getSubscriptions();
    }


    /**
     * Gets the affiliations for this node.
     *
     * @return The affiliations for all nodes.
     * @throws rocks.xmpp.core.stanza.model.StanzaException If the entity returned a stanza error.
     * @throws rocks.xmpp.core.session.NoResponseException  If the entity did not respond.
     * @see <a href="http://xmpp.org/extensions/xep-0060.html#entity-affiliations">5.7 Retrieve Affiliations</a>
     */
    public List<Affiliation> getAffiliations() throws XmppException {
        IQ result = xmppSession.query(new IQ(pubSubServiceAddress, IQ.Type.GET, PubSub.withAffiliations(nodeId)));
        PubSub pubSub = result.getExtension(PubSub.class);
        return pubSub.getAffiliations();
    }

    /**
     * Subscribes to this node.
     *
     * @return The subscription.
     * @throws rocks.xmpp.core.stanza.model.StanzaException If the entity returned a stanza error.
     * @throws rocks.xmpp.core.session.NoResponseException  If the entity did not respond.
     * @see <a href="http://xmpp.org/extensions/xep-0060.html#subscriber-subscribe">6.1 Subscribe to a Node</a>
     */
    public Subscription subscribe() throws XmppException {
        return subscribe(null);
    }

    /**
     * Subscribes to and configures this node.
     *
     * @param dataForm The configuration form.
     * @return The subscription.
     * @throws rocks.xmpp.core.stanza.model.StanzaException If the entity returned a stanza error.
     * @throws rocks.xmpp.core.session.NoResponseException  If the entity did not respond.
     * @see <a href="http://xmpp.org/extensions/xep-0060.html#subscriber-configure-subandconfig">6.3.7 Subscribe and Configure</a>
     */
    public Subscription subscribe(DataForm dataForm) throws XmppException {
        if (nodeId == null) {
            throw new IllegalArgumentException("nodeId must not be null");
        }
        IQ result = xmppSession.query(new IQ(pubSubServiceAddress, IQ.Type.SET, PubSub.withSubscribe(nodeId, xmppSession.getConnectedResource().asBareJid(), dataForm)));
        PubSub pubSub = result.getExtension(PubSub.class);
        return pubSub.getSubscription();
    }

    /**
     * Unsubscribes from this node.
     *
     * @throws rocks.xmpp.core.stanza.model.StanzaException If the entity returned a stanza error.
     * @throws rocks.xmpp.core.session.NoResponseException  If the entity did not respond.
     * @see <a href="http://xmpp.org/extensions/xep-0060.html#subscriber-unsubscribe">6.2 Unsubscribe from a Node</a>
     */
    public void unsubscribe() throws XmppException {
        this.unsubscribe(null);
    }

    /**
     * Unsubscribes from this node.
     *
     * @param subscriptionId The subscription id.
     * @throws rocks.xmpp.core.stanza.model.StanzaException If the entity returned a stanza error.
     * @throws rocks.xmpp.core.session.NoResponseException  If the entity did not respond.
     * @see <a href="http://xmpp.org/extensions/xep-0060.html#subscriber-unsubscribe">6.2 Unsubscribe from a Node</a>
     */
    public void unsubscribe(String subscriptionId) throws XmppException {
        xmppSession.query(new IQ(pubSubServiceAddress, IQ.Type.SET, PubSub.withUnsubscribe(nodeId, xmppSession.getConnectedResource().asBareJid(), subscriptionId)));
    }

    /**
     * Requests the subscription options for this node.
     *
     * @return The data form.
     * @throws rocks.xmpp.core.stanza.model.StanzaException If the entity returned a stanza error.
     * @throws rocks.xmpp.core.session.NoResponseException  If the entity did not respond.
     * @see <a href="http://xmpp.org/extensions/xep-0060.html#subscriber-configure-request">6.3.2 Request</a>
     */
    public DataForm getSubscriptionOptions() throws XmppException {
        IQ result = xmppSession.query(new IQ(pubSubServiceAddress, IQ.Type.GET, PubSub.withOptions(nodeId, xmppSession.getConnectedResource().asBareJid())));
        PubSub pubSub = result.getExtension(PubSub.class);
        return pubSub.getOptions().getDataForm();
    }

    /**
     * Submits subscription options for this node.
     *
     * @param dataForm The subscription options form.
     * @throws rocks.xmpp.core.stanza.model.StanzaException If the entity returned a stanza error.
     * @throws rocks.xmpp.core.session.NoResponseException  If the entity did not respond.
     * @see <a href="http://xmpp.org/extensions/xep-0060.html#subscriber-configure-submit">6.3.5 Form Submission</a>
     */
    public void submitSubscriptionOptions(DataForm dataForm) throws XmppException {
        xmppSession.query(new IQ(pubSubServiceAddress, IQ.Type.SET, PubSub.withOptions(nodeId, xmppSession.getConnectedResource().asBareJid())));
    }

    /**
     * Gets the default subscription options for a specific node.
     *
     * @return The default subscription options.
     * @throws rocks.xmpp.core.stanza.model.StanzaException If the entity returned a stanza error.
     * @throws rocks.xmpp.core.session.NoResponseException  If the entity did not respond.
     * @see <a href="http://xmpp.org/extensions/xep-0060.html#subscriber-configure-submit">6.4 Request Default Subscription Configuration Options</a>
     */
    public DataForm getDefaultSubscriptionOptions() throws XmppException {
        IQ result = xmppSession.query(new IQ(pubSubServiceAddress, IQ.Type.GET, PubSub.withDefault(nodeId)));
        PubSub pubSub = result.getExtension(PubSub.class);
        return pubSub.getDefault().getDataForm();
    }

    /**
     * Gets all items for this node.
     *
     * @return The items.
     * @throws rocks.xmpp.core.stanza.model.StanzaException If the entity returned a stanza error.
     * @throws rocks.xmpp.core.session.NoResponseException  If the entity did not respond.
     * @see <a href="http://xmpp.org/extensions/xep-0060.html#subscriber-retrieve-requestall">6.5.2 Requesting All Items</a>
     */
    public List<rocks.xmpp.extensions.pubsub.model.Item> getItems() throws XmppException {
        IQ result = xmppSession.query(new IQ(pubSubServiceAddress, IQ.Type.GET, PubSub.withItems(nodeId)));
        PubSub pubSub = result.getExtension(PubSub.class);
        return pubSub.getItems();
    }

    /**
     * Gets one or more items with a given item id for a specific node.
     *
     * @param ids The item ids.
     * @return The items.
     * @throws rocks.xmpp.core.stanza.model.StanzaException If the entity returned a stanza error.
     * @throws rocks.xmpp.core.session.NoResponseException  If the entity did not respond.
     * @see <a href="http://xmpp.org/extensions/xep-0060.html#subscriber-retrieve-returnnotify">6.5.6 Returning Notifications Only</a>
     * @see <a href="http://xmpp.org/extensions/xep-0060.html#subscriber-retrieve-requestone">6.5.8 Requesting a Particular Item</a>
     */
    public List<rocks.xmpp.extensions.pubsub.model.Item> getItems(String... ids) throws XmppException {
        IQ result = xmppSession.query(new IQ(pubSubServiceAddress, IQ.Type.GET, PubSub.withItems(nodeId, ids)));
        PubSub pubSub = result.getExtension(PubSub.class);
        return pubSub.getItems();
    }


    /**
     * Gets the most recent items.
     *
     * @param maxItems The maximal number of items.
     * @return The items.
     * @throws rocks.xmpp.core.stanza.model.StanzaException If the entity returned a stanza error.
     * @throws rocks.xmpp.core.session.NoResponseException  If the entity did not respond.
     * @see <a href="http://xmpp.org/extensions/xep-0060.html#subscriber-retrieve-requestrecent">6.5.7 Requesting the Most Recent Items</a>
     */
    public List<rocks.xmpp.extensions.pubsub.model.Item> getItems(int maxItems) throws XmppException {
        IQ result = xmppSession.query(new IQ(pubSubServiceAddress, IQ.Type.GET, PubSub.withItems(nodeId, maxItems)));
        PubSub pubSub = result.getExtension(PubSub.class);
        return pubSub.getItems();
    }

    /**
     * Publishes an item to this node.
     *
     * @param item The item to be published. Note that this item must be known to the {@link rocks.xmpp.core.session.context.CoreContext}, so that it can be marshalled into XML.
     * @return The item id, generated by the pubsub service.
     * @throws rocks.xmpp.core.stanza.model.StanzaException If the entity returned a stanza error.
     * @throws rocks.xmpp.core.session.NoResponseException  If the entity did not respond.
     * @see <a href="http://xmpp.org/extensions/xep-0060.html#publisher-publish">7.1 Publish an Item to a Node</a>
     */
    public String publish(Object item) throws XmppException {
        return publish(null, item);
    }

    /**
     * Publishes an item to this node.
     *
     * @param id   The item's id.
     * @param item The item to be published. Note that this item must be known to the {@link rocks.xmpp.core.session.context.CoreContext}, so that it can be marshalled into XML.
     * @return The item id.
     * @throws rocks.xmpp.core.stanza.model.StanzaException If the entity returned a stanza error.
     * @throws rocks.xmpp.core.session.NoResponseException  If the entity did not respond.
     * @see <a href="http://xmpp.org/extensions/xep-0060.html#publisher-publish">7.1 Publish an Item to a Node</a>
     */
    public String publish(String id, Object item) throws XmppException {
        IQ result = xmppSession.query(new IQ(pubSubServiceAddress, IQ.Type.SET, PubSub.withPublish(nodeId, id, item)));
        PubSub pubSub = result.getExtension(PubSub.class);
        if (pubSub != null && pubSub.getPublish() != null && pubSub.getPublish().getItem() != null) {
            return pubSub.getPublish().getItem().getId();
        }
        return id;
    }

    /**
     * Deletes an item from this node.
     *
     * @param id     The item id.
     * @param notify If the pubsub service shall notify the subscribers about the deletion.
     * @throws rocks.xmpp.core.stanza.model.StanzaException If the entity returned a stanza error.
     * @throws rocks.xmpp.core.session.NoResponseException  If the entity did not respond.
     * @see <a href="http://xmpp.org/extensions/xep-0060.html#publisher-delete">7.2 Delete an Item from a Node</a>
     */
    private void deleteItem(String id, boolean notify) throws XmppException {
        xmppSession.query(new IQ(pubSubServiceAddress, IQ.Type.SET, PubSub.withRetract(nodeId, id, notify)));
    }

    /**
     * Creates a node.
     *
     * @return The node id.
     * @throws rocks.xmpp.core.stanza.model.StanzaException If the entity returned a stanza error.
     * @throws rocks.xmpp.core.session.NoResponseException  If the entity did not respond.
     * @see <a href="http://xmpp.org/extensions/xep-0060.html#owner-create">8.1 Create a Node</a>
     */
    public String create() throws XmppException {
        return create(null);
    }

    /**
     * Creates and configures this node.
     *
     * @param dataForm The configuration form.
     * @return The node id.
     * @throws rocks.xmpp.core.stanza.model.StanzaException If the entity returned a stanza error.
     * @throws rocks.xmpp.core.session.NoResponseException  If the entity did not respond.
     * @see <a href="http://xmpp.org/extensions/xep-0060.html#owner-create-and-configure">8.1.3 Create and Configure a Node</a>
     */
    public String create(DataForm dataForm) throws XmppException {
        IQ result = xmppSession.query(new IQ(pubSubServiceAddress, IQ.Type.SET, PubSub.withCreate(nodeId, dataForm)));
        if (nodeId != null) {
            return nodeId;
        }
        PubSub pubSub = result.getExtension(PubSub.class);
        if (pubSub != null) {
            String generatedNodeId = pubSub.getNode();
            if (generatedNodeId != null) {
                this.nodeId = generatedNodeId;
            }
        }
        return nodeId;
    }

    /**
     * Gets the node configuration form.
     *
     * @return The configuration form.
     * @throws rocks.xmpp.core.stanza.model.StanzaException If the entity returned a stanza error.
     * @throws rocks.xmpp.core.session.NoResponseException  If the entity did not respond.
     * @see <a href="http://xmpp.org/extensions/xep-0060.html#owner-configure-request">8.2.1 Request</a>
     */
    public DataForm getNodeConfiguration() throws XmppException {
        IQ result = xmppSession.query(new IQ(pubSubServiceAddress, IQ.Type.GET, PubSubOwner.withConfigure(nodeId)));
        PubSubOwner pubSubOwner = result.getExtension(PubSubOwner.class);
        return pubSubOwner.getConfigurationForm();
    }

    /**
     * Submits the node configuration form.
     *
     * @param dataForm The configuration form.
     * @throws rocks.xmpp.core.stanza.model.StanzaException If the entity returned a stanza error.
     * @throws rocks.xmpp.core.session.NoResponseException  If the entity did not respond.
     * @see <a href="http://xmpp.org/extensions/xep-0060.html#owner-configure-submit">8.2.4 Form Submission</a>
     */
    public void submitNodeConfiguration(DataForm dataForm) throws XmppException {
        xmppSession.query(new IQ(pubSubServiceAddress, IQ.Type.SET, PubSubOwner.withConfigure(nodeId, dataForm)));
    }

    /**
     * Deletes a node on the pubsub service.
     *
     * @throws rocks.xmpp.core.stanza.model.StanzaException If the entity returned a stanza error.
     * @throws rocks.xmpp.core.session.NoResponseException  If the entity did not respond.
     * @see <a href="http://xmpp.org/extensions/xep-0060.html#owner-delete">8.4 Delete a Node</a>
     */
    public void delete() throws XmppException {
        xmppSession.query(new IQ(pubSubServiceAddress, IQ.Type.SET, PubSubOwner.withDelete(nodeId)));
    }

    /**
     * Deletes this node and specifies a replacement node.
     *
     * @param uri The replacement node.
     * @throws rocks.xmpp.core.stanza.model.StanzaException If the entity returned a stanza error.
     * @throws rocks.xmpp.core.session.NoResponseException  If the entity did not respond.
     * @see <a href="http://xmpp.org/extensions/xep-0060.html#owner-delete">8.4 Delete a Node</a>
     */
    public void delete(URI uri) throws XmppException {
        xmppSession.query(new IQ(pubSubServiceAddress, IQ.Type.SET, PubSubOwner.withDelete(nodeId, uri)));
    }

    /**
     * Purges this node of all published items.
     *
     * @throws rocks.xmpp.core.stanza.model.StanzaException If the entity returned a stanza error.
     * @throws rocks.xmpp.core.session.NoResponseException  If the entity did not respond.
     * @see <a href="http://xmpp.org/extensions/xep-0060.html#owner-purge">8.5 Purge All Node Items</a>
     */
    public void purge() throws XmppException {
        xmppSession.query(new IQ(pubSubServiceAddress, IQ.Type.SET, PubSubOwner.withPurge(nodeId)));
    }

    /**
     * Gets the (sub-)nodes, which hierarchically reside under this node, e.g. the "second-level" nodes.
     *
     * @return The list of nodes.
     * @throws rocks.xmpp.core.stanza.model.StanzaException If the entity returned a stanza error.
     * @throws rocks.xmpp.core.session.NoResponseException  If the entity did not respond.
     * @see <a href="http://xmpp.org/extensions/xep-0060.html#entity-nodes">5.2 Discover Nodes</a>
     */
    public List<PubSubNode> getNodes() throws XmppException {
        ItemNode itemNode = serviceDiscoveryManager.discoverItems(pubSubServiceAddress, nodeId);
        List<PubSubNode> nodes = new ArrayList<>();
        for (Item item : itemNode.getItems()) {
            PubSubNode n = new PubSubNode(item.getNode(), item.getName(), pubSubServiceAddress, xmppSession);
            nodes.add(n);
        }
        return nodes;
    }

    /**
     * Gets the name.
     *
     * @return The name.
     */
    public String getName() {
        return name;
    }

    /**
     * Gets the node id.
     *
     * @return The node id.
     */
    public String getId() {
        return nodeId;
    }

    /**
     * Gets the type of this node.
     *
     * @return The type.
     */
    public Type getType() {
        return type;
    }

    @Override
    public String toString() {
        return nodeId;
    }

    /**
     * The node type.
     */
    public enum Type {
        LEAF,
        COLLECTION,
    }
}
TOP

Related Classes of rocks.xmpp.extensions.pubsub.PubSubNode

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.