1
0
Fork 0
mirror of https://github.com/vanitasvitae/Smack.git synced 2024-06-25 04:44:49 +02:00
Smack/smack-extensions/src/main/java/org/jivesoftware/smackx/receipts/DeliveryReceiptManager.java
Florian Schmaus fcb4844d10 Improve DeliveryReceiptManager
Use anonymous inner classes for packet listeners so that the
processPacket() method is not exposed as part of the Managers public
API.

And some small fixes.
2015-01-08 23:15:18 +01:00

207 lines
7.8 KiB
Java

/**
*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.receipts;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.ConnectionCreationListener;
import org.jivesoftware.smack.Manager;
import org.jivesoftware.smack.PacketListener;
import org.jivesoftware.smack.XMPPConnectionRegistry;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.filter.AndFilter;
import org.jivesoftware.smack.filter.PacketExtensionFilter;
import org.jivesoftware.smack.filter.PacketFilter;
import org.jivesoftware.smack.filter.PacketTypeFilter;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.packet.Packet;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
/**
* Manager for XEP-0184: Message Delivery Receipts. This class implements
* the manager for {@link DeliveryReceipt} support, enabling and disabling of
* automatic DeliveryReceipt transmission.
*
* @author Georg Lukas
* @see <a href="http://xmpp.org/extensions/xep-0184.html">XEP-0184: Message Delivery Receipts</a>
*/
public class DeliveryReceiptManager extends Manager {
private static final PacketFilter MESSAGES_WITH_DEVLIERY_RECEIPT_REQUEST = new AndFilter(PacketTypeFilter.MESSAGE,
new PacketExtensionFilter(new DeliveryReceiptRequest()));
private static final PacketFilter MESSAGES_WITH_DELIVERY_RECEIPT = new AndFilter(PacketTypeFilter.MESSAGE,
new PacketExtensionFilter(DeliveryReceipt.ELEMENT, DeliveryReceipt.NAMESPACE));
private static Map<XMPPConnection, DeliveryReceiptManager> instances = new WeakHashMap<XMPPConnection, DeliveryReceiptManager>();
static {
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
public void connectionCreated(XMPPConnection connection) {
getInstanceFor(connection);
}
});
}
private boolean auto_receipts_enabled = false;
private final Set<ReceiptReceivedListener> receiptReceivedListeners = new CopyOnWriteArraySet<ReceiptReceivedListener>();
private DeliveryReceiptManager(XMPPConnection connection) {
super(connection);
ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(connection);
sdm.addFeature(DeliveryReceipt.NAMESPACE);
// Add the packet listener to handling incoming delivery receipts
connection.addAsyncPacketListener(new PacketListener() {
@Override
public void processPacket(Packet packet) throws NotConnectedException {
DeliveryReceipt dr = DeliveryReceipt.from(packet);
// notify listeners of incoming receipt
for (ReceiptReceivedListener l : receiptReceivedListeners) {
l.onReceiptReceived(packet.getFrom(), packet.getTo(), dr.getId(), packet);
}
}
}, MESSAGES_WITH_DELIVERY_RECEIPT);
// Add the packet listener to handle incoming delivery receipt requests
connection.addAsyncPacketListener(new PacketListener() {
@Override
public void processPacket(Packet packet) throws NotConnectedException {
// if enabled, automatically send a receipt
if (!auto_receipts_enabled) {
return;
}
Message ack = new Message(packet.getFrom(), Message.Type.normal);
ack.addExtension(new DeliveryReceipt(packet.getPacketID()));
connection().sendPacket(ack);
}
}, MESSAGES_WITH_DEVLIERY_RECEIPT_REQUEST);
}
/**
* Obtain the DeliveryReceiptManager responsible for a connection.
*
* @param connection the connection object.
*
* @return the DeliveryReceiptManager instance for the given connection
*/
public static synchronized DeliveryReceiptManager getInstanceFor(XMPPConnection connection) {
DeliveryReceiptManager receiptManager = instances.get(connection);
if (receiptManager == null) {
receiptManager = new DeliveryReceiptManager(connection);
instances.put(connection, receiptManager);
}
return receiptManager;
}
/**
* Returns true if Delivery Receipts are supported by a given JID
*
* @param jid
* @return true if supported
* @throws SmackException if there was no response from the server.
* @throws XMPPException
*/
public boolean isSupported(String jid) throws SmackException, XMPPException {
return ServiceDiscoveryManager.getInstanceFor(connection()).supportsFeature(jid,
DeliveryReceipt.NAMESPACE);
}
/**
* Configure whether the {@link DeliveryReceiptManager} should automatically
* reply to incoming {@link DeliveryReceipt}s. By default, this feature is off.
*
* @param new_state whether automatic transmission of
* DeliveryReceipts should be enabled or disabled
*/
public void setAutoReceiptsEnabled(boolean new_state) {
auto_receipts_enabled = new_state;
}
/**
* Helper method to enable automatic DeliveryReceipt transmission.
*/
public void enableAutoReceipts() {
setAutoReceiptsEnabled(true);
}
/**
* Helper method to disable automatic DeliveryReceipt transmission.
*/
public void disableAutoReceipts() {
setAutoReceiptsEnabled(false);
}
/**
* Check if AutoReceipts are enabled on this connection.
*/
public boolean getAutoReceiptsEnabled() {
return this.auto_receipts_enabled;
}
/**
* Get informed about incoming delivery receipts with a {@link ReceiptReceivedListener}.
*
* @param listener the listener to be informed about new receipts
*/
public void addReceiptReceivedListener(ReceiptReceivedListener listener) {
receiptReceivedListeners.add(listener);
}
/**
* Stop getting informed about incoming delivery receipts.
*
* @param listener the listener to be removed
*/
public void removeReceiptReceivedListener(ReceiptReceivedListener listener) {
receiptReceivedListeners.remove(listener);
}
/**
* Test if a message requires a delivery receipt.
*
* @param message Packet object to check for a DeliveryReceiptRequest
*
* @return true if a delivery receipt was requested
*/
public static boolean hasDeliveryReceiptRequest(Message message) {
return (DeliveryReceiptRequest.from(message) != null);
}
/**
* Add a delivery receipt request to an outgoing packet.
*
* Only message packets may contain receipt requests as of XEP-0184,
* 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
* @deprecated use {@link DeliveryReceiptRequest#addTo(Message)}
*/
@Deprecated
public static String addDeliveryReceiptRequest(Message m) {
return DeliveryReceiptRequest.addTo(m);
}
}