Apply refinements and fixes to the MAM code

SMACK-625.
This commit is contained in:
Florian Schmaus 2016-07-23 15:45:45 +02:00
parent 189cac072b
commit aeb385a022
21 changed files with 194 additions and 236 deletions

View File

@ -148,6 +148,19 @@ public abstract class Stanza implements TopLevelStreamElement {
return id != null; return id != null;
} }
/**
* Set the stanza id if none is set.
*
* @return the stanza id.
* @since 4.2
*/
public String setStanzaId() {
if (!hasStanzaIdSet()) {
setStanzaId(StanzaIdUtil.newStanzaId());
}
return getStanzaId();
}
/** /**
* Returns who the stanza(/packet) is being sent "to", or <tt>null</tt> if * Returns who the stanza(/packet) is being sent "to", or <tt>null</tt> if
* the value is not set. The XMPP protocol often makes the "to" * the value is not set. The XMPP protocol often makes the "to"

View File

@ -34,13 +34,14 @@ import org.jivesoftware.smack.XMPPConnectionRegistry;
import org.jivesoftware.smack.XMPPException.XMPPErrorException; import org.jivesoftware.smack.XMPPException.XMPPErrorException;
import org.jivesoftware.smack.filter.IQReplyFilter; import org.jivesoftware.smack.filter.IQReplyFilter;
import org.jivesoftware.smack.packet.IQ; import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.IQ.Type;
import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.util.Objects;
import org.jivesoftware.smackx.disco.ServiceDiscoveryManager; import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
import org.jivesoftware.smackx.forward.packet.Forwarded; import org.jivesoftware.smackx.forward.packet.Forwarded;
import org.jivesoftware.smackx.mam.element.MamElements; import org.jivesoftware.smackx.mam.element.MamElements;
import org.jivesoftware.smackx.mam.element.MamFinIQ; import org.jivesoftware.smackx.mam.element.MamFinIQ;
import org.jivesoftware.smackx.mam.element.MamPrefsIQ; import org.jivesoftware.smackx.mam.element.MamPrefsIQ;
import org.jivesoftware.smackx.mam.element.MamPrefsIQ.DefaultBehavior;
import org.jivesoftware.smackx.mam.element.MamQueryIQ; import org.jivesoftware.smackx.mam.element.MamQueryIQ;
import org.jivesoftware.smackx.mam.filter.MamResultFilter; import org.jivesoftware.smackx.mam.filter.MamResultFilter;
import org.jivesoftware.smackx.rsm.packet.RSMSet; import org.jivesoftware.smackx.rsm.packet.RSMSet;
@ -50,11 +51,12 @@ import org.jxmpp.jid.Jid;
import org.jxmpp.util.XmppDateTime; import org.jxmpp.util.XmppDateTime;
/** /**
* Message Archive Management Manager class. * A Manager for Message Archive Management (XEP-0313).
* *
* @see <a href="http://xmpp.org/extensions/xep-0313.html">XEP-0313: Message * @see <a href="http://xmpp.org/extensions/xep-0313.html">XEP-0313: Message
* Archive Management</a> * Archive Management</a>
* @author Fernando Ramirez and Florian Schmaus * @author Florian Schmaus
* @author Fernando Ramirez
* *
*/ */
public final class MamManager extends Manager { public final class MamManager extends Manager {
@ -223,7 +225,9 @@ public final class MamManager extends Manager {
addAdditionalFields(additionalFields, dataForm); addAdditionalFields(additionalFields, dataForm);
} }
MamQueryIQ mamQueryIQ = prepareMamQueryIQSet(dataForm, queryId); MamQueryIQ mamQueryIQ = new MamQueryIQ(queryId, dataForm);
mamQueryIQ.setType(IQ.Type.set);
addResultsLimit(max, mamQueryIQ); addResultsLimit(max, mamQueryIQ);
return queryArchive(mamQueryIQ); return queryArchive(mamQueryIQ);
} }
@ -273,11 +277,6 @@ public final class MamManager extends Manager {
dataForm.addField(formField); dataForm.addField(formField);
} }
private void preparePageQuery(MamQueryIQ mamQueryIQ, RSMSet rsmSet) {
mamQueryIQ.setType(IQ.Type.set);
mamQueryIQ.addExtension(rsmSet);
}
/** /**
* Returns a page of the archive. * Returns a page of the archive.
* *
@ -293,7 +292,8 @@ public final class MamManager extends Manager {
public MamQueryResult page(DataForm dataForm, RSMSet rsmSet) throws NoResponseException, XMPPErrorException, public MamQueryResult page(DataForm dataForm, RSMSet rsmSet) throws NoResponseException, XMPPErrorException,
NotConnectedException, InterruptedException, NotLoggedInException { NotConnectedException, InterruptedException, NotLoggedInException {
MamQueryIQ mamQueryIQ = new MamQueryIQ(UUID.randomUUID().toString(), dataForm); MamQueryIQ mamQueryIQ = new MamQueryIQ(UUID.randomUUID().toString(), dataForm);
preparePageQuery(mamQueryIQ, rsmSet); mamQueryIQ.setType(IQ.Type.set);
mamQueryIQ.addExtension(rsmSet);
return queryArchive(mamQueryIQ); return queryArchive(mamQueryIQ);
} }
@ -373,20 +373,11 @@ public final class MamManager extends Manager {
public List<FormField> retrieveFormFields() throws NoResponseException, XMPPErrorException, NotConnectedException, public List<FormField> retrieveFormFields() throws NoResponseException, XMPPErrorException, NotConnectedException,
InterruptedException, NotLoggedInException { InterruptedException, NotLoggedInException {
String queryId = UUID.randomUUID().toString(); String queryId = UUID.randomUUID().toString();
MamQueryIQ mamQueryIQ = prepareMamQueryIQGet(queryId); MamQueryIQ mamQueryIq = new MamQueryIQ(queryId);
return queryFormFields(mamQueryIQ);
}
private MamQueryIQ prepareMamQueryIQSet(DataForm dataForm, String queryId) { MamQueryIQ mamResponseQueryIq = connection().createPacketCollectorAndSend(mamQueryIq).nextResultOrThrow();
MamQueryIQ mamQueryIQ = new MamQueryIQ(queryId, dataForm);
mamQueryIQ.setType(IQ.Type.set);
return mamQueryIQ;
}
private MamQueryIQ prepareMamQueryIQGet(String queryId) { return mamResponseQueryIq.getDataForm().getFields();
MamQueryIQ mamQueryIQ = new MamQueryIQ(queryId, null);
mamQueryIQ.setType(IQ.Type.get);
return mamQueryIQ;
} }
private MamQueryResult queryArchive(MamQueryIQ mamQueryIq) throws NoResponseException, XMPPErrorException, private MamQueryResult queryArchive(MamQueryIQ mamQueryIq) throws NoResponseException, XMPPErrorException,
@ -435,23 +426,6 @@ public final class MamManager extends Manager {
} }
} }
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. * Returns true if Message Archive Management is supported by the server.
* *
@ -466,7 +440,7 @@ public final class MamManager extends Manager {
return ServiceDiscoveryManager.getInstanceFor(connection()).serverSupportsFeature(MamElements.NAMESPACE); return ServiceDiscoveryManager.getInstanceFor(connection()).serverSupportsFeature(MamElements.NAMESPACE);
} }
private DataForm getNewMamForm() { private static DataForm getNewMamForm() {
FormField field = new FormField(FormField.FORM_TYPE); FormField field = new FormField(FormField.FORM_TYPE);
field.setType(FormField.Type.hidden); field.setType(FormField.Type.hidden);
field.addValue(MamElements.NAMESPACE); field.addValue(MamElements.NAMESPACE);
@ -487,15 +461,10 @@ public final class MamManager extends Manager {
*/ */
public MamPrefsResult retrieveArchivingPreferences() throws NoResponseException, XMPPErrorException, public MamPrefsResult retrieveArchivingPreferences() throws NoResponseException, XMPPErrorException,
NotConnectedException, InterruptedException, NotLoggedInException { NotConnectedException, InterruptedException, NotLoggedInException {
MamPrefsIQ mamPrefIQ = prepareRetrievePreferencesStanza(); MamPrefsIQ mamPrefIQ = new MamPrefsIQ();
return queryMamPrefs(mamPrefIQ); return queryMamPrefs(mamPrefIQ);
} }
private MamPrefsIQ prepareRetrievePreferencesStanza() {
MamPrefsIQ mamPrefIQ = new MamPrefsIQ(Type.get, null, null, null);
return mamPrefIQ;
}
/** /**
* Update the preferences in the server. * Update the preferences in the server.
* *
@ -505,9 +474,8 @@ public final class MamManager extends Manager {
* @param neverJids * @param neverJids
* is the list of JIDs that should never have messages to/from * is the list of JIDs that should never have messages to/from
* archived in the user's store * archived in the user's store
* @param defaultField * @param defaultBehavior
* can be "roster", "always", "never" (look at the XEP-0313 * can be "roster", "always", "never" (see XEP-0313)
* documentation)
* @return the MAM preferences result * @return the MAM preferences result
* @throws NoResponseException * @throws NoResponseException
* @throws XMPPErrorException * @throws XMPPErrorException
@ -515,18 +483,14 @@ public final class MamManager extends Manager {
* @throws InterruptedException * @throws InterruptedException
* @throws NotLoggedInException * @throws NotLoggedInException
*/ */
public MamPrefsResult updateArchivingPreferences(List<Jid> alwaysJids, List<Jid> neverJids, String defaultField) public MamPrefsResult updateArchivingPreferences(List<Jid> alwaysJids, List<Jid> neverJids, DefaultBehavior defaultBehavior)
throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException, throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException,
NotLoggedInException { NotLoggedInException {
MamPrefsIQ mamPrefIQ = prepareUpdatePreferencesStanza(alwaysJids, neverJids, defaultField); Objects.requireNonNull(defaultBehavior, "Default behavior must be set");
MamPrefsIQ mamPrefIQ = new MamPrefsIQ(alwaysJids, neverJids, defaultBehavior);
return queryMamPrefs(mamPrefIQ); 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. * MAM preferences result class.
* *
@ -544,16 +508,8 @@ public final class MamManager extends Manager {
private MamPrefsResult queryMamPrefs(MamPrefsIQ mamPrefsIQ) throws NoResponseException, XMPPErrorException, private MamPrefsResult queryMamPrefs(MamPrefsIQ mamPrefsIQ) throws NoResponseException, XMPPErrorException,
NotConnectedException, InterruptedException, NotLoggedInException { NotConnectedException, InterruptedException, NotLoggedInException {
final XMPPConnection connection = getAuthenticatedConnectionOrThrow(); final XMPPConnection connection = getAuthenticatedConnectionOrThrow();
MamPrefsIQ mamPrefsResultIQ = null;
PacketCollector prefsResultIQCollector = connection
.createPacketCollector(new IQReplyFilter(mamPrefsIQ, connection));
try { MamPrefsIQ mamPrefsResultIQ = connection.createPacketCollectorAndSend(mamPrefsIQ).nextResultOrThrow();
connection.sendStanza(mamPrefsIQ);
mamPrefsResultIQ = prefsResultIQCollector.nextResultOrThrow();
} finally {
prefsResultIQCollector.cancel();
}
return new MamPrefsResult(mamPrefsResultIQ, DataForm.from(mamPrefsIQ)); return new MamPrefsResult(mamPrefsResultIQ, DataForm.from(mamPrefsIQ));
} }

View File

@ -153,7 +153,7 @@ public class MamElements {
/** /**
* list of JIDs. * list of JIDs.
*/ */
private List<Jid> alwaysJids; private final List<Jid> alwaysJids;
/** /**
* Always JID list element constructor. * Always JID list element constructor.

View File

@ -33,6 +33,13 @@ import org.jxmpp.jid.Jid;
*/ */
public class MamPrefsIQ extends IQ { public class MamPrefsIQ extends IQ {
public enum DefaultBehavior {
always,
never,
roster,
;
}
/** /**
* the preferences element. * the preferences element.
*/ */
@ -43,65 +50,44 @@ public class MamPrefsIQ extends IQ {
*/ */
public static final String NAMESPACE = MamElements.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. * list of always.
*/ */
private List<Jid> alwaysJids; private final List<Jid> alwaysJids;
/** /**
* list of never. * list of never.
*/ */
private List<Jid> neverJids; private final List<Jid> neverJids;
/** /**
* default field. * default field.
*/ */
private String defaultField; private final DefaultBehavior defaultBehavior;
/**
* Construct a new MAM {@code <prefs/>} IQ retrieval request (IQ type 'get').
*/
public MamPrefsIQ() {
super(ELEMENT, NAMESPACE);
alwaysJids = null;
neverJids = null;
defaultBehavior = null;
}
/** /**
* MAM preferences IQ constructor. * MAM preferences IQ constructor.
* *
* @param type
* @param alwaysJids * @param alwaysJids
* @param neverJids * @param neverJids
* @param defaultField * @param defaultBehavior
*/ */
public MamPrefsIQ(Type type, List<Jid> alwaysJids, List<Jid> neverJids, String defaultField) { public MamPrefsIQ(List<Jid> alwaysJids, List<Jid> neverJids, DefaultBehavior defaultBehavior) {
super(ELEMENT, NAMESPACE); super(ELEMENT, NAMESPACE);
this.setType(type); setType(Type.set);
this.isUpdate = this.getType().equals(Type.set);
this.isResult = this.getType().equals(Type.result);
this.alwaysJids = alwaysJids; this.alwaysJids = alwaysJids;
this.neverJids = neverJids; this.neverJids = neverJids;
this.defaultField = defaultField; this.defaultBehavior = defaultBehavior;
}
/**
* 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;
} }
/** /**
@ -123,19 +109,24 @@ public class MamPrefsIQ extends IQ {
} }
/** /**
* Get the default field. * Get the default behavior.
* *
* @return the default field * @return the default behavior.
*/ */
public String getDefault() { public DefaultBehavior getDefault() {
return defaultField; return defaultBehavior;
} }
@Override @Override
protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) { protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) {
if (isUpdate || isResult) { if (getType().equals(IQ.Type.set) || getType().equals(IQ.Type.result)) {
xml.attribute("default", defaultField); xml.attribute("default", defaultBehavior);
}
if (alwaysJids == null && neverJids == null) {
xml.setEmptyElement();
return xml;
} }
xml.rightAngleBracket(); xml.rightAngleBracket();

View File

@ -51,6 +51,7 @@ public class MamQueryIQ extends IQ {
*/ */
public MamQueryIQ(String queryId) { public MamQueryIQ(String queryId) {
this(queryId, null, null); this(queryId, null, null);
setType(IQ.Type.get);
} }
/** /**

View File

@ -31,7 +31,7 @@ import org.jivesoftware.smackx.mam.element.MamQueryIQ;
*/ */
public class MamResultFilter extends FlexibleStanzaTypeFilter<Message> { public class MamResultFilter extends FlexibleStanzaTypeFilter<Message> {
private String queryId; private final String queryId;
public MamResultFilter(MamQueryIQ mamQueryIQ) { public MamResultFilter(MamQueryIQ mamQueryIQ) {
super(Message.class); super(Message.class);

View File

@ -17,6 +17,7 @@
package org.jivesoftware.smackx.mam.provider; package org.jivesoftware.smackx.mam.provider;
import org.jivesoftware.smack.provider.IQProvider; import org.jivesoftware.smack.provider.IQProvider;
import org.jivesoftware.smack.util.ParserUtils;
import org.jivesoftware.smackx.mam.element.MamFinIQ; import org.jivesoftware.smackx.mam.element.MamFinIQ;
import org.jivesoftware.smackx.rsm.packet.RSMSet; import org.jivesoftware.smackx.rsm.packet.RSMSet;
import org.jivesoftware.smackx.rsm.provider.RSMSetProvider; import org.jivesoftware.smackx.rsm.provider.RSMSetProvider;
@ -35,20 +36,23 @@ public class MamFinIQProvider extends IQProvider<MamFinIQ> {
@Override @Override
public MamFinIQ parse(XmlPullParser parser, int initialDepth) throws Exception { public MamFinIQ parse(XmlPullParser parser, int initialDepth) throws Exception {
String queryId = parser.getAttributeValue("", "queryid"); String queryId = parser.getAttributeValue("", "queryid");
boolean complete = Boolean.parseBoolean(parser.getAttributeValue("", "complete")); boolean complete = ParserUtils.getBooleanAttribute(parser, "complete", false);
boolean stable = Boolean.parseBoolean(parser.getAttributeValue("", "stable")); boolean stable = ParserUtils.getBooleanAttribute(parser, "stable", true);
RSMSet rsmSet = null; RSMSet rsmSet = null;
outerloop: while (true) { outerloop: while (true) {
int eventType = parser.next(); int eventType = parser.next();
if (eventType == XmlPullParser.START_TAG) { switch (eventType) {
case XmlPullParser.START_TAG:
if (parser.getName().equals(RSMSet.ELEMENT)) { if (parser.getName().equals(RSMSet.ELEMENT)) {
rsmSet = new RSMSetProvider().parse(parser); rsmSet = RSMSetProvider.INSTANCE.parse(parser);
} }
} else if (eventType == XmlPullParser.END_TAG) { break;
case XmlPullParser.END_TAG:
if (parser.getDepth() == initialDepth) { if (parser.getDepth() == initialDepth) {
break outerloop; break outerloop;
} }
break;
} }
} }

View File

@ -16,15 +16,17 @@
*/ */
package org.jivesoftware.smackx.mam.provider; package org.jivesoftware.smackx.mam.provider;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.jivesoftware.smack.packet.IQ.Type;
import org.jivesoftware.smack.provider.IQProvider; import org.jivesoftware.smack.provider.IQProvider;
import org.jivesoftware.smackx.mam.element.MamPrefsIQ; import org.jivesoftware.smackx.mam.element.MamPrefsIQ;
import org.jivesoftware.smackx.mam.element.MamPrefsIQ.DefaultBehavior;
import org.jxmpp.jid.Jid; import org.jxmpp.jid.Jid;
import org.jxmpp.jid.impl.JidCreate; import org.jxmpp.jid.impl.JidCreate;
import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
/** /**
* MAM Preferences IQ Provider class. * MAM Preferences IQ Provider class.
@ -37,9 +39,13 @@ import org.xmlpull.v1.XmlPullParser;
public class MamPrefsIQProvider extends IQProvider<MamPrefsIQ> { public class MamPrefsIQProvider extends IQProvider<MamPrefsIQ> {
@Override @Override
public MamPrefsIQ parse(XmlPullParser parser, int initialDepth) throws Exception { public MamPrefsIQ parse(XmlPullParser parser, int initialDepth) throws XmlPullParserException, IOException {
String iqType = parser.getAttributeValue("", "type"); String iqType = parser.getAttributeValue("", "type");
String defaultField = parser.getAttributeValue("", "default"); String defaultBehaviorString = parser.getAttributeValue("", "default");
DefaultBehavior defaultBehavior = null;
if (defaultBehaviorString != null) {
defaultBehavior = DefaultBehavior.valueOf(defaultBehaviorString);
}
if (iqType == null) { if (iqType == null) {
iqType = "result"; iqType = "result";
@ -49,40 +55,52 @@ public class MamPrefsIQProvider extends IQProvider<MamPrefsIQ> {
List<Jid> neverJids = null; List<Jid> neverJids = null;
outerloop: while (true) { outerloop: while (true) {
int eventType = parser.next(); final int eventType = parser.next();
if (eventType == XmlPullParser.START_TAG) { final String name = parser.getName();
if (parser.getName().equals("always")) { switch (eventType) {
case XmlPullParser.START_TAG:
switch (name) {
case "always":
alwaysJids = iterateJids(parser); alwaysJids = iterateJids(parser);
} break;
if (parser.getName().equals("never")) { case "never":
neverJids = iterateJids(parser); neverJids = iterateJids(parser);
break;
} }
} else if (eventType == XmlPullParser.END_TAG) { break;
case XmlPullParser.END_TAG:
if (parser.getDepth() == initialDepth) { if (parser.getDepth() == initialDepth) {
break outerloop; break outerloop;
} }
break;
} }
} }
return new MamPrefsIQ(Type.fromString(iqType), alwaysJids, neverJids, defaultField); return new MamPrefsIQ(alwaysJids, neverJids, defaultBehavior);
} }
private List<Jid> iterateJids(XmlPullParser parser) throws Exception { private static List<Jid> iterateJids(XmlPullParser parser) throws XmlPullParserException, IOException {
List<Jid> jids = new ArrayList<>(); List<Jid> jids = new ArrayList<>();
int initialDepth = parser.getDepth(); int initialDepth = parser.getDepth();
outerloop: while (true) { outerloop: while (true) {
int eventType = parser.next(); final int eventType = parser.next();
if (eventType == XmlPullParser.START_TAG) { final String name = parser.getName();
if (parser.getName().equals("jid")) { switch (eventType) {
case XmlPullParser.START_TAG:
switch (name) {
case "jid":
parser.next(); parser.next();
jids.add(JidCreate.from(parser.getText())); jids.add(JidCreate.from(parser.getText()));
break;
} }
} else if (eventType == XmlPullParser.END_TAG) { break;
case XmlPullParser.END_TAG:
if (parser.getDepth() == initialDepth) { if (parser.getDepth() == initialDepth) {
break outerloop; break outerloop;
} }
break;
} }
} }

View File

@ -39,16 +39,22 @@ public class MamQueryIQProvider extends IQProvider<MamQueryIQ> {
String node = parser.getAttributeValue("", "node"); String node = parser.getAttributeValue("", "node");
outerloop: while (true) { outerloop: while (true) {
int eventType = parser.next(); final int eventType = parser.next();
final String name = parser.getName();
if (eventType == XmlPullParser.START_TAG) { switch (eventType) {
if (parser.getName().equals(DataForm.ELEMENT)) { case XmlPullParser.START_TAG:
dataForm = new DataFormProvider().parse(parser); switch (name) {
case DataForm.ELEMENT:
dataForm = DataFormProvider.INSTANCE.parse(parser);
break;
} }
} else if (eventType == XmlPullParser.END_TAG) { break;
case XmlPullParser.END_TAG:
if (parser.getDepth() == initialDepth) { if (parser.getDepth() == initialDepth) {
break outerloop; break outerloop;
} }
break;
} }
} }

View File

@ -39,15 +39,21 @@ public class MamResultProvider extends ExtensionElementProvider<MamResultExtensi
String id = parser.getAttributeValue("", "id"); String id = parser.getAttributeValue("", "id");
outerloop: while (true) { outerloop: while (true) {
int eventType = parser.next(); final int eventType = parser.next();
if (eventType == XmlPullParser.START_TAG) { final String name = parser.getName();
if (parser.getName().equals(Forwarded.ELEMENT)) { switch (eventType) {
forwarded = new ForwardedProvider().parse(parser); case XmlPullParser.START_TAG:
switch (name) {
case Forwarded.ELEMENT:
forwarded = ForwardedProvider.INSTANCE.parse(parser);
break;
} }
} else if (eventType == XmlPullParser.END_TAG) { break;
case XmlPullParser.END_TAG:
if (parser.getDepth() == initialDepth) { if (parser.getDepth() == initialDepth) {
break outerloop; break outerloop;
} }
break;
} }
} }

View File

@ -31,7 +31,7 @@ import org.jxmpp.util.XmppDateTime;
public class FiltersTest extends MamTest { public class FiltersTest extends MamTest {
private String getMamXMemberWith(List<String> fieldsNames, List<String> fieldsValues) { private static String getMamXMemberWith(List<String> fieldsNames, List<String> fieldsValues) {
String xml = "<x xmlns='jabber:x:data' type='submit'>" + "<field var='FORM_TYPE' type='hidden'>" + "<value>" String xml = "<x xmlns='jabber:x:data' type='submit'>" + "<field var='FORM_TYPE' type='hidden'>" + "<value>"
+ MamElements.NAMESPACE + "</value>" + "</field>"; + MamElements.NAMESPACE + "</value>" + "</field>";

View File

@ -28,16 +28,10 @@ import org.xmlpull.v1.XmlPullParser;
public class MamFinProviderTest extends MamTest { public class MamFinProviderTest extends MamTest {
String exmapleMamFinXml = "<fin xmlns='urn:xmpp:mam:1' stable='true'>" static final 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 xmlns='http://jabber.org/protocol/rsm'>" + "<max>10</max>" + "<after>09af3-cc343-b409f</after>"
+ "</set>" + "</fin>"; + "</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 @Test
public void checkMamFinProvider() throws Exception { public void checkMamFinProvider() throws Exception {
XmlPullParser parser = PacketParserUtils.getParserFor(exmapleMamFinXml); XmlPullParser parser = PacketParserUtils.getParserFor(exmapleMamFinXml);
@ -54,7 +48,18 @@ public class MamFinProviderTest extends MamTest {
@Test @Test
public void checkQueryLimitedResults() throws Exception { public void checkQueryLimitedResults() throws Exception {
IQ iq = (IQ) PacketParserUtils.parseStanza(getIQLimitedResultsExample()); // @formatter:off
final String IQ_LIMITED_RESULTS_EXAMPLE = "<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>";
// @formatter:on
IQ iq = (IQ) PacketParserUtils.parseStanza(IQ_LIMITED_RESULTS_EXAMPLE);
MamFinIQ mamFinIQ = (MamFinIQ) iq; MamFinIQ mamFinIQ = (MamFinIQ) iq;
Assert.assertEquals(mamFinIQ.getType(), Type.result); Assert.assertEquals(mamFinIQ.getType(), Type.result);

View File

@ -50,20 +50,20 @@ public class MamPrefIQProviderTest extends MamTest {
XmlPullParser parser1 = PacketParserUtils.getParserFor(exampleMamPrefsIQ1); XmlPullParser parser1 = PacketParserUtils.getParserFor(exampleMamPrefsIQ1);
MamPrefsIQ mamPrefIQ1 = new MamPrefsIQProvider().parse(parser1); MamPrefsIQ mamPrefIQ1 = new MamPrefsIQProvider().parse(parser1);
Assert.assertTrue(mamPrefIQ1.isUpdate()); Assert.assertEquals(IQ.Type.set, mamPrefIQ1.getType());
Assert.assertEquals(mamPrefIQ1.getAlwaysJids().get(0), "romeo@montague.lit"); Assert.assertEquals(mamPrefIQ1.getAlwaysJids().get(0), "romeo@montague.lit");
Assert.assertEquals(mamPrefIQ1.getNeverJids().get(0), "montague@montague.lit"); Assert.assertEquals(mamPrefIQ1.getNeverJids().get(0), "montague@montague.lit");
XmlPullParser parser2 = PacketParserUtils.getParserFor(exampleMamPrefsIQ2); XmlPullParser parser2 = PacketParserUtils.getParserFor(exampleMamPrefsIQ2);
MamPrefsIQ mamPrefIQ2 = new MamPrefsIQProvider().parse(parser2); MamPrefsIQ mamPrefIQ2 = new MamPrefsIQProvider().parse(parser2);
Assert.assertTrue(mamPrefIQ2.isUpdate()); Assert.assertEquals(IQ.Type.set, mamPrefIQ2.getType());
Assert.assertEquals(mamPrefIQ2.getAlwaysJids().get(0), "romeo@montague.lit"); Assert.assertEquals(mamPrefIQ2.getAlwaysJids().get(0), "romeo@montague.lit");
Assert.assertEquals(mamPrefIQ2.getAlwaysJids().get(1), "montague@montague.lit"); Assert.assertEquals(mamPrefIQ2.getAlwaysJids().get(1), "montague@montague.lit");
Assert.assertTrue(mamPrefIQ2.getNeverJids().isEmpty()); Assert.assertTrue(mamPrefIQ2.getNeverJids().isEmpty());
XmlPullParser parser3 = PacketParserUtils.getParserFor(exampleMamPrefsIQ3); XmlPullParser parser3 = PacketParserUtils.getParserFor(exampleMamPrefsIQ3);
MamPrefsIQ mamPrefIQ3 = new MamPrefsIQProvider().parse(parser3); MamPrefsIQ mamPrefIQ3 = new MamPrefsIQProvider().parse(parser3);
Assert.assertFalse(mamPrefIQ3.isUpdate()); Assert.assertEquals(IQ.Type.set, mamPrefIQ3.getType());
} }
@Test @Test

View File

@ -16,8 +16,7 @@
*/ */
package org.jivesoftware.smackx.mam; package org.jivesoftware.smackx.mam;
import java.lang.reflect.Method; import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smackx.mam.element.MamQueryIQ; import org.jivesoftware.smackx.mam.element.MamQueryIQ;
import org.jivesoftware.smackx.rsm.packet.RSMSet; import org.jivesoftware.smackx.rsm.packet.RSMSet;
import org.jivesoftware.smackx.xdata.packet.DataForm; import org.jivesoftware.smackx.xdata.packet.DataForm;
@ -27,25 +26,21 @@ import org.junit.Assert;
public class PagingTest extends MamTest { public class PagingTest extends MamTest {
String pagingStanza = "<iq id='sarasa' type='set'>" + "<query xmlns='urn:xmpp:mam:1' queryid='testid'>" private static final 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'>" + "<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'>" + "<value>urn:xmpp:mam:1</value>" + "</field>" + "</x>" + "<set xmlns='http://jabber.org/protocol/rsm'>"
+ "<max>10</max>" + "</set>" + "</query>" + "</iq>"; + "<max>10</max>" + "</set>" + "</query>" + "</iq>";
@Test @Test
public void checkPageQueryStanza() throws Exception { public void checkPageQueryStanza() throws Exception {
Method methodPreparePageQuery = MamManager.class.getDeclaredMethod("preparePageQuery", MamQueryIQ.class,
RSMSet.class);
methodPreparePageQuery.setAccessible(true);
DataForm dataForm = getNewMamForm(); DataForm dataForm = getNewMamForm();
int max = 10; int max = 10;
RSMSet rsmSet = new RSMSet(max); RSMSet rsmSet = new RSMSet(max);
MamQueryIQ mamQueryIQ = new MamQueryIQ(queryId, dataForm); MamQueryIQ mamQueryIQ = new MamQueryIQ(queryId, dataForm);
mamQueryIQ.setStanzaId("sarasa"); mamQueryIQ.setStanzaId("sarasa");
mamQueryIQ.setType(IQ.Type.set);
methodPreparePageQuery.invoke(mamManager, mamQueryIQ, rsmSet); mamQueryIQ.addExtension(rsmSet);
Assert.assertEquals(mamQueryIQ.getDataForm(), dataForm); Assert.assertEquals(mamQueryIQ.getDataForm(), dataForm);
Assert.assertEquals(mamQueryIQ.getDataForm().getFields().get(0).getValues().get(0), "urn:xmpp:mam:1"); Assert.assertEquals(mamQueryIQ.getDataForm().getFields().get(0).getValues().get(0), "urn:xmpp:mam:1");

View File

@ -16,7 +16,6 @@
*/ */
package org.jivesoftware.smackx.mam; package org.jivesoftware.smackx.mam;
import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -25,12 +24,13 @@ import org.jxmpp.jid.Jid;
import org.jxmpp.jid.impl.JidCreate; import org.jxmpp.jid.impl.JidCreate;
import org.jivesoftware.smackx.mam.element.MamElements; import org.jivesoftware.smackx.mam.element.MamElements;
import org.jivesoftware.smackx.mam.element.MamPrefsIQ; import org.jivesoftware.smackx.mam.element.MamPrefsIQ;
import org.jivesoftware.smackx.mam.element.MamPrefsIQ.DefaultBehavior;
import org.junit.Assert; import org.junit.Assert;
public class PreferencesTest extends MamTest { public class PreferencesTest {
String retrievePrefsStanzaExample = "<iq id='sarasa' type='get'>" + "<prefs xmlns='" + MamElements.NAMESPACE String retrievePrefsStanzaExample = "<iq id='sarasa' type='get'>" + "<prefs xmlns='" + MamElements.NAMESPACE
+ "'></prefs>" + "</iq>"; + "'/>" + "</iq>";
String updatePrefsStanzaExample = "<iq id='sarasa' type='set'>" + "<prefs xmlns='" + MamElements.NAMESPACE String updatePrefsStanzaExample = "<iq id='sarasa' type='set'>" + "<prefs xmlns='" + MamElements.NAMESPACE
+ "' default='roster'>" + "<always>" + "<jid>romeo@montague.lit</jid>" + "<jid>other@montague.lit</jid>" + "' default='roster'>" + "<always>" + "<jid>romeo@montague.lit</jid>" + "<jid>other@montague.lit</jid>"
@ -38,21 +38,13 @@ public class PreferencesTest extends MamTest {
@Test @Test
public void checkRetrievePrefsStanza() throws Exception { public void checkRetrievePrefsStanza() throws Exception {
Method prepareRetrievePreferencesStanza = MamManager.class MamPrefsIQ mamPrefIQ = new MamPrefsIQ();
.getDeclaredMethod("prepareRetrievePreferencesStanza");
prepareRetrievePreferencesStanza.setAccessible(true);
MamPrefsIQ mamPrefIQ = (MamPrefsIQ) prepareRetrievePreferencesStanza.invoke(mamManager);
mamPrefIQ.setStanzaId("sarasa"); mamPrefIQ.setStanzaId("sarasa");
Assert.assertEquals(mamPrefIQ.toXML().toString(), retrievePrefsStanzaExample); Assert.assertEquals(mamPrefIQ.toXML().toString(), retrievePrefsStanzaExample);
} }
@Test @Test
public void checkUpdatePrefsStanza() throws Exception { 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<>(); List<Jid> alwaysJids = new ArrayList<>();
alwaysJids.add(JidCreate.from("romeo@montague.lit")); alwaysJids.add(JidCreate.from("romeo@montague.lit"));
alwaysJids.add(JidCreate.from("other@montague.lit")); alwaysJids.add(JidCreate.from("other@montague.lit"));
@ -60,7 +52,7 @@ public class PreferencesTest extends MamTest {
List<Jid> neverJids = new ArrayList<>(); List<Jid> neverJids = new ArrayList<>();
neverJids.add(JidCreate.from("montague@montague.lit")); neverJids.add(JidCreate.from("montague@montague.lit"));
MamPrefsIQ mamPrefIQ = (MamPrefsIQ) prepareUpdatePreferencesStanza.invoke(mamManager, alwaysJids, neverJids, "roster"); MamPrefsIQ mamPrefIQ = new MamPrefsIQ(alwaysJids, neverJids, DefaultBehavior.roster);
mamPrefIQ.setStanzaId("sarasa"); mamPrefIQ.setStanzaId("sarasa");
Assert.assertEquals(mamPrefIQ.toXML().toString(), updatePrefsStanzaExample); Assert.assertEquals(mamPrefIQ.toXML().toString(), updatePrefsStanzaExample);
} }

View File

@ -30,10 +30,10 @@ import org.junit.Assert;
public class RetrieveFormFieldsTest extends MamTest { public class RetrieveFormFieldsTest extends MamTest {
String retrieveFormFieldStanza = "<iq id='sarasa' type='get'>" + "<query xmlns='" + MamElements.NAMESPACE private static final String retrieveFormFieldStanza = "<iq id='sarasa' type='get'>" + "<query xmlns='" + MamElements.NAMESPACE
+ "' queryid='testid'></query>" + "</iq>"; + "' queryid='testid'></query>" + "</iq>";
String additionalFieldsStanza = "<x xmlns='jabber:x:data' type='submit'>" + "<field var='FORM_TYPE' type='hidden'>" private static final String additionalFieldsStanza = "<x xmlns='jabber:x:data' type='submit'>" + "<field var='FORM_TYPE' type='hidden'>"
+ "<value>" + MamElements.NAMESPACE + "</value>" + "</field>" + "<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:free-text-search' type='text-single'>" + "<value>Hi</value>" + "</field>"
+ "<field var='urn:example:xmpp:stanza-content' type='jid-single'>" + "<value>Hi2</value>" + "</field>" + "<field var='urn:example:xmpp:stanza-content' type='jid-single'>" + "<value>Hi2</value>" + "</field>"
@ -41,10 +41,7 @@ public class RetrieveFormFieldsTest extends MamTest {
@Test @Test
public void checkRetrieveFormFieldsStanza() throws Exception { public void checkRetrieveFormFieldsStanza() throws Exception {
Method methodPrepareMamQueryIQGet = MamManager.class.getDeclaredMethod("prepareMamQueryIQGet", String.class); MamQueryIQ mamQueryIQ = new MamQueryIQ(queryId);
methodPrepareMamQueryIQGet.setAccessible(true);
MamQueryIQ mamQueryIQ = (MamQueryIQ) methodPrepareMamQueryIQGet.invoke(mamManager, queryId);
mamQueryIQ.setStanzaId("sarasa"); mamQueryIQ.setStanzaId("sarasa");
Assert.assertEquals(mamQueryIQ.toXML().toString(), retrieveFormFieldStanza); Assert.assertEquals(mamQueryIQ.toXML().toString(), retrieveFormFieldStanza);

View File

@ -36,6 +36,8 @@ import org.xmlpull.v1.XmlPullParser;
*/ */
public class ForwardedProvider extends ExtensionElementProvider<Forwarded> { public class ForwardedProvider extends ExtensionElementProvider<Forwarded> {
public static final ForwardedProvider INSTANCE = new ForwardedProvider();
private static final Logger LOGGER = Logger.getLogger(ForwardedProvider.class.getName()); private static final Logger LOGGER = Logger.getLogger(ForwardedProvider.class.getName());
@Override @Override

View File

@ -1,6 +1,6 @@
/** /**
* *
* Copyright © 2014 Florian Schmaus * Copyright © 2014-2016 Florian Schmaus
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -26,6 +26,8 @@ import org.xmlpull.v1.XmlPullParserException;
public class RSMSetProvider extends ExtensionElementProvider<RSMSet> { public class RSMSetProvider extends ExtensionElementProvider<RSMSet> {
public static final RSMSetProvider INSTANCE = new RSMSetProvider();
@Override @Override
public RSMSet parse(XmlPullParser parser, int initialDepth) public RSMSet parse(XmlPullParser parser, int initialDepth)
throws XmlPullParserException, IOException { throws XmlPullParserException, IOException {

View File

@ -40,6 +40,8 @@ import java.util.List;
*/ */
public class DataFormProvider extends ExtensionElementProvider<DataForm> { public class DataFormProvider extends ExtensionElementProvider<DataForm> {
public static final DataFormProvider INSTANCE = new DataFormProvider();
@Override @Override
public DataForm parse(XmlPullParser parser, int initialDepth) throws public DataForm parse(XmlPullParser parser, int initialDepth) throws
Exception { Exception {

View File

@ -16,8 +16,9 @@
*/ */
package org.jivesoftware.smackx.mam; package org.jivesoftware.smackx.mam;
import static org.junit.Assert.assertEquals;
import java.util.List; import java.util.List;
import java.util.UUID;
import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest; import org.igniterealtime.smack.inttest.AbstractSmackIntegrationTest;
import org.igniterealtime.smack.inttest.SmackIntegrationTest; import org.igniterealtime.smack.inttest.SmackIntegrationTest;
@ -30,8 +31,7 @@ import org.jivesoftware.smack.XMPPException.XMPPErrorException;
import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smackx.forward.packet.Forwarded; import org.jivesoftware.smackx.forward.packet.Forwarded;
import org.jivesoftware.smackx.mam.MamManager.MamQueryResult; import org.jivesoftware.smackx.mam.MamManager.MamQueryResult;
import org.junit.Assert; import org.jxmpp.jid.EntityBareJid;
import org.jxmpp.jid.Jid;
public class MamIntegrationTest extends AbstractSmackIntegrationTest { public class MamIntegrationTest extends AbstractSmackIntegrationTest {
@ -49,8 +49,19 @@ public class MamIntegrationTest extends AbstractSmackIntegrationTest {
} }
private Message getConTwoLastMessageSentFrom(Jid userOne) throws NoResponseException, XMPPErrorException, @SmackIntegrationTest
NotConnectedException, InterruptedException, NotLoggedInException { public void mamTest() throws NotConnectedException, InterruptedException, NoResponseException, XMPPErrorException,
NotLoggedInException {
EntityBareJid userOne = conOne.getUser().asEntityBareJid();
EntityBareJid userTwo = conTwo.getUser().asEntityBareJid();
Message message = new Message(userTwo);
String messageId = message.setStanzaId();
String messageBody = "test message";
message.setBody(messageBody);
conOne.sendStanza(message);
int pageSize = 20; int pageSize = 20;
MamQueryResult mamQueryResult = mamManagerConTwo.queryArchive(pageSize, null, null, userOne, null); MamQueryResult mamQueryResult = mamManagerConTwo.queryArchive(pageSize, null, null, userOne, null);
@ -59,35 +70,12 @@ public class MamIntegrationTest extends AbstractSmackIntegrationTest {
} }
List<Forwarded> forwardedMessages = mamQueryResult.forwardedMessages; List<Forwarded> forwardedMessages = mamQueryResult.forwardedMessages;
Message messageFromMAM = (Message) forwardedMessages.get(forwardedMessages.size() - 1).getForwardedStanza(); Message mamMessage = (Message) forwardedMessages.get(forwardedMessages.size() - 1).getForwardedStanza();
return messageFromMAM;
}
private Message prepareMessage(Jid to, String messageId, String body) { assertEquals(messageId, mamMessage.getStanzaId());
Message message = new Message(); assertEquals(messageBody, mamMessage.getBody());
message.setTo(to); assertEquals(conOne.getUser(), mamMessage.getFrom());
message.setStanzaId(messageId); assertEquals(userTwo, mamMessage.getTo());
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());
} }
} }

View File

@ -1,21 +0,0 @@
/**
*
* 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;

View File

@ -0,0 +1 @@
../../../../../../../../smack-experimental/src/main/java/org/jivesoftware/smackx/mam/package-info.java