Commit ab4a1523 authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gato

Fixed directed presences for groupchats and one-2-one. JM-1273, JM-1274 and JM-1275

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@9932 b35dd754-fafc-0310-a699-88a17e54d16e
parent 34fd4775
......@@ -156,7 +156,7 @@ public class PresenceRouter extends BasicModule {
// The user sent a directed presence to an entity
// Broadcast it to all connected resources
for (JID jid : routingTable.getRoutes(recipientJID)) {
for (JID jid : routingTable.getRoutes(recipientJID, senderJID)) {
// Register the sent directed presence
updateHandler.directedPresenceSent(packet, jid, recipientJID.toString());
// Route the packet
......
......@@ -283,16 +283,22 @@ public interface RoutingTable {
* included in the answer in case the specified full JID exists or an empty collection
* if the full JID does not exist. Moreover, when passing a bare JID a list of full
* JIDs will be returned for each available resource associated to the bare JID. In
* any case, only JIDs of <tt>available</tt> client sessions are returned.<p>
* any case, only JIDs of <tt>available</tt> client sessions are returned. However,
* there is an exception with directed presences. Unavailable routes may be returned
* if and only if the owner of the route sent a directed presence to the requester
* thus becoming available to the requester. If requester is <tt>null</tt> then only
* available resources are considered.<p>
*
* When asking for routes to components a single element will be returned in the answer
* only if an internal or external component is found for the specified route address.
* If no component was found then an empty collection will be returned.
*
* @param route The address we want a route to.
* @param requester The address of the entity requesting the routes or null if we don't
* care about directed presences.
* @return list of routes associated to the specified route address.
*/
List<JID> getRoutes(JID route);
List<JID> getRoutes(JID route, JID requester);
/**
* Returns true if a route of a client session has been successfully removed. When running
......
......@@ -551,7 +551,7 @@ public class SessionManager extends BasicModule implements ClusterEventListener
Presence presence;
// Get list of sessions of the same user
JID searchJID = new JID(session.getAddress().getNode(), session.getAddress().getDomain(), null);
List<JID> addresses = routingTable.getRoutes(searchJID);
List<JID> addresses = routingTable.getRoutes(searchJID, null);
for (JID address : addresses) {
if (address.equals(session.getAddress())) {
continue;
......@@ -575,7 +575,7 @@ public class SessionManager extends BasicModule implements ClusterEventListener
public void broadcastPresenceToOtherResources(JID originatingResource, Presence presence) {
// Get list of sessions of the same user
JID searchJID = new JID(originatingResource.getNode(), originatingResource.getDomain(), null);
List<JID> addresses = routingTable.getRoutes(searchJID);
List<JID> addresses = routingTable.getRoutes(searchJID, null);
for (JID address : addresses) {
if (address.equals(originatingResource)) {
continue;
......@@ -621,7 +621,7 @@ public class SessionManager extends BasicModule implements ClusterEventListener
// Check presence's priority of other available resources
JID searchJID = new JID(session.getAddress().toBareJID());
for (JID address : routingTable.getRoutes(searchJID)) {
for (JID address : routingTable.getRoutes(searchJID, null)) {
if (address.equals(session.getAddress())) {
continue;
}
......@@ -812,7 +812,7 @@ public class SessionManager extends BasicModule implements ClusterEventListener
public Collection<ClientSession> getSessions(String username) {
List<ClientSession> sessionList = new ArrayList<ClientSession>();
if (username != null) {
List<JID> addresses = routingTable.getRoutes(new JID(username, serverName, null, true));
List<JID> addresses = routingTable.getRoutes(new JID(username, serverName, null, true), null);
for (JID address : addresses) {
sessionList.add(routingTable.getClientRoute(address));
}
......@@ -889,12 +889,12 @@ public class SessionManager extends BasicModule implements ClusterEventListener
* @return number of available sessions for a user.
*/
public int getActiveSessionCount(String username) {
return routingTable.getRoutes(new JID(username, serverName, null, true)).size();
return routingTable.getRoutes(new JID(username, serverName, null, true), null).size();
}
public int getSessionCount(String username) {
// TODO Count ALL sessions not only available
return routingTable.getRoutes(new JID(username, serverName, null, true)).size();
return routingTable.getRoutes(new JID(username, serverName, null, true), null).size();
}
/**
......@@ -985,7 +985,7 @@ public class SessionManager extends BasicModule implements ClusterEventListener
*/
public void userBroadcast(String username, Packet packet) throws PacketException {
// TODO broadcast to ALL sessions of the user and not only available
for (JID address : routingTable.getRoutes(new JID(username, serverName, null))) {
for (JID address : routingTable.getRoutes(new JID(username, serverName, null), null)) {
packet.setTo(address);
routingTable.routePacket(address, packet, true);
}
......
......@@ -150,7 +150,7 @@ public class PresenceSubscribeHandler extends BasicModule implements ChannelHand
// a module, the module will be able to handle the packet. If the handler is a
// Session the packet will be routed to the client. If a route cannot be found
// then the packet will be delivered based on its recipient and sender.
List<JID> jids = routingTable.getRoutes(recipientJID);
List<JID> jids = routingTable.getRoutes(recipientJID, null);
if (!jids.isEmpty()) {
for (JID jid : jids) {
Presence presenteToSend = presence.createCopy();
......
......@@ -452,8 +452,11 @@ public class PresenceUpdateHandler extends BasicModule implements ChannelHandler
}
}
public boolean hasDirectPresence(Session session, JID recipientJID) {
Collection<DirectedPresence> directedPresences = directedPresencesCache.get(session.getAddress().toString());
public boolean hasDirectPresence(JID ownerJID, JID recipientJID) {
if (recipientJID == null) {
return false;
}
Collection<DirectedPresence> directedPresences = directedPresencesCache.get(ownerJID.toString());
if (directedPresences != null) {
String recipient = recipientJID.toBareJID();
for (DirectedPresence directedPresence : directedPresences) {
......
......@@ -53,7 +53,7 @@ public class SocketPacketWriteHandler implements ChannelHandler {
}
else {
// JID is of the form <user@domain>
for (JID route : routingTable.getRoutes(recipient)) {
for (JID route : routingTable.getRoutes(recipient, null)) {
routingTable.routePacket(route, packet, false);
}
}
......
......@@ -582,7 +582,7 @@ public class Roster implements Cacheable, Externalizable {
continue;
}
JID searchNode = new JID(item.getJid().getNode(), item.getJid().getDomain(), null, true);
for (JID jid : routingTable.getRoutes(searchNode)) {
for (JID jid : routingTable.getRoutes(searchNode, null)) {
try {
routingTable.routePacket(jid, packet, false);
}
......@@ -600,7 +600,7 @@ public class Roster implements Cacheable, Externalizable {
// Outgoing presence notifications are blocked for this contact
continue;
}
for (JID jid: routingTable.getRoutes(new JID(contact))) {
for (JID jid: routingTable.getRoutes(new JID(contact), null)) {
try {
routingTable.routePacket(jid, packet, false);
}
......
......@@ -32,9 +32,9 @@ import org.jivesoftware.openfire.user.UserNotFoundException;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.StringUtils;
import org.jivesoftware.util.lock.LockManager;
import org.jivesoftware.util.cache.Cache;
import org.jivesoftware.util.cache.CacheFactory;
import org.jivesoftware.util.lock.LockManager;
import org.xmpp.packet.JID;
import org.xmpp.packet.PacketError;
import org.xmpp.packet.Presence;
......@@ -432,7 +432,7 @@ public class PresenceManagerImpl extends BasicModule implements PresenceManager
if (userManager.isRegisteredUser(userJID.getNode())) {
for (ClientSession session : sessionManager.getSessions(userJID.getNode())) {
// Do not send an unavailable presence if the user sent a direct available presence
if (presenceUpdateHandler.hasDirectPresence(session, recipientJID)) {
if (presenceUpdateHandler.hasDirectPresence(session.getAddress(), recipientJID)) {
continue;
}
Presence presencePacket = new Presence();
......
......@@ -88,6 +88,7 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust
private IQRouter iqRouter;
private MessageRouter messageRouter;
private PresenceRouter presenceRouter;
private PresenceUpdateHandler presenceUpdateHandler;
public RoutingTableImpl() {
super("Routing table");
......@@ -200,7 +201,8 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust
clientRoute = anonymousUsersCache.get(jid.toString());
}
if (clientRoute != null) {
if (!clientRoute.isAvailable() && routeOnlyAvailable(packet, fromServer)) {
if (!clientRoute.isAvailable() && routeOnlyAvailable(packet, fromServer) &&
!presenceUpdateHandler.hasDirectPresence(packet.getTo(), packet.getFrom())) {
// Packet should only be sent to available sessions and the route is not available
routed = false;
}
......@@ -363,8 +365,8 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust
*/
private boolean routeToBareJID(JID recipientJID, Message packet) {
List<ClientSession> sessions = new ArrayList<ClientSession>();
// Get existing AVAILABLE sessions of this user
for (JID address : getRoutes(recipientJID)) {
// Get existing AVAILABLE sessions of this user or AVAILABLE to the sender of the packet
for (JID address : getRoutes(recipientJID, packet.getFrom())) {
ClientSession session = getClientRoute(address);
if (session != null) {
sessions.add(session);
......@@ -570,8 +572,7 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust
return componentsCache.containsKey(jid.getDomain());
}
public List<JID> getRoutes(JID route) {
// TODO Refactor API to be able to get c2s sessions available only/all
public List<JID> getRoutes(JID route, JID requester) {
List<JID> jids = new ArrayList<JID>();
if (serverName.equals(route.getDomain())) {
// Address belongs to local user
......@@ -581,7 +582,8 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust
if (clientRoute == null) {
clientRoute = anonymousUsersCache.get(route.toString());
}
if (clientRoute != null && clientRoute.isAvailable()) {
if (clientRoute != null &&
(clientRoute.isAvailable() || presenceUpdateHandler.hasDirectPresence(route, requester))) {
jids.add(route);
}
}
......@@ -595,7 +597,8 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust
if (clientRoute == null) {
clientRoute = anonymousUsersCache.get(jid);
}
if (clientRoute != null && clientRoute.isAvailable()) {
if (clientRoute != null && (clientRoute.isAvailable() ||
presenceUpdateHandler.hasDirectPresence(new JID(jid), requester))) {
jids.add(new JID(jid));
}
}
......@@ -696,6 +699,7 @@ public class RoutingTableImpl extends BasicModule implements RoutingTable, Clust
iqRouter = server.getIQRouter();
messageRouter = server.getMessageRouter();
presenceRouter = server.getPresenceRouter();
presenceUpdateHandler = server.getPresenceUpdateHandler();
// Listen to cluster events
ClusterManager.addListener(this);
}
......
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