From af4ea681ee9bd960121987b0145b0436f0b704b1 Mon Sep 17 00:00:00 2001 From: Matt Tucker Date: Mon, 7 Apr 2003 05:40:28 +0000 Subject: [PATCH] Wait for server response before returning roster. git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@1867 b35dd754-fafc-0310-a699-88a17e54d16e --- source/org/jivesoftware/smack/Roster.java | 9 ++++++-- .../org/jivesoftware/smack/RosterEntry.java | 3 +-- .../org/jivesoftware/smack/RosterGroup.java | 18 +++++++++++---- .../jivesoftware/smack/XMPPConnection.java | 23 ++++++++++++++++--- 4 files changed, 42 insertions(+), 11 deletions(-) diff --git a/source/org/jivesoftware/smack/Roster.java b/source/org/jivesoftware/smack/Roster.java index d9f6bf8f9..3aa989683 100644 --- a/source/org/jivesoftware/smack/Roster.java +++ b/source/org/jivesoftware/smack/Roster.java @@ -68,6 +68,9 @@ public class Roster { private XMPPConnection connection; private Map groups; + // The roster is marked as initialized when at least a single roster packet + // has been recieved and processed. + boolean rosterInitialized = false; Roster(final XMPPConnection connection) { this.connection = connection; @@ -163,8 +166,7 @@ public class Roster { RosterPacket rosterPacket = (RosterPacket)packet; for (Iterator i=rosterPacket.getRosterItems(); i.hasNext(); ) { RosterPacket.Item item = (RosterPacket.Item)i.next(); - RosterEntry entry = new RosterEntry(item.getUser(), item.getName(), - connection); + RosterEntry entry = new RosterEntry(item.getUser(), item.getName(), connection); // Find the list of groups that the user currently belongs to. List currentGroupNames = new ArrayList(); for (Iterator j = entry.getGroups(); j.hasNext(); ) { @@ -206,6 +208,9 @@ public class Roster { } } } + + // Mark the roster as initialized. + rosterInitialized = true; } } } diff --git a/source/org/jivesoftware/smack/RosterEntry.java b/source/org/jivesoftware/smack/RosterEntry.java index 46bffc3bb..08e6c32e1 100644 --- a/source/org/jivesoftware/smack/RosterEntry.java +++ b/source/org/jivesoftware/smack/RosterEntry.java @@ -55,11 +55,10 @@ public class RosterEntry { * @return an iterator for the groups this entry belongs to. */ public Iterator getGroups() { - Roster roster = connection.getRoster(); List results = new ArrayList(); // Loop through all roster groups and find the ones that contain this // entry. This algorithm should be fine - for (Iterator i=roster.getGroups(); i.hasNext(); ) { + for (Iterator i=connection.roster.getGroups(); i.hasNext(); ) { RosterGroup group = (RosterGroup)i.next(); if (group.contains(this)) { results.add(group); diff --git a/source/org/jivesoftware/smack/RosterGroup.java b/source/org/jivesoftware/smack/RosterGroup.java index 4be53f0ac..27487db7e 100644 --- a/source/org/jivesoftware/smack/RosterGroup.java +++ b/source/org/jivesoftware/smack/RosterGroup.java @@ -131,10 +131,10 @@ public class RosterGroup { } /** - * Returns true if an entry is part of the group. + * Returns true if an entry is part of this group. * - * @param entry - * @return + * @param entry a roster entry. + * @return true if the entry is part of this group. */ public boolean contains(RosterEntry entry) { synchronized (entries) { @@ -142,6 +142,11 @@ public class RosterGroup { } } + /** + * Adds a roster entry to this group. + * + * @param entry a roster entry. + */ public void addEntry(RosterEntry entry) { // Only add the entry if it isn't already in the list. synchronized (entries) { @@ -155,6 +160,11 @@ public class RosterGroup { } } + /** + * Removes a roster entry from this group. + * + * @param entry a roster entry. + */ public void removeEntry(RosterEntry entry) { // Only remove the entry if it's in the entry list. synchronized (entries) { @@ -184,4 +194,4 @@ public class RosterGroup { } } } -} +} \ No newline at end of file diff --git a/source/org/jivesoftware/smack/XMPPConnection.java b/source/org/jivesoftware/smack/XMPPConnection.java index 2a6865833..17738c5d1 100644 --- a/source/org/jivesoftware/smack/XMPPConnection.java +++ b/source/org/jivesoftware/smack/XMPPConnection.java @@ -53,8 +53,7 @@ package org.jivesoftware.smack; import org.jivesoftware.smack.packet.*; -import org.jivesoftware.smack.filter.PacketIDFilter; -import org.jivesoftware.smack.filter.PacketFilter; +import org.jivesoftware.smack.filter.*; import javax.swing.*; import java.net.*; @@ -109,7 +108,7 @@ public class XMPPConnection { private PacketWriter packetWriter; private PacketReader packetReader; - private Roster roster = null; + Roster roster = null; private AccountManager accountManager = null; Writer writer; @@ -330,6 +329,24 @@ public class XMPPConnection { * @return the user's roster, or null if the user has not logged in yet. */ public Roster getRoster() { + if (roster == null) { + return null; + } + // If this is the first time the user has asked for the roster after calling + // login, we want to wait up to 2 seconds for the server to send back the + // user's roster. This behavior shields API users from having to worry about the + // fact that roster operations are asynchronous, although they'll still have to + // listen for changes to the roster. Note: because of this waiting logic, internal + // Smack code should be wary about calling the getRoster method, and may need to + // access the roster object directly. + int elapsed = 0; + while (!roster.rosterInitialized && elapsed <= 2000) { + try { + Thread.sleep(500); + } + catch (Exception e) { } + elapsed += 500; + } return roster; }