Custom attributes in RosterPacket.Item

I’m trying to use Smack to integrate with HipChat via xmpp, but the only snag I’ve run into is getting the mention name from the roster. In HipChat, you can change the name that people reference you with, and that’s reflected in the “mention_name” attribute of the roster. Unfortunately, it looks like RosterPacketProvider#parseItem only pulls a few values (jid, name, etc) and discards the rest.

Is there a way that I can get that info that I’m overlooking?

I made a change to 4.2.0-alpha4 to store and expose all the custom attributes. If there’s not current way to get that info, is this something that could be integrated?

Is there a way that I can get that info that I’m overlooking?
You could subclass RosterPacket(Item), register a custom provider and a listener collecting the stanzas.

is this something that could be integrated?
It’s borderline because I’m not sure if XMPP should be extended that way. Extension elements in roster stanzas are one thing, but custom attributes are another. Since you appear to have already the source code, it sure would help if you showed us what you intend to upstream. It’s always easier to discuss code than (more or less) abstract ideas.

I wasn’t able to get it to work by returning a subclass of RosterPacket.Item because I couldn’t figure out how to modify the listeners in Roster that transform that into a RosterEntry, but I was able to just copy RosterPacketProvider and record the mention name for each JID as they’re parsed out. That works like a charm, so I don’t necessarily need any changes to smack-im.

Regardless, below is the diff of what I was talking about adding. Pretty simple (and not necessarily ready to merge), but it got the job done.

Thanks for the help!

diff --git a/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterEntry.java b/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterEntry.java
index 7f38c70..120578a 100644
--- a/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterEntry.java
+++ b/smack-im/src/main/java/org/jivesoftware/smack/roster/RosterEntry.java
@@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List;
+import java.util.Map; import org.jivesoftware.smack.Manager; import org.jivesoftware.smack.SmackException.NoResponseException;
@@ -86,6 +87,10 @@ public final class RosterEntry extends Manager {
         return item.getName();
     } +    public Map<String, String> getAttrs() {
+        return item.getAttrs();
+    }
+
     /**
      * Sets the name associated with this entry.
      *
diff --git a/smack-im/src/main/java/org/jivesoftware/smack/roster/packet/RosterPacket.java b/smack-im/src/main/java/org/jivesoftware/smack/roster/packet/RosterPacket.java
index f74ec37..242d8ca 100644
--- a/smack-im/src/main/java/org/jivesoftware/smack/roster/packet/RosterPacket.java
+++ b/smack-im/src/main/java/org/jivesoftware/smack/roster/packet/RosterPacket.java
@@ -29,6 +29,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Locale;
+import java.util.Map; import java.util.Set; import java.util.concurrent.CopyOnWriteArraySet; @@ -128,6 +129,7 @@ public class RosterPacket extends IQ {
         private ItemType itemType = ItemType.none;
         private boolean approved;
         private final Set<String> groupNames;
+        private Map<String, String> attrs;          /**
          * Creates a new roster item.
@@ -205,6 +207,14 @@ public class RosterPacket extends IQ {
             return itemType;
         } +        public void setAttrs(Map<String, String> attrs) {
+            this.attrs = attrs;
+        }
+
+        public Map<String, String> getAttrs() {
+            return attrs;
+        }
+
         /**
          * Sets the roster item type.
          *
diff --git a/smack-im/src/main/java/org/jivesoftware/smack/roster/provider/RosterPacketProvider.java b/smack-im/src/main/java/org/jivesoftware/smack/roster/provider/RosterPacketProvider.java
index bec3563..924524e 100644
--- a/smack-im/src/main/java/org/jivesoftware/smack/roster/provider/RosterPacketProvider.java
+++ b/smack-im/src/main/java/org/jivesoftware/smack/roster/provider/RosterPacketProvider.java
@@ -17,6 +17,8 @@ package org.jivesoftware.smack.roster.provider; import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map; import org.jivesoftware.smack.SmackException; import org.jivesoftware.smack.packet.IQ;
@@ -73,6 +75,14 @@ public class RosterPacketProvider extends IQProvider<RosterPacket> {          // Create item.
         RosterPacket.Item item = new RosterPacket.Item(jid, itemName);
+
+        Map<String, String> attrs = new HashMap<>();
+        for(int i = 0; i < parser.getAttributeCount(); i++) {
+            attrs.put(parser.getAttributeName(i), parser.getAttributeValue(i));
+        }
+
+        item.setAttrs(attrs);
+
         // Set status.
         String ask = parser.getAttributeValue("", "ask");
         item.setSubscriptionPending("subscribe".equals(ask));