Commit d96d3767 authored by Armando Jagucki's avatar Armando Jagucki Committed by ajagucki

The PEPService.sendNotification method is now able to send to the full JID of...

The PEPService.sendNotification method is now able to send to the full JID of the recipient for all of its connected resources that the service has presence information about.

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/branches@8852 b35dd754-fafc-0310-a699-88a17e54d16e
parent 1d90be73
...@@ -480,10 +480,9 @@ public class IQPEPHandler extends IQHandler implements ServerIdentitiesProvider, ...@@ -480,10 +480,9 @@ public class IQPEPHandler extends IQHandler implements ServerIdentitiesProvider,
return; return;
} }
// FIXME: Instead of the bare JID, use the full JID. Only change this // Get the sender's full JID considering they may be logged in from multiple
// when PEPService's sendNotification() is able to send to the full // clients with different notification filters.
// JID. See its FIXME as well. String jidFrom = packet.getFrom().toString();
String jidFrom = packet.getFrom().toBareJID();
// For each feature variable, or in this case node ID, ending in "+notify" -- add // For each feature variable, or in this case node ID, ending in "+notify" -- add
// the node ID to the set of filtered nodes that jidFrom is interested in being // the node ID to the set of filtered nodes that jidFrom is interested in being
......
...@@ -28,8 +28,10 @@ import org.jivesoftware.openfire.pubsub.models.AccessModel; ...@@ -28,8 +28,10 @@ import org.jivesoftware.openfire.pubsub.models.AccessModel;
import org.jivesoftware.openfire.pubsub.models.PublisherModel; import org.jivesoftware.openfire.pubsub.models.PublisherModel;
import org.jivesoftware.openfire.roster.Roster; import org.jivesoftware.openfire.roster.Roster;
import org.jivesoftware.openfire.roster.RosterItem; import org.jivesoftware.openfire.roster.RosterItem;
import org.jivesoftware.openfire.session.ClientSession;
import org.jivesoftware.openfire.user.UserNotFoundException; import org.jivesoftware.openfire.user.UserNotFoundException;
import org.jivesoftware.openfire.PacketRouter; import org.jivesoftware.openfire.PacketRouter;
import org.jivesoftware.openfire.SessionManager;
import org.jivesoftware.openfire.XMPPServer; import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.util.StringUtils; import org.jivesoftware.util.StringUtils;
import org.xmpp.packet.JID; import org.xmpp.packet.JID;
...@@ -37,6 +39,7 @@ import org.xmpp.packet.Message; ...@@ -37,6 +39,7 @@ import org.xmpp.packet.Message;
import org.xmpp.packet.Packet; import org.xmpp.packet.Packet;
import org.xmpp.packet.PacketExtension; import org.xmpp.packet.PacketExtension;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
...@@ -312,79 +315,92 @@ public class PEPService implements PubSubService { ...@@ -312,79 +315,92 @@ public class PEPService implements PubSubService {
public void sendNotification(Node node, Message message, JID recipientJID) { public void sendNotification(Node node, Message message, JID recipientJID) {
message.setFrom(getAddress()); message.setFrom(getAddress());
// FIXME: Send to the full JID if this PEPService can retrieve presence // If this PEPService can retrieve presence information for the recipient,
// for the recipient. // collect all of their full JIDs and send the notification to each below.
Collection<JID> recipientFullJIDs = new ArrayList<JID>();
if (XMPPServer.getInstance().isLocal(recipientJID)) {
for (ClientSession clientSession : SessionManager.getInstance().getSessions(recipientJID.getNode())) {
recipientFullJIDs.add(clientSession.getAddress());
}
}
else {
recipientFullJIDs.add(recipientJID);
}
message.setTo(recipientJID); message.setTo(recipientJID);
message.setID(node.getNodeID() + "__" + recipientJID.toBareJID() + "__" + StringUtils.randomString(5)); message.setID(node.getNodeID() + "__" + recipientJID.toBareJID() + "__" + StringUtils.randomString(5));
// Include an Extended Stanza Addressing "replyto" extension specifying the publishing for (JID recipientFullJID : recipientFullJIDs) {
// resource. However, only include the extension if the receiver has a presence subscription // Include an Extended Stanza Addressing "replyto" extension specifying the publishing
// to the service owner. // resource. However, only include the extension if the receiver has a presence subscription
try { // to the service owner.
// Get the full JID of the item publisher from the node that was published to. try {
// This full JID will be used as the "replyto" address in the addressing extension. // Get the full JID of the item publisher from the node that was published to.
JID publisher = null; // This full JID will be used as the "replyto" address in the addressing extension.
JID publisher = null;
Element itemsElement = message.getElement().element("event").element("items");
String publishedItemID = itemsElement.element("item").attributeValue("id"); Element itemsElement = message.getElement().element("event").element("items");
String nodeIDPublishedTo = itemsElement.attributeValue("node"); String publishedItemID = itemsElement.element("item").attributeValue("id");
String nodeIDPublishedTo = itemsElement.attributeValue("node");
// Check if the recipientJID is interested in notifications for this node.
// If the recipient has not yet requested any notification filtering, continue and send // Check if the recipientFullJID is interested in notifications for this node.
// the notification. // If the recipient has not yet requested any notification filtering, continue and send
Map<String, HashSet<String>> filteredNodesMap = XMPPServer.getInstance().getIQPEPHandler().getFilteredNodesMap(); // the notification.
HashSet<String> filteredNodesSet = filteredNodesMap.get(recipientJID.toBareJID()); Map<String, HashSet<String>> filteredNodesMap = XMPPServer.getInstance().getIQPEPHandler().getFilteredNodesMap();
if (filteredNodesSet != null && !filteredNodesSet.contains(nodeIDPublishedTo)) { HashSet<String> filteredNodesSet = filteredNodesMap.get(recipientFullJID.toString());
return; if (filteredNodesSet != null && !filteredNodesSet.contains(nodeIDPublishedTo)) {
} return;
}
if (node.isCollectionNode()) {
for (Node leafNode : node.getNodes()) {
if (leafNode.getNodeID().equals(nodeIDPublishedTo)) {
publisher = leafNode.getPublishedItem(publishedItemID).getPublisher();
if (node.isCollectionNode()) { // Ensure the recipientJID has access to receive notifications for items published to the leaf node.
for (Node leafNode : node.getNodes()) { AccessModel accessModel = leafNode.getAccessModel();
if (leafNode.getNodeID().equals(nodeIDPublishedTo)) { if (!accessModel.canAccessItems(leafNode, recipientFullJID, publisher)) {
publisher = leafNode.getPublishedItem(publishedItemID).getPublisher(); return;
}
// Ensure the recipientJID has access to receive notifications for items published to the leaf node.
AccessModel accessModel = leafNode.getAccessModel(); break;
if (!accessModel.canAccessItems(leafNode, recipientJID, publisher)) {
return;
} }
break;
} }
} }
} else {
else { publisher = node.getPublishedItem(publishedItemID).getPublisher();
publisher = node.getPublishedItem(publishedItemID).getPublisher(); }
}
// Ensure the recipient is subscribed to the service owner's (publisher's) presence.
Roster roster = XMPPServer.getInstance().getRosterManager().getRoster(publisher.getNode());
RosterItem item = roster.getRosterItem(recipientFullJID);
// Ensure the recipient is subscribed to the service owner's (publisher's) presence. if (item.getSubStatus() == RosterItem.SUB_BOTH || item.getSubStatus() == RosterItem.SUB_FROM) {
Roster roster = XMPPServer.getInstance().getRosterManager().getRoster(publisher.getNode()); Element addresses = DocumentHelper.createElement(QName.get("addresses", "http://jabber.org/protocol/address"));
RosterItem item = roster.getRosterItem(recipientJID); Element address = addresses.addElement("address");
address.addAttribute("type", "replyto");
address.addAttribute("jid", publisher.toString());
if (item.getSubStatus() == RosterItem.SUB_BOTH || item.getSubStatus() == RosterItem.SUB_FROM) { Message extendedMessage = message.createCopy();
Element addresses = DocumentHelper.createElement(QName.get("addresses", "http://jabber.org/protocol/address")); extendedMessage.addExtension(new PacketExtension(addresses));
Element address = addresses.addElement("address");
address.addAttribute("type", "replyto");
address.addAttribute("jid", publisher.toString());
Message extendedMessage = message.createCopy(); extendedMessage.setTo(recipientFullJID);
extendedMessage.addExtension(new PacketExtension(addresses)); router.route(extendedMessage);
router.route(extendedMessage); return;
return; }
}
catch (IndexOutOfBoundsException e) {
// Do not add addressing extension to message.
}
catch (UserNotFoundException e) {
// Do not add addressing extension to message.
}
catch (NullPointerException e) {
// Do not add addressing extension to message.
} }
} }
catch (IndexOutOfBoundsException e) {
// Do not add addressing extension to message.
}
catch (UserNotFoundException e) {
// Do not add addressing extension to message.
}
catch (NullPointerException e) {
// Do not add addressing extension to message.
}
router.route(message); router.route(message);
} }
......
...@@ -373,12 +373,14 @@ public class UserManager implements IQResultListener { ...@@ -373,12 +373,14 @@ public class UserManager implements IQResultListener {
// Analyze the disco result packet // Analyze the disco result packet
if (IQ.Type.result == packet.getType()) { if (IQ.Type.result == packet.getType()) {
Element child = packet.getChildElement(); Element child = packet.getChildElement();
for (Iterator it=child.elementIterator("identity"); it.hasNext();) { if (child != null) {
Element identity = (Element) it.next(); for (Iterator it=child.elementIterator("identity"); it.hasNext();) {
String accountType = identity.attributeValue("type"); Element identity = (Element) it.next();
if ("registered".equals(accountType) || "admin".equals(accountType)) { String accountType = identity.attributeValue("type");
isRegistered = Boolean.TRUE; if ("registered".equals(accountType) || "admin".equals(accountType)) {
break; isRegistered = Boolean.TRUE;
break;
}
} }
} }
} }
......
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