Listing Supported PubSub Features

When you perform a ServiceDiscoveryManager.getItems() on a pubsub JID (see Making Sense of Services), the server returns 2 types of information:

  1. the identity (<identity>) of the JID as defined in the Service Discovery Identities. You use the information here to determine what exactly is the JID. If you are looking for a pubsub service, then the category should contain pubsub value.
  2. the feature (<feature>) that is supported by the identity. In the case of a pubsub, these can be features like ability to create/delete nodes, persist items, etc. A list of the pubsub features can be found here.

This is typically how the packet will look like

<iq id=”SOKMA-5″ to=”fred@localhost/Smack” from=”pubsub.localhost” type=”result”>
<query xmlns=”http://jabber.org/protocol/disco#info”&gt;
<identity category=”pubsub” name=”Publish-Subscribe service” type=”service”/>
<feature var=”http://jabber.org/protocol/pubsub”/&gt;
<feature var=”http://jabber.org/protocol/pubsub#collections”/&gt;
<feature var=”http://jabber.org/protocol/pubsub#config-node”/&gt;
<feature var=”http://jabber.org/protocol/pubsub#create-and-configure”/&gt;
<feature var=”http://jabber.org/protocol/pubsub#create-nodes”/&gt;


</query>
</iq>

Although Smack allows you to retrieve the list of identities by the DiscoveryInfo.getIdentities() method, there seems to be no provision for retrieving a list of supported features associated with an identity (see thread). While there is a getFeatures() method, this however is not public. The only way seem to be explicitly asking if a feature is supported (DiscoverInfo.containsFeature(String)); for example if you want to check if a pubsub service supports user created nodes, you do the following

DiscoverInfo info = mgr.discoverInfo(“pubsub_jid@xmpp_server.org”);
if (info.containsFeature(“http://jabber.org/protocol/pubsub#create-nodes&#8221;)) {
//do something

So to get a list of the features here is a utility method

public static List<DiscoverInfo.Feature> extractFeature(String s) throws Exception {
   List<DiscoverInfo.Feature> list = new LinkedList<DiscoverInfo.Feature>();
   QName var = new QName(“var”);
   ByteArrayInputStream bis = new ByteArrayInputStream(s.getBytes());
   XMLEventReader xer = XMLInputFactory.newFactory().createXMLEventReader(bis);
   out:
   while (xer.hasNext()) {
      XMLEvent evt = xer.nextEvent();
      switch (evt.getEventType()) {
  
      case XMLStreamConstants.START_ELEMENT:
            StartElement st = evt.asStartElement();
            if (“feature”.equals(st.getName().getLocalPart()))
               list.add(new DiscoverInfo.Feature(
            st.getAttributeByName(var).getValue()));
            break;
         case XMLStreamConstants.END_DOCUMENT:
            break out;
         default:
      } //switch
   } // while
   xer.close();
   bis.close();
   return (list);
}

and the following code snippet shows how to use this utility method

DiscoverInfo info = mgr.discoverInfo(“pubsub_jid@xmpp_server.org”);
List<DiscoverInfo.Feature> featureList = extractFeature(info.getChildElementXML());