diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java index 61b26d082..479f7945b 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/disco/packet/DiscoverInfo.java @@ -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 getIdentities(String category, String type) { + List res = new ArrayList(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.

diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java index 4d1fc7acd..8a13c1262 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/PubSubManager.java @@ -171,11 +171,24 @@ final public class PubSubManager info.setNode(id); DiscoverInfo infoReply = (DiscoverInfo) con.createPacketCollectorAndSend(info).nextResultOrThrow(); - - if (infoReply.getIdentities().get(0).getType().equals(NodeType.leaf.toString())) - node = new LeafNode(con, id); - else - node = new CollectionNode(con, id); + + if (infoReply.hasIdentity(PubSub.ELEMENT, "leaf")) { + node = new LeafNode(con, id); + } + 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); }