mirror of
https://codeberg.org/Mercury-IM/Smack
synced 2024-11-26 08:12:05 +01:00
Make PubSubManager.getNode(String) more robust
I've got reports from users that in some cases there can be multiple identities. Not just one, and in this case, the node type may not be the first identity. We now iterate over all identities until we either found one of type "leaf" or "collection". For example one user reports an ejabberd with PEP case, where the first identity is of type "pep", the second of type "leaf" and a third one with category "account" and type "registered". Also extend DiscoverInfo API with hasIdentity(String, String) and getIdentities(String, String).
This commit is contained in:
parent
8d7b329432
commit
17bb738e9e
2 changed files with 52 additions and 5 deletions
|
@ -19,6 +19,7 @@ package org.jivesoftware.smackx.disco.packet;
|
|||
import org.jivesoftware.smack.packet.IQ;
|
||||
import org.jivesoftware.smack.util.XmlStringBuilder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
|
@ -129,6 +130,39 @@ public class DiscoverInfo extends IQ implements Cloneable {
|
|||
return Collections.unmodifiableList(identities);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this DiscoverInfo contains at least one Identity of the given category and type.
|
||||
*
|
||||
* @param category the category to look for.
|
||||
* @param type the type to look for.
|
||||
* @return true if this DiscoverInfo contains a Identity of the given category and type.
|
||||
*/
|
||||
public boolean hasIdentity(String category, String type) {
|
||||
for (Identity identity : identities) {
|
||||
if (identity.getCategory().equals(category) && identity.getType().equals(type)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all Identities of the given category and type of this DiscoverInfo.
|
||||
*
|
||||
* @param category category the category to look for.
|
||||
* @param type type the type to look for.
|
||||
* @return a list of Identites with the given category and type.
|
||||
*/
|
||||
public List<Identity> getIdentities(String category, String type) {
|
||||
List<Identity> res = new ArrayList<Identity>(identities.size());
|
||||
for (Identity identity : identities) {
|
||||
if (identity.getCategory().equals(category) && identity.getType().equals(type)) {
|
||||
res.add(identity);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the node attribute that supplements the 'jid' attribute. A node is merely
|
||||
* something that is associated with a JID and for which the JID can provide information.<p>
|
||||
|
|
|
@ -172,10 +172,23 @@ final public class PubSubManager
|
|||
|
||||
DiscoverInfo infoReply = (DiscoverInfo) con.createPacketCollectorAndSend(info).nextResultOrThrow();
|
||||
|
||||
if (infoReply.getIdentities().get(0).getType().equals(NodeType.leaf.toString()))
|
||||
if (infoReply.hasIdentity(PubSub.ELEMENT, "leaf")) {
|
||||
node = new LeafNode(con, id);
|
||||
else
|
||||
}
|
||||
else if (infoReply.hasIdentity(PubSub.ELEMENT, "collection")) {
|
||||
node = new CollectionNode(con, id);
|
||||
}
|
||||
else {
|
||||
// XEP-60 5.3 states that
|
||||
// "The 'disco#info' result MUST include an identity with a category of 'pubsub' and a type of either 'leaf' or 'collection'."
|
||||
// If this is not the case, then we are dealing with an PubSub implementation that doesn't follow the specification.
|
||||
throw new AssertionError(
|
||||
"PubSub service '"
|
||||
+ to
|
||||
+ "' returned disco info result for node '"
|
||||
+ id
|
||||
+ "', but it did not contain an Identity of type 'leaf' or 'collection' (and category 'pubsub'), which is not allowed according to XEP-60 5.3.");
|
||||
}
|
||||
node.setTo(to);
|
||||
nodeMap.put(id, node);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue