rosterItems.put(item.getJid().toBareJID(), item);
}
// Add RosterItems that belong only to shared groups
Map<JID,List<Group>> sharedUsers = getSharedUsers(sharedGroups);
for (Map.Entry<JID, List<Group>> entry : sharedUsers.entrySet()) {
JID jid = entry.getKey();
List<Group> groups = entry.getValue();
try {
Collection<Group> itemGroups = new ArrayList<Group>();
String nickname = "";
RosterItem item = new RosterItem(jid, RosterItem.SUB_TO, RosterItem.ASK_NONE,
RosterItem.RECV_NONE, nickname , null);
// Add the shared groups to the new roster item
for (Group group : groups) {
if (group.isUser(jid)) {
item.addSharedGroup(group);
itemGroups.add(group);
}
else {
item.addInvisibleSharedGroup(group);
}
}
// Set subscription type to BOTH if the roster user belongs to a shared group
// that is mutually visible with a shared group of the new roster item
if (rosterManager.hasMutualVisibility(username, sharedGroups, jid, itemGroups)) {
item.setSubStatus(RosterItem.SUB_BOTH);
}
else {
// Set subscription type to FROM if the contact does not belong to any of
// the associated shared groups
boolean belongsToGroup = false;
for (Group group : groups) {
if (group.isUser(jid)) {
belongsToGroup = true;
}
}
if (!belongsToGroup) {
item.setSubStatus(RosterItem.SUB_FROM);
}
}
// Set nickname and store in memory only if subscription type is not FROM.
// Roster items with subscription type FROM that exist only because of shared
// groups will be recreated on demand in #getRosterItem(JID) and #isRosterItem()
// but will never be stored in memory nor in the database. This is an important
// optimization to reduce objects in memory and avoid loading users in memory
// to get their nicknames that will never be shown
if (item.getSubStatus() != RosterItem.SUB_FROM) {
item.setNickname(UserNameManager.getUserName(jid));
rosterItems.put(item.getJid().toBareJID(), item);
}
else {
// Cache information about shared contacts with subscription status FROM
implicitFrom
.put(item.getJid().toBareJID(), item.getInvisibleSharedGroupsNames());
}
}
catch (UserNotFoundException e) {
Log.error("Groups (" + groups + ") include non-existent username (" +
jid.getNode() +
")");
}
}
// Fire event indicating that a roster has just been loaded
RosterEventDispatcher.rosterLoaded(this);