From 31244ae9829865dd1898fdbc57e05bb391865342 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Thu, 19 Apr 2018 11:05:43 +0200 Subject: [PATCH] Make PubSub elements namespace aware Also fixes SMACK-814. --- .../smackx/pubsub/Affiliation.java | 50 +++++++--- .../smackx/pubsub/AffiliationsExtension.java | 14 ++- .../smackx/pubsub/EventElement.java | 4 +- .../smackx/pubsub/FormNodeType.java | 2 +- .../org/jivesoftware/smackx/pubsub/Item.java | 91 +++++++++++++------ .../smackx/pubsub/ItemsExtension.java | 9 +- .../jivesoftware/smackx/pubsub/LeafNode.java | 2 +- .../org/jivesoftware/smackx/pubsub/Node.java | 53 ++++++----- .../smackx/pubsub/NodeExtension.java | 10 +- .../smackx/pubsub/PayloadItem.java | 44 +++++---- .../smackx/pubsub/PubSubElementType.java | 46 +++++----- .../smackx/pubsub/PubSubManager.java | 4 +- .../smackx/pubsub/RetractItem.java | 2 +- .../smackx/pubsub/SubscriptionsExtension.java | 39 +++++++- .../smackx/pubsub/packet/PubSub.java | 7 +- .../smackx/pubsub/packet/PubSubNamespace.java | 25 +++-- .../pubsub/provider/AffiliationProvider.java | 7 +- .../pubsub/provider/AffiliationsProvider.java | 4 +- .../smackx/pubsub/provider/EventProvider.java | 1 + .../smackx/pubsub/provider/ItemProvider.java | 14 ++- .../provider/SubscriptionsProvider.java | 5 +- .../smackx/pubsub/ItemValidationTest.java | 41 +++++---- .../smackx/pubsub/PubSubNodeTest.java | 48 +++++++++- .../pubsub/provider/PubSubProviderTest.java | 2 +- .../smackx/omemo/OmemoManager.java | 3 +- 25 files changed, 354 insertions(+), 173 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 2eb44cb8b..e33848714 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 @@ -18,6 +18,7 @@ package org.jivesoftware.smackx.pubsub; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.packet.ExtensionElement; +import org.jivesoftware.smack.util.Objects; import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smack.util.XmlStringBuilder; @@ -38,10 +39,30 @@ import org.jxmpp.jid.BareJid; public class Affiliation implements ExtensionElement { public static final String ELEMENT = "affiliation"; + public enum AffiliationNamespace { + basic(PubSubElementType.AFFILIATIONS), + owner(PubSubElementType.AFFILIATIONS_OWNER), + ; + public final PubSubElementType type; + + AffiliationNamespace(PubSubElementType type) { + this.type = type; + } + + public static AffiliationNamespace fromXmlns(String xmlns) { + for (AffiliationNamespace affiliationsNamespace : AffiliationNamespace.values()) { + if (affiliationsNamespace.type.getNamespace().getXmlns().equals(xmlns)) { + return affiliationsNamespace; + } + } + throw new IllegalArgumentException("Invalid affiliations namespace: " + xmlns); + } + } + private final BareJid jid; private final String node; private final Type affiliation; - private final PubSubNamespace namespace; + private final AffiliationNamespace namespace; public enum Type { member, none, outcast, owner, publisher @@ -54,14 +75,21 @@ public class Affiliation implements ExtensionElement { * @param affiliation the optional affiliation. */ public Affiliation(String node, Type affiliation) { + this(node, affiliation, affiliation == null ? AffiliationNamespace.basic : AffiliationNamespace.owner); + } + + /** + * Constructs an affiliation. + * + * @param node The node the user is affiliated with. + * @param affiliation the optional affiliation. + * @param namespace the affiliation's namespace. + */ + public Affiliation(String node, Type affiliation, AffiliationNamespace namespace) { this.node = StringUtils.requireNotNullOrEmpty(node, "node must not be null or empty"); this.affiliation = affiliation; this.jid = null; - if (affiliation != null) { - namespace = PubSubNamespace.BASIC; - } else { - namespace = PubSubNamespace.OWNER; - } + this.namespace = Objects.requireNonNull(namespace); } /** @@ -71,10 +99,10 @@ public class Affiliation implements ExtensionElement { * @param affiliation */ public Affiliation(BareJid jid, Type affiliation) { - this(jid, affiliation, PubSubNamespace.OWNER); + this(jid, affiliation, AffiliationNamespace.owner); } - public Affiliation(BareJid jid, Type affiliation, PubSubNamespace namespace) { + public Affiliation(BareJid jid, Type affiliation, AffiliationNamespace namespace) { this.jid = jid; this.affiliation = affiliation; this.node = null; @@ -124,11 +152,11 @@ public class Affiliation implements ExtensionElement { @Override public String getNamespace() { - return namespace.getXmlns(); + return getPubSubNamespace().getXmlns(); } public PubSubNamespace getPubSubNamespace() { - return namespace; + return namespace.type.getNamespace(); } /** @@ -139,7 +167,7 @@ public class Affiliation implements ExtensionElement { */ public boolean isAffiliationModification() { if (jid != null && affiliation != null) { - assert (node == null && namespace == PubSubNamespace.OWNER); + assert (node == null && namespace == AffiliationNamespace.owner); return true; } return false; 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 ab1561ed0..b874568ba 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 @@ -21,6 +21,8 @@ import java.util.List; import org.jivesoftware.smack.util.XmlStringBuilder; +import org.jivesoftware.smackx.pubsub.Affiliation.AffiliationNamespace; + /** * Represents the affiliations element of the reply to a request for affiliations. * It is defined in the specification in section 5.7 Retrieve Affiliations and @@ -33,15 +35,23 @@ public class AffiliationsExtension extends NodeExtension { private final String node; public AffiliationsExtension() { - this(null, null); + this(null); } public AffiliationsExtension(List subList) { this(subList, null); } + public AffiliationsExtension(AffiliationNamespace affiliationsNamespace, List subList) { + this(affiliationsNamespace, subList, null); + } + public AffiliationsExtension(List subList, String node) { - super(PubSubElementType.AFFILIATIONS); + this(AffiliationNamespace.basic, subList, node); + } + + public AffiliationsExtension(AffiliationNamespace affiliationsNamespace, List subList, String node) { + super(affiliationsNamespace.type); items = subList; this.node = node; } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/EventElement.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/EventElement.java index e057ae2b3..09f785f64 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/EventElement.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/EventElement.java @@ -42,7 +42,7 @@ public class EventElement implements EmbeddedPacketExtension { /** * The constant String "http://jabber.org/protocol/pubsub#event". */ - public static final String NAMESPACE = PubSubNamespace.EVENT.getXmlns(); + public static final String NAMESPACE = PubSubNamespace.event.getXmlns(); private final EventElementType type; private final NodeExtension ext; @@ -72,7 +72,7 @@ public class EventElement implements EmbeddedPacketExtension { @Override public String getNamespace() { - return PubSubNamespace.EVENT.getXmlns(); + return PubSubNamespace.event.getXmlns(); } @Override diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/FormNodeType.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/FormNodeType.java index 31298d941..a4e3f9bb9 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/FormNodeType.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/FormNodeType.java @@ -43,7 +43,7 @@ public enum FormNodeType { } public static FormNodeType valueOfFromElementName(String elem, String configNamespace) { - if ("configure".equals(elem) && PubSubNamespace.OWNER.getXmlns().equals(configNamespace)) { + if ("configure".equals(elem) && PubSubNamespace.owner.getXmlns().equals(configNamespace)) { return CONFIGURE_OWNER; } return valueOf(elem.toUpperCase(Locale.US)); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/Item.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/Item.java index 8207a56a1..053168224 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/Item.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/Item.java @@ -17,6 +17,7 @@ package org.jivesoftware.smackx.pubsub; import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.util.XmlStringBuilder; import org.jivesoftware.smackx.pubsub.provider.ItemProvider; @@ -50,7 +51,27 @@ import org.jivesoftware.smackx.pubsub.provider.ItemProvider; * @author Robin Collier */ public class Item extends NodeExtension { - private String id; + public enum ItemNamespace { + pubsub(PubSubElementType.ITEM), + event(PubSubElementType.ITEM_EVENT), + ; + private final PubSubElementType type; + + ItemNamespace(PubSubElementType type) { + this.type = type; + } + + public static ItemNamespace fromXmlns(String xmlns) { + for (ItemNamespace itemNamespace : ItemNamespace.values()) { + if (itemNamespace.type.getNamespace().getXmlns().equals(xmlns)) { + return itemNamespace; + } + } + throw new IllegalArgumentException("Invalid item namespace: " + xmlns); + } + } + + private final String itemId; /** * Create an empty Item with no id. This is a valid item for nodes which are configured @@ -60,7 +81,7 @@ public class Item extends NodeExtension { * method in this case. */ public Item() { - super(PubSubElementType.ITEM); + this(ItemNamespace.pubsub, null, null); } /** @@ -71,9 +92,18 @@ public class Item extends NodeExtension { * Passing null is the equivalent of calling {@link #Item()}. */ public Item(String itemId) { - // The element type is actually irrelevant since we override getNamespace() to return null - super(PubSubElementType.ITEM); - id = itemId; + this(ItemNamespace.pubsub, itemId, null); + } + + /** + * Create an Item with an id but no payload. This is a valid item for nodes which are configured + * so that {@link ConfigureForm#isDeliverPayloads()} is false. + * + * @param itemId The id if the item. It must be unique within the node unless overwriting and existing item. + * Passing null is the equivalent of calling {@link #Item()}. + */ + public Item(ItemNamespace itemNamespace, String itemId) { + this(itemNamespace, itemId, null); } /** @@ -88,8 +118,23 @@ public class Item extends NodeExtension { * @param nodeId The id of the node which the item was published to. */ public Item(String itemId, String nodeId) { - super(PubSubElementType.ITEM_EVENT, nodeId); - id = itemId; + this(ItemNamespace.pubsub, itemId, nodeId); + } + + /** + * Create an Item with an id and a node id. + *

+ * Note: This is not valid for publishing an item to a node, only receiving from + * one as part of {@link Message}. If used to create an Item to publish + * (via {@link LeafNode#publish(Item)}, the server may return an + * error for an invalid packet. + * + * @param itemId The id of the item. + * @param nodeId The id of the node which the item was published to. + */ + public Item(ItemNamespace itemNamespace, String itemId, String nodeId) { + super(itemNamespace.type, nodeId); + this.itemId = itemId; } /** @@ -98,36 +143,30 @@ public class Item extends NodeExtension { * @return The id */ public String getId() { - return id; + return itemId; } @Override - public String getNamespace() { - return null; + public XmlStringBuilder toXML() { + XmlStringBuilder xml = getCommonXml(); + + xml.closeEmptyElement(); + + return xml; } - @Override - public String toXML() { - StringBuilder builder = new StringBuilder(""); - - return builder.toString(); + return xml; } @Override public String toString() { return getClass().getName() + " | Content [" + toXML() + "]"; } + } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/ItemsExtension.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/ItemsExtension.java index bad417083..c49b52403 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/ItemsExtension.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/ItemsExtension.java @@ -19,6 +19,7 @@ package org.jivesoftware.smackx.pubsub; import java.util.List; import org.jivesoftware.smack.packet.ExtensionElement; +import org.jivesoftware.smack.packet.NamedElement; /** * This class is used for multiple purposes. @@ -37,7 +38,7 @@ import org.jivesoftware.smack.packet.ExtensionElement; public class ItemsExtension extends NodeExtension implements EmbeddedPacketExtension { protected ItemsElementType type; protected Boolean notify; - protected List items; + protected List items; public enum ItemsElementType { /** An items element, which has an optional max_items attribute when requesting items. */ @@ -82,7 +83,7 @@ public class ItemsExtension extends NodeExtension implements EmbeddedPacketExten * @param nodeId The node to which the items are being sent or deleted * @param items The list of {@link Item} or {@link RetractItem} */ - public ItemsExtension(ItemsElementType itemsType, String nodeId, List items) { + public ItemsExtension(ItemsElementType itemsType, String nodeId, List items) { super(itemsType.getNodeElement(), nodeId); type = itemsType; this.items = items; @@ -134,7 +135,7 @@ public class ItemsExtension extends NodeExtension implements EmbeddedPacketExten * * @return List of {@link Item}, {@link RetractItem}, or null */ - public List getItems() { + public List getItems() { return items; } @@ -167,7 +168,7 @@ public class ItemsExtension extends NodeExtension implements EmbeddedPacketExten } else { builder.append("'>"); - for (ExtensionElement item : items) { + for (NamedElement item : items) { builder.append(item.toXML()); } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/LeafNode.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/LeafNode.java index d882d36a2..1bd204970 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/LeafNode.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/LeafNode.java @@ -341,7 +341,7 @@ public class LeafNode extends Node { * @throws InterruptedException */ public void deleteAllItems() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { - PubSub request = createPubsubPacket(Type.set, new NodeExtension(PubSubElementType.PURGE_OWNER, getId()), PubSubElementType.PURGE_OWNER.getNamespace()); + PubSub request = createPubsubPacket(Type.set, new NodeExtension(PubSubElementType.PURGE_OWNER, getId())); pubSubManager.getConnection().createStanzaCollectorAndSend(request).nextResultOrThrow(); } 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 770bf8ff9..3d35e5d25 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 @@ -34,6 +34,8 @@ import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smackx.delay.DelayInformationManager; import org.jivesoftware.smackx.disco.packet.DiscoverInfo; +import org.jivesoftware.smackx.pubsub.Affiliation.AffiliationNamespace; +import org.jivesoftware.smackx.pubsub.SubscriptionsExtension.SubscriptionsNamespace; import org.jivesoftware.smackx.pubsub.listener.ItemDeleteListener; import org.jivesoftware.smackx.pubsub.listener.ItemEventListener; import org.jivesoftware.smackx.pubsub.listener.NodeConfigListener; @@ -84,7 +86,7 @@ public abstract class Node { */ public ConfigureForm getNodeConfiguration() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { PubSub pubSub = createPubsubPacket(Type.get, new NodeExtension( - PubSubElementType.CONFIGURE_OWNER, getId()), PubSubNamespace.OWNER); + PubSubElementType.CONFIGURE_OWNER, getId())); Stanza reply = sendPubsubPacket(pubSub); return NodeUtils.getFormFromPacket(reply, PubSubElementType.CONFIGURE_OWNER); } @@ -100,7 +102,7 @@ public abstract class Node { */ public void sendConfigurationForm(Form submitForm) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { PubSub packet = createPubsubPacket(Type.set, new FormNode(FormNodeType.CONFIGURE_OWNER, - getId(), submitForm), PubSubNamespace.OWNER); + getId(), submitForm)); pubSubManager.getConnection().createStanzaCollectorAndSend(packet).nextResultOrThrow(); } @@ -152,7 +154,7 @@ public abstract class Node { */ public List getSubscriptions(List additionalExtensions, Collection returnedExtensions) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { - return getSubscriptions(additionalExtensions, returnedExtensions, null); + return getSubscriptions(SubscriptionsNamespace.basic, additionalExtensions, returnedExtensions); } /** @@ -197,13 +199,15 @@ public abstract class Node { public List getSubscriptionsAsOwner(List additionalExtensions, Collection returnedExtensions) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { - return getSubscriptions(additionalExtensions, returnedExtensions, PubSubNamespace.OWNER); + return getSubscriptions(SubscriptionsNamespace.owner, additionalExtensions, returnedExtensions); } - private List getSubscriptions(List additionalExtensions, - Collection returnedExtensions, PubSubNamespace pubSubNamespace) + private List getSubscriptions(SubscriptionsNamespace subscriptionsNamespace, List additionalExtensions, + Collection returnedExtensions) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { - PubSub pubSub = createPubsubPacket(Type.get, new NodeExtension(PubSubElementType.SUBSCRIPTIONS, getId()), pubSubNamespace); + PubSubElementType pubSubElementType = subscriptionsNamespace.type; + + PubSub pubSub = createPubsubPacket(Type.get, new NodeExtension(pubSubElementType, getId())); if (additionalExtensions != null) { for (ExtensionElement pe : additionalExtensions) { pubSub.addExtension(pe); @@ -213,7 +217,7 @@ public abstract class Node { if (returnedExtensions != null) { returnedExtensions.addAll(reply.getExtensions()); } - SubscriptionsExtension subElem = reply.getExtension(PubSubElementType.SUBSCRIPTIONS); + SubscriptionsExtension subElem = reply.getExtension(pubSubElementType); return subElem.getSubscriptions(); } @@ -237,8 +241,7 @@ public abstract class Node { throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { PubSub pubSub = createPubsubPacket(Type.set, - new SubscriptionsExtension(getId(), changedSubs), - PubSubNamespace.OWNER); + new SubscriptionsExtension(SubscriptionsNamespace.owner, getId(), changedSubs)); return sendPubsubPacket(pubSub); } @@ -275,7 +278,7 @@ public abstract class Node { public List getAffiliations(List additionalExtensions, Collection returnedExtensions) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { - return getAffiliations(PubSubNamespace.BASIC, additionalExtensions, returnedExtensions); + return getAffiliations(AffiliationNamespace.basic, additionalExtensions, returnedExtensions); } /** @@ -315,14 +318,15 @@ public abstract class Node { public List getAffiliationsAsOwner(List additionalExtensions, Collection returnedExtensions) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { - return getAffiliations(PubSubNamespace.OWNER, additionalExtensions, returnedExtensions); + return getAffiliations(AffiliationNamespace.owner, additionalExtensions, returnedExtensions); } - private List getAffiliations(PubSubNamespace namespace, List additionalExtensions, + private List getAffiliations(AffiliationNamespace affiliationsNamespace, List additionalExtensions, Collection returnedExtensions) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { + PubSubElementType pubSubElementType = affiliationsNamespace.type; - PubSub pubSub = createPubsubPacket(Type.get, new NodeExtension(PubSubElementType.AFFILIATIONS, getId()), namespace); + PubSub pubSub = createPubsubPacket(Type.get, new NodeExtension(pubSubElementType, getId())); if (additionalExtensions != null) { for (ExtensionElement pe : additionalExtensions) { pubSub.addExtension(pe); @@ -332,7 +336,7 @@ public abstract class Node { if (returnedExtensions != null) { returnedExtensions.addAll(reply.getExtensions()); } - AffiliationsExtension affilElem = reply.getExtension(PubSubElementType.AFFILIATIONS); + AffiliationsExtension affilElem = reply.getExtension(pubSubElementType); return affilElem.getAffiliations(); } @@ -355,13 +359,12 @@ public abstract class Node { public PubSub modifyAffiliationAsOwner(List affiliations) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { for (Affiliation affiliation : affiliations) { - if (affiliation.getPubSubNamespace() != PubSubNamespace.OWNER) { + 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); + PubSub pubSub = createPubsubPacket(Type.set, new AffiliationsExtension(AffiliationNamespace.owner, affiliations, getId())); return sendPubsubPacket(pubSub); } @@ -567,12 +570,8 @@ public abstract class Node { return super.toString() + " " + getClass().getName() + " id: " + id; } - protected PubSub createPubsubPacket(Type type, ExtensionElement ext) { - return createPubsubPacket(type, ext, null); - } - - protected PubSub createPubsubPacket(Type type, ExtensionElement ext, PubSubNamespace ns) { - return PubSub.createPubsubPacket(pubSubManager.getServiceJid(), type, ext, ns); + protected PubSub createPubsubPacket(Type type, NodeExtension ext) { + return PubSub.createPubsubPacket(pubSubManager.getServiceJid(), type, ext); } protected PubSub sendPubsubPacket(PubSub packet) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { @@ -611,7 +610,7 @@ public abstract class Node { @Override @SuppressWarnings({ "rawtypes", "unchecked" }) public void processStanza(Stanza packet) { - EventElement event = packet.getExtension("event", PubSubNamespace.EVENT.getXmlns()); + EventElement event = packet.getExtension("event", PubSubNamespace.event.getXmlns()); ItemsExtension itemsElem = (ItemsExtension) event.getEvent(); ItemPublishEvent eventItems = new ItemPublishEvent(itemsElem.getNode(), itemsElem.getItems(), getSubscriptionIds(packet), DelayInformationManager.getDelayTimestamp(packet)); // TODO: Use AsyncButOrdered (with Node as Key?) @@ -635,7 +634,7 @@ public abstract class Node { @Override public void processStanza(Stanza packet) { // CHECKSTYLE:OFF - EventElement event = packet.getExtension("event", PubSubNamespace.EVENT.getXmlns()); + EventElement event = packet.getExtension("event", PubSubNamespace.event.getXmlns()); List extList = event.getExtensions(); @@ -674,7 +673,7 @@ public abstract class Node { @Override public void processStanza(Stanza packet) { - EventElement event = packet.getExtension("event", PubSubNamespace.EVENT.getXmlns()); + EventElement event = packet.getExtension("event", PubSubNamespace.event.getXmlns()); ConfigurationEvent config = (ConfigurationEvent) event.getEvent(); // TODO: Use AsyncButOrdered (with Node as Key?) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/NodeExtension.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/NodeExtension.java index fd6667c79..a699e51ee 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/NodeExtension.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/NodeExtension.java @@ -18,6 +18,8 @@ package org.jivesoftware.smackx.pubsub; import org.jivesoftware.smack.packet.ExtensionElement; +import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace; + /** * A class which represents a common element within the pubsub defined * schemas. One which has a node as an attribute. This class is @@ -66,9 +68,13 @@ public class NodeExtension implements ExtensionElement { return element.getElementName(); } + public PubSubNamespace getPubSubNamespace() { + return element.getNamespace(); + } + @Override - public String getNamespace() { - return element.getNamespace().getXmlns(); + public final String getNamespace() { + return getPubSubNamespace().getXmlns(); } @Override diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PayloadItem.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PayloadItem.java index 6fb8aef42..d6860606d 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PayloadItem.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PayloadItem.java @@ -18,6 +18,7 @@ package org.jivesoftware.smackx.pubsub; import org.jivesoftware.smack.packet.ExtensionElement; import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.util.XmlStringBuilder; import org.jivesoftware.smackx.pubsub.provider.ItemProvider; @@ -93,7 +94,25 @@ public class PayloadItem extends Item { * @param payloadExt A {@link ExtensionElement} which represents the payload data. */ public PayloadItem(String itemId, String nodeId, E payloadExt) { - super(itemId, nodeId); + this(ItemNamespace.pubsub, itemId, nodeId, payloadExt); + } + + /** + * Create an Item with an id, node id and payload. + * + *

+ * Note: This is not valid for publishing an item to a node, only receiving from + * one as part of {@link Message}. If used to create an Item to publish + * (via {@link LeafNode#publish(Item)}, the server may return an + * error for an invalid packet. + *

+ * + * @param itemId The id of this item. + * @param nodeId The id of the node the item was published to. + * @param payloadExt A {@link ExtensionElement} which represents the payload data. + */ + public PayloadItem(ItemNamespace itemNamespace, String itemId, String nodeId, E payloadExt) { + super(itemNamespace, itemId, nodeId); if (payloadExt == null) throw new IllegalArgumentException("payload cannot be 'null'"); @@ -111,25 +130,14 @@ public class PayloadItem extends Item { } @Override - public String toXML() { - StringBuilder builder = new StringBuilder("'); - builder.append(payload.toXML()); - builder.append(""); - - return builder.toString(); + return xml; } @Override diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubElementType.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubElementType.java index d6f1cac8a..63a114d96 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubElementType.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubElementType.java @@ -27,28 +27,30 @@ import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace; * @author Robin Collier */ public enum PubSubElementType { - CREATE("create", PubSubNamespace.BASIC), - DELETE("delete", PubSubNamespace.OWNER), - DELETE_EVENT("delete", PubSubNamespace.EVENT), - CONFIGURE("configure", PubSubNamespace.BASIC), - CONFIGURE_OWNER("configure", PubSubNamespace.OWNER), - CONFIGURATION("configuration", PubSubNamespace.EVENT), - OPTIONS("options", PubSubNamespace.BASIC), - DEFAULT("default", PubSubNamespace.OWNER), - ITEMS("items", PubSubNamespace.BASIC), - ITEMS_EVENT("items", PubSubNamespace.EVENT), - ITEM("item", PubSubNamespace.BASIC), - ITEM_EVENT("item", PubSubNamespace.EVENT), - PUBLISH("publish", PubSubNamespace.BASIC), - PUBLISH_OPTIONS("publish-options", PubSubNamespace.BASIC), - PURGE_OWNER("purge", PubSubNamespace.OWNER), - PURGE_EVENT("purge", PubSubNamespace.EVENT), - RETRACT("retract", PubSubNamespace.BASIC), - AFFILIATIONS("affiliations", PubSubNamespace.BASIC), - SUBSCRIBE("subscribe", PubSubNamespace.BASIC), - SUBSCRIPTION("subscription", PubSubNamespace.BASIC), - SUBSCRIPTIONS("subscriptions", PubSubNamespace.BASIC), - UNSUBSCRIBE("unsubscribe", PubSubNamespace.BASIC); + CREATE("create", PubSubNamespace.basic), + DELETE("delete", PubSubNamespace.owner), + DELETE_EVENT("delete", PubSubNamespace.event), + CONFIGURE("configure", PubSubNamespace.basic), + CONFIGURE_OWNER("configure", PubSubNamespace.owner), + CONFIGURATION("configuration", PubSubNamespace.event), + OPTIONS("options", PubSubNamespace.basic), + DEFAULT("default", PubSubNamespace.owner), + ITEMS("items", PubSubNamespace.basic), + ITEMS_EVENT("items", PubSubNamespace.event), + ITEM("item", PubSubNamespace.basic), + ITEM_EVENT("item", PubSubNamespace.event), + PUBLISH("publish", PubSubNamespace.basic), + PUBLISH_OPTIONS("publish-options", PubSubNamespace.basic), + PURGE_OWNER("purge", PubSubNamespace.owner), + PURGE_EVENT("purge", PubSubNamespace.event), + RETRACT("retract", PubSubNamespace.basic), + AFFILIATIONS("affiliations", PubSubNamespace.basic), + AFFILIATIONS_OWNER("affiliations", PubSubNamespace.owner), + SUBSCRIBE("subscribe", PubSubNamespace.basic), + SUBSCRIPTION("subscription", PubSubNamespace.basic), + SUBSCRIPTIONS("subscriptions", PubSubNamespace.basic), + SUBSCRIPTIONS_OWNER("subscriptions", PubSubNamespace.owner), + UNSUBSCRIBE("unsubscribe", PubSubNamespace.basic); private final String eName; private final PubSubNamespace nSpace; diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java index 94fd03bf9..89c791bce 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java @@ -157,7 +157,7 @@ public final class PubSubManager extends Manager { */ public LeafNode createNode() throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { PubSub reply = sendPubsubPacket(Type.set, new NodeExtension(PubSubElementType.CREATE), null); - NodeExtension elem = reply.getExtension("create", PubSubNamespace.BASIC.getXmlns()); + NodeExtension elem = reply.getExtension("create", PubSubNamespace.basic.getXmlns()); LeafNode newNode = new LeafNode(this, elem.getNode()); nodeMap.put(newNode.getId(), newNode); @@ -195,7 +195,7 @@ public final class PubSubManager extends Manager { * @throws InterruptedException */ public Node createNode(String nodeId, Form config) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException { - PubSub request = PubSub.createPubsubPacket(pubSubService, Type.set, new NodeExtension(PubSubElementType.CREATE, nodeId), null); + PubSub request = PubSub.createPubsubPacket(pubSubService, Type.set, new NodeExtension(PubSubElementType.CREATE, nodeId)); boolean isLeafNode = true; if (config != null) { diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/RetractItem.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/RetractItem.java index ab01ef5c4..b63e1c8d6 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/RetractItem.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/RetractItem.java @@ -50,7 +50,7 @@ public class RetractItem implements ExtensionElement { @Override public String getNamespace() { - return PubSubNamespace.EVENT.getXmlns(); + return PubSubNamespace.event.getXmlns(); } @Override diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/SubscriptionsExtension.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/SubscriptionsExtension.java index ec70ce2f1..f67fa0a41 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/SubscriptionsExtension.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/SubscriptionsExtension.java @@ -25,6 +25,26 @@ import java.util.List; * @author Robin Collier */ public class SubscriptionsExtension extends NodeExtension { + public enum SubscriptionsNamespace { + basic(PubSubElementType.SUBSCRIPTIONS), + owner(PubSubElementType.SUBSCRIPTIONS_OWNER), + ; + public final PubSubElementType type; + + SubscriptionsNamespace(PubSubElementType type) { + this.type = type; + } + + public static SubscriptionsNamespace fromXmlns(String xmlns) { + for (SubscriptionsNamespace subscriptionsNamespace : SubscriptionsNamespace.values()) { + if (subscriptionsNamespace.type.getNamespace().getXmlns().equals(xmlns)) { + return subscriptionsNamespace; + } + } + throw new IllegalArgumentException("Invalid Subscription namespace: " + xmlns); + } + } + protected List items = Collections.emptyList(); /** @@ -33,10 +53,7 @@ public class SubscriptionsExtension extends NodeExtension { * @param subList The list of subscriptions */ public SubscriptionsExtension(List subList) { - super(PubSubElementType.SUBSCRIPTIONS); - - if (subList != null) - items = subList; + this(SubscriptionsNamespace.basic, null, subList); } /** @@ -46,7 +63,19 @@ public class SubscriptionsExtension extends NodeExtension { * @param subList The list of subscriptions */ public SubscriptionsExtension(String nodeId, List subList) { - super(PubSubElementType.SUBSCRIPTIONS, nodeId); + this(SubscriptionsNamespace.basic, nodeId, subList); + } + + /** + * Subscriptions to the specified node. + * + * @param subscriptionsNamespace the namespace used by this element + * @param nodeId The node subscribed to + * @param subList The list of subscriptions + * @since 4.3 + */ + public SubscriptionsExtension(SubscriptionsNamespace subscriptionsNamespace, String nodeId, List subList) { + super(subscriptionsNamespace.type, nodeId); if (subList != null) items = subList; diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/packet/PubSub.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/packet/PubSub.java index 4e0ebea7b..730fcbc56 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/packet/PubSub.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/packet/PubSub.java @@ -19,6 +19,7 @@ package org.jivesoftware.smackx.pubsub.packet; import org.jivesoftware.smack.packet.ExtensionElement; import org.jivesoftware.smack.packet.IQ; +import org.jivesoftware.smackx.pubsub.NodeExtension; import org.jivesoftware.smackx.pubsub.PubSubElementType; import org.jxmpp.jid.Jid; @@ -43,7 +44,7 @@ public class PubSub extends IQ { } public PubSub(Jid to, Type type, PubSubNamespace ns) { - super(ELEMENT, (ns == null ? PubSubNamespace.BASIC : ns).getXmlns()); + super(ELEMENT, (ns == null ? PubSubNamespace.basic : ns).getXmlns()); setTo(to); setType(type); } @@ -78,8 +79,8 @@ public class PubSub extends IQ { return xml; } - public static PubSub createPubsubPacket(Jid to, Type type, ExtensionElement extension, PubSubNamespace ns) { - PubSub pubSub = new PubSub(to, type, ns); + public static PubSub createPubsubPacket(Jid to, Type type, NodeExtension extension) { + PubSub pubSub = new PubSub(to, type, extension.getPubSubNamespace()); pubSub.addExtension(extension); return pubSub; } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/packet/PubSubNamespace.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/packet/PubSubNamespace.java index 83d319420..ca6ad5747 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/packet/PubSubNamespace.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/packet/PubSubNamespace.java @@ -16,8 +16,6 @@ */ package org.jivesoftware.smackx.pubsub.packet; -import java.util.Locale; - /** * Defines all the valid namespaces that are used with the {@link PubSub} packet * as defined by the specification. @@ -25,10 +23,10 @@ import java.util.Locale; * @author Robin Collier */ public enum PubSubNamespace { - BASIC(null), - ERROR("errors"), - EVENT("event"), - OWNER("owner"); + basic(null), + error("errors"), + event("event"), + owner("owner"); private final String fragment; private final String fullNamespace; @@ -54,10 +52,17 @@ public enum PubSubNamespace { int index = ns.lastIndexOf('#'); if (index != -1) { - String suffix = ns.substring(ns.lastIndexOf('#') + 1); - return valueOf(suffix.toUpperCase(Locale.US)); + // We found an extended namespace. + if (index > ns.length()) { + throw new IllegalArgumentException(ns + " is not a valid PubSub namespace"); + } + String suffix = ns.substring(index + 1); + return valueOf(suffix); } - else - return BASIC; + + if (!PubSub.NAMESPACE.equals(ns)) { + throw new IllegalArgumentException(ns + " is not a valid PubSub namespace"); + } + return basic; } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/AffiliationProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/AffiliationProvider.java index 09d51c466..cee29f7b3 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/AffiliationProvider.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/AffiliationProvider.java @@ -21,7 +21,7 @@ import org.jivesoftware.smack.provider.ExtensionElementProvider; import org.jivesoftware.smack.util.ParserUtils; import org.jivesoftware.smackx.pubsub.Affiliation; -import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace; +import org.jivesoftware.smackx.pubsub.Affiliation.AffiliationNamespace; import org.jxmpp.jid.BareJid; import org.xmlpull.v1.XmlPullParser; @@ -39,6 +39,8 @@ public class AffiliationProvider extends ExtensionElementProvider { throws Exception { String node = parser.getAttributeValue(null, "node"); BareJid jid = ParserUtils.getBareJidAttribute(parser); + String namespaceString = parser.getNamespace(); + AffiliationNamespace namespace = AffiliationNamespace.fromXmlns(namespaceString); String affiliationString = parser.getAttributeValue(null, "affiliation"); Affiliation.Type affiliationType = null; @@ -48,10 +50,9 @@ public class AffiliationProvider extends ExtensionElementProvider { Affiliation affiliation; if (node != null && jid == null) { // affiliationType may be empty - affiliation = new Affiliation(node, affiliationType); + affiliation = new Affiliation(node, affiliationType, namespace); } else if (node == null && jid != null) { - PubSubNamespace namespace = null; // TODO affiliation = new Affiliation(jid, affiliationType, namespace); } else { diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/AffiliationsProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/AffiliationsProvider.java index 14bf80dee..3a2df7c5c 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/AffiliationsProvider.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/AffiliationsProvider.java @@ -23,6 +23,7 @@ import org.jivesoftware.smack.packet.ExtensionElement; import org.jivesoftware.smack.provider.EmbeddedExtensionProvider; import org.jivesoftware.smackx.pubsub.Affiliation; +import org.jivesoftware.smackx.pubsub.Affiliation.AffiliationNamespace; import org.jivesoftware.smackx.pubsub.AffiliationsExtension; /** @@ -34,7 +35,8 @@ import org.jivesoftware.smackx.pubsub.AffiliationsExtension; @SuppressWarnings("unchecked") @Override protected AffiliationsExtension createReturnExtension(String currentElement, String currentNamespace, Map attributeMap, List content) { - return new AffiliationsExtension((List) content); + AffiliationNamespace affiliationsNamespace = AffiliationNamespace.fromXmlns(currentNamespace); + return new AffiliationsExtension(affiliationsNamespace, (List) content); } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/EventProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/EventProvider.java index af09a2bc9..48a7dade5 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/EventProvider.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/EventProvider.java @@ -35,6 +35,7 @@ import org.jivesoftware.smackx.pubsub.NodeExtension; public class EventProvider extends EmbeddedExtensionProvider { @Override protected EventElement createReturnExtension(String currentElement, String currentNamespace, Map attMap, List content) { + // TODO: Shouldn't be an embedded extension provider. return new EventElement(EventElementType.valueOf(content.get(0).getElementName()), (NodeExtension) content.get(0)); } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/ItemProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/ItemProvider.java index 1f078cef2..9f2587837 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/ItemProvider.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/ItemProvider.java @@ -22,6 +22,7 @@ import org.jivesoftware.smack.provider.ProviderManager; import org.jivesoftware.smack.util.PacketParserUtils; import org.jivesoftware.smackx.pubsub.Item; +import org.jivesoftware.smackx.pubsub.Item.ItemNamespace; import org.jivesoftware.smackx.pubsub.PayloadItem; import org.jivesoftware.smackx.pubsub.SimplePayload; import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace; @@ -29,8 +30,8 @@ import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace; import org.xmlpull.v1.XmlPullParser; /** - * Parses an item element as is defined in both the {@link PubSubNamespace#BASIC} and - * {@link PubSubNamespace#EVENT} namespaces. To parse the item contents, it will use whatever + * Parses an item element as is defined in both the {@link PubSubNamespace#basic} and + * {@link PubSubNamespace#event} namespaces. To parse the item contents, it will use whatever * {@link ExtensionElementProvider} is registered in smack.providers for its element name and namespace. If no * provider is registered, it will return a {@link SimplePayload}. * @@ -42,11 +43,13 @@ public class ItemProvider extends ExtensionElementProvider { throws Exception { String id = parser.getAttributeValue(null, "id"); String node = parser.getAttributeValue(null, "node"); + String xmlns = parser.getNamespace(); + ItemNamespace itemNamespace = ItemNamespace.fromXmlns(xmlns); int tag = parser.next(); if (tag == XmlPullParser.END_TAG) { - return new Item(id, node); + return new Item(itemNamespace, id, node); } else { String payloadElemName = parser.getName(); @@ -54,11 +57,12 @@ public class ItemProvider extends ExtensionElementProvider { final ExtensionElementProvider extensionProvider = ProviderManager.getExtensionProvider(payloadElemName, payloadNS); if (extensionProvider == null) { + // TODO: Should we use StandardExtensionElement in this case? And probably remove SimplePayload all together. CharSequence payloadText = PacketParserUtils.parseElement(parser, true); - return new PayloadItem<>(id, node, new SimplePayload(payloadElemName, payloadNS, payloadText)); + return new PayloadItem<>(itemNamespace, id, node, new SimplePayload(payloadElemName, payloadNS, payloadText)); } else { - return new PayloadItem<>(id, node, extensionProvider.parse(parser)); + return new PayloadItem<>(itemNamespace, id, node, extensionProvider.parse(parser)); } } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/SubscriptionsProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/SubscriptionsProvider.java index 71191adfb..9e132c066 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/SubscriptionsProvider.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/provider/SubscriptionsProvider.java @@ -24,6 +24,7 @@ import org.jivesoftware.smack.provider.EmbeddedExtensionProvider; import org.jivesoftware.smackx.pubsub.Subscription; import org.jivesoftware.smackx.pubsub.SubscriptionsExtension; +import org.jivesoftware.smackx.pubsub.SubscriptionsExtension.SubscriptionsNamespace; /** * Parses the subscriptions element out of the PubSub IQ message from @@ -35,7 +36,9 @@ public class SubscriptionsProvider extends EmbeddedExtensionProvider attributeMap, List content) { - return new SubscriptionsExtension(attributeMap.get("node"), (List) content); + SubscriptionsNamespace subscriptionsNamespace = SubscriptionsNamespace.fromXmlns(currentNamespace); + String nodeId = attributeMap.get("node"); + return new SubscriptionsExtension(subscriptionsNamespace, nodeId, (List) content); } } diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/pubsub/ItemValidationTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/pubsub/ItemValidationTest.java index 97d49b2b8..735baf8aa 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/pubsub/ItemValidationTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/pubsub/ItemValidationTest.java @@ -22,6 +22,7 @@ import static org.junit.Assert.assertTrue; import org.jivesoftware.smack.ThreadedDummyConnection; import org.jivesoftware.smack.packet.ExtensionElement; +import org.jivesoftware.smack.packet.NamedElement; import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.util.PacketParserUtils; @@ -60,16 +61,16 @@ public class ItemValidationTest extends InitExtensions { @Test public void verifyBasicItem() throws Exception { Item simpleItem = new Item(); - String simpleCtrl = ""; - assertXMLEqual(simpleCtrl, simpleItem.toXML()); + String simpleCtrl = ""; + assertXMLEqual(simpleCtrl, simpleItem.toXML().toString()); Item idItem = new Item("uniqueid"); - String idCtrl = ""; - assertXMLEqual(idCtrl, idItem.toXML()); + String idCtrl = ""; + assertXMLEqual(idCtrl, idItem.toXML().toString()); Item itemWithNodeId = new Item("testId", "testNode"); - String nodeIdCtrl = ""; - assertXMLEqual(nodeIdCtrl, itemWithNodeId.toXML()); + String nodeIdCtrl = ""; + assertXMLEqual(nodeIdCtrl, itemWithNodeId.toXML().toString()); } @Test @@ -77,16 +78,16 @@ public class ItemValidationTest extends InitExtensions { SimplePayload payload = new SimplePayload(null, null, "This is the payload"); PayloadItem simpleItem = new PayloadItem<>(payload); - String simpleCtrl = "" + payload.toXML() + ""; - assertXMLEqual(simpleCtrl, simpleItem.toXML()); + String simpleCtrl = "" + payload.toXML() + ""; + assertXMLEqual(simpleCtrl, simpleItem.toXML().toString()); PayloadItem idItem = new PayloadItem<>("uniqueid", payload); - String idCtrl = "" + payload.toXML() + ""; - assertXMLEqual(idCtrl, idItem.toXML()); + String idCtrl = "" + payload.toXML() + ""; + assertXMLEqual(idCtrl, idItem.toXML().toString()); PayloadItem itemWithNodeId = new PayloadItem<>("testId", "testNode", payload); - String nodeIdCtrl = "" + payload.toXML() + ""; - assertXMLEqual(nodeIdCtrl, itemWithNodeId.toXML()); + String nodeIdCtrl = "" + payload.toXML() + ""; + assertXMLEqual(nodeIdCtrl, itemWithNodeId.toXML().toString()); } @Test @@ -101,7 +102,7 @@ public class ItemValidationTest extends InitExtensions { ""); Stanza message = PacketParserUtils.parseMessage(parser); - ExtensionElement eventExt = message.getExtension(PubSubNamespace.EVENT.getXmlns()); + ExtensionElement eventExt = message.getExtension(PubSubNamespace.event.getXmlns()); assertTrue(eventExt instanceof EventElement); EventElement event = (EventElement) eventExt; @@ -110,7 +111,7 @@ public class ItemValidationTest extends InitExtensions { assertTrue(event.getExtensions().get(0) instanceof ItemsExtension); assertEquals(1, ((ItemsExtension) event.getExtensions().get(0)).items.size()); - ExtensionElement itemExt = ((ItemsExtension) event.getExtensions().get(0)).items.get(0); + NamedElement itemExt = ((ItemsExtension) event.getExtensions().get(0)).items.get(0); assertTrue(itemExt instanceof Item); assertEquals("testid1", ((Item) itemExt).getId()); } @@ -131,9 +132,9 @@ public class ItemValidationTest extends InitExtensions { ""); Stanza message = PacketParserUtils.parseMessage(parser); - ExtensionElement eventExt = message.getExtension(PubSubNamespace.EVENT.getXmlns()); + ExtensionElement eventExt = message.getExtension(PubSubNamespace.event.getXmlns()); EventElement event = (EventElement) eventExt; - ExtensionElement itemExt = ((ItemsExtension) event.getExtensions().get(0)).items.get(0); + NamedElement itemExt = ((ItemsExtension) event.getExtensions().get(0)).items.get(0); assertTrue(itemExt instanceof PayloadItem); PayloadItem item = (PayloadItem) itemExt; @@ -177,9 +178,9 @@ public class ItemValidationTest extends InitExtensions { ""); Stanza message = PacketParserUtils.parseMessage(parser); - ExtensionElement eventExt = message.getExtension(PubSubNamespace.EVENT.getXmlns()); + ExtensionElement eventExt = message.getExtension(PubSubNamespace.event.getXmlns()); EventElement event = (EventElement) eventExt; - ExtensionElement itemExt = ((ItemsExtension) event.getExtensions().get(0)).items.get(0); + NamedElement itemExt = ((ItemsExtension) event.getExtensions().get(0)).items.get(0); assertTrue(itemExt instanceof PayloadItem); PayloadItem item = (PayloadItem) itemExt; @@ -209,7 +210,7 @@ public class ItemValidationTest extends InitExtensions { ""); Stanza message = PacketParserUtils.parseMessage(parser); - ExtensionElement eventExt = message.getExtension(PubSubNamespace.EVENT.getXmlns()); + ExtensionElement eventExt = message.getExtension(PubSubNamespace.event.getXmlns()); assertTrue(eventExt instanceof EventElement); EventElement event = (EventElement) eventExt; @@ -218,7 +219,7 @@ public class ItemValidationTest extends InitExtensions { assertTrue(event.getExtensions().get(0) instanceof ItemsExtension); assertEquals(1, ((ItemsExtension) event.getExtensions().get(0)).items.size()); - ExtensionElement itemExt = ((ItemsExtension) event.getExtensions().get(0)).items.get(0); + NamedElement itemExt = ((ItemsExtension) event.getExtensions().get(0)).items.get(0); assertTrue(itemExt instanceof PayloadItem); PayloadItem item = (PayloadItem) itemExt; diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/pubsub/PubSubNodeTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/pubsub/PubSubNodeTest.java index 28bf82a31..3d2341a9b 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/pubsub/PubSubNodeTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/pubsub/PubSubNodeTest.java @@ -1,6 +1,6 @@ /** * - * Copyright 2018 Timothy Pitt + * Copyright 2018 Timothy Pitt, Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,17 +24,25 @@ import java.util.List; import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.ThreadedDummyConnection; +import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.packet.IQ.Type; +import org.jivesoftware.smack.test.util.SmackTestSuite; import org.jivesoftware.smack.test.util.TestUtils; import org.jivesoftware.smack.util.PacketParserUtils; -import org.jivesoftware.smackx.pubsub.packet.PubSub; +import org.jivesoftware.smackx.pubsub.Affiliation.AffiliationNamespace; +import org.jivesoftware.smackx.pubsub.packet.PubSub; +import org.jivesoftware.smackx.pubsub.packet.PubSubNamespace; + +import org.jivesoftware.util.ConnectionUtils; +import org.jivesoftware.util.Protocol; import org.junit.Test; import org.jxmpp.jid.JidTestUtil; import org.jxmpp.jid.impl.JidCreate; import org.xmlpull.v1.XmlPullParser; -public class PubSubNodeTest { +public class PubSubNodeTest extends SmackTestSuite { @Test public void modifySubscriptionsAsOwnerTest() throws InterruptedException, SmackException, IOException, XMPPException, Exception { @@ -55,7 +63,7 @@ public class PubSubNodeTest { XmlPullParser parser = TestUtils.getIQParser(request.toXML().toString()); PubSub pubsubResult = (PubSub) PacketParserUtils.parseIQ(parser); - SubscriptionsExtension subElem = pubsubResult.getExtension(PubSubElementType.SUBSCRIPTIONS); + SubscriptionsExtension subElem = pubsubResult.getExtension(PubSubElementType.SUBSCRIPTIONS_OWNER); List subscriptions = subElem.getSubscriptions(); assertEquals(2, subscriptions.size()); @@ -67,4 +75,36 @@ public class PubSubNodeTest { assertEquals("juliet@capulet.org", sub2.getJid().toString()); assertEquals(Subscription.State.none, sub2.getState()); } + + @Test + public void getAffiliationsAsOwnerTest() throws InterruptedException, SmackException, IOException, XMPPException, Exception { + Protocol protocol = new Protocol(); + XMPPConnection connection = ConnectionUtils.createMockedConnection(protocol, JidTestUtil.FULL_JID_1_RESOURCE_1); + + PubSubManager mgr = new PubSubManager(connection, JidTestUtil.PUBSUB_EXAMPLE_ORG); + Node testNode = new LeafNode(mgr, "princely_musings"); + + List affiliations = Arrays.asList( + new Affiliation(JidTestUtil.BARE_JID_1, Affiliation.Type.member), + new Affiliation(JidTestUtil.BARE_JID_2, Affiliation.Type.publisher) + ); + AffiliationsExtension affiliationsExtension = new AffiliationsExtension(AffiliationNamespace.owner, affiliations); + PubSub response = new PubSub(JidTestUtil.PUBSUB_EXAMPLE_ORG, Type.result, PubSubNamespace.owner); + response.addExtension(affiliationsExtension); + protocol.addResponse(response); + + List returnedAffiliations = testNode.getAffiliationsAsOwner(); + + PubSub request = (PubSub) protocol.getRequests().get(0); + assertEquals("http://jabber.org/protocol/pubsub#owner", request.getChildElementNamespace()); + assertEquals("pubsub", request.getChildElementName()); + + Affiliation affiliationOne = returnedAffiliations.get(0); + assertEquals(affiliationOne.getJid(), JidTestUtil.BARE_JID_1); + assertEquals(affiliationOne.getAffiliation(), Affiliation.Type.member); + + Affiliation affiliationTwo = returnedAffiliations.get(1); + assertEquals(affiliationTwo.getJid(), JidTestUtil.BARE_JID_2); + assertEquals(affiliationTwo.getAffiliation(), Affiliation.Type.publisher); + } } diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/pubsub/provider/PubSubProviderTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/pubsub/provider/PubSubProviderTest.java index 14e2ea2ae..faa734d5e 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/pubsub/provider/PubSubProviderTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/pubsub/provider/PubSubProviderTest.java @@ -50,7 +50,7 @@ public class PubSubProviderTest { // @formatter:on XmlPullParser parser = TestUtils.getIQParser(resultStanza); PubSub pubsubResult = (PubSub) PacketParserUtils.parseIQ(parser); - SubscriptionsExtension subElem = pubsubResult.getExtension(PubSubElementType.SUBSCRIPTIONS); + SubscriptionsExtension subElem = pubsubResult.getExtension(PubSubElementType.SUBSCRIPTIONS_OWNER); List subscriptions = subElem.getSubscriptions(); assertEquals(2, subscriptions.size()); diff --git a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java index 01228f4f4..174063acd 100644 --- a/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java +++ b/smack-omemo/src/main/java/org/jivesoftware/smackx/omemo/OmemoManager.java @@ -39,6 +39,7 @@ import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.packet.ExtensionElement; import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.packet.NamedElement; import org.jivesoftware.smack.packet.Stanza; import org.jivesoftware.smack.util.Async; import org.jivesoftware.smackx.carbons.CarbonManager; @@ -776,7 +777,7 @@ public final class OmemoManager extends Manager { continue; } - for (ExtensionElement item : ((ItemsExtension) items).getItems()) { + for (NamedElement item : ((ItemsExtension) items).getItems()) { if (!(item instanceof PayloadItem)) { continue; }