diff --git a/source/org/jivesoftware/smack/Roster.java b/source/org/jivesoftware/smack/Roster.java index 97463e38b..8c17c8073 100644 --- a/source/org/jivesoftware/smack/Roster.java +++ b/source/org/jivesoftware/smack/Roster.java @@ -46,7 +46,7 @@ import java.util.concurrent.ConcurrentHashMap; * @see XMPPConnection#getRoster() * @author Matt Tucker */ -public class Roster { +public class Roster implements ConnectionListener { /** * The default subscription processing mode to use when a Roster is created. By default @@ -63,6 +63,7 @@ public class Roster { // The roster is marked as initialized when at least a single roster packet // has been recieved and processed. boolean rosterInitialized = false; + private PresencePacketListener presencePacket; private SubscriptionMode subscriptionMode = getDefaultSubscriptionMode(); @@ -107,7 +108,10 @@ public class Roster { connection.addPacketListener(new RosterPacketListener(), rosterFilter); // Listen for any presence packets. PacketFilter presenceFilter = new PacketTypeFilter(Presence.class); - connection.addPacketListener(new PresencePacketListener(), presenceFilter); + presencePacket = new PresencePacketListener(); + connection.addPacketListener(presencePacket, presenceFilter); + // Listen for connection events + connection.addConnectionListener(this); } /** @@ -304,6 +308,25 @@ public class Roster { return Collections.unmodifiableCollection(allEntries); } + /** + * Changes the presence of available contacts offline by simulating an unavailable + * presence sent from the server. After a disconnection, every Presence is set + * to offline. + */ + private void setOfflinePresences() { + Presence packetUnavailable; + for (String user : new ArrayList(presenceMap.keySet())) { + Map resources = presenceMap.get(user); + if (resources != null) { + for (String resource : new ArrayList(resources.keySet())) { + packetUnavailable = new Presence(Presence.Type.unavailable); + packetUnavailable.setFrom(user + "/" + resource); + presencePacket.processPacket(packetUnavailable); + } + } + } + } + /** * Returns a count of the unfiled entries in the roster. An unfiled entry is * an entry that doesn't belong to any groups. @@ -770,10 +793,10 @@ public class Roster { } } } - // Remove all the groups with no entries. We have to do this because - // RosterGroup.removeEntry removes the entry immediately (locally) and the - // group could remain empty. - // TODO Check the performance/logic for rosters with large number of groups + // Remove all the groups with no entries. We have to do this because + // RosterGroup.removeEntry removes the entry immediately (locally) and the + // group could remain empty. + // TODO Check the performance/logic for rosters with large number of groups for (RosterGroup group : getGroups()) { if (group.getEntryCount() == 0) { groups.remove(group.getName()); @@ -791,4 +814,26 @@ public class Roster { fireRosterChangedEvent(addedEntries, updatedEntries, deletedEntries); } } + + public void connectionClosed() { + // Changes the presence available contacts to unavailable + this.setOfflinePresences(); + } + + public void connectionClosedOnError(Exception e) { + // Changes the presence available contacts to unavailable + this.setOfflinePresences(); + } + + public void reconnectingIn(int seconds) { + // Ignore + } + + public void reconnectionFailed(Exception e) { + // Ignore + } + + public void reconectionSuccessful() { + // Ignore + } } \ No newline at end of file