@SpecCompliant(spec = "rfc3921bis-08", section = "2.1.5", status = FINISHED, coverage = PARTIAL),
@SpecCompliant(spec = "rfc3921bis-08", section = "2.1.6", status = FINISHED, coverage = PARTIAL, comment = "only set-related content applies"),
@SpecCompliant(spec = "rfc3921bis-08", section = "2.5", status = FINISHED, coverage = COMPLETE, comment = "only calling from here") })
@Override
protected Stanza handleSet(IQStanza stanza, ServerRuntimeContext serverRuntimeContext, SessionContext sessionContext) {
RosterManager rosterManager = (RosterManager) serverRuntimeContext.getStorageProvider(RosterManager.class);
if (rosterManager == null) {
return handleCannotRetrieveRoster(stanza, sessionContext);
}
Entity user = extractUniqueSenderJID(stanza, sessionContext);
if (user == null || !user.isResourceSet()) {
return ServerErrorResponses.getInstance().getStanzaError(StanzaErrorCondition.UNKNOWN_SENDER, stanza,
StanzaErrorType.MODIFY,
"sender info insufficient: " + ((user == null) ? "no from" : user.getFullQualifiedName()), null,
null);
}
RosterItem setRosterItem;
try {
setRosterItem = RosterUtils.parseRosterItem(stanza);
} catch (RosterBadRequestException e) {
return ServerErrorResponses.getInstance().getStanzaError(StanzaErrorCondition.BAD_REQUEST, stanza,
StanzaErrorType.MODIFY, e.getMessage(), null, null);
} catch (RosterNotAcceptableException e) {
return ServerErrorResponses.getInstance().getStanzaError(StanzaErrorCondition.NOT_ACCEPTABLE, stanza,
StanzaErrorType.MODIFY, e.getMessage(), null, null);
}
Entity contactJid = setRosterItem.getJid().getBareJID();
RosterItem existingItem;
try {
existingItem = rosterManager.getContact(user.getBareJID(), contactJid);
} catch (RosterException e) {
existingItem = null;
}
if (setRosterItem.getSubscriptionType() == REMOVE) {
// remove is handled in separate method, return afterwards
return rosterItemRemove(stanza, sessionContext, rosterManager, user, contactJid, existingItem);
} /* else: all other subscription types are ignored in a roster set and have been filtered out by RosterUtils.parseRosterItem() */
// proper set (update, not a remove)
if (existingItem == null) {
existingItem = new RosterItem(contactJid, NONE);
}
if (setRosterItem.getName() != null) {
existingItem.setName(setRosterItem.getName());
logger.debug(user.getBareJID() + " roster: set roster item name to " + setRosterItem.getName());
}
existingItem.setGroups(setRosterItem.getGroups());
logger.debug(user.getBareJID() + " roster: roster item groups set to " + setRosterItem.getGroups());
try {
// update contact persistently
rosterManager.addContact(user.getBareJID(), existingItem);
} catch (RosterException e) {
return ServerErrorResponses.getInstance().getStanzaError(StanzaErrorCondition.BAD_REQUEST, stanza,
StanzaErrorType.CANCEL, "roster item contact not (yet) in roster: " + contactJid, null, null);
}