From 32fd52ea8e69b3f71ed81cdacd267a9d739b7f68 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Fri, 24 Feb 2017 19:33:11 +0100 Subject: [PATCH] Sync MAM API with PubSub API: One MamManager per MAM archive address --- .../jivesoftware/smackx/mam/MamManager.java | 103 ++++++++++++------ 1 file changed, 71 insertions(+), 32 deletions(-) diff --git a/smack-experimental/src/main/java/org/jivesoftware/smackx/mam/MamManager.java b/smack-experimental/src/main/java/org/jivesoftware/smackx/mam/MamManager.java index ea2e96831..07a45977b 100644 --- a/smack-experimental/src/main/java/org/jivesoftware/smackx/mam/MamManager.java +++ b/smack-experimental/src/main/java/org/jivesoftware/smackx/mam/MamManager.java @@ -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 INSTANCES = new WeakHashMap<>(); + private static final Map> 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 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 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 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 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 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 retrieveFormFields(Jid archiveAddress, String node) + public List 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 forwardedMessages; public final MamFinIQ mamFin; - private final Jid to; private final String node; private final DataForm form; - private MamQueryResult(List forwardedMessages, MamFinIQ mamFin, Jid to, String node, DataForm form) { + private MamQueryResult(List 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. *