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 0bc1c2194..663259a2d 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 @@ -211,7 +211,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; } @@ -219,7 +220,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-core/src/main/java/org/jivesoftware/smack/packet/XMPPError.java b/smack-core/src/main/java/org/jivesoftware/smack/packet/XMPPError.java index b4fefd171..367286e32 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 @@ -40,7 +40,7 @@ import org.jivesoftware.smack.util.XmlStringBuilder; * feature-not-implementedCANCEL * goneMODIFY * jid-malformedMODIFY - * no-acceptable MODIFY + * not-acceptable MODIFY * not-allowedCANCEL * not-authorizedAUTH * payment-requiredAUTH @@ -282,7 +282,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"); @@ -354,8 +354,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 f5f605548..b419e1e3a 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 @@ -447,7 +447,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 849eeb96e..06ad8bfc7 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 @@ -699,12 +699,15 @@ 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 */ 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 0c23c91ee..809434071 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 @@ -156,10 +156,23 @@ public class FileTransferManager extends Manager { 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 = IQ.createErrorResponse(initiation, new XMPPError(XMPPError.Condition.no_acceptable)); - connection().sendPacket(rejection); + // 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). + IQ rejection = IQ.createErrorResponse(initiation, 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 68eadb695..719a74896 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 @@ -254,18 +254,6 @@ public class FileTransferNegotiator extends Manager { } } - /** - * 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 = IQ.createErrorResponse(si, error); - connection().sendPacket(iqPacket); - } - /** * Returns a new, unique, stream ID to identify a file transfer. * 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 228fa77d7..abca27920 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 5495bc228..4d1fc7acd 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; 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 f3e035adb..5bb905813 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. @@ -44,8 +44,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 { XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() { @@ -63,7 +62,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)); @@ -81,6 +79,7 @@ public class DeliveryReceiptManager extends Manager implements PacketListener { if (receiptManager == null) { receiptManager = new DeliveryReceiptManager(connection); + instances.put(connection, receiptManager); } return receiptManager; @@ -102,20 +101,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); @@ -183,8 +179,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); } /** @@ -194,8 +189,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); } 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 c32b05091..410be9827 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 4c4c8e6a5..460b6e906 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 2b96a0923..d1e61830c 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 39540dbdf..c52150fc5 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() {