From fc39ac88bd7c082aab8860399aa354ff5c1c6264 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Wed, 9 Jul 2014 12:57:51 +0200 Subject: [PATCH 1/4] Add support for retrieving PubSub Node affiliations This also marks the starting point for extending the PubSub API to allow additional packet extensions to be added to the request. This is for example useful if one wants to limit the result with "Result Set Management (XEP-59)". Fixes SMACK-580. --- .../org/jivesoftware/smackx/pubsub/Node.java | 109 +++++++++++++++--- .../smackx/pubsub/PubSubManager.java | 68 +++-------- .../smackx/pubsub/packet/PubSub.java | 27 ++++- .../smackx/pubsub/packet/PubSubNamespace.java | 2 +- 4 files changed, 136 insertions(+), 70 deletions(-) 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 a5a052d55..facbbcb93 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 @@ -98,7 +98,9 @@ abstract public class Node */ public ConfigureForm getNodeConfiguration() throws NoResponseException, XMPPErrorException, NotConnectedException { - Packet reply = sendPubsubPacket(Type.GET, new NodeExtension(PubSubElementType.CONFIGURE_OWNER, getId()), PubSubNamespace.OWNER); + PubSub pubSub = createPubsubPacket(Type.GET, new NodeExtension( + PubSubElementType.CONFIGURE_OWNER, getId()), PubSubNamespace.OWNER); + Packet reply = sendPubsubPacket(pubSub); return NodeUtils.getFormFromPacket(reply, PubSubElementType.CONFIGURE_OWNER); } @@ -112,7 +114,8 @@ abstract public class Node */ public void sendConfigurationForm(Form submitForm) throws NoResponseException, XMPPErrorException, NotConnectedException { - PubSub packet = createPubsubPacket(Type.SET, new FormNode(FormNodeType.CONFIGURE_OWNER, getId(), submitForm), PubSubNamespace.OWNER); + PubSub packet = createPubsubPacket(Type.SET, new FormNode(FormNodeType.CONFIGURE_OWNER, + getId(), submitForm), PubSubNamespace.OWNER); con.createPacketCollectorAndSend(packet).nextResultOrThrow(); } @@ -143,11 +146,85 @@ abstract public class Node */ public List getSubscriptions() throws NoResponseException, XMPPErrorException, NotConnectedException { - PubSub reply = (PubSub)sendPubsubPacket(Type.GET, new NodeExtension(PubSubElementType.SUBSCRIPTIONS, getId())); - SubscriptionsExtension subElem = (SubscriptionsExtension)reply.getExtension(PubSubElementType.SUBSCRIPTIONS); - return subElem.getSubscriptions(); + return getSubscriptions(null, null); } + /** + * Get the subscriptions currently associated with this node. + *

+ * {@code additionalExtensions} can be used e.g. to add a "Result Set Management" extension. + * {@code returnedExtensions} will be filled with the packet extensions found in the answer. + *

+ * + * @param additionalExtensions + * @param returnedExtensions a collection that will be filled with the returned packet + * extensions + * @return List of {@link Subscription} + * @throws NoResponseException + * @throws XMPPErrorException + * @throws NotConnectedException + */ + public List getSubscriptions(List additionalExtensions, Collection returnedExtensions) + throws NoResponseException, XMPPErrorException, NotConnectedException { + PubSub pubSub = createPubsubPacket(Type.GET, new NodeExtension( + PubSubElementType.SUBSCRIPTIONS, getId())); + if (additionalExtensions != null) { + for (PacketExtension pe : additionalExtensions) { + pubSub.addExtension(pe); + } + } + PubSub reply = (PubSub) sendPubsubPacket(pubSub); + if (returnedExtensions != null) { + returnedExtensions.addAll(reply.getExtensions()); + } + SubscriptionsExtension subElem = (SubscriptionsExtension) reply.getExtension(PubSubElementType.SUBSCRIPTIONS); + return subElem.getSubscriptions(); + } + + /** + * Get the affiliations of this node. + * + * @return List of {@link Affiliation} + * @throws NoResponseException + * @throws XMPPErrorException + * @throws NotConnectedException + */ + public List getAffiliations() throws NoResponseException, XMPPErrorException, + NotConnectedException { + return getAffiliations(null, null); + } + + /** + * Get the affiliations of this node. + *

+ * {@code additionalExtensions} can be used e.g. to add a "Result Set Management" extension. + * {@code returnedExtensions} will be filled with the packet extensions found in the answer. + *

+ * + * @param additionalExtensions additional {@code PacketExtensions} add to the request + * @param returnedExtensions a collection that will be filled with the returned packet + * extensions + * @return List of {@link Affiliation} + * @throws NoResponseException + * @throws XMPPErrorException + * @throws NotConnectedException + */ + public List getAffiliations(List additionalExtensions, Collection returnedExtensions) + throws NoResponseException, XMPPErrorException, NotConnectedException { + PubSub pubSub = createPubsubPacket(Type.GET, new NodeExtension(PubSubElementType.AFFILIATIONS, getId())); + if (additionalExtensions != null) { + for (PacketExtension pe : additionalExtensions) { + pubSub.addExtension(pe); + } + } + PubSub reply = (PubSub) sendPubsubPacket(pubSub); + if (returnedExtensions != null) { + returnedExtensions.addAll(reply.getExtensions()); + } + AffiliationsExtension affilElem = (AffiliationsExtension) reply.getExtension(PubSubElementType.AFFILIATIONS); + return affilElem.getAffiliations(); + } + /** * The user subscribes to the node using the supplied jid. The * bare jid portion of this one must match the jid for the connection. @@ -167,7 +244,8 @@ abstract public class Node */ public Subscription subscribe(String jid) throws NoResponseException, XMPPErrorException, NotConnectedException { - PubSub reply = (PubSub)sendPubsubPacket(Type.SET, new SubscribeExtension(jid, getId())); + PubSub pubSub = createPubsubPacket(Type.SET, new SubscribeExtension(jid, getId())); + PubSub reply = (PubSub)sendPubsubPacket(pubSub); return (Subscription)reply.getExtension(PubSubElementType.SUBSCRIPTION); } @@ -191,9 +269,9 @@ abstract public class Node */ public Subscription subscribe(String jid, SubscribeForm subForm) throws NoResponseException, XMPPErrorException, NotConnectedException { - PubSub request = createPubsubPacket(Type.SET, new SubscribeExtension(jid, getId())); + PubSub request = createPubsubPacket(Type.SET, new SubscribeExtension(jid, getId())); request.addExtension(new FormNode(FormNodeType.OPTIONS, subForm)); - PubSub reply = (PubSub)PubSubManager.sendPubsubPacket(con, jid, Type.SET, request); + PubSub reply = (PubSub)PubSubManager.sendPubsubPacket(con, request); return (Subscription)reply.getExtension(PubSubElementType.SUBSCRIPTION); } @@ -224,7 +302,7 @@ abstract public class Node */ public void unsubscribe(String jid, String subscriptionId) throws NoResponseException, XMPPErrorException, NotConnectedException { - sendPubsubPacket(Type.SET, new UnsubscribeExtension(jid, getId(), subscriptionId)); + sendPubsubPacket(createPubsubPacket(Type.SET, new UnsubscribeExtension(jid, getId(), subscriptionId))); } /** @@ -256,7 +334,7 @@ abstract public class Node */ public SubscribeForm getSubscriptionOptions(String jid, String subscriptionId) throws NoResponseException, XMPPErrorException, NotConnectedException { - PubSub packet = (PubSub)sendPubsubPacket(Type.GET, new OptionsExtension(jid, getId(), subscriptionId)); + PubSub packet = (PubSub)sendPubsubPacket(createPubsubPacket(Type.GET, new OptionsExtension(jid, getId(), subscriptionId))); FormNode ext = (FormNode)packet.getExtension(PubSubElementType.OPTIONS); return new SubscribeForm(ext.getForm()); } @@ -357,17 +435,12 @@ abstract public class Node protected PubSub createPubsubPacket(Type type, PacketExtension ext, PubSubNamespace ns) { - return PubSubManager.createPubsubPacket(to, type, ext, ns); + return PubSub.createPubsubPacket(to, type, ext, ns); } - protected Packet sendPubsubPacket(Type type, NodeExtension ext) throws NoResponseException, XMPPErrorException, NotConnectedException + protected Packet sendPubsubPacket(PubSub packet) throws NoResponseException, XMPPErrorException, NotConnectedException { - return PubSubManager.sendPubsubPacket(con, to, type, ext); - } - - protected Packet sendPubsubPacket(Type type, NodeExtension ext, PubSubNamespace ns) throws NoResponseException, XMPPErrorException, NotConnectedException - { - return PubSubManager.sendPubsubPacket(con, to, type, ext, ns); + return PubSubManager.sendPubsubPacket(con, packet); } 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 9ac1cbee9..23bb17cef 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 @@ -16,6 +16,7 @@ */ package org.jivesoftware.smackx.pubsub; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -86,7 +87,7 @@ final public class PubSubManager */ public LeafNode createNode() throws NoResponseException, XMPPErrorException, NotConnectedException { - PubSub reply = (PubSub)sendPubsubPacket(Type.SET, new NodeExtension(PubSubElementType.CREATE)); + PubSub reply = (PubSub)sendPubsubPacket(Type.SET, new NodeExtension(PubSubElementType.CREATE), null); NodeExtension elem = (NodeExtension)reply.getExtension("create", PubSubNamespace.BASIC.getXmlns()); LeafNode newNode = new LeafNode(con, elem.getNode()); @@ -126,7 +127,7 @@ final public class PubSubManager */ public Node createNode(String name, Form config) throws NoResponseException, XMPPErrorException, NotConnectedException { - PubSub request = createPubsubPacket(to, Type.SET, new NodeExtension(PubSubElementType.CREATE, name)); + PubSub request = PubSub.createPubsubPacket(to, Type.SET, new NodeExtension(PubSubElementType.CREATE, name), null); boolean isLeafNode = true; if (config != null) @@ -140,7 +141,7 @@ final public class PubSubManager // Errors will cause exceptions in getReply, so it only returns // on success. - sendPubsubPacket(con, to, Type.SET, request); + sendPubsubPacket(con, request); Node newNode = isLeafNode ? new LeafNode(con, name) : new CollectionNode(con, name); newNode.setTo(to); nodeMap.put(newNode.getId(), newNode); @@ -217,7 +218,7 @@ final public class PubSubManager */ public List getSubscriptions() throws NoResponseException, XMPPErrorException, NotConnectedException { - Packet reply = sendPubsubPacket(Type.GET, new NodeExtension(PubSubElementType.SUBSCRIPTIONS)); + Packet reply = sendPubsubPacket(Type.GET, new NodeExtension(PubSubElementType.SUBSCRIPTIONS), null); SubscriptionsExtension subElem = (SubscriptionsExtension)reply.getExtension(PubSubElementType.SUBSCRIPTIONS.getElementName(), PubSubElementType.SUBSCRIPTIONS.getNamespace().getXmlns()); return subElem.getSubscriptions(); } @@ -233,7 +234,7 @@ final public class PubSubManager */ public List getAffiliations() throws NoResponseException, XMPPErrorException, NotConnectedException { - PubSub reply = (PubSub)sendPubsubPacket(Type.GET, new NodeExtension(PubSubElementType.AFFILIATIONS)); + PubSub reply = (PubSub)sendPubsubPacket(Type.GET, new NodeExtension(PubSubElementType.AFFILIATIONS), null); AffiliationsExtension listElem = (AffiliationsExtension)reply.getExtension(PubSubElementType.AFFILIATIONS); return listElem.getAffiliations(); } @@ -282,53 +283,22 @@ final public class PubSubManager ServiceDiscoveryManager mgr = ServiceDiscoveryManager.getInstanceFor(con); return mgr.discoverInfo(to); } - - private Packet sendPubsubPacket(Type type, PacketExtension ext, PubSubNamespace ns) throws NoResponseException, XMPPErrorException, NotConnectedException + + private Packet sendPubsubPacket(Type type, PacketExtension ext, PubSubNamespace ns) + throws NoResponseException, XMPPErrorException, NotConnectedException { + return sendPubsubPacket(con, to, type, Collections.singletonList(ext), ns); + } + + static Packet sendPubsubPacket(XMPPConnection con, String to, Type type, List extList, PubSubNamespace ns) throws NoResponseException, XMPPErrorException, NotConnectedException { - return sendPubsubPacket(con, to, type, ext, ns); + PubSub pubSub = new PubSub(to, type, ns); + for (PacketExtension pe : extList) { + pubSub.addExtension(pe); + } + return sendPubsubPacket(con ,pubSub); } - private Packet sendPubsubPacket(Type type, PacketExtension ext) throws NoResponseException, XMPPErrorException, NotConnectedException - { - return sendPubsubPacket(type, ext, null); - } - - static PubSub createPubsubPacket(String to, Type type, PacketExtension ext) - { - return createPubsubPacket(to, type, ext, null); - } - - static PubSub createPubsubPacket(String to, Type type, PacketExtension ext, PubSubNamespace ns) - { - PubSub request = new PubSub(); - request.setTo(to); - request.setType(type); - - if (ns != null) - { - request.setPubSubNamespace(ns); - } - request.addExtension(ext); - - return request; - } - - static Packet sendPubsubPacket(XMPPConnection con, String to, Type type, PacketExtension ext) throws NoResponseException, XMPPErrorException, NotConnectedException - { - return sendPubsubPacket(con, to, type, ext, null); - } - - static Packet sendPubsubPacket(XMPPConnection con, String to, Type type, PacketExtension ext, PubSubNamespace ns) throws NoResponseException, XMPPErrorException, NotConnectedException - { - return con.createPacketCollectorAndSend(createPubsubPacket(to, type, ext, ns)).nextResultOrThrow(); - } - - static Packet sendPubsubPacket(XMPPConnection con, String to, Type type, PubSub packet) throws NoResponseException, XMPPErrorException, NotConnectedException - { - return sendPubsubPacket(con, to, type, packet, null); - } - - static Packet sendPubsubPacket(XMPPConnection con, String to, Type type, PubSub packet, PubSubNamespace ns) throws NoResponseException, XMPPErrorException, NotConnectedException + static Packet sendPubsubPacket(XMPPConnection con, PubSub packet) throws NoResponseException, XMPPErrorException, NotConnectedException { return con.createPacketCollectorAndSend(packet).nextResultOrThrow(); } 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 4dd383ac2..f175939d3 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 @@ -29,15 +29,33 @@ import org.jivesoftware.smackx.pubsub.PubSubElementType; */ public class PubSub extends IQ { + public static final String ELEMENT = "pubsub"; + public static final String NAMESPACE = "http://jabber.org/protocol/pubsub"; + private PubSubNamespace ns = PubSubNamespace.BASIC; - + + public PubSub() { + } + + public PubSub(String to, Type type) { + setTo(to); + setType(type); + } + + public PubSub(String to, Type type, PubSubNamespace ns) { + this(to, type); + if (ns != null) { + setPubSubNamespace(ns); + } + } + /** * Returns the XML element name of the extension sub-packet root element. * * @return the XML element name of the packet extension. */ public String getElementName() { - return "pubsub"; + return ELEMENT; } /** @@ -106,4 +124,9 @@ public class PubSub extends IQ return buf.toString(); } + public static PubSub createPubsubPacket(String to, Type type, PacketExtension extension, PubSubNamespace ns) { + PubSub pubSub = new PubSub(to, type, ns); + 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 d14a510f8..9437eb565 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 @@ -40,7 +40,7 @@ public enum PubSubNamespace public String getXmlns() { - String ns = "http://jabber.org/protocol/pubsub"; + String ns = PubSub.NAMESPACE; if (fragment != null) ns += '#' + fragment; From cde6dd65b342c8d5a8030d1baa6dbfd85a5bd262 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sat, 12 Jul 2014 12:39:04 +0200 Subject: [PATCH 2/4] Fix typo: s/no_acceptable/not_acceptable in XMPPError.Condition --- .../java/org/jivesoftware/smack/packet/XMPPError.java | 8 ++++---- .../smackx/bytestreams/ibb/InBandBytestreamManager.java | 2 +- .../bytestreams/socks5/Socks5BytestreamManager.java | 2 +- .../smackx/filetransfer/FileTransferManager.java | 2 +- .../bytestreams/ibb/InBandBytestreamRequestTest.java | 2 +- .../smackx/bytestreams/ibb/InitiationListenerTest.java | 4 ++-- .../smackx/bytestreams/socks5/InitiationListenerTest.java | 4 ++-- .../bytestreams/socks5/Socks5ByteStreamManagerTest.java | 2 +- 8 files changed, 13 insertions(+), 13 deletions(-) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/XMPPError.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/XMPPError.java index a11c98d32..c3343759b 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/XMPPError.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/XMPPError.java @@ -38,7 +38,7 @@ import java.util.Map; * feature-not-implementedCANCEL * goneMODIFY * jid-malformedMODIFY - * no-acceptable MODIFY + * not-acceptable MODIFY * not-allowedCANCEL * not-authorizedAUTH * payment-requiredAUTH @@ -276,7 +276,7 @@ public class XMPPError { public static final Condition gone = new Condition("gone"); public static final Condition item_not_found = new Condition("item-not-found"); public static final Condition jid_malformed = new Condition("jid-malformed"); - public static final Condition no_acceptable = new Condition("not-acceptable"); + public static final Condition not_acceptable = new Condition("not-acceptable"); public static final Condition not_allowed = new Condition("not-allowed"); public static final Condition not_authorized = new Condition("not-authorized"); public static final Condition payment_required = new Condition("payment-required"); @@ -348,8 +348,8 @@ public class XMPPError { Condition.gone, Type.MODIFY)); instances.put(Condition.jid_malformed, new XMPPError.ErrorSpecification( Condition.jid_malformed, Type.MODIFY)); - instances.put(Condition.no_acceptable, new XMPPError.ErrorSpecification( - Condition.no_acceptable, Type.MODIFY)); + instances.put(Condition.not_acceptable, new XMPPError.ErrorSpecification( + Condition.not_acceptable, Type.MODIFY)); instances.put(Condition.not_allowed, new XMPPError.ErrorSpecification( Condition.not_allowed, Type.CANCEL)); instances.put(Condition.not_authorized, new XMPPError.ErrorSpecification( diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamManager.java index 1e95de0f3..fbf4db419 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamManager.java @@ -451,7 +451,7 @@ public class InBandBytestreamManager implements BytestreamManager { * @throws NotConnectedException */ protected void replyRejectPacket(IQ request) throws NotConnectedException { - XMPPError xmppError = new XMPPError(XMPPError.Condition.no_acceptable); + XMPPError xmppError = new XMPPError(XMPPError.Condition.not_acceptable); IQ error = IQ.createErrorResponse(request, xmppError); this.connection.sendPacket(error); } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java index 7f16950e5..e95dd0db4 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java @@ -708,7 +708,7 @@ public final class Socks5BytestreamManager implements BytestreamManager { * @throws NotConnectedException */ protected void replyRejectPacket(IQ packet) throws NotConnectedException { - XMPPError xmppError = new XMPPError(XMPPError.Condition.no_acceptable); + XMPPError xmppError = new XMPPError(XMPPError.Condition.not_acceptable); IQ errorIQ = IQ.createErrorResponse(packet, xmppError); this.connection.sendPacket(errorIQ); } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferManager.java index e6a517544..923cd04ba 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferManager.java @@ -174,7 +174,7 @@ public class FileTransferManager { IQ rejection = FileTransferNegotiator.createIQ( initiation.getPacketID(), initiation.getFrom(), initiation .getTo(), IQ.Type.ERROR); - rejection.setError(new XMPPError(XMPPError.Condition.no_acceptable)); + rejection.setError(new XMPPError(XMPPError.Condition.not_acceptable)); connection.sendPacket(rejection); } } diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamRequestTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamRequestTest.java index fe6073d4f..a4d94a11f 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamRequestTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/InBandBytestreamRequestTest.java @@ -84,7 +84,7 @@ public class InBandBytestreamRequestTest { // assert that reply is the correct error packet assertEquals(initiatorJID, argument.getValue().getTo()); assertEquals(IQ.Type.ERROR, argument.getValue().getType()); - assertEquals(XMPPError.Condition.no_acceptable.toString(), + assertEquals(XMPPError.Condition.not_acceptable.toString(), argument.getValue().getError().getCondition()); } diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/InitiationListenerTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/InitiationListenerTest.java index 8077a8366..4eeb90273 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/InitiationListenerTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/ibb/InitiationListenerTest.java @@ -92,7 +92,7 @@ public class InitiationListenerTest { // assert that reply is the correct error packet assertEquals(initiatorJID, argument.getValue().getTo()); assertEquals(IQ.Type.ERROR, argument.getValue().getType()); - assertEquals(XMPPError.Condition.no_acceptable.toString(), + assertEquals(XMPPError.Condition.not_acceptable.toString(), argument.getValue().getError().getCondition()); } @@ -210,7 +210,7 @@ public class InitiationListenerTest { // assert that reply is the correct error packet assertEquals(initiatorJID, argument.getValue().getTo()); assertEquals(IQ.Type.ERROR, argument.getValue().getType()); - assertEquals(XMPPError.Condition.no_acceptable.toString(), + assertEquals(XMPPError.Condition.not_acceptable.toString(), argument.getValue().getError().getCondition()); } diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/InitiationListenerTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/InitiationListenerTest.java index dcdbfe896..169058a46 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/InitiationListenerTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/InitiationListenerTest.java @@ -99,7 +99,7 @@ public class InitiationListenerTest { // assert that reply is the correct error packet assertEquals(initiatorJID, argument.getValue().getTo()); assertEquals(IQ.Type.ERROR, argument.getValue().getType()); - assertEquals(XMPPError.Condition.no_acceptable.toString(), + assertEquals(XMPPError.Condition.not_acceptable.toString(), argument.getValue().getError().getCondition()); } @@ -189,7 +189,7 @@ public class InitiationListenerTest { // assert that reply is the correct error packet assertEquals(initiatorJID, argument.getValue().getTo()); assertEquals(IQ.Type.ERROR, argument.getValue().getType()); - assertEquals(XMPPError.Condition.no_acceptable.toString(), + assertEquals(XMPPError.Condition.not_acceptable.toString(), argument.getValue().getError().getCondition()); } diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ByteStreamManagerTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ByteStreamManagerTest.java index d6923bb09..48c2a4b62 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ByteStreamManagerTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5ByteStreamManagerTest.java @@ -424,7 +424,7 @@ public class Socks5ByteStreamManagerTest { Verification.requestTypeGET); // build error packet to reject SOCKS5 Bytestream - XMPPError xmppError = new XMPPError(XMPPError.Condition.no_acceptable); + XMPPError xmppError = new XMPPError(XMPPError.Condition.not_acceptable); IQ rejectPacket = new IQ() { public String getChildElementXML() { From c063fb137689a987bb7a589443ac4ac74e136dc3 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sat, 12 Jul 2014 13:50:50 +0200 Subject: [PATCH 3/4] Reply correct error code on XEP-65 Stream rejection this was previously erroneously changed with 197548b548c0436108cb20f33859172a70d0bf8f from 'forbidden' to 'not-acceptable'. We now change it back to 'forbidden'. Also delete FileTransferNegotiator.rejectStream(StreamInitation) because it is dead code and add some comments and javadoc. --- .../socks5/Socks5BytestreamManager.java | 3 +++ .../smackx/filetransfer/FileTransferManager.java | 14 +++++++++++++- .../filetransfer/FileTransferNegotiator.java | 14 -------------- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java index e95dd0db4..c7e199044 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5BytestreamManager.java @@ -703,6 +703,9 @@ public final class Socks5BytestreamManager implements BytestreamManager { /** * Responses to the given packet's sender with a XMPP error that a SOCKS5 Bytestream is not * accepted. + *

+ * Specified in XEP-65 5.3.1 (Example 13) + *

* * @param packet Packet that should be answered with a not-acceptable error * @throws NotConnectedException diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferManager.java index 923cd04ba..b1659fff5 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferManager.java @@ -168,13 +168,25 @@ public class FileTransferManager { return transfer; } + /** + * Reject an incoming file transfer. + *

+ * Specified in XEP-95 4.2 and 3.2 Example 8 + *

+ * @param request + * @throws NotConnectedException + */ protected void rejectIncomingFileTransfer(FileTransferRequest request) throws NotConnectedException { StreamInitiation initiation = request.getStreamInitiation(); IQ rejection = FileTransferNegotiator.createIQ( initiation.getPacketID(), initiation.getFrom(), initiation .getTo(), IQ.Type.ERROR); - rejection.setError(new XMPPError(XMPPError.Condition.not_acceptable)); + // Reject as specified in XEP-95 4.2. Note that this is not to be confused with the Socks 5 + // Bytestream rejection as specified in XEP-65 5.3.1 Example 13, which says that + // 'not-acceptable' should be returned. This is done by Smack in + // Socks5BytestreamManager.replyRejectPacket(IQ). + rejection.setError(new XMPPError(XMPPError.Condition.forbidden)); connection.sendPacket(rejection); } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java index 0f59deec9..575b63291 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/filetransfer/FileTransferNegotiator.java @@ -322,20 +322,6 @@ public class FileTransferNegotiator { } } - /** - * Reject a stream initiation request from a remote user. - * - * @param si The Stream Initiation request to reject. - * @throws NotConnectedException - */ - public void rejectStream(final StreamInitiation si) throws NotConnectedException { - XMPPError error = new XMPPError(XMPPError.Condition.forbidden, "Offer Declined"); - IQ iqPacket = createIQ(si.getPacketID(), si.getFrom(), si.getTo(), - IQ.Type.ERROR); - iqPacket.setError(error); - connection.sendPacket(iqPacket); - } - /** * Returns a new, unique, stream ID to identify a file transfer. * From bd0ada480b9373c4522be3eb71763aed5c864ec0 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 13 Jul 2014 10:16:10 +0200 Subject: [PATCH 4/4] Improve DeliveryReceipt code, add javadoc Also make Packet.getExtension() use Generics --- .../org/jivesoftware/smack/packet/Packet.java | 5 +++-- .../smackx/receipts/DeliveryReceipt.java | 13 +++++++++++- .../receipts/DeliveryReceiptManager.java | 21 ++++++++----------- .../receipts/DeliveryReceiptRequest.java | 13 +++++++++++- .../receipts/ReceiptReceivedListener.java | 13 +++++++++++- 5 files changed, 48 insertions(+), 17 deletions(-) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/packet/Packet.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/Packet.java index 02b53ee11..6f6c2c209 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/packet/Packet.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/packet/Packet.java @@ -240,7 +240,8 @@ public abstract class Packet { * @param namespace the XML element namespace of the packet extension. * @return the extension, or null if it doesn't exist. */ - public PacketExtension getExtension(String elementName, String namespace) { + @SuppressWarnings("unchecked") + public PE getExtension(String elementName, String namespace) { if (namespace == null) { return null; } @@ -248,7 +249,7 @@ public abstract class Packet { if ((elementName == null || elementName.equals(ext.getElementName())) && namespace.equals(ext.getNamespace())) { - return ext; + return (PE) ext; } } return null; diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceipt.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceipt.java index ccee66e0d..febbde7af 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceipt.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceipt.java @@ -1,6 +1,6 @@ /** * - * Copyright the original author or authors + * Copyright 2013-2014 the original author or authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ package org.jivesoftware.smackx.receipts; import java.util.List; import java.util.Map; +import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.PacketExtension; import org.jivesoftware.smack.provider.EmbeddedExtensionProvider; @@ -63,6 +64,16 @@ public class DeliveryReceipt implements PacketExtension return ""; } + /** + * Get the {@link DeliveryReceipt} extension of the packet, if any. + * + * @param p the packet + * @return the {@link DeliveryReceipt} extension or {@code null} + */ + public static DeliveryReceipt getFrom(Packet p) { + return p.getExtension(ELEMENT, NAMESPACE); + } + /** * This Provider parses and returns DeliveryReceipt packets. */ diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceiptManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceiptManager.java index ba3633ddd..c9cdfad21 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceiptManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceiptManager.java @@ -1,6 +1,6 @@ /** * - * Copyright 2013 Georg Lukas + * Copyright 2013-2014 Georg Lukas * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,8 +43,7 @@ import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; */ public class DeliveryReceiptManager extends Manager implements PacketListener { - private static Map instances = - Collections.synchronizedMap(new WeakHashMap()); + private static Map instances = new WeakHashMap(); static { XMPPConnection.addConnectionCreationListener(new ConnectionCreationListener() { @@ -62,7 +61,6 @@ public class DeliveryReceiptManager extends Manager implements PacketListener { super(connection); ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(connection); sdm.addFeature(DeliveryReceipt.NAMESPACE); - instances.put(connection, this); // register listener for delivery receipts and requests connection.addPacketListener(this, new PacketExtensionFilter(DeliveryReceipt.NAMESPACE)); @@ -80,6 +78,7 @@ public class DeliveryReceiptManager extends Manager implements PacketListener { if (receiptManager == null) { receiptManager = new DeliveryReceiptManager(connection); + instances.put(connection, receiptManager); } return receiptManager; @@ -101,20 +100,17 @@ public class DeliveryReceiptManager extends Manager implements PacketListener { // handle incoming receipts and receipt requests @Override public void processPacket(Packet packet) throws NotConnectedException { - DeliveryReceipt dr = (DeliveryReceipt)packet.getExtension( - DeliveryReceipt.ELEMENT, DeliveryReceipt.NAMESPACE); + DeliveryReceipt dr = DeliveryReceipt.getFrom(packet); if (dr != null) { // notify listeners of incoming receipt for (ReceiptReceivedListener l : receiptReceivedListeners) { l.onReceiptReceived(packet.getFrom(), packet.getTo(), dr.getId()); } - } // if enabled, automatically send a receipt if (auto_receipts_enabled) { - DeliveryReceiptRequest drr = (DeliveryReceiptRequest)packet.getExtension( - DeliveryReceiptRequest.ELEMENT, DeliveryReceipt.NAMESPACE); + DeliveryReceiptRequest drr = DeliveryReceiptRequest.getFrom(packet); if (drr != null) { XMPPConnection connection = connection(); Message ack = new Message(packet.getFrom(), Message.Type.normal); @@ -182,8 +178,7 @@ public class DeliveryReceiptManager extends Manager implements PacketListener { * @return true if a delivery receipt was requested */ public static boolean hasDeliveryReceiptRequest(Packet p) { - return (p.getExtension(DeliveryReceiptRequest.ELEMENT, - DeliveryReceipt.NAMESPACE) != null); + return (DeliveryReceiptRequest.getFrom(p) != null); } /** @@ -193,8 +188,10 @@ public class DeliveryReceiptManager extends Manager implements PacketListener { * therefore only allow Message as the parameter type. * * @param m Message object to add a request to + * @return the Message ID which will be used as receipt ID */ - public static void addDeliveryReceiptRequest(Message m) { + public static String addDeliveryReceiptRequest(Message m) { m.addExtension(new DeliveryReceiptRequest()); + return m.getPacketID(); } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceiptRequest.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceiptRequest.java index e1c432b5a..2831ccd2f 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceiptRequest.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceiptRequest.java @@ -1,6 +1,6 @@ /** * - * Copyright the original author or authors + * Copyright 2013-2014 the original author or authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ */ package org.jivesoftware.smackx.receipts; +import org.jivesoftware.smack.packet.Packet; import org.jivesoftware.smack.packet.PacketExtension; import org.jivesoftware.smack.provider.PacketExtensionProvider; import org.xmlpull.v1.XmlPullParser; @@ -45,6 +46,16 @@ public class DeliveryReceiptRequest implements PacketExtension return ""; } + /** + * Get the {@link DeliveryReceiptRequest} extension of the packet, if any. + * + * @param p the packet + * @return the {@link DeliveryReceiptRequest} extension or {@code null} + */ + public static DeliveryReceiptRequest getFrom(Packet p) { + return p.getExtension(ELEMENT, DeliveryReceipt.NAMESPACE); + } + /** * This Provider parses and returns DeliveryReceiptRequest packets. */ diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/ReceiptReceivedListener.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/ReceiptReceivedListener.java index 3b3f81dbb..dcaf23a66 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/ReceiptReceivedListener.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/ReceiptReceivedListener.java @@ -1,6 +1,6 @@ /** * - * Copyright 2013 Georg Lukas + * Copyright 2013-2014 Georg Lukas * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,5 +22,16 @@ package org.jivesoftware.smackx.receipts; * Implement this and add a listener to get notified. */ public interface ReceiptReceivedListener { + /** + * Callback invoked when a new receipt got received. + *

+ * {@code receiptId} correspondents to the message ID, which can be obtained with + * {@link org.jivesoftware.smack.packet.Packet#getPacketID()}. + *

+ * + * @param fromJid the jid that send this receipt + * @param toJid the jid which received this receipt + * @param receiptId the message ID of the packet which has been received and this receipt is for + */ void onReceiptReceived(String fromJid, String toJid, String receiptId); }