Sync MAM API with PubSub API: One MamManager per MAM archive address

This commit is contained in:
Florian Schmaus 2017-02-24 19:33:11 +01:00
parent 00005d87be
commit 32fd52ea8e
1 changed files with 71 additions and 32 deletions

View File

@ -1,6 +1,6 @@
/**
*
* Copyright © 2016 Florian Schmaus and Fernando Ramirez
* Copyright © 2016-2017 Florian Schmaus, Fernando Ramirez
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -18,6 +18,7 @@ package org.jivesoftware.smackx.mam;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@ -47,6 +48,8 @@ import org.jivesoftware.smackx.mam.filter.MamResultFilter;
import org.jivesoftware.smackx.rsm.packet.RSMSet;
import org.jivesoftware.smackx.xdata.FormField;
import org.jivesoftware.smackx.xdata.packet.DataForm;
import org.jxmpp.jid.EntityBareJid;
import org.jxmpp.jid.EntityFullJid;
import org.jxmpp.jid.Jid;
import org.jxmpp.util.XmppDateTime;
@ -70,7 +73,7 @@ public final class MamManager extends Manager {
});
}
private static final Map<XMPPConnection, MamManager> INSTANCES = new WeakHashMap<>();
private static final Map<XMPPConnection, Map<Jid, MamManager>> INSTANCES = new WeakHashMap<>();
/**
* Get the singleton instance of MamManager.
@ -78,19 +81,29 @@ public final class MamManager extends Manager {
* @param connection
* @return the instance of MamManager
*/
public static synchronized MamManager getInstanceFor(XMPPConnection connection) {
MamManager mamManager = INSTANCES.get(connection);
public static MamManager getInstanceFor(XMPPConnection connection) {
return getInstanceFor(connection, null);
}
if (mamManager == null) {
mamManager = new MamManager(connection);
INSTANCES.put(connection, mamManager);
public static synchronized MamManager getInstanceFor(XMPPConnection connection, Jid archiveAddress) {
Map<Jid, MamManager> managers = INSTANCES.get(connection);
if (managers == null) {
managers = new HashMap<>();
INSTANCES.put(connection, managers);
}
MamManager mamManager = managers.get(archiveAddress);
if (mamManager == null) {
mamManager = new MamManager(connection, archiveAddress);
managers.put(archiveAddress, mamManager);
}
return mamManager;
}
private MamManager(XMPPConnection connection) {
private final Jid archiveAddress;
private MamManager(XMPPConnection connection, Jid archiveAddress) {
super(connection);
this.archiveAddress = archiveAddress;
}
/**
@ -106,7 +119,7 @@ public final class MamManager extends Manager {
*/
public MamQueryResult queryArchive(Integer max) throws NoResponseException, XMPPErrorException,
NotConnectedException, InterruptedException, NotLoggedInException {
return queryArchive(null, null, max, null, null, null, null);
return queryArchive(null, max, null, null, null, null);
}
/**
@ -122,7 +135,7 @@ public final class MamManager extends Manager {
*/
public MamQueryResult queryArchive(Jid withJid) throws NoResponseException, XMPPErrorException,
NotConnectedException, InterruptedException, NotLoggedInException {
return queryArchive(null, null, null, null, null, withJid, null);
return queryArchive(null, null, null, null, withJid, null);
}
/**
@ -142,7 +155,7 @@ public final class MamManager extends Manager {
*/
public MamQueryResult queryArchive(Date start, Date end) throws NoResponseException, XMPPErrorException,
NotConnectedException, InterruptedException, NotLoggedInException {
return queryArchive(null, null, null, start, end, null, null);
return queryArchive(null, null, start, end, null, null);
}
/**
@ -158,7 +171,7 @@ public final class MamManager extends Manager {
*/
public MamQueryResult queryArchive(List<FormField> additionalFields) throws NoResponseException, XMPPErrorException,
NotConnectedException, InterruptedException, NotLoggedInException {
return queryArchive(null, null, null, null, null, null, additionalFields);
return queryArchive(null, null, null, null, null, additionalFields);
}
/**
@ -175,7 +188,7 @@ public final class MamManager extends Manager {
*/
public MamQueryResult queryArchiveWithStartDate(Date start) throws NoResponseException, XMPPErrorException,
NotConnectedException, InterruptedException, NotLoggedInException {
return queryArchive(null, null, null, start, null, null, null);
return queryArchive(null, null, start, null, null, null);
}
/**
@ -192,7 +205,7 @@ public final class MamManager extends Manager {
*/
public MamQueryResult queryArchiveWithEndDate(Date end) throws NoResponseException, XMPPErrorException,
NotConnectedException, InterruptedException, NotLoggedInException {
return queryArchive(null, null, null, null, end, null, null);
return queryArchive(null, null, null, end, null, null);
}
@ -215,7 +228,7 @@ public final class MamManager extends Manager {
public MamQueryResult queryArchive(Integer max, Date start, Date end, Jid withJid, List<FormField> additionalFields)
throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException,
NotLoggedInException {
return queryArchive(null, null, max, start, end, withJid, additionalFields);
return queryArchive(null, max, start, end, withJid, additionalFields);
}
@ -224,7 +237,6 @@ public final class MamManager extends Manager {
* filters: max count, start date, end date, from/to JID and with additional fields. When archiveAddress is null the
* default, the server will be requested.
*
* @param archiveAddress can be null
* @param node The Pubsub node name, can be null
* @param max
* @param start
@ -238,7 +250,7 @@ public final class MamManager extends Manager {
* @throws InterruptedException
* @throws NotLoggedInException
*/
public MamQueryResult queryArchive(Jid archiveAddress, String node, Integer max, Date start, Date end, Jid withJid,
public MamQueryResult queryArchive(String node, Integer max, Date start, Date end, Jid withJid,
List<FormField> additionalFields)
throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException,
NotLoggedInException {
@ -321,14 +333,13 @@ public final class MamManager extends Manager {
public MamQueryResult page(DataForm dataForm, RSMSet rsmSet) throws NoResponseException, XMPPErrorException,
NotConnectedException, InterruptedException, NotLoggedInException {
return page(null, null, dataForm, rsmSet);
return page(null, dataForm, rsmSet);
}
/**
* Returns a page of the archive.
*
* @param archiveAddress can be null
* @param node The Pubsub node name, can be null
* @param dataForm
* @param rsmSet
@ -339,7 +350,7 @@ public final class MamManager extends Manager {
* @throws InterruptedException
* @throws NotLoggedInException
*/
public MamQueryResult page(Jid archiveAddress, String node, DataForm dataForm, RSMSet rsmSet)
public MamQueryResult page(String node, DataForm dataForm, RSMSet rsmSet)
throws NoResponseException, XMPPErrorException,
NotConnectedException, InterruptedException, NotLoggedInException {
MamQueryIQ mamQueryIQ = new MamQueryIQ(UUID.randomUUID().toString(), node, dataForm);
@ -367,7 +378,7 @@ public final class MamManager extends Manager {
XMPPErrorException, NotConnectedException, InterruptedException, NotLoggedInException {
RSMSet previousResultRsmSet = mamQueryResult.mamFin.getRSMSet();
RSMSet requestRsmSet = new RSMSet(count, previousResultRsmSet.getLast(), RSMSet.PageDirection.after);
return page(mamQueryResult.to, mamQueryResult.node, mamQueryResult.form, requestRsmSet);
return page(mamQueryResult, requestRsmSet);
}
/**
@ -388,7 +399,14 @@ public final class MamManager extends Manager {
XMPPErrorException, NotConnectedException, InterruptedException, NotLoggedInException {
RSMSet previousResultRsmSet = mamQueryResult.mamFin.getRSMSet();
RSMSet requestRsmSet = new RSMSet(count, previousResultRsmSet.getFirst(), RSMSet.PageDirection.before);
return page(mamQueryResult.to, mamQueryResult.node, mamQueryResult.form, requestRsmSet);
return page(mamQueryResult, requestRsmSet);
}
private MamQueryResult page(MamQueryResult mamQueryResult, RSMSet requestRsmSet) throws NoResponseException,
XMPPErrorException, NotConnectedException, NotLoggedInException, InterruptedException {
ensureMamQueryResultMatchesThisManager(mamQueryResult);
return page(mamQueryResult.node, mamQueryResult.form, requestRsmSet);
}
/**
@ -409,7 +427,7 @@ public final class MamManager extends Manager {
RSMSet rsmSet = new RSMSet(null, firstMessageId, -1, -1, null, max, null, -1);
DataForm dataForm = getNewMamForm();
addWithJid(chatJid, dataForm);
return page(null, null, dataForm, rsmSet);
return page(null, dataForm, rsmSet);
}
/**
@ -430,7 +448,7 @@ public final class MamManager extends Manager {
RSMSet rsmSet = new RSMSet(lastMessageId, null, -1, -1, null, max, null, -1);
DataForm dataForm = getNewMamForm();
addWithJid(chatJid, dataForm);
return page(null, null, dataForm, rsmSet);
return page(null, dataForm, rsmSet);
}
/**
@ -462,13 +480,12 @@ public final class MamManager extends Manager {
*/
public List<FormField> retrieveFormFields() throws NoResponseException, XMPPErrorException, NotConnectedException,
InterruptedException, NotLoggedInException {
return retrieveFormFields(null, null);
return retrieveFormFields(null);
}
/**
* Get the form fields supported by the server.
*
* @param archiveAddress can be null
* @param node The Pubsub node name, can be null
* @return the list of form fields.
* @throws NoResponseException
@ -477,7 +494,7 @@ public final class MamManager extends Manager {
* @throws InterruptedException
* @throws NotLoggedInException
*/
public List<FormField> retrieveFormFields(Jid archiveAddress, String node)
public List<FormField> retrieveFormFields(String node)
throws NoResponseException, XMPPErrorException, NotConnectedException,
InterruptedException, NotLoggedInException {
String queryId = UUID.randomUUID().toString();
@ -516,7 +533,7 @@ public final class MamManager extends Manager {
forwardedMessages.add(mamResultExtension.getForwarded());
}
return new MamQueryResult(forwardedMessages, mamFinIQ, mamQueryIq.getTo(), mamQueryIq.getNode(), DataForm.from(mamQueryIq));
return new MamQueryResult(forwardedMessages, mamFinIQ, mamQueryIq.getNode(), DataForm.from(mamQueryIq));
}
/**
@ -526,19 +543,41 @@ public final class MamManager extends Manager {
public final static class MamQueryResult {
public final List<Forwarded> forwardedMessages;
public final MamFinIQ mamFin;
private final Jid to;
private final String node;
private final DataForm form;
private MamQueryResult(List<Forwarded> forwardedMessages, MamFinIQ mamFin, Jid to, String node, DataForm form) {
private MamQueryResult(List<Forwarded> forwardedMessages, MamFinIQ mamFin, String node, DataForm form) {
this.forwardedMessages = forwardedMessages;
this.mamFin = mamFin;
this.to = to;
this.node = node;
this.form = form;
}
}
private void ensureMamQueryResultMatchesThisManager(MamQueryResult mamQueryResult) {
EntityFullJid localAddress = connection().getUser();
EntityBareJid localBareAddress = null;
if (localAddress != null) {
localBareAddress = localAddress.asEntityBareJid();
}
boolean isLocalUserArchive = archiveAddress == null || archiveAddress.equals(localBareAddress);
Jid finIqFrom = mamQueryResult.mamFin.getFrom();
if (finIqFrom != null) {
if (finIqFrom.equals(archiveAddress) || (isLocalUserArchive && finIqFrom.equals(localBareAddress))) {
return;
}
throw new IllegalArgumentException("The given MamQueryResult is from the MAM archive '" + finIqFrom
+ "' whereas this MamManager is responsible for '" + archiveAddress + '\'');
}
else if (!isLocalUserArchive) {
throw new IllegalArgumentException(
"The given MamQueryResult is from the local entity (user) MAM archive, whereas this MamManager is responsible for '"
+ archiveAddress + '\'');
}
}
/**
* Returns true if Message Archive Management is supported by the server.
*