From fce0aeadef50b04bcc4b403a5edff5588d14d76f Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sat, 6 Jun 2015 11:14:26 +0200 Subject: [PATCH] Add support for PubSub affiliation actions as owner SMACK-675. --- .../smackx/pubsub/Affiliation.java | 14 ++++ .../smackx/pubsub/AffiliationsExtension.java | 48 ++++++------ .../org/jivesoftware/smackx/pubsub/Node.java | 78 ++++++++++++++++++- 3 files changed, 116 insertions(+), 24 deletions(-) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/Affiliation.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/Affiliation.java index 14dbe86ff..9bd1b8c2f 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/Affiliation.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/Affiliation.java @@ -130,6 +130,20 @@ public class Affiliation implements ExtensionElement return namespace; } + /** + * Check if this is an affiliation element to modify affiliations on a node. + * + * @return true if this is an affiliation element to modify affiliations on a node, false otherwise. + * @since 4.2 + */ + public boolean isAffiliationModification() { + if (jid != null && affiliation != null) { + assert(node == null && namespace == PubSubNamespace.OWNER); + return true; + } + return false; + } + @Override public XmlStringBuilder toXML() { XmlStringBuilder xml = new XmlStringBuilder(this); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/AffiliationsExtension.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/AffiliationsExtension.java index 9a3f50725..b365adc47 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/AffiliationsExtension.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/AffiliationsExtension.java @@ -19,26 +19,33 @@ package org.jivesoftware.smackx.pubsub; import java.util.Collections; import java.util.List; +import org.jivesoftware.smack.util.XmlStringBuilder; + /** * Represents the affiliations element of the reply to a request for affiliations. - * It is defined in the specification in section 5.7 Retrieve Affiliations. + * It is defined in the specification in section 5.7 Retrieve Affiliations and + * 8.9 Manage Affiliations. * * @author Robin Collier */ public class AffiliationsExtension extends NodeExtension { protected List items = Collections.emptyList(); + private final String node; - public AffiliationsExtension() - { - super(PubSubElementType.AFFILIATIONS); - } + public AffiliationsExtension() { + this(null, null); + } - public AffiliationsExtension(List subList) - { - super(PubSubElementType.AFFILIATIONS); - items = subList; - } + public AffiliationsExtension(List subList) { + this(subList, null); + } + + public AffiliationsExtension(List subList, String node) { + super(PubSubElementType.AFFILIATIONS); + items = subList; + this.node = node; + } public List getAffiliations() { @@ -54,19 +61,14 @@ public class AffiliationsExtension extends NodeExtension } else { - StringBuilder builder = new StringBuilder("<"); - builder.append(getElementName()); - builder.append(">"); - - for (Affiliation item : items) - { - builder.append(item.toXML()); - } - - builder.append(""); - return builder.toString(); + // Can't use XmlStringBuilder(this), because we don't want the namespace to be included + XmlStringBuilder xml = new XmlStringBuilder(); + xml.openElement(getElementName()); + xml.optAttribute("node", node); + xml.rightAngleBracket(); + xml.append(items); + xml.closeElement(this); + return xml; } } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/Node.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/Node.java index 3bfcf35d9..8053b3494 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/Node.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/Node.java @@ -256,7 +256,54 @@ abstract public class Node public List getAffiliations(List additionalExtensions, Collection returnedExtensions) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { - PubSub pubSub = createPubsubPacket(Type.get, new NodeExtension(PubSubElementType.AFFILIATIONS, getId())); + return getAffiliations(PubSubNamespace.BASIC, additionalExtensions, returnedExtensions); + } + + /** + * Retrieve the affiliation list for this node as owner. + * + * @return list of entities whose affiliation is not 'none'. + * @throws NoResponseException + * @throws XMPPErrorException + * @throws NotConnectedException + * @throws InterruptedException + * @see #getAffiliations(List, Collection) + * @since 4.2 + */ + public List getAffiliationsAsOwner() + throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { + + return getAffiliationsAsOwner(null, null); + } + + /** + * Retrieve the affiliation list for this node as owner. + *

+ * Note that this is an optional PubSub feature ('pubusb#modify-affiliations'). + *

+ * + * @param additionalExtensions optional additional extension elements add to the request. + * @param returnedExtensions an optional collection that will be filled with the returned + * extension elements. + * @return list of entities whose affiliation is not 'none'. + * @throws NoResponseException + * @throws XMPPErrorException + * @throws NotConnectedException + * @throws InterruptedException + * @see XEP-60 § 8.9.1 Retrieve Affiliations List + * @since 4.2 + */ + public List getAffiliationsAsOwner(List additionalExtensions, Collection returnedExtensions) + throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { + + return getAffiliations(PubSubNamespace.OWNER, additionalExtensions, returnedExtensions); + } + + private List getAffiliations(PubSubNamespace namespace, List additionalExtensions, + Collection returnedExtensions) throws NoResponseException, XMPPErrorException, + NotConnectedException, InterruptedException { + + PubSub pubSub = createPubsubPacket(Type.get, new NodeExtension(PubSubElementType.AFFILIATIONS, getId()), namespace); if (additionalExtensions != null) { for (ExtensionElement pe : additionalExtensions) { pubSub.addExtension(pe); @@ -270,6 +317,35 @@ abstract public class Node return affilElem.getAffiliations(); } + /** + * Modify the affiliations for this PubSub node as owner. The {@link Affiliation}s given must be created with the + * {@link Affiliation#Affiliation(org.jxmpp.jid.BareJid, Affiliation.Type)} constructor. + *

+ * Note that this is an optional PubSub feature ('pubusb#modify-affiliations'). + *

+ * + * @param affiliations + * @return null or a PubSub stanza with additional information on success. + * @throws NoResponseException + * @throws XMPPErrorException + * @throws NotConnectedException + * @throws InterruptedException + * @see XEP-60 § 8.9.2 Modify Affiliation + * @since 4.2 + */ + public PubSub modifyAffiliationAsOwner(List affiliations) throws NoResponseException, + XMPPErrorException, NotConnectedException, InterruptedException { + for (Affiliation affiliation : affiliations) { + if (affiliation.getPubSubNamespace() != PubSubNamespace.OWNER) { + throw new IllegalArgumentException("Must use Affiliation(BareJid, Type) affiliations"); + } + } + + PubSub pubSub = createPubsubPacket(Type.set, new AffiliationsExtension(affiliations, getId()), + PubSubNamespace.OWNER); + return sendPubsubPacket(pubSub); + } + /** * The user subscribes to the node using the supplied jid. The * bare jid portion of this one must match the jid for the connection.