* @return <tt>true</tt> if the subscription state has changed.
*/
private boolean manageSub(JID target, boolean isSending, Presence.Type type, Roster roster)
throws UserAlreadyExistsException, SharedGroupException
{
RosterItem item = null;
RosterItem.AskType oldAsk;
RosterItem.SubType oldSub = null;
RosterItem.RecvType oldRecv;
boolean newItem = false;
try {
if (roster.isRosterItem(target)) {
item = roster.getRosterItem(target);
}
else {
if (Presence.Type.unsubscribed == type || Presence.Type.unsubscribe == type ||
Presence.Type.subscribed == type) {
// Do not create a roster item when processing a confirmation of
// an unsubscription or receiving an unsubscription request or a
// subscription approval from an unknown user
return false;
}
item = roster.createRosterItem(target, false, true);
newItem = true;
}
// Get a snapshot of the item state
oldAsk = item.getAskStatus();
oldSub = item.getSubStatus();
oldRecv = item.getRecvStatus();
// Update the item state based in the received presence type
updateState(item, type, isSending);
// Update the roster IF the item state has changed
if (oldAsk != item.getAskStatus() || oldSub != item.getSubStatus() ||
oldRecv != item.getRecvStatus()) {
roster.updateRosterItem(item);
}
else if (newItem) {
// Do not push items with a state of "None + Pending In"
if (item.getSubStatus() != RosterItem.SUB_NONE ||
item.getRecvStatus() != RosterItem.RECV_SUBSCRIBE) {
roster.broadcast(item, false);
}
}
}
catch (UserNotFoundException e) {
// Should be there because we just checked that it's an item
Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
}
return oldSub != item.getSubStatus();
}