powered by Jive Software

How can a syncronous roster update be performed?

I am trying to syncronously add and remove users from a roster, but it appears that my approach is not working. It appears that Smack’s cached copy of the Roster is not being correctly updated. Any insights would be much appreciated! Here’s more info:

Reason for Performing a Syncronous Update: After adding/removing a user from the roster, I need to exchange that roster with another user (via a RosterExchangeManager.send). If a traditional roster.add/remove is performed, the roster update does not complete before the RosterExchangeManager.send is executed.

Current Approach Design/Results:

  1. Send a packet to the XCP server requesting that UserB be removed from UserA’s roster

a. The server receives the request to add/remove an entry to/from UserA’s roster.

  1. Wait for the server response

a. The server responds with and IQ of type “result,” indicating a successful roster update.

b. A check of the server’s XCP database confirms that UserB *has *been removed UserA’s roster.

  1. Send a packet to the XCP server requesting UserA’s new roster (in order to update Smack’s cached copy)

  2. Wait for the server response

a. The server logs reveal that the server correctly responds to the request with the updated version of the user’s roster.

  1. Send the roster item exchange message with UserA’s current roster

a. The return of connection.getRoster(), which is sent in the call to RosterExhcangeManager.send, sends UserA’s original roster rather than UserA’s updated roster

Current Approach Code (may contain transcription errors):

public void removeEntry(String userId) {

// userId is the bare JID of the user

RosterEntry entryToRemove = connection.getRoster().getEntry(userId);

if (null != entryToRemove) {

  RosterPacket.Item itemToRemove = new RosterPacket.Item(

entryToRemove.getUser(), entryToRemove.getName());

  itemToRemove.setItemType(RosterPacket.ItemType.remove);

  RosterPacket removePacket = new RosterPacket();

  removePacket.setType(IQ.Type.SET);

  removePacket.addRosterItem(itemToRemove);

  PacketCollector serverResponseCollector = connection.createPacketCollector(new

PacketIDFilter(removePacket.getPacketId()));

  connection.sendPacket(removePacket);

  IQ serverResponse = (IQ) serverResponseCollector.nextResult(

SmackConfiguration.getPacketReplyTimeout());

  serverResponseCollector.cancel();

  ... // handle error conditions

  // reload the roster that is cached by Smack

  RosterPacket requestRosterPacker = new RosterPacket();

  PacketCollector requestRosterResponseCollector = connection.createPacketCollector(

new PacketIDfileter(requestRosterPacker.getPacketID()));

  connection.sendPacket(requestRosterPacket);

  RosterPacket requestRosterResponse = (RosterPacket) 

  requestRosterResponseCollector.nextResult(SmackConfiguration.getPacketReplyTime out());

  requestRosterResponseCollector.cancel();

  ... // handle error conditions

  ... // perform roster exchange via RosterExchangeManager.send

}