mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-26 00:02:06 +01:00
Implement Message Archive Management (MAM) XEP-0313
Fixes SMACK-625
This commit is contained in:
parent
b91978dcc4
commit
189cac072b
29 changed files with 2637 additions and 0 deletions
|
@ -85,6 +85,7 @@ Experimental Smack Extensions and currently supported XEPs of smack-experimental
|
|||
| [Internet of Things - Discovery](iot.md) | [XEP-0347](http://xmpp.org/extensions/xep-0347.html) | Describes how Things can be installed and discovered by their owners. |
|
||||
| Google GCM JSON payload | n/a | Semantically the same as XEP-0335: JSON Containers |
|
||||
| Client State Indication | [XEP-0352](http://xmpp.org/extensions/xep-0352.html) | A way for the client to indicate its active/inactive state. |
|
||||
| Message Archive Management | [XEP-0313](http://xmpp.org/extensions/xep-0313.html) | Query and control an archive of messages stored on a server. |
|
||||
|
||||
|
||||
Legacy Smack Extensions and currently supported XEPs of smack-legacy
|
||||
|
|
|
@ -0,0 +1,561 @@
|
|||
/**
|
||||
*
|
||||
* Copyright © 2016 Florian Schmaus and Fernando Ramirez
|
||||
*
|
||||
* 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.mam;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import org.jivesoftware.smack.ConnectionCreationListener;
|
||||
import org.jivesoftware.smack.Manager;
|
||||
import org.jivesoftware.smack.PacketCollector;
|
||||
import org.jivesoftware.smack.SmackException.NoResponseException;
|
||||
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
||||
import org.jivesoftware.smack.SmackException.NotLoggedInException;
|
||||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smack.XMPPConnectionRegistry;
|
||||
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
|
||||
import org.jivesoftware.smack.filter.IQReplyFilter;
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.IQ.Type;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
|
||||
import org.jivesoftware.smackx.forward.packet.Forwarded;
|
||||
import org.jivesoftware.smackx.mam.element.MamElements;
|
||||
import org.jivesoftware.smackx.mam.element.MamFinIQ;
|
||||
import org.jivesoftware.smackx.mam.element.MamPrefsIQ;
|
||||
import org.jivesoftware.smackx.mam.element.MamQueryIQ;
|
||||
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.Jid;
|
||||
import org.jxmpp.util.XmppDateTime;
|
||||
|
||||
/**
|
||||
* Message Archive Management Manager class.
|
||||
*
|
||||
* @see <a href="http://xmpp.org/extensions/xep-0313.html">XEP-0313: Message
|
||||
* Archive Management</a>
|
||||
* @author Fernando Ramirez and Florian Schmaus
|
||||
*
|
||||
*/
|
||||
public final class MamManager extends Manager {
|
||||
|
||||
static {
|
||||
XMPPConnectionRegistry.addConnectionCreationListener(new ConnectionCreationListener() {
|
||||
@Override
|
||||
public void connectionCreated(XMPPConnection connection) {
|
||||
getInstanceFor(connection);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static final Map<XMPPConnection, MamManager> INSTANCES = new WeakHashMap<>();
|
||||
|
||||
/**
|
||||
* Get the singleton instance of MamManager.
|
||||
*
|
||||
* @param connection
|
||||
* @return the instance of MamManager
|
||||
*/
|
||||
public static synchronized MamManager getInstanceFor(XMPPConnection connection) {
|
||||
MamManager mamManager = INSTANCES.get(connection);
|
||||
|
||||
if (mamManager == null) {
|
||||
mamManager = new MamManager(connection);
|
||||
INSTANCES.put(connection, mamManager);
|
||||
}
|
||||
|
||||
return mamManager;
|
||||
}
|
||||
|
||||
private MamManager(XMPPConnection connection) {
|
||||
super(connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query archive with a maximum amount of results.
|
||||
*
|
||||
* @param max
|
||||
* @return the MAM query result
|
||||
* @throws NoResponseException
|
||||
* @throws XMPPErrorException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
* @throws NotLoggedInException
|
||||
*/
|
||||
public MamQueryResult queryArchive(Integer max) throws NoResponseException, XMPPErrorException,
|
||||
NotConnectedException, InterruptedException, NotLoggedInException {
|
||||
return queryArchive(max, null, null, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query archive with a JID (only messages from/to the JID).
|
||||
*
|
||||
* @param withJid
|
||||
* @return the MAM query result
|
||||
* @throws NoResponseException
|
||||
* @throws XMPPErrorException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
* @throws NotLoggedInException
|
||||
*/
|
||||
public MamQueryResult queryArchive(Jid withJid) throws NoResponseException, XMPPErrorException,
|
||||
NotConnectedException, InterruptedException, NotLoggedInException {
|
||||
return queryArchive(null, null, null, withJid, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query archive filtering by start and/or end date. If start == null, the
|
||||
* value of 'start' will be equal to the date/time of the earliest message
|
||||
* stored in the archive. If end == null, the value of 'end' will be equal
|
||||
* to the date/time of the most recent message stored in the archive.
|
||||
*
|
||||
* @param start
|
||||
* @param end
|
||||
* @return the MAM query result
|
||||
* @throws NoResponseException
|
||||
* @throws XMPPErrorException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
* @throws NotLoggedInException
|
||||
*/
|
||||
public MamQueryResult queryArchive(Date start, Date end) throws NoResponseException, XMPPErrorException,
|
||||
NotConnectedException, InterruptedException, NotLoggedInException {
|
||||
return queryArchive(null, start, end, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query Archive adding filters with additional fields.
|
||||
*
|
||||
* @param additionalFields
|
||||
* @return the MAM query result
|
||||
* @throws NoResponseException
|
||||
* @throws XMPPErrorException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
* @throws NotLoggedInException
|
||||
*/
|
||||
public MamQueryResult queryArchive(List<FormField> additionalFields) throws NoResponseException, XMPPErrorException,
|
||||
NotConnectedException, InterruptedException, NotLoggedInException {
|
||||
return queryArchive(null, null, null, null, additionalFields);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query archive filtering by start date. The value of 'end' will be equal
|
||||
* to the date/time of the most recent message stored in the archive.
|
||||
*
|
||||
* @param start
|
||||
* @return the MAM query result
|
||||
* @throws NoResponseException
|
||||
* @throws XMPPErrorException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
* @throws NotLoggedInException
|
||||
*/
|
||||
public MamQueryResult queryArchiveWithStartDate(Date start) throws NoResponseException, XMPPErrorException,
|
||||
NotConnectedException, InterruptedException, NotLoggedInException {
|
||||
return queryArchive(null, start, null, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query archive filtering by end date. The value of 'start' will be equal
|
||||
* to the date/time of the earliest message stored in the archive.
|
||||
*
|
||||
* @param end
|
||||
* @return the MAM query result
|
||||
* @throws NoResponseException
|
||||
* @throws XMPPErrorException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
* @throws NotLoggedInException
|
||||
*/
|
||||
public MamQueryResult queryArchiveWithEndDate(Date end) throws NoResponseException, XMPPErrorException,
|
||||
NotConnectedException, InterruptedException, NotLoggedInException {
|
||||
return queryArchive(null, null, end, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Query archive applying filters: max count, start date, end date, from/to
|
||||
* JID and with additional fields.
|
||||
*
|
||||
* @param max
|
||||
* @param start
|
||||
* @param end
|
||||
* @param withJid
|
||||
* @param additionalFields
|
||||
* @return the MAM query result
|
||||
* @throws NoResponseException
|
||||
* @throws XMPPErrorException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
* @throws NotLoggedInException
|
||||
*/
|
||||
public MamQueryResult queryArchive(Integer max, Date start, Date end, Jid withJid, List<FormField> additionalFields)
|
||||
throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException,
|
||||
NotLoggedInException {
|
||||
DataForm dataForm = null;
|
||||
String queryId = UUID.randomUUID().toString();
|
||||
|
||||
if (start != null || end != null || withJid != null || additionalFields != null) {
|
||||
dataForm = getNewMamForm();
|
||||
addStart(start, dataForm);
|
||||
addEnd(end, dataForm);
|
||||
addWithJid(withJid, dataForm);
|
||||
addAdditionalFields(additionalFields, dataForm);
|
||||
}
|
||||
|
||||
MamQueryIQ mamQueryIQ = prepareMamQueryIQSet(dataForm, queryId);
|
||||
addResultsLimit(max, mamQueryIQ);
|
||||
return queryArchive(mamQueryIQ);
|
||||
}
|
||||
|
||||
private static void addAdditionalFields(List<FormField> additionalFields, DataForm dataForm) {
|
||||
if (additionalFields == null) {
|
||||
return;
|
||||
}
|
||||
for (FormField formField : additionalFields) {
|
||||
dataForm.addField(formField);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addResultsLimit(Integer max, MamQueryIQ mamQueryIQ) {
|
||||
if (max == null) {
|
||||
return;
|
||||
}
|
||||
RSMSet rsmSet = new RSMSet(max);
|
||||
mamQueryIQ.addExtension(rsmSet);
|
||||
|
||||
}
|
||||
|
||||
private static void addWithJid(Jid withJid, DataForm dataForm) {
|
||||
if (withJid == null) {
|
||||
return;
|
||||
}
|
||||
FormField formField = new FormField("with");
|
||||
formField.addValue(withJid.toString());
|
||||
dataForm.addField(formField);
|
||||
}
|
||||
|
||||
private static void addEnd(Date end, DataForm dataForm) {
|
||||
if (end == null) {
|
||||
return;
|
||||
}
|
||||
FormField formField = new FormField("end");
|
||||
formField.addValue(XmppDateTime.formatXEP0082Date(end));
|
||||
dataForm.addField(formField);
|
||||
}
|
||||
|
||||
private static void addStart(Date start, DataForm dataForm) {
|
||||
if (start == null) {
|
||||
return;
|
||||
}
|
||||
FormField formField = new FormField("start");
|
||||
formField.addValue(XmppDateTime.formatXEP0082Date(start));
|
||||
dataForm.addField(formField);
|
||||
}
|
||||
|
||||
private void preparePageQuery(MamQueryIQ mamQueryIQ, RSMSet rsmSet) {
|
||||
mamQueryIQ.setType(IQ.Type.set);
|
||||
mamQueryIQ.addExtension(rsmSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a page of the archive.
|
||||
*
|
||||
* @param dataForm
|
||||
* @param rsmSet
|
||||
* @return the MAM query result
|
||||
* @throws NoResponseException
|
||||
* @throws XMPPErrorException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
* @throws NotLoggedInException
|
||||
*/
|
||||
public MamQueryResult page(DataForm dataForm, RSMSet rsmSet) throws NoResponseException, XMPPErrorException,
|
||||
NotConnectedException, InterruptedException, NotLoggedInException {
|
||||
MamQueryIQ mamQueryIQ = new MamQueryIQ(UUID.randomUUID().toString(), dataForm);
|
||||
preparePageQuery(mamQueryIQ, rsmSet);
|
||||
return queryArchive(mamQueryIQ);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next page of the archive.
|
||||
*
|
||||
* @param mamQueryResult
|
||||
* is the previous query result
|
||||
* @param count
|
||||
* is the amount of messages that a page contains
|
||||
* @return the MAM query result
|
||||
* @throws NoResponseException
|
||||
* @throws XMPPErrorException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
* @throws NotLoggedInException
|
||||
*/
|
||||
public MamQueryResult pageNext(MamQueryResult mamQueryResult, int count) throws NoResponseException,
|
||||
XMPPErrorException, NotConnectedException, InterruptedException, NotLoggedInException {
|
||||
RSMSet previousResultRsmSet = mamQueryResult.mamFin.getRSMSet();
|
||||
RSMSet requestRsmSet = new RSMSet(count, previousResultRsmSet.getLast(), RSMSet.PageDirection.after);
|
||||
return page(mamQueryResult.form, requestRsmSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain page before the first message saved (specific chat).
|
||||
*
|
||||
* @param chatJid
|
||||
* @param firstMessageId
|
||||
* @param max
|
||||
* @return the MAM query result
|
||||
* @throws XMPPErrorException
|
||||
* @throws NotLoggedInException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
* @throws NoResponseException
|
||||
*/
|
||||
public MamQueryResult pageBefore(Jid chatJid, String firstMessageId, int max) throws XMPPErrorException,
|
||||
NotLoggedInException, NotConnectedException, InterruptedException, NoResponseException {
|
||||
RSMSet rsmSet = new RSMSet(null, firstMessageId, -1, -1, null, max, null, -1);
|
||||
DataForm dataForm = getNewMamForm();
|
||||
addWithJid(chatJid, dataForm);
|
||||
return page(dataForm, rsmSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain page after the last message saved (specific chat).
|
||||
*
|
||||
* @param chatJid
|
||||
* @param lastMessageId
|
||||
* @param max
|
||||
* @return the MAM query result
|
||||
* @throws XMPPErrorException
|
||||
* @throws NotLoggedInException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
* @throws NoResponseException
|
||||
*/
|
||||
public MamQueryResult pageAfter(Jid chatJid, String lastMessageId, int max) throws XMPPErrorException,
|
||||
NotLoggedInException, NotConnectedException, InterruptedException, NoResponseException {
|
||||
RSMSet rsmSet = new RSMSet(lastMessageId, null, -1, -1, null, max, null, -1);
|
||||
DataForm dataForm = getNewMamForm();
|
||||
addWithJid(chatJid, dataForm);
|
||||
return page(dataForm, rsmSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the form fields supported by the server.
|
||||
*
|
||||
* @return the list of form fields.
|
||||
* @throws NoResponseException
|
||||
* @throws XMPPErrorException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
* @throws NotLoggedInException
|
||||
*/
|
||||
public List<FormField> retrieveFormFields() throws NoResponseException, XMPPErrorException, NotConnectedException,
|
||||
InterruptedException, NotLoggedInException {
|
||||
String queryId = UUID.randomUUID().toString();
|
||||
MamQueryIQ mamQueryIQ = prepareMamQueryIQGet(queryId);
|
||||
return queryFormFields(mamQueryIQ);
|
||||
}
|
||||
|
||||
private MamQueryIQ prepareMamQueryIQSet(DataForm dataForm, String queryId) {
|
||||
MamQueryIQ mamQueryIQ = new MamQueryIQ(queryId, dataForm);
|
||||
mamQueryIQ.setType(IQ.Type.set);
|
||||
return mamQueryIQ;
|
||||
}
|
||||
|
||||
private MamQueryIQ prepareMamQueryIQGet(String queryId) {
|
||||
MamQueryIQ mamQueryIQ = new MamQueryIQ(queryId, null);
|
||||
mamQueryIQ.setType(IQ.Type.get);
|
||||
return mamQueryIQ;
|
||||
}
|
||||
|
||||
private MamQueryResult queryArchive(MamQueryIQ mamQueryIq) throws NoResponseException, XMPPErrorException,
|
||||
NotConnectedException, InterruptedException, NotLoggedInException {
|
||||
final XMPPConnection connection = getAuthenticatedConnectionOrThrow();
|
||||
MamFinIQ mamFinIQ = null;
|
||||
|
||||
PacketCollector mamFinIQCollector = connection.createPacketCollector(new IQReplyFilter(mamQueryIq, connection));
|
||||
|
||||
PacketCollector.Configuration resultCollectorConfiguration = PacketCollector.newConfiguration()
|
||||
.setStanzaFilter(new MamResultFilter(mamQueryIq)).setCollectorToReset(mamFinIQCollector);
|
||||
PacketCollector resultCollector = connection.createPacketCollector(resultCollectorConfiguration);
|
||||
|
||||
try {
|
||||
connection.sendStanza(mamQueryIq);
|
||||
mamFinIQ = mamFinIQCollector.nextResultOrThrow();
|
||||
} finally {
|
||||
mamFinIQCollector.cancel();
|
||||
resultCollector.cancel();
|
||||
}
|
||||
|
||||
List<Forwarded> forwardedMessages = new ArrayList<>(resultCollector.getCollectedCount());
|
||||
|
||||
for (Message resultMessage = resultCollector
|
||||
.pollResult(); resultMessage != null; resultMessage = resultCollector.pollResult()) {
|
||||
MamElements.MamResultExtension mamResultExtension = MamElements.MamResultExtension.from(resultMessage);
|
||||
forwardedMessages.add(mamResultExtension.getForwarded());
|
||||
}
|
||||
|
||||
return new MamQueryResult(forwardedMessages, mamFinIQ, DataForm.from(mamQueryIq));
|
||||
}
|
||||
|
||||
/**
|
||||
* MAM query result class.
|
||||
*
|
||||
*/
|
||||
public final static class MamQueryResult {
|
||||
public final List<Forwarded> forwardedMessages;
|
||||
public final MamFinIQ mamFin;
|
||||
private final DataForm form;
|
||||
|
||||
private MamQueryResult(List<Forwarded> forwardedMessages, MamFinIQ mamFin, DataForm form) {
|
||||
this.forwardedMessages = forwardedMessages;
|
||||
this.mamFin = mamFin;
|
||||
this.form = form;
|
||||
}
|
||||
}
|
||||
|
||||
private List<FormField> queryFormFields(MamQueryIQ mamQueryIq) throws NoResponseException, XMPPErrorException,
|
||||
NotConnectedException, InterruptedException, NotLoggedInException {
|
||||
final XMPPConnection connection = connection();
|
||||
MamQueryIQ mamResponseQueryIQ = null;
|
||||
PacketCollector mamResponseQueryIQCollector = connection
|
||||
.createPacketCollector(new IQReplyFilter(mamQueryIq, connection));
|
||||
|
||||
try {
|
||||
connection.sendStanza(mamQueryIq);
|
||||
mamResponseQueryIQ = mamResponseQueryIQCollector.nextResultOrThrow();
|
||||
} finally {
|
||||
mamResponseQueryIQCollector.cancel();
|
||||
}
|
||||
|
||||
return mamResponseQueryIQ.getDataForm().getFields();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if Message Archive Management is supported by the server.
|
||||
*
|
||||
* @return true if Message Archive Management is supported by the server.
|
||||
* @throws NotConnectedException
|
||||
* @throws XMPPErrorException
|
||||
* @throws NoResponseException
|
||||
* @throws InterruptedException
|
||||
*/
|
||||
public boolean isSupportedByServer()
|
||||
throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
|
||||
return ServiceDiscoveryManager.getInstanceFor(connection()).serverSupportsFeature(MamElements.NAMESPACE);
|
||||
}
|
||||
|
||||
private DataForm getNewMamForm() {
|
||||
FormField field = new FormField(FormField.FORM_TYPE);
|
||||
field.setType(FormField.Type.hidden);
|
||||
field.addValue(MamElements.NAMESPACE);
|
||||
DataForm form = new DataForm(DataForm.Type.submit);
|
||||
form.addField(field);
|
||||
return form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the preferences stored in the server.
|
||||
*
|
||||
* @return the MAM preferences result
|
||||
* @throws NoResponseException
|
||||
* @throws XMPPErrorException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
* @throws NotLoggedInException
|
||||
*/
|
||||
public MamPrefsResult retrieveArchivingPreferences() throws NoResponseException, XMPPErrorException,
|
||||
NotConnectedException, InterruptedException, NotLoggedInException {
|
||||
MamPrefsIQ mamPrefIQ = prepareRetrievePreferencesStanza();
|
||||
return queryMamPrefs(mamPrefIQ);
|
||||
}
|
||||
|
||||
private MamPrefsIQ prepareRetrievePreferencesStanza() {
|
||||
MamPrefsIQ mamPrefIQ = new MamPrefsIQ(Type.get, null, null, null);
|
||||
return mamPrefIQ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the preferences in the server.
|
||||
*
|
||||
* @param alwaysJids
|
||||
* is the list of JIDs that should always have messages to/from
|
||||
* archived in the user's store
|
||||
* @param neverJids
|
||||
* is the list of JIDs that should never have messages to/from
|
||||
* archived in the user's store
|
||||
* @param defaultField
|
||||
* can be "roster", "always", "never" (look at the XEP-0313
|
||||
* documentation)
|
||||
* @return the MAM preferences result
|
||||
* @throws NoResponseException
|
||||
* @throws XMPPErrorException
|
||||
* @throws NotConnectedException
|
||||
* @throws InterruptedException
|
||||
* @throws NotLoggedInException
|
||||
*/
|
||||
public MamPrefsResult updateArchivingPreferences(List<Jid> alwaysJids, List<Jid> neverJids, String defaultField)
|
||||
throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException,
|
||||
NotLoggedInException {
|
||||
MamPrefsIQ mamPrefIQ = prepareUpdatePreferencesStanza(alwaysJids, neverJids, defaultField);
|
||||
return queryMamPrefs(mamPrefIQ);
|
||||
}
|
||||
|
||||
private MamPrefsIQ prepareUpdatePreferencesStanza(List<Jid> alwaysJids, List<Jid> neverJids, String defaultField) {
|
||||
MamPrefsIQ mamPrefIQ = new MamPrefsIQ(Type.set, alwaysJids, neverJids, defaultField);
|
||||
return mamPrefIQ;
|
||||
}
|
||||
|
||||
/**
|
||||
* MAM preferences result class.
|
||||
*
|
||||
*/
|
||||
public final static class MamPrefsResult {
|
||||
public final MamPrefsIQ mamPrefs;
|
||||
public final DataForm form;
|
||||
|
||||
private MamPrefsResult(MamPrefsIQ mamPrefs, DataForm form) {
|
||||
this.mamPrefs = mamPrefs;
|
||||
this.form = form;
|
||||
}
|
||||
}
|
||||
|
||||
private MamPrefsResult queryMamPrefs(MamPrefsIQ mamPrefsIQ) throws NoResponseException, XMPPErrorException,
|
||||
NotConnectedException, InterruptedException, NotLoggedInException {
|
||||
final XMPPConnection connection = getAuthenticatedConnectionOrThrow();
|
||||
MamPrefsIQ mamPrefsResultIQ = null;
|
||||
PacketCollector prefsResultIQCollector = connection
|
||||
.createPacketCollector(new IQReplyFilter(mamPrefsIQ, connection));
|
||||
|
||||
try {
|
||||
connection.sendStanza(mamPrefsIQ);
|
||||
mamPrefsResultIQ = prefsResultIQCollector.nextResultOrThrow();
|
||||
} finally {
|
||||
prefsResultIQCollector.cancel();
|
||||
}
|
||||
|
||||
return new MamPrefsResult(mamPrefsResultIQ, DataForm.from(mamPrefsIQ));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,215 @@
|
|||
/**
|
||||
*
|
||||
* Copyright © 2016 Florian Schmaus and Fernando Ramirez
|
||||
*
|
||||
* 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.mam.element;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jivesoftware.smack.packet.Element;
|
||||
import org.jivesoftware.smack.packet.ExtensionElement;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.util.StringUtils;
|
||||
import org.jivesoftware.smack.util.XmlStringBuilder;
|
||||
import org.jivesoftware.smackx.forward.packet.Forwarded;
|
||||
import org.jxmpp.jid.Jid;
|
||||
|
||||
/**
|
||||
* MAM elements.
|
||||
*
|
||||
* @see <a href="http://xmpp.org/extensions/xep-0313.html">XEP-0313: Message
|
||||
* Archive Management</a>
|
||||
* @author Fernando Ramirez and Florian Schmaus
|
||||
*
|
||||
*/
|
||||
public class MamElements {
|
||||
|
||||
public static final String NAMESPACE = "urn:xmpp:mam:1";
|
||||
|
||||
/**
|
||||
* MAM result extension class.
|
||||
*
|
||||
* @see <a href="http://xmpp.org/extensions/xep-0313.html">XEP-0313: Message
|
||||
* Archive Management</a>
|
||||
*
|
||||
*/
|
||||
public static class MamResultExtension implements ExtensionElement {
|
||||
|
||||
/**
|
||||
* result element.
|
||||
*/
|
||||
public static final String ELEMENT = "result";
|
||||
|
||||
/**
|
||||
* id of the result.
|
||||
*/
|
||||
private final String id;
|
||||
|
||||
/**
|
||||
* the forwarded element.
|
||||
*/
|
||||
private final Forwarded forwarded;
|
||||
|
||||
/**
|
||||
* the query id.
|
||||
*/
|
||||
private String queryId;
|
||||
|
||||
/**
|
||||
* MAM result extension constructor.
|
||||
*
|
||||
* @param queryId
|
||||
* @param id
|
||||
* @param forwarded
|
||||
*/
|
||||
public MamResultExtension(String queryId, String id, Forwarded forwarded) {
|
||||
if (StringUtils.isEmpty(id)) {
|
||||
throw new IllegalArgumentException("id must not be null or empty");
|
||||
}
|
||||
if (forwarded == null) {
|
||||
throw new IllegalArgumentException("forwarded must no be null");
|
||||
}
|
||||
this.id = id;
|
||||
this.forwarded = forwarded;
|
||||
this.queryId = queryId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the id.
|
||||
*
|
||||
* @return the id
|
||||
*/
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the forwarded element.
|
||||
*
|
||||
* @return the forwarded element
|
||||
*/
|
||||
public Forwarded getForwarded() {
|
||||
return forwarded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get query id.
|
||||
*
|
||||
* @return the query id
|
||||
*/
|
||||
public final String getQueryId() {
|
||||
return queryId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getElementName() {
|
||||
return ELEMENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getNamespace() {
|
||||
return NAMESPACE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence toXML() {
|
||||
XmlStringBuilder xml = new XmlStringBuilder();
|
||||
xml.halfOpenElement(this);
|
||||
xml.xmlnsAttribute(NAMESPACE);
|
||||
xml.optAttribute("queryid", getQueryId());
|
||||
xml.optAttribute("id", getId());
|
||||
xml.rightAngleBracket();
|
||||
|
||||
xml.element(getForwarded());
|
||||
|
||||
xml.closeElement(this);
|
||||
return xml;
|
||||
}
|
||||
|
||||
public static MamResultExtension from(Message message) {
|
||||
return (MamResultExtension) message.getExtension(ELEMENT, NAMESPACE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Always JID list element class for the MamPrefsIQ.
|
||||
*
|
||||
*/
|
||||
public static class AlwaysJidListElement implements Element {
|
||||
|
||||
/**
|
||||
* list of JIDs.
|
||||
*/
|
||||
private List<Jid> alwaysJids;
|
||||
|
||||
/**
|
||||
* Always JID list element constructor.
|
||||
*
|
||||
* @param alwaysJids
|
||||
*/
|
||||
AlwaysJidListElement(List<Jid> alwaysJids) {
|
||||
this.alwaysJids = alwaysJids;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence toXML() {
|
||||
XmlStringBuilder xml = new XmlStringBuilder();
|
||||
xml.openElement("always");
|
||||
|
||||
for (Jid jid : alwaysJids) {
|
||||
xml.element("jid", jid);
|
||||
}
|
||||
|
||||
xml.closeElement("always");
|
||||
return xml;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Never JID list element class for the MamPrefsIQ.
|
||||
*
|
||||
*/
|
||||
public static class NeverJidListElement implements Element {
|
||||
|
||||
/**
|
||||
* list of JIDs
|
||||
*/
|
||||
private List<Jid> neverJids;
|
||||
|
||||
/**
|
||||
* Never JID list element constructor.
|
||||
*
|
||||
* @param neverJids
|
||||
*/
|
||||
public NeverJidListElement(List<Jid> neverJids) {
|
||||
this.neverJids = neverJids;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence toXML() {
|
||||
XmlStringBuilder xml = new XmlStringBuilder();
|
||||
xml.openElement("never");
|
||||
|
||||
for (Jid jid : neverJids) {
|
||||
xml.element("jid", jid);
|
||||
}
|
||||
|
||||
xml.closeElement("never");
|
||||
return xml;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
/**
|
||||
*
|
||||
* Copyright © 2016 Fernando Ramirez
|
||||
*
|
||||
* 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.mam.element;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smackx.rsm.packet.RSMSet;
|
||||
|
||||
/**
|
||||
* MAM fin IQ class.
|
||||
*
|
||||
* @see <a href="http://xmpp.org/extensions/xep-0313.html">XEP-0313: Message
|
||||
* Archive Management</a>
|
||||
* @author Fernando Ramirez
|
||||
*
|
||||
*/
|
||||
public class MamFinIQ extends IQ {
|
||||
|
||||
/**
|
||||
* fin element.
|
||||
*/
|
||||
public static final String ELEMENT = "fin";
|
||||
|
||||
/**
|
||||
* the IQ NAMESPACE.
|
||||
*/
|
||||
public static final String NAMESPACE = MamElements.NAMESPACE;
|
||||
|
||||
/**
|
||||
* RSM set.
|
||||
*/
|
||||
private final RSMSet rsmSet;
|
||||
|
||||
/**
|
||||
* if is complete.
|
||||
*/
|
||||
private final boolean complete;
|
||||
|
||||
/**
|
||||
* if is stable.
|
||||
*/
|
||||
private final boolean stable;
|
||||
|
||||
/**
|
||||
* the query id.
|
||||
*/
|
||||
private final String queryId;
|
||||
|
||||
/**
|
||||
* MamFinIQ constructor.
|
||||
*
|
||||
* @param queryId
|
||||
* @param rsmSet
|
||||
* @param complete
|
||||
* @param stable
|
||||
*/
|
||||
public MamFinIQ(String queryId, RSMSet rsmSet, boolean complete, boolean stable) {
|
||||
super(ELEMENT, NAMESPACE);
|
||||
if (rsmSet == null) {
|
||||
throw new IllegalArgumentException("rsmSet must not be null");
|
||||
}
|
||||
this.rsmSet = rsmSet;
|
||||
this.complete = complete;
|
||||
this.stable = stable;
|
||||
this.queryId = queryId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get RSM set.
|
||||
*
|
||||
* @return the RSM set
|
||||
*/
|
||||
public RSMSet getRSMSet() {
|
||||
return rsmSet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return if it is complete.
|
||||
*
|
||||
* @return true if it is complete
|
||||
*/
|
||||
public boolean isComplete() {
|
||||
return complete;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return if it is stable.
|
||||
*
|
||||
* @return true if it is stable
|
||||
*/
|
||||
public boolean isStable() {
|
||||
return stable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get query id.
|
||||
*
|
||||
* @return the query id
|
||||
*/
|
||||
public final String getQueryId() {
|
||||
return queryId;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) {
|
||||
xml.optAttribute("queryid", queryId);
|
||||
xml.optBooleanAttribute("complete", complete);
|
||||
xml.optBooleanAttribute("stable", stable);
|
||||
if (rsmSet == null) {
|
||||
xml.setEmptyElement();
|
||||
} else {
|
||||
xml.rightAngleBracket();
|
||||
xml.element(rsmSet);
|
||||
}
|
||||
return xml;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
/**
|
||||
*
|
||||
* Copyright © 2016 Florian Schmaus and Fernando Ramirez
|
||||
*
|
||||
* 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.mam.element;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smackx.mam.element.MamElements.AlwaysJidListElement;
|
||||
import org.jivesoftware.smackx.mam.element.MamElements.NeverJidListElement;
|
||||
import org.jxmpp.jid.Jid;
|
||||
|
||||
/**
|
||||
* MAM Preferences IQ class.
|
||||
*
|
||||
* @see <a href="http://xmpp.org/extensions/xep-0313.html">XEP-0313: Message
|
||||
* Archive Management</a>
|
||||
* @author Fernando Ramirez and Florian Schmaus
|
||||
*
|
||||
*/
|
||||
public class MamPrefsIQ extends IQ {
|
||||
|
||||
/**
|
||||
* the preferences element.
|
||||
*/
|
||||
public static final String ELEMENT = "prefs";
|
||||
|
||||
/**
|
||||
* the IQ NAMESPACE.
|
||||
*/
|
||||
public static final String NAMESPACE = MamElements.NAMESPACE;
|
||||
|
||||
/**
|
||||
* true if it is a request for update preferences.
|
||||
*/
|
||||
private boolean isUpdate;
|
||||
|
||||
/**
|
||||
* true if it is a result preferences.
|
||||
*/
|
||||
private boolean isResult;
|
||||
|
||||
/**
|
||||
* list of always.
|
||||
*/
|
||||
private List<Jid> alwaysJids;
|
||||
|
||||
/**
|
||||
* list of never.
|
||||
*/
|
||||
private List<Jid> neverJids;
|
||||
|
||||
/**
|
||||
* default field.
|
||||
*/
|
||||
private String defaultField;
|
||||
|
||||
/**
|
||||
* MAM preferences IQ constructor.
|
||||
*
|
||||
* @param type
|
||||
* @param alwaysJids
|
||||
* @param neverJids
|
||||
* @param defaultField
|
||||
*/
|
||||
public MamPrefsIQ(Type type, List<Jid> alwaysJids, List<Jid> neverJids, String defaultField) {
|
||||
super(ELEMENT, NAMESPACE);
|
||||
this.setType(type);
|
||||
this.isUpdate = this.getType().equals(Type.set);
|
||||
this.isResult = this.getType().equals(Type.result);
|
||||
this.alwaysJids = alwaysJids;
|
||||
this.neverJids = neverJids;
|
||||
this.defaultField = defaultField;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if it is a request for update preferences.
|
||||
*
|
||||
* @return the update preferences boolean
|
||||
*/
|
||||
public boolean isUpdate() {
|
||||
return isUpdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if it is a result.
|
||||
*
|
||||
* @return the result preferences boolean
|
||||
*/
|
||||
public boolean isResult() {
|
||||
return isUpdate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of always store info JIDs.
|
||||
*
|
||||
* @return the always list
|
||||
*/
|
||||
public List<Jid> getAlwaysJids() {
|
||||
return alwaysJids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of never store info JIDs.
|
||||
*
|
||||
* @return the never list
|
||||
*/
|
||||
public List<Jid> getNeverJids() {
|
||||
return neverJids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default field.
|
||||
*
|
||||
* @return the default field
|
||||
*/
|
||||
public String getDefault() {
|
||||
return defaultField;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) {
|
||||
|
||||
if (isUpdate || isResult) {
|
||||
xml.attribute("default", defaultField);
|
||||
}
|
||||
|
||||
xml.rightAngleBracket();
|
||||
|
||||
if (alwaysJids != null) {
|
||||
MamElements.AlwaysJidListElement alwaysElement = new AlwaysJidListElement(alwaysJids);
|
||||
xml.element(alwaysElement);
|
||||
}
|
||||
|
||||
if (neverJids != null) {
|
||||
MamElements.NeverJidListElement neverElement = new NeverJidListElement(neverJids);
|
||||
xml.element(neverElement);
|
||||
}
|
||||
|
||||
return xml;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
/**
|
||||
*
|
||||
* Copyright © 2016 Florian Schmaus and Fernando Ramirez
|
||||
*
|
||||
* 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.mam.element;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smackx.xdata.FormField;
|
||||
import org.jivesoftware.smackx.xdata.packet.DataForm;
|
||||
|
||||
/**
|
||||
* MAM Query IQ class.
|
||||
*
|
||||
* @see <a href="http://xmpp.org/extensions/xep-0313.html">XEP-0313: Message
|
||||
* Archive Management</a>
|
||||
* @author Fernando Ramirez and Florian Schmaus
|
||||
*
|
||||
*/
|
||||
public class MamQueryIQ extends IQ {
|
||||
|
||||
/**
|
||||
* the MAM query IQ element.
|
||||
*/
|
||||
public static final String ELEMENT = QUERY_ELEMENT;
|
||||
|
||||
/**
|
||||
* the MAM query IQ NAMESPACE.
|
||||
*/
|
||||
public static final String NAMESPACE = MamElements.NAMESPACE;
|
||||
|
||||
private final String queryId;
|
||||
private final String node;
|
||||
private final DataForm dataForm;
|
||||
|
||||
/**
|
||||
* MAM query IQ constructor.
|
||||
*
|
||||
* @param queryId
|
||||
*/
|
||||
public MamQueryIQ(String queryId) {
|
||||
this(queryId, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* MAM query IQ constructor.
|
||||
*
|
||||
* @param form
|
||||
*/
|
||||
public MamQueryIQ(DataForm form) {
|
||||
this(null, null, form);
|
||||
}
|
||||
|
||||
/**
|
||||
* MAM query IQ constructor.
|
||||
*
|
||||
* @param queryId
|
||||
* @param form
|
||||
*/
|
||||
public MamQueryIQ(String queryId, DataForm form) {
|
||||
this(queryId, null, form);
|
||||
}
|
||||
|
||||
/**
|
||||
* MAM query IQ constructor.
|
||||
*
|
||||
* @param queryId
|
||||
* @param node
|
||||
* @param dataForm
|
||||
*/
|
||||
public MamQueryIQ(String queryId, String node, DataForm dataForm) {
|
||||
super(ELEMENT, NAMESPACE);
|
||||
this.queryId = queryId;
|
||||
this.node = node;
|
||||
this.dataForm = dataForm;
|
||||
|
||||
if (dataForm != null) {
|
||||
FormField field = dataForm.getHiddenFormTypeField();
|
||||
if (field == null) {
|
||||
throw new IllegalArgumentException("If a data form is given it must posses a hidden form type field");
|
||||
}
|
||||
if (!field.getValues().get(0).equals(MamElements.NAMESPACE)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Value of the hidden form type field must be '" + MamElements.NAMESPACE + "'");
|
||||
}
|
||||
addExtension(dataForm);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get query id.
|
||||
*
|
||||
* @return the query id
|
||||
*/
|
||||
public String getQueryId() {
|
||||
return queryId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the data form.
|
||||
*
|
||||
* @return the data form
|
||||
*/
|
||||
public DataForm getDataForm() {
|
||||
return dataForm;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) {
|
||||
xml.optAttribute("queryid", queryId);
|
||||
xml.optAttribute("node", node);
|
||||
xml.rightAngleBracket();
|
||||
return xml;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2016 Fernando Ramirez
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Packet classes and interfaces for Message Archive Management (MAM) XEP-0313.
|
||||
*
|
||||
* @see <a href="http://xmpp.org/extensions/xep-0313.html">XEP-0313: Message
|
||||
* Archive Management</a>
|
||||
*
|
||||
*/
|
||||
package org.jivesoftware.smackx.mam.element;
|
|
@ -0,0 +1,53 @@
|
|||
/**
|
||||
*
|
||||
* Copyright © 2016 Florian Schmaus and Fernando Ramirez
|
||||
*
|
||||
* 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.mam.filter;
|
||||
|
||||
import org.jivesoftware.smack.filter.FlexibleStanzaTypeFilter;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smackx.mam.element.MamElements.MamResultExtension;
|
||||
import org.jivesoftware.smackx.mam.element.MamQueryIQ;
|
||||
|
||||
/**
|
||||
* MAM result filter class.
|
||||
*
|
||||
* @see <a href="http://xmpp.org/extensions/xep-0313.html">XEP-0313: Message
|
||||
* Archive Management</a>
|
||||
* @author Fernando Ramirez and Florian Schmaus
|
||||
*
|
||||
*/
|
||||
public class MamResultFilter extends FlexibleStanzaTypeFilter<Message> {
|
||||
|
||||
private String queryId;
|
||||
|
||||
public MamResultFilter(MamQueryIQ mamQueryIQ) {
|
||||
super(Message.class);
|
||||
this.queryId = mamQueryIQ.getQueryId();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean acceptSpecific(Message message) {
|
||||
MamResultExtension mamResultExtension = MamResultExtension.from(message);
|
||||
|
||||
if (mamResultExtension == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String resultQueryId = mamResultExtension.getQueryId();
|
||||
return ((queryId == null && resultQueryId == null) || (queryId != null && queryId.equals(resultQueryId)));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2016 Fernando Ramirez
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Filters of Message Archive Management (MAM) XEP-0313.
|
||||
*
|
||||
* @see <a href="http://xmpp.org/extensions/xep-0313.html">XEP-0313: Message
|
||||
* Archive Management</a>
|
||||
*
|
||||
*/
|
||||
package org.jivesoftware.smackx.mam.filter;
|
|
@ -0,0 +1,25 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2016 Fernando Ramirez
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* XEP-0313: Message Archive Management.
|
||||
*
|
||||
* @see <a href="http://xmpp.org/extensions/xep-0313.html">XEP-0313: Message
|
||||
* Archive Management</a>
|
||||
*
|
||||
*/
|
||||
package org.jivesoftware.smackx.mam;
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2016 Fernando Ramirez
|
||||
*
|
||||
* 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.mam.provider;
|
||||
|
||||
import org.jivesoftware.smack.provider.IQProvider;
|
||||
import org.jivesoftware.smackx.mam.element.MamFinIQ;
|
||||
import org.jivesoftware.smackx.rsm.packet.RSMSet;
|
||||
import org.jivesoftware.smackx.rsm.provider.RSMSetProvider;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
/**
|
||||
* MAM Fin IQ Provider class.
|
||||
*
|
||||
* @see <a href="http://xmpp.org/extensions/xep-0313.html">XEP-0313: Message
|
||||
* Archive Management</a>
|
||||
* @author Fernando Ramirez
|
||||
*
|
||||
*/
|
||||
public class MamFinIQProvider extends IQProvider<MamFinIQ> {
|
||||
|
||||
@Override
|
||||
public MamFinIQ parse(XmlPullParser parser, int initialDepth) throws Exception {
|
||||
String queryId = parser.getAttributeValue("", "queryid");
|
||||
boolean complete = Boolean.parseBoolean(parser.getAttributeValue("", "complete"));
|
||||
boolean stable = Boolean.parseBoolean(parser.getAttributeValue("", "stable"));
|
||||
RSMSet rsmSet = null;
|
||||
|
||||
outerloop: while (true) {
|
||||
int eventType = parser.next();
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
if (parser.getName().equals(RSMSet.ELEMENT)) {
|
||||
rsmSet = new RSMSetProvider().parse(parser);
|
||||
}
|
||||
} else if (eventType == XmlPullParser.END_TAG) {
|
||||
if (parser.getDepth() == initialDepth) {
|
||||
break outerloop;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new MamFinIQ(queryId, rsmSet, complete, stable);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2016 Fernando Ramirez
|
||||
*
|
||||
* 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.mam.provider;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ.Type;
|
||||
import org.jivesoftware.smack.provider.IQProvider;
|
||||
import org.jivesoftware.smackx.mam.element.MamPrefsIQ;
|
||||
import org.jxmpp.jid.Jid;
|
||||
import org.jxmpp.jid.impl.JidCreate;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
/**
|
||||
* MAM Preferences IQ Provider class.
|
||||
*
|
||||
* @see <a href="http://xmpp.org/extensions/xep-0313.html">XEP-0313: Message
|
||||
* Archive Management</a>
|
||||
* @author Fernando Ramirez
|
||||
*
|
||||
*/
|
||||
public class MamPrefsIQProvider extends IQProvider<MamPrefsIQ> {
|
||||
|
||||
@Override
|
||||
public MamPrefsIQ parse(XmlPullParser parser, int initialDepth) throws Exception {
|
||||
String iqType = parser.getAttributeValue("", "type");
|
||||
String defaultField = parser.getAttributeValue("", "default");
|
||||
|
||||
if (iqType == null) {
|
||||
iqType = "result";
|
||||
}
|
||||
|
||||
List<Jid> alwaysJids = null;
|
||||
List<Jid> neverJids = null;
|
||||
|
||||
outerloop: while (true) {
|
||||
int eventType = parser.next();
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
if (parser.getName().equals("always")) {
|
||||
alwaysJids = iterateJids(parser);
|
||||
}
|
||||
if (parser.getName().equals("never")) {
|
||||
neverJids = iterateJids(parser);
|
||||
}
|
||||
} else if (eventType == XmlPullParser.END_TAG) {
|
||||
if (parser.getDepth() == initialDepth) {
|
||||
break outerloop;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new MamPrefsIQ(Type.fromString(iqType), alwaysJids, neverJids, defaultField);
|
||||
}
|
||||
|
||||
private List<Jid> iterateJids(XmlPullParser parser) throws Exception {
|
||||
List<Jid> jids = new ArrayList<>();
|
||||
|
||||
int initialDepth = parser.getDepth();
|
||||
|
||||
outerloop: while (true) {
|
||||
int eventType = parser.next();
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
if (parser.getName().equals("jid")) {
|
||||
parser.next();
|
||||
jids.add(JidCreate.from(parser.getText()));
|
||||
}
|
||||
} else if (eventType == XmlPullParser.END_TAG) {
|
||||
if (parser.getDepth() == initialDepth) {
|
||||
break outerloop;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return jids;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2016 Fernando Ramirez
|
||||
*
|
||||
* 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.mam.provider;
|
||||
|
||||
import org.jivesoftware.smack.provider.IQProvider;
|
||||
import org.jivesoftware.smackx.mam.element.MamQueryIQ;
|
||||
import org.jivesoftware.smackx.xdata.packet.DataForm;
|
||||
import org.jivesoftware.smackx.xdata.provider.DataFormProvider;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
/**
|
||||
* MAM Query IQ Provider class.
|
||||
*
|
||||
* @see <a href="http://xmpp.org/extensions/xep-0313.html">XEP-0313: Message
|
||||
* Archive Management</a>
|
||||
* @author Fernando Ramirez
|
||||
*
|
||||
*/
|
||||
public class MamQueryIQProvider extends IQProvider<MamQueryIQ> {
|
||||
|
||||
@Override
|
||||
public MamQueryIQ parse(XmlPullParser parser, int initialDepth) throws Exception {
|
||||
DataForm dataForm = null;
|
||||
String queryId = parser.getAttributeValue("", "queryid");
|
||||
String node = parser.getAttributeValue("", "node");
|
||||
|
||||
outerloop: while (true) {
|
||||
int eventType = parser.next();
|
||||
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
if (parser.getName().equals(DataForm.ELEMENT)) {
|
||||
dataForm = new DataFormProvider().parse(parser);
|
||||
}
|
||||
} else if (eventType == XmlPullParser.END_TAG) {
|
||||
if (parser.getDepth() == initialDepth) {
|
||||
break outerloop;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new MamQueryIQ(queryId, node, dataForm);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2016 Fernando Ramirez
|
||||
*
|
||||
* 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.mam.provider;
|
||||
|
||||
import org.jivesoftware.smack.provider.ExtensionElementProvider;
|
||||
import org.jivesoftware.smackx.forward.packet.Forwarded;
|
||||
import org.jivesoftware.smackx.forward.provider.ForwardedProvider;
|
||||
import org.jivesoftware.smackx.mam.element.MamElements.MamResultExtension;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
/**
|
||||
* MAM Result Provider class.
|
||||
*
|
||||
* @see <a href="http://xmpp.org/extensions/xep-0313.html">XEP-0313: Message
|
||||
* Archive Management</a>
|
||||
* @author Fernando Ramirez
|
||||
*
|
||||
*/
|
||||
public class MamResultProvider extends ExtensionElementProvider<MamResultExtension> {
|
||||
|
||||
@Override
|
||||
public MamResultExtension parse(XmlPullParser parser, int initialDepth) throws Exception {
|
||||
Forwarded forwarded = null;
|
||||
String queryId = parser.getAttributeValue("", "queryid");
|
||||
String id = parser.getAttributeValue("", "id");
|
||||
|
||||
outerloop: while (true) {
|
||||
int eventType = parser.next();
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
if (parser.getName().equals(Forwarded.ELEMENT)) {
|
||||
forwarded = new ForwardedProvider().parse(parser);
|
||||
}
|
||||
} else if (eventType == XmlPullParser.END_TAG) {
|
||||
if (parser.getDepth() == initialDepth) {
|
||||
break outerloop;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new MamResultExtension(queryId, id, forwarded);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2016 Fernando Ramirez
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provider classes of Message Archive Management (MAM) XEP-0313.
|
||||
*
|
||||
* @see <a href="http://xmpp.org/extensions/xep-0313.html">XEP-0313: Message
|
||||
* Archive Management</a>
|
||||
*
|
||||
*/
|
||||
package org.jivesoftware.smackx.mam.provider;
|
|
@ -52,6 +52,28 @@
|
|||
<className>org.jivesoftware.smackx.gcm.provider.GcmExtensionProvider</className>
|
||||
</extensionProvider>
|
||||
|
||||
<!-- XEP-0313 Message Archive Management -->
|
||||
<iqProvider>
|
||||
<elementName>prefs</elementName>
|
||||
<namespace>urn:xmpp:mam:1</namespace>
|
||||
<className>org.jivesoftware.smackx.mam.provider.MamPrefsIQProvider</className>
|
||||
</iqProvider>
|
||||
<iqProvider>
|
||||
<elementName>query</elementName>
|
||||
<namespace>urn:xmpp:mam:1</namespace>
|
||||
<className>org.jivesoftware.smackx.mam.provider.MamQueryIQProvider</className>
|
||||
</iqProvider>
|
||||
<iqProvider>
|
||||
<elementName>fin</elementName>
|
||||
<namespace>urn:xmpp:mam:1</namespace>
|
||||
<className>org.jivesoftware.smackx.mam.provider.MamFinIQProvider</className>
|
||||
</iqProvider>
|
||||
<extensionProvider>
|
||||
<elementName>result</elementName>
|
||||
<namespace>urn:xmpp:mam:1</namespace>
|
||||
<className>org.jivesoftware.smackx.mam.provider.MamResultProvider</className>
|
||||
</extensionProvider>
|
||||
|
||||
<!-- XEP-0347: Internet of Things - Discovery -->
|
||||
<iqProvider>
|
||||
<elementName>register</elementName>
|
||||
|
|
|
@ -0,0 +1,160 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2016 Fernando Ramirez
|
||||
*
|
||||
* 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.mam;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.jivesoftware.smackx.mam.element.MamElements;
|
||||
import org.jivesoftware.smackx.xdata.packet.DataForm;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.jxmpp.jid.Jid;
|
||||
import org.jxmpp.jid.impl.JidCreate;
|
||||
import org.jxmpp.util.XmppDateTime;
|
||||
|
||||
public class FiltersTest extends MamTest {
|
||||
|
||||
private String getMamXMemberWith(List<String> fieldsNames, List<String> fieldsValues) {
|
||||
String xml = "<x xmlns='jabber:x:data' type='submit'>" + "<field var='FORM_TYPE' type='hidden'>" + "<value>"
|
||||
+ MamElements.NAMESPACE + "</value>" + "</field>";
|
||||
|
||||
for (int i = 0; i < fieldsNames.size() && i < fieldsValues.size(); i++) {
|
||||
xml += "<field var='" + fieldsNames.get(i) + "'>" + "<value>" + fieldsValues.get(i) + "</value>"
|
||||
+ "</field>";
|
||||
}
|
||||
|
||||
xml += "</x>";
|
||||
return xml;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkStartDateFilter() throws Exception {
|
||||
Method methodAddStartDateFilter = MamManager.class.getDeclaredMethod("addStart", Date.class, DataForm.class);
|
||||
methodAddStartDateFilter.setAccessible(true);
|
||||
|
||||
Date date = new Date();
|
||||
DataForm dataForm = getNewMamForm();
|
||||
methodAddStartDateFilter.invoke(mamManager, date, dataForm);
|
||||
|
||||
List<String> fields = new ArrayList<>();
|
||||
fields.add("start");
|
||||
List<String> values = new ArrayList<>();
|
||||
values.add(XmppDateTime.formatXEP0082Date(date));
|
||||
|
||||
Assert.assertEquals(dataForm.toXML().toString(), getMamXMemberWith(fields, values));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkEndDateFilter() throws Exception {
|
||||
Method methodAddEndDateFilter = MamManager.class.getDeclaredMethod("addEnd", Date.class, DataForm.class);
|
||||
methodAddEndDateFilter.setAccessible(true);
|
||||
|
||||
Date date = new Date();
|
||||
DataForm dataForm = getNewMamForm();
|
||||
methodAddEndDateFilter.invoke(mamManager, date, dataForm);
|
||||
|
||||
List<String> fields = new ArrayList<>();
|
||||
fields.add("end");
|
||||
List<String> values = new ArrayList<>();
|
||||
values.add(XmppDateTime.formatXEP0082Date(date));
|
||||
|
||||
Assert.assertEquals(dataForm.toXML().toString(), getMamXMemberWith(fields, values));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkWithJidFilter() throws Exception {
|
||||
Method methodAddJidFilter = MamManager.class.getDeclaredMethod("addWithJid", Jid.class, DataForm.class);
|
||||
methodAddJidFilter.setAccessible(true);
|
||||
|
||||
String jid = "test@jid.com";
|
||||
DataForm dataForm = getNewMamForm();
|
||||
methodAddJidFilter.invoke(mamManager, JidCreate.from(jid), dataForm);
|
||||
|
||||
List<String> fields = new ArrayList<>();
|
||||
fields.add("with");
|
||||
List<String> values = new ArrayList<>();
|
||||
values.add(jid);
|
||||
|
||||
Assert.assertEquals(dataForm.toXML().toString(), getMamXMemberWith(fields, values));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkMultipleFilters() throws Exception {
|
||||
Method methodAddStartDateFilter = MamManager.class.getDeclaredMethod("addStart", Date.class, DataForm.class);
|
||||
methodAddStartDateFilter.setAccessible(true);
|
||||
Method methodAddEndDateFilter = MamManager.class.getDeclaredMethod("addEnd", Date.class, DataForm.class);
|
||||
methodAddEndDateFilter.setAccessible(true);
|
||||
Method methodAddJidFilter = MamManager.class.getDeclaredMethod("addWithJid", Jid.class, DataForm.class);
|
||||
methodAddJidFilter.setAccessible(true);
|
||||
|
||||
DataForm dataForm = getNewMamForm();
|
||||
Date date = new Date();
|
||||
String dateString = XmppDateTime.formatXEP0082Date(date);
|
||||
String jid = "test@jid.com";
|
||||
|
||||
methodAddStartDateFilter.invoke(mamManager, date, dataForm);
|
||||
methodAddEndDateFilter.invoke(mamManager, date, dataForm);
|
||||
methodAddJidFilter.invoke(mamManager, JidCreate.from(jid), dataForm);
|
||||
String dataFormResult = dataForm.toXML().toString();
|
||||
|
||||
List<String> fields = new ArrayList<>();
|
||||
List<String> values = new ArrayList<>();
|
||||
|
||||
fields.add("start");
|
||||
values.add(dateString);
|
||||
Assert.assertNotEquals(dataFormResult, getMamXMemberWith(fields, values));
|
||||
|
||||
fields.add("end");
|
||||
values.add(dateString);
|
||||
Assert.assertNotEquals(dataFormResult, getMamXMemberWith(fields, values));
|
||||
|
||||
fields.clear();
|
||||
values.clear();
|
||||
|
||||
fields.add("start");
|
||||
values.add(dateString);
|
||||
fields.add("with");
|
||||
values.add(jid);
|
||||
Assert.assertNotEquals(dataFormResult, getMamXMemberWith(fields, values));
|
||||
|
||||
fields.clear();
|
||||
values.clear();
|
||||
|
||||
fields.add("end");
|
||||
values.add(dateString);
|
||||
fields.add("with");
|
||||
values.add(jid);
|
||||
fields.add("start");
|
||||
values.add(dateString);
|
||||
Assert.assertNotEquals(dataFormResult, getMamXMemberWith(fields, values));
|
||||
|
||||
fields.clear();
|
||||
values.clear();
|
||||
|
||||
fields.add("start");
|
||||
values.add(dateString);
|
||||
fields.add("end");
|
||||
values.add(dateString);
|
||||
fields.add("with");
|
||||
values.add(jid);
|
||||
Assert.assertEquals(dataFormResult, getMamXMemberWith(fields, values));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2016 Fernando Ramirez
|
||||
*
|
||||
* 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.mam;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.IQ.Type;
|
||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||
import org.jivesoftware.smackx.mam.element.MamFinIQ;
|
||||
import org.jivesoftware.smackx.mam.provider.MamFinIQProvider;
|
||||
import org.jivesoftware.smackx.rsm.packet.RSMSet;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
public class MamFinProviderTest extends MamTest {
|
||||
|
||||
String exmapleMamFinXml = "<fin xmlns='urn:xmpp:mam:1' stable='true'>"
|
||||
+ "<set xmlns='http://jabber.org/protocol/rsm'>" + "<max>10</max>" + "<after>09af3-cc343-b409f</after>"
|
||||
+ "</set>" + "</fin>";
|
||||
|
||||
private String getIQLimitedResultsExample() {
|
||||
return "<iq type='result' id='u29303'>" + "<fin xmlns='urn:xmpp:mam:1' complete='true'>"
|
||||
+ "<set xmlns='http://jabber.org/protocol/rsm'>" + "<first index='0'>23452-4534-1</first>"
|
||||
+ "<last>390-2342-22</last>" + "<count>16</count>" + "</set>" + "</fin>" + "</iq>";
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkMamFinProvider() throws Exception {
|
||||
XmlPullParser parser = PacketParserUtils.getParserFor(exmapleMamFinXml);
|
||||
MamFinIQ mamFinIQ = new MamFinIQProvider().parse(parser);
|
||||
|
||||
Assert.assertFalse(mamFinIQ.isComplete());
|
||||
Assert.assertTrue(mamFinIQ.isStable());
|
||||
Assert.assertNull(mamFinIQ.getQueryId());
|
||||
|
||||
RSMSet rsmSet = mamFinIQ.getRSMSet();
|
||||
Assert.assertEquals(rsmSet.getAfter(), "09af3-cc343-b409f");
|
||||
Assert.assertEquals(rsmSet.getMax(), 10);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkQueryLimitedResults() throws Exception {
|
||||
IQ iq = (IQ) PacketParserUtils.parseStanza(getIQLimitedResultsExample());
|
||||
|
||||
MamFinIQ mamFinIQ = (MamFinIQ) iq;
|
||||
Assert.assertEquals(mamFinIQ.getType(), Type.result);
|
||||
|
||||
Assert.assertTrue(mamFinIQ.isComplete());
|
||||
Assert.assertEquals(mamFinIQ.getRSMSet().getCount(), 16);
|
||||
Assert.assertEquals(mamFinIQ.getRSMSet().getFirst(), "23452-4534-1");
|
||||
Assert.assertEquals(mamFinIQ.getRSMSet().getFirstIndex(), 0);
|
||||
Assert.assertEquals(mamFinIQ.getRSMSet().getLast(), "390-2342-22");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2016 Fernando Ramirez
|
||||
*
|
||||
* 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.mam;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||
import org.jivesoftware.smackx.mam.element.MamPrefsIQ;
|
||||
import org.jivesoftware.smackx.mam.provider.MamPrefsIQProvider;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.jxmpp.jid.Jid;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
public class MamPrefIQProviderTest extends MamTest {
|
||||
|
||||
String exampleMamPrefsIQ1 = "<iq type='set' id='juliet3'>" + "<prefs xmlns='urn:xmpp:mam:1' default='roster'>"
|
||||
+ "<always>" + "<jid>romeo@montague.lit</jid>" + "</always>" + "<never>"
|
||||
+ "<jid>montague@montague.lit</jid>" + "</never>" + "</prefs>" + "</iq>";
|
||||
|
||||
String exampleMamPrefsIQ2 = "<iq type='set' id='juliet3'>" + "<prefs xmlns='urn:xmpp:mam:1' default='roster'>"
|
||||
+ "<always>" + "<jid>romeo@montague.lit</jid>" + "<jid>montague@montague.lit</jid>" + "</always>"
|
||||
+ "<never>" + "</never>" + "</prefs>" + "</iq>";
|
||||
|
||||
String exampleMamPrefsIQ3 = "<iq type='get' id='juliet3'>" + "<prefs xmlns='urn:xmpp:mam:1'>" + "</prefs>"
|
||||
+ "</iq>";
|
||||
|
||||
String exampleMamPrefsResultIQ = "<iq type='result' id='juliet3'>"
|
||||
+ "<prefs xmlns='urn:xmpp:mam:1' default='roster'>" + "<always>" + "<jid>romeo@montague.lit</jid>"
|
||||
+ "</always>" + "<never>" + "<jid>sarasa@montague.lit</jid>" + "<jid>montague@montague.lit</jid>"
|
||||
+ "</never>" + "</prefs>" + "</iq>";
|
||||
|
||||
@Test
|
||||
public void checkMamPrefsIQProvider() throws Exception {
|
||||
XmlPullParser parser1 = PacketParserUtils.getParserFor(exampleMamPrefsIQ1);
|
||||
MamPrefsIQ mamPrefIQ1 = new MamPrefsIQProvider().parse(parser1);
|
||||
|
||||
Assert.assertTrue(mamPrefIQ1.isUpdate());
|
||||
Assert.assertEquals(mamPrefIQ1.getAlwaysJids().get(0), "romeo@montague.lit");
|
||||
Assert.assertEquals(mamPrefIQ1.getNeverJids().get(0), "montague@montague.lit");
|
||||
|
||||
XmlPullParser parser2 = PacketParserUtils.getParserFor(exampleMamPrefsIQ2);
|
||||
MamPrefsIQ mamPrefIQ2 = new MamPrefsIQProvider().parse(parser2);
|
||||
Assert.assertTrue(mamPrefIQ2.isUpdate());
|
||||
Assert.assertEquals(mamPrefIQ2.getAlwaysJids().get(0), "romeo@montague.lit");
|
||||
Assert.assertEquals(mamPrefIQ2.getAlwaysJids().get(1), "montague@montague.lit");
|
||||
Assert.assertTrue(mamPrefIQ2.getNeverJids().isEmpty());
|
||||
|
||||
XmlPullParser parser3 = PacketParserUtils.getParserFor(exampleMamPrefsIQ3);
|
||||
MamPrefsIQ mamPrefIQ3 = new MamPrefsIQProvider().parse(parser3);
|
||||
Assert.assertFalse(mamPrefIQ3.isUpdate());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkMamPrefResult() throws Exception {
|
||||
IQ iq = (IQ) PacketParserUtils.parseStanza(exampleMamPrefsResultIQ);
|
||||
|
||||
MamPrefsIQ mamPrefsIQ = (MamPrefsIQ) iq;
|
||||
|
||||
List<Jid> alwaysJids = mamPrefsIQ.getAlwaysJids();
|
||||
List<Jid> neverJids = mamPrefsIQ.getNeverJids();
|
||||
|
||||
Assert.assertEquals(alwaysJids.size(), 1);
|
||||
Assert.assertEquals(neverJids.size(), 2);
|
||||
Assert.assertEquals(alwaysJids.get(0).toString(), "romeo@montague.lit");
|
||||
Assert.assertEquals(neverJids.get(1).toString(), "montague@montague.lit");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2016 Fernando Ramirez
|
||||
*
|
||||
* 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.mam;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.IQ.Type;
|
||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||
import org.jivesoftware.smackx.mam.element.MamQueryIQ;
|
||||
import org.jivesoftware.smackx.xdata.FormField;
|
||||
import org.jivesoftware.smackx.xdata.packet.DataForm;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class MamQueryIQProviderTest {
|
||||
|
||||
String exampleMamQueryIQ1 = "<iq type='set' id='query4'>" + "<query xmlns='urn:xmpp:mam:1' queryid='test'>"
|
||||
+ "<x xmlns='jabber:x:data' type='submit'>" + "<field type='hidden' var='FORM_TYPE'>"
|
||||
+ "<value>urn:xmpp:mam:1</value>" + "</field>"
|
||||
+ "<field type='text-single' var='urn:example:xmpp:free-text-search'>"
|
||||
+ "<value>Where arth thou, my Juliet?</value>" + "</field>"
|
||||
+ "<field type='text-single' var='urn:example:xmpp:stanza-content'>"
|
||||
+ "<value>{http://jabber.org/protocol/mood}mood/lonely</value>" + "</field>" + "</x>" + "</query>"
|
||||
+ "</iq>";
|
||||
|
||||
String exampleMamQueryIQ2 = "<iq type='result' id='form1'>" + "<query xmlns='urn:xmpp:mam:1'>"
|
||||
+ "<x xmlns='jabber:x:data' type='form'>" + "<field type='hidden' var='FORM_TYPE'>"
|
||||
+ "<value>urn:xmpp:mam:1</value>" + "</field>" + "<field type='jid-single' var='with'/>"
|
||||
+ "<field type='text-single' var='start'/>" + "<field type='text-single' var='end'/>"
|
||||
+ "<field type='text-single' var='urn:example:xmpp:free-text-search'/>"
|
||||
+ "<field type='text-single' var='urn:example:xmpp:stanza-content'/>" + "</x>" + "</query>" + "</iq>";
|
||||
|
||||
@Test
|
||||
public void checkMamQueryIQProvider() throws Exception {
|
||||
// example 1
|
||||
IQ iq1 = (IQ) PacketParserUtils.parseStanza(exampleMamQueryIQ1);
|
||||
MamQueryIQ mamQueryIQ1 = (MamQueryIQ) iq1;
|
||||
|
||||
Assert.assertEquals(mamQueryIQ1.getType(), Type.set);
|
||||
Assert.assertEquals(mamQueryIQ1.getQueryId(), "test");
|
||||
|
||||
DataForm dataForm1 = (DataForm) mamQueryIQ1.getExtension(DataForm.NAMESPACE);
|
||||
Assert.assertEquals(dataForm1.getType(), DataForm.Type.submit);
|
||||
|
||||
List<FormField> fields1 = dataForm1.getFields();
|
||||
Assert.assertEquals(fields1.get(0).getType(), FormField.Type.hidden);
|
||||
Assert.assertEquals(fields1.get(1).getType(), FormField.Type.text_single);
|
||||
Assert.assertEquals(fields1.get(1).getValues().get(0), "Where arth thou, my Juliet?");
|
||||
Assert.assertEquals(fields1.get(2).getValues().get(0), "{http://jabber.org/protocol/mood}mood/lonely");
|
||||
|
||||
// example2
|
||||
IQ iq2 = (IQ) PacketParserUtils.parseStanza(exampleMamQueryIQ2);
|
||||
MamQueryIQ mamQueryIQ2 = (MamQueryIQ) iq2;
|
||||
|
||||
Assert.assertEquals(mamQueryIQ2.getType(), Type.result);
|
||||
Assert.assertNull(mamQueryIQ2.getQueryId());
|
||||
|
||||
DataForm dataForm2 = (DataForm) mamQueryIQ2.getExtension(DataForm.NAMESPACE);
|
||||
Assert.assertEquals(dataForm2.getType(), DataForm.Type.form);
|
||||
|
||||
List<FormField> fields2 = dataForm2.getFields();
|
||||
Assert.assertEquals(fields2.get(0).getValues().get(0), "urn:xmpp:mam:1");
|
||||
Assert.assertTrue(fields2.get(0).getValues().size() == 1);
|
||||
Assert.assertEquals(fields2.get(1).getType(), FormField.Type.jid_single);
|
||||
Assert.assertEquals(fields2.get(2).getType(), FormField.Type.text_single);
|
||||
Assert.assertEquals(fields2.get(2).getValues(), new ArrayList<>());
|
||||
Assert.assertEquals(fields2.get(4).getVariable(), "urn:example:xmpp:free-text-search");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2016 Fernando Ramirez
|
||||
*
|
||||
* 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.mam;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.util.PacketParserUtils;
|
||||
import org.jivesoftware.smackx.forward.packet.Forwarded;
|
||||
import org.jivesoftware.smackx.mam.element.MamElements.MamResultExtension;
|
||||
import org.jivesoftware.smackx.mam.provider.MamResultProvider;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
public class MamResultProviderTest {
|
||||
|
||||
String exampleMamResultXml = "<result xmlns='urn:xmpp:mam:1' queryid='f27' id='28482-98726-73623'>"
|
||||
+ "<forwarded xmlns='urn:xmpp:forward:0'>" + "<delay xmlns='urn:xmpp:delay' stamp='2010-07-10T23:08:25Z'/>"
|
||||
+ "<message xmlns='jabber:client'" + "to='juliet@capulet.lit/balcony'" + "from='romeo@montague.lit/orchard'"
|
||||
+ "type='chat'>"
|
||||
+ "<body>Call me but love, and I'll be new baptized; Henceforth I never will be Romeo.</body>"
|
||||
+ "</message>" + "</forwarded>" + "</result>";
|
||||
|
||||
String exampleResultMessage = "<message id='aeb213' to='juliet@capulet.lit/chamber'>"
|
||||
+ "<result xmlns='urn:xmpp:mam:1' queryid='f27' id='28482-98726-73623'>"
|
||||
+ "<forwarded xmlns='urn:xmpp:forward:0'>" + "<delay xmlns='urn:xmpp:delay' stamp='2010-07-10T23:08:25Z'/>"
|
||||
+ "<message xmlns='jabber:client' from='witch@shakespeare.lit' to='macbeth@shakespeare.lit'>"
|
||||
+ "<body>Hail to thee</body>" + "</message>" + "</forwarded>" + "</result>" + "</message>";
|
||||
|
||||
@Test
|
||||
public void checkMamResultProvider() throws Exception {
|
||||
XmlPullParser parser = PacketParserUtils.getParserFor(exampleMamResultXml);
|
||||
MamResultExtension mamResultExtension = new MamResultProvider().parse(parser);
|
||||
|
||||
Assert.assertEquals(mamResultExtension.getQueryId(), "f27");
|
||||
Assert.assertEquals(mamResultExtension.getId(), "28482-98726-73623");
|
||||
|
||||
GregorianCalendar calendar = new GregorianCalendar(2010, 7 - 1, 10, 23, 8, 25);
|
||||
calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
Date date = calendar.getTime();
|
||||
|
||||
Forwarded forwarded = mamResultExtension.getForwarded();
|
||||
Assert.assertEquals(forwarded.getDelayInformation().getStamp(), date);
|
||||
|
||||
Message message = (Message) forwarded.getForwardedStanza();
|
||||
Assert.assertEquals(message.getFrom(), "romeo@montague.lit/orchard");
|
||||
Assert.assertEquals(message.getTo(), "juliet@capulet.lit/balcony");
|
||||
Assert.assertEquals(message.getBody(),
|
||||
"Call me but love, and I'll be new baptized; Henceforth I never will be Romeo.");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkResultsParse() throws Exception {
|
||||
Message message = (Message) PacketParserUtils.parseStanza(exampleResultMessage);
|
||||
MamResultExtension mamResultExtension = MamResultExtension.from(message);
|
||||
|
||||
Assert.assertEquals(mamResultExtension.getQueryId(), "f27");
|
||||
Assert.assertEquals(mamResultExtension.getId(), "28482-98726-73623");
|
||||
|
||||
GregorianCalendar calendar = new GregorianCalendar(2010, 7 - 1, 10, 23, 8, 25);
|
||||
calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
Date date = calendar.getTime();
|
||||
|
||||
Forwarded forwarded = mamResultExtension.getForwarded();
|
||||
Assert.assertEquals(forwarded.getDelayInformation().getStamp(), date);
|
||||
|
||||
Message forwardedMessage = (Message) forwarded.getForwardedStanza();
|
||||
Assert.assertEquals(forwardedMessage.getFrom(), "witch@shakespeare.lit");
|
||||
Assert.assertEquals(forwardedMessage.getTo(), "macbeth@shakespeare.lit");
|
||||
Assert.assertEquals(forwardedMessage.getBody(), "Hail to thee");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2016 Fernando Ramirez
|
||||
*
|
||||
* 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.mam;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.jivesoftware.smack.XMPPConnection;
|
||||
import org.jivesoftware.smackx.ExperimentalInitializerTest;
|
||||
import org.jivesoftware.smackx.xdata.packet.DataForm;
|
||||
import org.junit.Before;
|
||||
|
||||
public class MamTest extends ExperimentalInitializerTest {
|
||||
|
||||
protected XMPPConnection connection;
|
||||
protected String queryId;
|
||||
protected MamManager mamManager;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
// mock connection
|
||||
connection = mock(XMPPConnection.class);
|
||||
|
||||
// test query id
|
||||
queryId = "testid";
|
||||
|
||||
// MamManager instance
|
||||
mamManager = MamManager.getInstanceFor(connection);
|
||||
}
|
||||
|
||||
protected DataForm getNewMamForm() throws NoSuchMethodException, SecurityException, IllegalAccessException,
|
||||
IllegalArgumentException, InvocationTargetException {
|
||||
Method methodGetNewMamForm = MamManager.class.getDeclaredMethod("getNewMamForm");
|
||||
methodGetNewMamForm.setAccessible(true);
|
||||
return (DataForm) methodGetNewMamForm.invoke(mamManager);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2016 Fernando Ramirez
|
||||
*
|
||||
* 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.mam;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.jivesoftware.smackx.mam.element.MamQueryIQ;
|
||||
import org.jivesoftware.smackx.rsm.packet.RSMSet;
|
||||
import org.jivesoftware.smackx.xdata.packet.DataForm;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
||||
public class PagingTest extends MamTest {
|
||||
|
||||
String pagingStanza = "<iq id='sarasa' type='set'>" + "<query xmlns='urn:xmpp:mam:1' queryid='testid'>"
|
||||
+ "<x xmlns='jabber:x:data' type='submit'>" + "<field var='FORM_TYPE' type='hidden'>"
|
||||
+ "<value>urn:xmpp:mam:1</value>" + "</field>" + "</x>" + "<set xmlns='http://jabber.org/protocol/rsm'>"
|
||||
+ "<max>10</max>" + "</set>" + "</query>" + "</iq>";
|
||||
|
||||
@Test
|
||||
public void checkPageQueryStanza() throws Exception {
|
||||
Method methodPreparePageQuery = MamManager.class.getDeclaredMethod("preparePageQuery", MamQueryIQ.class,
|
||||
RSMSet.class);
|
||||
methodPreparePageQuery.setAccessible(true);
|
||||
|
||||
DataForm dataForm = getNewMamForm();
|
||||
int max = 10;
|
||||
RSMSet rsmSet = new RSMSet(max);
|
||||
|
||||
MamQueryIQ mamQueryIQ = new MamQueryIQ(queryId, dataForm);
|
||||
mamQueryIQ.setStanzaId("sarasa");
|
||||
|
||||
methodPreparePageQuery.invoke(mamManager, mamQueryIQ, rsmSet);
|
||||
|
||||
Assert.assertEquals(mamQueryIQ.getDataForm(), dataForm);
|
||||
Assert.assertEquals(mamQueryIQ.getDataForm().getFields().get(0).getValues().get(0), "urn:xmpp:mam:1");
|
||||
Assert.assertEquals(mamQueryIQ.toXML().toString(), pagingStanza);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2016 Fernando Ramirez
|
||||
*
|
||||
* 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.mam;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.jxmpp.jid.Jid;
|
||||
import org.jxmpp.jid.impl.JidCreate;
|
||||
import org.jivesoftware.smackx.mam.element.MamElements;
|
||||
import org.jivesoftware.smackx.mam.element.MamPrefsIQ;
|
||||
import org.junit.Assert;
|
||||
|
||||
public class PreferencesTest extends MamTest {
|
||||
|
||||
String retrievePrefsStanzaExample = "<iq id='sarasa' type='get'>" + "<prefs xmlns='" + MamElements.NAMESPACE
|
||||
+ "'></prefs>" + "</iq>";
|
||||
|
||||
String updatePrefsStanzaExample = "<iq id='sarasa' type='set'>" + "<prefs xmlns='" + MamElements.NAMESPACE
|
||||
+ "' default='roster'>" + "<always>" + "<jid>romeo@montague.lit</jid>" + "<jid>other@montague.lit</jid>"
|
||||
+ "</always>" + "<never>" + "<jid>montague@montague.lit</jid>" + "</never>" + "</prefs>" + "</iq>";
|
||||
|
||||
@Test
|
||||
public void checkRetrievePrefsStanza() throws Exception {
|
||||
Method prepareRetrievePreferencesStanza = MamManager.class
|
||||
.getDeclaredMethod("prepareRetrievePreferencesStanza");
|
||||
prepareRetrievePreferencesStanza.setAccessible(true);
|
||||
|
||||
MamPrefsIQ mamPrefIQ = (MamPrefsIQ) prepareRetrievePreferencesStanza.invoke(mamManager);
|
||||
mamPrefIQ.setStanzaId("sarasa");
|
||||
Assert.assertEquals(mamPrefIQ.toXML().toString(), retrievePrefsStanzaExample);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkUpdatePrefsStanza() throws Exception {
|
||||
Method prepareUpdatePreferencesStanza = MamManager.class.getDeclaredMethod("prepareUpdatePreferencesStanza",
|
||||
List.class, List.class, String.class);
|
||||
prepareUpdatePreferencesStanza.setAccessible(true);
|
||||
|
||||
List<Jid> alwaysJids = new ArrayList<>();
|
||||
alwaysJids.add(JidCreate.from("romeo@montague.lit"));
|
||||
alwaysJids.add(JidCreate.from("other@montague.lit"));
|
||||
|
||||
List<Jid> neverJids = new ArrayList<>();
|
||||
neverJids.add(JidCreate.from("montague@montague.lit"));
|
||||
|
||||
MamPrefsIQ mamPrefIQ = (MamPrefsIQ) prepareUpdatePreferencesStanza.invoke(mamManager, alwaysJids, neverJids, "roster");
|
||||
mamPrefIQ.setStanzaId("sarasa");
|
||||
Assert.assertEquals(mamPrefIQ.toXML().toString(), updatePrefsStanzaExample);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2016 Fernando Ramirez
|
||||
*
|
||||
* 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.mam;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smack.packet.Message.Type;
|
||||
import org.jivesoftware.smackx.delay.packet.DelayInformation;
|
||||
import org.jivesoftware.smackx.forward.packet.Forwarded;
|
||||
import org.jivesoftware.smackx.mam.element.MamElements;
|
||||
import org.jivesoftware.smackx.mam.element.MamElements.MamResultExtension;
|
||||
import org.jivesoftware.smackx.mam.element.MamQueryIQ;
|
||||
import org.jivesoftware.smackx.xdata.packet.DataForm;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.jxmpp.jid.impl.JidCreate;
|
||||
|
||||
public class QueryArchiveTest extends MamTest {
|
||||
|
||||
String mamSimpleQueryIQ = "<iq id='sarasa' type='set'>" + "<query xmlns='urn:xmpp:mam:1' queryid='testid'>"
|
||||
+ "<x xmlns='jabber:x:data' type='submit'>" + "<field var='FORM_TYPE' type='hidden'>" + "<value>"
|
||||
+ MamElements.NAMESPACE + "</value>" + "</field>" + "</x>" + "</query>" + "</iq>";
|
||||
|
||||
String mamQueryResultExample = "<message to='hag66@shakespeare.lit/pda' from='coven@chat.shakespeare.lit' id='iasd207'>"
|
||||
+ "<result xmlns='urn:xmpp:mam:1' queryid='g27' id='34482-21985-73620'>"
|
||||
+ "<forwarded xmlns='urn:xmpp:forward:0'>"
|
||||
+ "<delay xmlns='urn:xmpp:delay' stamp='2002-10-13T23:58:37.000+00:00'></delay>" + "<message "
|
||||
+ "from='coven@chat.shakespeare.lit/firstwitch' " + "id='162BEBB1-F6DB-4D9A-9BD8-CFDCC801A0B2' "
|
||||
+ "type='chat'>" + "<body>Thrice the brinded cat hath mew.</body>" + "</message>" + "</forwarded>"
|
||||
+ "</result>" + "</message>";
|
||||
|
||||
@Test
|
||||
public void checkMamQueryIQ() throws Exception {
|
||||
DataForm dataForm = getNewMamForm();
|
||||
MamQueryIQ mamQueryIQ = new MamQueryIQ(queryId, dataForm);
|
||||
mamQueryIQ.setType(IQ.Type.set);
|
||||
mamQueryIQ.setStanzaId("sarasa");
|
||||
Assert.assertEquals(mamQueryIQ.toXML().toString(), mamSimpleQueryIQ);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkMamQueryResults() throws Exception {
|
||||
Message message = new Message();
|
||||
message.setStanzaId("iasd207");
|
||||
message.setFrom(JidCreate.from("coven@chat.shakespeare.lit"));
|
||||
message.setTo(JidCreate.from("hag66@shakespeare.lit/pda"));
|
||||
|
||||
GregorianCalendar calendar = new GregorianCalendar(2002, 10 - 1, 13, 23, 58, 37);
|
||||
calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
Date date = calendar.getTime();
|
||||
|
||||
DelayInformation delay = new DelayInformation(date);
|
||||
Message forwardedMessage = new Message();
|
||||
forwardedMessage.setFrom(JidCreate.from("coven@chat.shakespeare.lit/firstwitch"));
|
||||
forwardedMessage.setStanzaId("162BEBB1-F6DB-4D9A-9BD8-CFDCC801A0B2");
|
||||
forwardedMessage.setType(Type.chat);
|
||||
forwardedMessage.setBody("Thrice the brinded cat hath mew.");
|
||||
|
||||
Forwarded forwarded = new Forwarded(delay, forwardedMessage);
|
||||
|
||||
message.addExtension(new MamResultExtension("g27", "34482-21985-73620", forwarded));
|
||||
|
||||
Assert.assertEquals(message.toXML().toString(), mamQueryResultExample);
|
||||
|
||||
MamResultExtension mamResultExtension = MamResultExtension.from(message);
|
||||
|
||||
Assert.assertEquals(mamResultExtension.getId(), "34482-21985-73620");
|
||||
Assert.assertEquals(mamResultExtension.getForwarded().getDelayInformation().getStamp(), date);
|
||||
|
||||
Message resultMessage = (Message) mamResultExtension.getForwarded().getForwardedStanza();
|
||||
Assert.assertEquals(resultMessage.getFrom(), JidCreate.from("coven@chat.shakespeare.lit/firstwitch"));
|
||||
Assert.assertEquals(resultMessage.getStanzaId(), "162BEBB1-F6DB-4D9A-9BD8-CFDCC801A0B2");
|
||||
Assert.assertEquals(resultMessage.getType(), Type.chat);
|
||||
Assert.assertEquals(resultMessage.getBody(), "Thrice the brinded cat hath mew.");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2016 Fernando Ramirez
|
||||
*
|
||||
* 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.mam;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smackx.mam.element.MamElements;
|
||||
import org.jivesoftware.smackx.mam.element.MamQueryIQ;
|
||||
import org.jivesoftware.smackx.xdata.packet.DataForm;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ResultsLimitTest extends MamTest {
|
||||
|
||||
String resultsLimitStanza = "<iq id='sarasa' type='set'>" + "<query xmlns='urn:xmpp:mam:1' queryid='testid'>"
|
||||
+ "<x xmlns='jabber:x:data' type='submit'>" + "<field var='FORM_TYPE' type='hidden'>" + "<value>"
|
||||
+ MamElements.NAMESPACE + "</value>" + "</field>" + "</x>" + "<set xmlns='http://jabber.org/protocol/rsm'>"
|
||||
+ "<max>10</max>" + "</set>" + "</query>" + "</iq>";
|
||||
|
||||
@Test
|
||||
public void checkResultsLimit() throws Exception {
|
||||
Method methodAddResultsLimit = MamManager.class.getDeclaredMethod("addResultsLimit", Integer.class,
|
||||
MamQueryIQ.class);
|
||||
methodAddResultsLimit.setAccessible(true);
|
||||
|
||||
DataForm dataForm = getNewMamForm();
|
||||
MamQueryIQ mamQueryIQ = new MamQueryIQ(queryId, dataForm);
|
||||
mamQueryIQ.setType(IQ.Type.set);
|
||||
mamQueryIQ.setStanzaId("sarasa");
|
||||
|
||||
methodAddResultsLimit.invoke(mamManager, 10, mamQueryIQ);
|
||||
Assert.assertEquals(mamQueryIQ.toXML().toString(), resultsLimitStanza);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2016 Fernando Ramirez
|
||||
*
|
||||
* 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.mam;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jivesoftware.smackx.mam.element.MamElements;
|
||||
import org.jivesoftware.smackx.mam.element.MamQueryIQ;
|
||||
import org.jivesoftware.smackx.xdata.FormField;
|
||||
import org.jivesoftware.smackx.xdata.packet.DataForm;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
||||
public class RetrieveFormFieldsTest extends MamTest {
|
||||
|
||||
String retrieveFormFieldStanza = "<iq id='sarasa' type='get'>" + "<query xmlns='" + MamElements.NAMESPACE
|
||||
+ "' queryid='testid'></query>" + "</iq>";
|
||||
|
||||
String additionalFieldsStanza = "<x xmlns='jabber:x:data' type='submit'>" + "<field var='FORM_TYPE' type='hidden'>"
|
||||
+ "<value>" + MamElements.NAMESPACE + "</value>" + "</field>"
|
||||
+ "<field var='urn:example:xmpp:free-text-search' type='text-single'>" + "<value>Hi</value>" + "</field>"
|
||||
+ "<field var='urn:example:xmpp:stanza-content' type='jid-single'>" + "<value>Hi2</value>" + "</field>"
|
||||
+ "</x>";
|
||||
|
||||
@Test
|
||||
public void checkRetrieveFormFieldsStanza() throws Exception {
|
||||
Method methodPrepareMamQueryIQGet = MamManager.class.getDeclaredMethod("prepareMamQueryIQGet", String.class);
|
||||
methodPrepareMamQueryIQGet.setAccessible(true);
|
||||
|
||||
MamQueryIQ mamQueryIQ = (MamQueryIQ) methodPrepareMamQueryIQGet.invoke(mamManager, queryId);
|
||||
mamQueryIQ.setStanzaId("sarasa");
|
||||
|
||||
Assert.assertEquals(mamQueryIQ.toXML().toString(), retrieveFormFieldStanza);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkAddAdditionalFieldsStanza() throws Exception {
|
||||
Method methodAddAdditionalFields = MamManager.class.getDeclaredMethod("addAdditionalFields", List.class,
|
||||
DataForm.class);
|
||||
methodAddAdditionalFields.setAccessible(true);
|
||||
|
||||
DataForm dataForm = getNewMamForm();
|
||||
|
||||
List<FormField> additionalFields = new ArrayList<>();
|
||||
|
||||
FormField field1 = new FormField("urn:example:xmpp:free-text-search");
|
||||
field1.setType(FormField.Type.text_single);
|
||||
field1.addValue("Hi");
|
||||
|
||||
FormField field2 = new FormField("urn:example:xmpp:stanza-content");
|
||||
field2.setType(FormField.Type.jid_single);
|
||||
field2.addValue("Hi2");
|
||||
|
||||
additionalFields.add(field1);
|
||||
additionalFields.add(field2);
|
||||
|
||||
methodAddAdditionalFields.invoke(mamManager, additionalFields, dataForm);
|
||||
|
||||
String dataFormResult = dataForm.toXML().toString();
|
||||
|
||||
Assert.assertEquals(dataFormResult, additionalFieldsStanza);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2016 Fernando Ramirez
|
||||
*
|
||||
* 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.mam;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest;
|
||||
import org.igniterealtime.smack.inttest.SmackIntegrationTest;
|
||||
import org.igniterealtime.smack.inttest.SmackIntegrationTestEnvironment;
|
||||
import org.igniterealtime.smack.inttest.TestNotPossibleException;
|
||||
import org.jivesoftware.smack.SmackException.NoResponseException;
|
||||
import org.jivesoftware.smack.SmackException.NotConnectedException;
|
||||
import org.jivesoftware.smack.SmackException.NotLoggedInException;
|
||||
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
|
||||
import org.jivesoftware.smack.packet.Message;
|
||||
import org.jivesoftware.smackx.forward.packet.Forwarded;
|
||||
import org.jivesoftware.smackx.mam.MamManager.MamQueryResult;
|
||||
import org.junit.Assert;
|
||||
import org.jxmpp.jid.Jid;
|
||||
|
||||
public class MamIntegrationTest extends AbstractSmackIntegrationTest {
|
||||
|
||||
private final MamManager mamManagerConTwo;
|
||||
|
||||
public MamIntegrationTest(SmackIntegrationTestEnvironment environment) throws NoResponseException,
|
||||
XMPPErrorException, NotConnectedException, InterruptedException, TestNotPossibleException {
|
||||
super(environment);
|
||||
|
||||
mamManagerConTwo = MamManager.getInstanceFor(conTwo);
|
||||
|
||||
if (!mamManagerConTwo.isSupportedByServer()) {
|
||||
throw new TestNotPossibleException("Message Archive Management (XEP-0313) is not supported by the server.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Message getConTwoLastMessageSentFrom(Jid userOne) throws NoResponseException, XMPPErrorException,
|
||||
NotConnectedException, InterruptedException, NotLoggedInException {
|
||||
int pageSize = 20;
|
||||
MamQueryResult mamQueryResult = mamManagerConTwo.queryArchive(pageSize, null, null, userOne, null);
|
||||
|
||||
while (!mamQueryResult.mamFin.isComplete()) {
|
||||
mamQueryResult = mamManagerConTwo.pageNext(mamQueryResult, pageSize);
|
||||
}
|
||||
|
||||
List<Forwarded> forwardedMessages = mamQueryResult.forwardedMessages;
|
||||
Message messageFromMAM = (Message) forwardedMessages.get(forwardedMessages.size() - 1).getForwardedStanza();
|
||||
return messageFromMAM;
|
||||
}
|
||||
|
||||
private Message prepareMessage(Jid to, String messageId, String body) {
|
||||
Message message = new Message();
|
||||
message.setTo(to);
|
||||
message.setStanzaId(messageId);
|
||||
message.setBody(body);
|
||||
return message;
|
||||
}
|
||||
|
||||
@SmackIntegrationTest
|
||||
public void mamTest() throws Exception {
|
||||
Jid userOne = conOne.getUser().asEntityBareJid();
|
||||
Jid userTwo = conTwo.getUser().asEntityBareJid();
|
||||
|
||||
String messageId = UUID.randomUUID().toString();
|
||||
String messageBody = "test message";
|
||||
|
||||
Message message = prepareMessage(userTwo, messageId, messageBody);
|
||||
conOne.sendStanza(message);
|
||||
|
||||
Message mamMessage = getConTwoLastMessageSentFrom(userOne);
|
||||
|
||||
Assert.assertEquals(messageId, mamMessage.getStanzaId());
|
||||
Assert.assertEquals(messageBody, mamMessage.getBody());
|
||||
Assert.assertEquals(conOne.getUser(), mamMessage.getFrom());
|
||||
Assert.assertEquals(userTwo, mamMessage.getTo());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
/**
|
||||
*
|
||||
* Copyright 2016 Fernando Ramirez
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Message Archive Management (XEP-0313) integration tests.
|
||||
*/
|
||||
package org.jivesoftware.smackx.mam;
|
Loading…
Reference in a new issue