Commit 189d83f6 authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gato

Broadcast presence to shared contacts with subscription status FROM. JM-744

git-svn-id: http://svn.igniterealtime.org/svn/repos/wildfire/trunk@4216 b35dd754-fafc-0310-a699-88a17e54d16e
parent 7651bea5
...@@ -47,9 +47,14 @@ import java.util.concurrent.ConcurrentHashMap; ...@@ -47,9 +47,14 @@ import java.util.concurrent.ConcurrentHashMap;
public class Roster implements Cacheable { public class Roster implements Cacheable {
/** /**
* <p>Roster item cache - table: key jabberid string; value roster item.</p> * Roster item cache - table: key jabberid string; value roster item.
*/ */
protected ConcurrentHashMap<String, RosterItem> rosterItems = new ConcurrentHashMap<String, RosterItem>(); protected ConcurrentHashMap<String, RosterItem> rosterItems = new ConcurrentHashMap<String, RosterItem>();
/**
* Contacts with subscription FROM that only exist due to shared groups
* key: jabberid string; value: replciated key value.
*/
protected ConcurrentHashMap<String, String> implicitFrom = new ConcurrentHashMap<String, String>();
private RosterItemProvider rosterItemProvider; private RosterItemProvider rosterItemProvider;
private String username; private String username;
...@@ -146,6 +151,10 @@ public class Roster implements Cacheable { ...@@ -146,6 +151,10 @@ public class Roster implements Cacheable {
item.setNickname(UserNameManager.getUserName(jid)); item.setNickname(UserNameManager.getUserName(jid));
rosterItems.put(item.getJid().toBareJID(), item); rosterItems.put(item.getJid().toBareJID(), item);
} }
else {
// Cache information about shared contacts with subscription status FROM
implicitFrom.put(item.getJid().toBareJID(), item.getJid().toBareJID());
}
} }
catch (UserNotFoundException e) { catch (UserNotFoundException e) {
Log.error("Groups (" + sharedUsers.get(jid) + ") include non-existent username (" + Log.error("Groups (" + sharedUsers.get(jid) + ") include non-existent username (" +
...@@ -211,33 +220,9 @@ public class Roster implements Cacheable { ...@@ -211,33 +220,9 @@ public class Roster implements Cacheable {
* user and the susbcription only exists due to some shared groups or otherwise null. * user and the susbcription only exists due to some shared groups or otherwise null.
*/ */
private RosterItem getImplicitRosterItem(JID user) { private RosterItem getImplicitRosterItem(JID user) {
// Get the groups of this user if (implicitFrom.containsKey(user.toBareJID())) {
Collection<Group> userGroups = GroupManager.getInstance().getGroups(getUserJID()); return new RosterItem(user, RosterItem.SUB_FROM, RosterItem.ASK_NONE,
Collection<Group> sharedGroups = new ArrayList<Group>(userGroups.size()); RosterItem.RECV_NONE, "", null);
// Check if there is a public shared group. That means that anyone can see this user.
for (Group group : userGroups) {
if (rosterManager.isPulicSharedGroup(group)) {
// Only local users may see public shared groups
if (server.isLocal(user)) {
return new RosterItem(user, RosterItem.SUB_FROM, RosterItem.ASK_NONE,
RosterItem.RECV_NONE, "", null);
}
}
else if (rosterManager.isSharedGroup(group)) {
// This is a shared group that can be seen only by group members or
// (maybe) by other groups
sharedGroups.add(group);
}
}
if (!sharedGroups.isEmpty()) {
// Check if any group of the contact may see a shared group of this user
Collection<Group> contactGroups = GroupManager.getInstance().getGroups(user);
for (Group sharedGroup : sharedGroups) {
if (rosterManager.isSharedGroupVisible(sharedGroup, contactGroups)) {
return new RosterItem(user, RosterItem.SUB_FROM, RosterItem.ASK_NONE,
RosterItem.RECV_NONE, "", null);
}
}
} }
return null; return null;
} }
...@@ -555,6 +540,23 @@ public class Roster implements Cacheable { ...@@ -555,6 +540,23 @@ public class Roster implements Cacheable {
} }
} }
} }
// Broadcast presence to shared contacts whose subscription status is FROM
for (String contact : implicitFrom.keySet()) {
packet.setTo(contact);
if (list != null && list.shouldBlockPacket(packet)) {
// Outgoing presence notifications are blocked for this contact
continue;
}
for (ChannelHandler session : routingTable.getRoutes(new JID(contact))) {
try {
session.process(packet);
}
catch (Exception e) {
// Theoretically only happens if session has been closed.
Log.debug(e);
}
}
}
if (from != null) { if (from != null) {
// Broadcast presence to other user's resources // Broadcast presence to other user's resources
sessionManager.broadcastPresenceToOtherResources(from, packet); sessionManager.broadcastPresenceToOtherResources(from, packet);
...@@ -749,8 +751,12 @@ public class Roster implements Cacheable { ...@@ -749,8 +751,12 @@ public class Roster implements Cacheable {
if (item.isOnlyShared() && item.getSubStatus() == RosterItem.SUB_FROM) { if (item.isOnlyShared() && item.getSubStatus() == RosterItem.SUB_FROM) {
// Remove from memory and do nothing else // Remove from memory and do nothing else
rosterItems.remove(item.getJid().toBareJID()); rosterItems.remove(item.getJid().toBareJID());
// Cache information about shared contacts with subscription status FROM
implicitFrom.put(item.getJid().toBareJID(), item.getJid().toBareJID());
} }
else { else {
// Remove from list of shared contacts with status FROM (if any)
implicitFrom.remove(item.getJid().toBareJID());
// Brodcast to all the user resources of the updated roster item // Brodcast to all the user resources of the updated roster item
broadcast(item, true); broadcast(item, true);
// Probe the presence of the new group user // Probe the presence of the new group user
...@@ -854,8 +860,12 @@ public class Roster implements Cacheable { ...@@ -854,8 +860,12 @@ public class Roster implements Cacheable {
if (item.isOnlyShared() && item.getSubStatus() == RosterItem.SUB_FROM) { if (item.isOnlyShared() && item.getSubStatus() == RosterItem.SUB_FROM) {
// Remove from memory and do nothing else // Remove from memory and do nothing else
rosterItems.remove(item.getJid().toBareJID()); rosterItems.remove(item.getJid().toBareJID());
// Cache information about shared contacts with subscription status FROM
implicitFrom.put(item.getJid().toBareJID(), item.getJid().toBareJID());
} }
else { else {
// Remove from list of shared contacts with status FROM (if any)
implicitFrom.remove(item.getJid().toBareJID());
// Brodcast to all the user resources of the updated roster item // Brodcast to all the user resources of the updated roster item
broadcast(item, true); broadcast(item, true);
// Probe the presence of the new group user // Probe the presence of the new group user
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment