String peer = JIDUtils.getNodeID(packet.getElemTo());
String nick = packet.getElemCData("/presence/nick");
if (nick == null) {
nick = session.getUserName();
}
Packet rost_update =
new Packet(JabberIqRoster.createRosterPacket("set",
session.nextStanzaId(), peer, peer, session.getUserId(),
nick, "Anonymous peers", null,
JabberIqRoster.ANON));
results.offer(rost_update);
log.finest("Sending roster update: " + rost_update.toString());
}
Element result = packet.getElement().clone();
results.offer(new Packet(result));
// If this is unavailable presence, remove jid from Set
// otherwise add it to the Set
if (packet.getType() != null &&
packet.getType() == StanzaType.unavailable) {
removeDirectPresenceJID(packet.getElemTo(), session);
} else {
addDirectPresenceJID(packet.getElemTo(), session);
}
} else {
boolean first = false;
if (session.getSessionData(PRESENCE_KEY) == null) {
first = true;
}
// Store user presence for later time...
// To send response to presence probes for example.
session.putSessionData(PRESENCE_KEY, packet.getElement());
// Parse resource priority:
String priority = packet.getElemCData("/presence/priority");
if (priority != null) {
int pr = 1;
try {
pr = Integer.decode(priority);
} catch (NumberFormatException e) {
log.finer("Incorrect priority value: " + priority
+ ", setting 1 as default.");
pr = 1;
}
session.setPriority(pr);
}
// Special actions on the first availability presence
if (first && type == StanzaType.available) {
// Send presence probes to 'to' or 'both' contacts
sendPresenceBroadcast(StanzaType.probe, session, TO_SUBSCRIBED,
results, null, settings);
// Resend pending in subscription requests
resendPendingInRequests(session, results);
} // end of if (type == StanzaType.available)
// Broadcast initial presence to 'from' or 'both' contacts
sendPresenceBroadcast(type, session, FROM_SUBSCRIBED,
results, packet.getElement(), settings);
// Broadcast initial presence to other available user resources
// Element presence = packet.getElement().clone();
// Already done above, don't need to set it again here
// presence.setAttribute("from", session.getJID());
updateUserResources(packet.getElement(), session, results);
}
break;
case out_subscribe:
case out_unsubscribe:
if (pres_type == PresenceType.out_subscribe) {
SubscriptionType current_subscription =
roster_util.getBuddySubscription(session, packet.getElemTo());
if (current_subscription == null) {
roster_util.addBuddy(session, packet.getElemTo(), null, null);
} // end of if (current_subscription == null)
}
subscr_changed = roster_util.updateBuddySubscription(session, pres_type,
packet.getElemTo());
if (subscr_changed) {
roster_util.updateBuddyChange(session, results,
roster_util.getBuddyItem(session, packet.getElemTo()));
} // end of if (subscr_changed)
// According to RFC-3921 I must forward all these kind presence
// requests, it allows to resynchronize
// subscriptions in case of synchronization loss
forwardPresence(results, packet, session.getUserId());
break;
case out_subscribed:
case out_unsubscribed:
forwardPresence(results, packet, session.getUserId());
subscr_changed = roster_util.updateBuddySubscription(session, pres_type,
packet.getElemTo());
if (subscr_changed) {
roster_util.updateBuddyChange(session, results,
roster_util.getBuddyItem(session, packet.getElemTo()));
if (pres_type == PresenceType.out_subscribed) {
Element presence = (Element)session.getSessionData(PRESENCE_KEY);
if (presence != null) {
sendPresence(null, packet.getElemTo(), session.getJID(),
results, presence);
} else {
sendPresence(StanzaType.available, packet.getElemTo(),
session.getJID(), results, null);
}
} else {
sendPresence(StanzaType.unavailable, packet.getElemTo(),
session.getJID(), results, null);
}
} // end of if (subscr_changed)
break;
case in_initial:
if (packet.getElemFrom() == null) {
// That really happened already. It looks like a bug in tigase
// let's try to catch it here....
log.warning("Initial presence without from attribute set: "
+ packet.toString());
return;
}
// If other users are in 'to' or 'both' contacts, broadcast
// their preseces to all active resources
if (roster_util.isSubscribedTo(session, packet.getElemFrom())
|| (DynamicRoster.getBuddyItem(session, settings,
packet.getElemFrom()) != null)) {
updatePresenceChange(packet.getElement(), session, results);
} else {
// The code below looks like a bug to me.
// If the buddy is nt subscribed I should ignore all presences
// states from him. Commenting this out for now....
// Well, it is not a bug and it is intentional.
// All presences received from MUC come from not subscribed buddies
// therefore it seems presences from unknown buddy should be passed out
Element elem = packet.getElement().clone();
Packet result = new Packet(elem);
result.setTo(session.getConnectionId());
result.setFrom(packet.getTo());
results.offer(result);
}
break;
case in_subscribe:
// If the buddy is already subscribed then auto-reply with sybscribed
// presence stanza.
if (roster_util.isSubscribedFrom(session, packet.getElemFrom())) {
sendPresence(StanzaType.subscribed, packet.getElemFrom(),
session.getJID(), results, null);
} else {
SubscriptionType curr_sub =
roster_util.getBuddySubscription(session, packet.getElemFrom());
if (curr_sub == null) {
curr_sub = SubscriptionType.none;
roster_util.addBuddy(session, packet.getElemFrom(), null, null);
} // end of if (curr_sub == null)
roster_util.updateBuddySubscription(session, pres_type,
packet.getElemFrom());
updatePresenceChange(packet.getElement(), session, results);
} // end of else
break;
case in_unsubscribe:
subscr_changed = roster_util.updateBuddySubscription(session, pres_type,
packet.getElemFrom());
if (subscr_changed) {
// No longer needed according to RFC-3921-bis5
//sendPresence(StanzaType.unsubscribed, packet.getElemFrom(),
// session.getJID(), results, null);
//updatePresenceChange(packet.getElement(), session, results);
roster_util.updateBuddyChange(session, results,
roster_util.getBuddyItem(session, packet.getElemFrom()));
}
break;
case in_subscribed: {
SubscriptionType curr_sub =
roster_util.getBuddySubscription(session, packet.getElemFrom());
if (curr_sub == null) {
curr_sub = SubscriptionType.none;
roster_util.addBuddy(session, packet.getElemFrom(), null, null);
} // end of if (curr_sub == null)
subscr_changed = roster_util.updateBuddySubscription(session, pres_type,
packet.getElemFrom());
if (subscr_changed) {
//updatePresenceChange(packet.getElement(), session, results);
roster_util.updateBuddyChange(session, results,
roster_util.getBuddyItem(session, packet.getElemFrom()));
}
}
break;
case in_unsubscribed: {
SubscriptionType curr_sub =
roster_util.getBuddySubscription(session, packet.getElemFrom());
if (curr_sub != null) {
subscr_changed = roster_util.updateBuddySubscription(session, pres_type,
packet.getElemFrom());
if (subscr_changed) {
// No longer needed according to RFC-3921-bis5
//updatePresenceChange(packet.getElement(), session, results);
roster_util.updateBuddyChange(session, results,
roster_util.getBuddyItem(session, packet.getElemFrom()));
}
}
}
break;
case in_probe:
SubscriptionType buddy_subscr = null;
if (DynamicRoster.getBuddyItem(session, settings,
packet.getElemFrom()) != null) {
buddy_subscr = SubscriptionType.both;
} else {
buddy_subscr =
roster_util.getBuddySubscription(session, packet.getElemFrom());
}
if (buddy_subscr == null) {
buddy_subscr = SubscriptionType.none;
} // end of if (buddy_subscr == null)
switch (buddy_subscr) {
case none:
case none_pending_out:
case to:
results.offer(Authorization.FORBIDDEN.getResponseMessage(packet,
"Presence information is forbidden.", false));
break;
case none_pending_in:
case none_pending_out_in:
case to_pending_in:
results.offer(Authorization.NOT_AUTHORIZED.getResponseMessage(packet,
"You are not authorized to get presence information.", false));
break;
default:
break;
} // end of switch (buddy_subscr)
if (roster_util.isSubscribedFrom(buddy_subscr)) {
for (XMPPResourceConnection conn: session.getActiveSessions()) {
Element pres = (Element)conn.getSessionData(PRESENCE_KEY);
sendPresence(null, packet.getElemFrom(), conn.getJID(),
results, pres);
}
} // end of if (roster_util.isSubscribedFrom(session, packet.getElemFrom()))
break;
case error: {
// This is message to 'this' client probably
// Only error responses to DIRECT presence should be sent back
// to the client, all other should be ignored for now.
// Later on the Tigase should remember who responded with
// an error and don't send presence updates to this entity
Set<String> direct_presences =
(Set<String>) session.getSessionData(DIRECT_PRESENCE);
if (direct_presences != null &&
direct_presences.contains(packet.getElemFrom())) {
Element elem = packet.getElement().clone();
Packet result = new Packet(elem);
result.setTo(session.getConnectionId());
result.setFrom(packet.getTo());
results.offer(result);
} else {
// Ignore for now....
}
}