powered by Jive Software

createGroup and updating roster

What is the intended protocol when organizing roster entries into roster groups? I need to know how the API intended the message protocol to be in these situations. Currently what happens is I need to relog for the roster to be updated on the client after adding entries to groups, so I’m obviously doing something wrong. I first assumed that these changes would be pushed from the server so that the rosterListener fires, similar to what happens with presence changes, but at the moment the server doesn’t seem to do anything.

The application autoaccepts all subscription requests. Here is a stripped down example of what happens, I hope it makes things clearer:

//This populates the visual roster with roster entries

private void addEntryToList(RosterEntry entry) {

//Entry is not associated with any groups

if(entry.getGroups().isEmpty()) {

xmppManager.addToDefaultGroup(entry);

}

//Entry is associated with at least one group

for (RosterGroup group : entry.getGroups()) {

rosterModel.insertNode(new RosterNode(entry), locateGroup(group));

}

}

public void addToDefaultGroup(RosterEntry entry){

//Locate default group in roster

RosterGroup group = roster.getGroup(ROSTER_DEFAULT_GROUP);

//If default group does not exist, create it

if(group == null) group = roster.createGroup(ROSTER_DEFAULT_GROUP); <---- I assumed something would happen here serverside

//Add entry to default group

try {

group.addEntry(entry);

} catch (XMPPException ex) {

Logger.getLogger(ChatPluginModel.class.getName()).log(Level.SEVERE, null, ex);

}

}

Any help is appreciated!

Please let me know if I did not explain the issue well enough and I will try to provide further information.

Ok so I narrowed it down more.

What I’m doing:

I add a RosterEntry to a RosterGroup, and then loop through entry.getGroups() when adding it to the visual representation (see code examples above).

What’s wrong:

entry.getGroups() uses a *Roster *object which is local to that specific *RosterEntry *object. So, as I understand it from the code below, this means that *entry.getGroups() *uses an outdated *Roster *object when trying to locate the *groups *the *entry *belongs to. I confirmed this by looking at *entry.getGroups() *- which returns null. Which makes sense.

public class RosterEntry {

final private Roster roster;

public Collection getGroups() {

List results = new ArrayList();

// Loop through all roster groups and find the ones that contain this

// entry. This algorithm should be fine

for (RosterGroup group: roster.getGroups()) {

if (group.contains(this)) {

results.add(group);

}

}

return Collections.unmodifiableCollection(results);

}

}

So I’m wondering - how am I supposed to do this in a clean way? I guess I could manually add the entry to the group in the GUI without relying on the RosterListener whenever I do group changes, but it seems dirty and very error prone.

Figured it out. I was derping in the RosterListener by retrieving roster entries from an old instance of the Roster. Always use Connection#getRoster()…