Better threading logic when getting a roster. Also avoid loading LiteDebugger explicitly as an attempted fix for SMACK-7.

git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@2470 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
Matt Tucker 2005-03-30 01:53:51 +00:00 committed by matt
parent 92869fa583
commit fb22583ea7
2 changed files with 54 additions and 27 deletions

View File

@ -36,10 +36,6 @@ import java.util.*;
* <li> SUBSCRIPTION_REJECT_ALL -- reject all subscription requests. * <li> SUBSCRIPTION_REJECT_ALL -- reject all subscription requests.
* <li> SUBSCRIPTION_MANUAL -- manually process all subscription requests. </ul> * <li> SUBSCRIPTION_MANUAL -- manually process all subscription requests. </ul>
* *
* All presence subscription requests are automatically approved to this client
* are automatically approved. This logic will be updated in the future to allow for
* pluggable behavior.
*
* @see XMPPConnection#getRoster() * @see XMPPConnection#getRoster()
* @author Matt Tucker * @author Matt Tucker
*/ */
@ -244,6 +240,7 @@ public class Roster {
new PacketIDFilter(rosterPacket.getPacketID())); new PacketIDFilter(rosterPacket.getPacketID()));
connection.sendPacket(rosterPacket); connection.sendPacket(rosterPacket);
IQ response = (IQ)collector.nextResult(SmackConfiguration.getPacketReplyTimeout()); IQ response = (IQ)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
collector.cancel();
if (response == null) { if (response == null) {
throw new XMPPException("No response from the server."); throw new XMPPException("No response from the server.");
} }
@ -251,7 +248,6 @@ public class Roster {
else if (response.getType() == IQ.Type.ERROR) { else if (response.getType() == IQ.Type.ERROR) {
throw new XMPPException(response.getError()); throw new XMPPException(response.getError());
} }
collector.cancel();
// Create a presence subscription packet and send. // Create a presence subscription packet and send.
Presence presencePacket = new Presence(Presence.Type.SUBSCRIBE); Presence presencePacket = new Presence(Presence.Type.SUBSCRIBE);
@ -262,24 +258,40 @@ public class Roster {
/** /**
* Removes a roster entry from the roster. The roster entry will also be removed from the * Removes a roster entry from the roster. The roster entry will also be removed from the
* unfiled entries or from any roster group where it could belong and will no longer be part * unfiled entries or from any roster group where it could belong and will no longer be part
* of the roster. * of the roster. Note that this is an asynchronous call -- Smack must wait for the server
* to send an updated subscription status.
* *
* @param entry a roster entry. * @param entry a roster entry.
*/ */
public void removeEntry(RosterEntry entry) { public void removeEntry(RosterEntry entry) throws XMPPException {
// Only remove the entry if it's in the entry list. // Only remove the entry if it's in the entry list.
// The actual removal logic takes place in RosterPacketListenerprocess>>Packet(Packet) // The actual removal logic takes place in RosterPacketListenerprocess>>Packet(Packet)
synchronized (entries) { synchronized (entries) {
if (entries.contains(entry)) { if (!entries.contains(entry)) {
RosterPacket packet = new RosterPacket(); return;
packet.setType(IQ.Type.SET);
RosterPacket.Item item = RosterEntry.toRosterItem(entry);
// Set the item type as REMOVE so that the server will delete the entry
item.setItemType(RosterPacket.ItemType.REMOVE);
packet.addRosterItem(item);
connection.sendPacket(packet);
} }
} }
RosterPacket packet = new RosterPacket();
packet.setType(IQ.Type.SET);
RosterPacket.Item item = RosterEntry.toRosterItem(entry);
// Set the item type as REMOVE so that the server will delete the entry
item.setItemType(RosterPacket.ItemType.REMOVE);
packet.addRosterItem(item);
PacketCollector collector = connection.createPacketCollector(
new PacketIDFilter(packet.getPacketID()));
connection.sendPacket(packet);
IQ response = (IQ)collector.nextResult(SmackConfiguration.getPacketReplyTimeout());
collector.cancel();
if (response == null) {
throw new XMPPException("No response from the server.");
}
// If the server replied with an error, throw an exception.
else if (response.getType() == IQ.Type.ERROR) {
throw new XMPPException(response.getError());
}
else {
}
} }
/** /**
@ -756,7 +768,10 @@ public class Roster {
} }
// Mark the roster as initialized. // Mark the roster as initialized.
rosterInitialized = true; synchronized (this) {
rosterInitialized = true;
notifyAll();
}
// Fire event for roster listeners. // Fire event for roster listeners.
fireRosterChangedEvent(); fireRosterChangedEvent();

View File

@ -418,20 +418,27 @@ public class XMPPConnection {
return null; return null;
} }
// If this is the first time the user has asked for the roster after calling // 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 // login, we want to wait for the server to send back the user's roster. This
// user's roster. This behavior shields API users from having to worry about the // behavior shields API users from having to worry about the fact that roster
// fact that roster operations are asynchronous, although they'll still have to // operations are asynchronous, although they'll still have to listen for
// listen for changes to the roster. Note: because of this waiting logic, internal // 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 // Smack code should be wary about calling the getRoster method, and may need to
// access the roster object directly. // access the roster object directly.
int elapsed = 0; if (!roster.rosterInitialized) {
while (!roster.rosterInitialized && elapsed <= 2000) {
try { try {
Thread.sleep(500); synchronized (roster) {
long waitTime = SmackConfiguration.getPacketReplyTimeout();
long start = System.currentTimeMillis();
while (!roster.rosterInitialized) {
if (waitTime <= 0) {
break;
}
roster.wait(waitTime);
waitTime -= System.currentTimeMillis() - start;
}
}
} }
catch (Exception e) { catch (InterruptedException ie) { }
}
elapsed += 500;
} }
return roster; return roster;
} }
@ -724,7 +731,12 @@ public class XMPPConnection {
Class.forName("org.jivesoftware.smackx.debugger.EnhancedDebugger"); Class.forName("org.jivesoftware.smackx.debugger.EnhancedDebugger");
} }
catch (Exception ex) { catch (Exception ex) {
debuggerClass = LiteDebugger.class; try {
debuggerClass = Class.forName("org.jivesoftware.smack.debugger.LiteDebugger");
}
catch (Exception ex2) {
ex2.printStackTrace();
}
} }
} }
// Create a new debugger instance. If an exception occurs then disable the debugging // Create a new debugger instance. If an exception occurs then disable the debugging