mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-11-26 14:02:06 +01:00
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:
parent
92869fa583
commit
fb22583ea7
2 changed files with 54 additions and 27 deletions
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue