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

Contact Subscription: Implemented auto-subscriptions to PEP services via presence subscriptions.

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/branches@8812 b35dd754-fafc-0310-a699-88a17e54d16e
parent 7d10a3fd
...@@ -101,10 +101,10 @@ public class IQDiscoItemsHandler extends IQHandler implements ServerFeaturesProv ...@@ -101,10 +101,10 @@ public class IQDiscoItemsHandler extends IQHandler implements ServerFeaturesProv
// the reply. // the reply.
if (packet.getTo() != null && packet.getTo().getNode() != null) { if (packet.getTo() != null && packet.getTo().getNode() != null) {
String name = packet.getTo().getNode(); String name = packet.getTo().getNode();
reply.setChildElement(packet.getChildElement().createCopy()); reply.setChildElement(packet.getChildElement().createCopy());
Element queryElement = reply.getChildElement(); Element queryElement = reply.getChildElement();
List<UserItemsProvider> itemsProviders = XMPPServer.getInstance().getUserItemsProviders(); List<UserItemsProvider> itemsProviders = XMPPServer.getInstance().getUserItemsProviders();
if (itemsProviders.isEmpty()) { if (itemsProviders.isEmpty()) {
// If we didn't find any UserItemsProviders, then answer a not found error // If we didn't find any UserItemsProviders, then answer a not found error
...@@ -126,10 +126,10 @@ public class IQDiscoItemsHandler extends IQHandler implements ServerFeaturesProv ...@@ -126,10 +126,10 @@ public class IQDiscoItemsHandler extends IQHandler implements ServerFeaturesProv
} }
} }
} }
return reply; return reply;
} }
// Look for a DiscoItemsProvider associated with the requested entity. // Look for a DiscoItemsProvider associated with the requested entity.
// We consider the host of the recipient JID of the packet as the entity. It's the // We consider the host of the recipient JID of the packet as the entity. It's the
// DiscoItemsProvider responsibility to provide the items associated with the JID's name // DiscoItemsProvider responsibility to provide the items associated with the JID's name
......
...@@ -16,6 +16,7 @@ import org.jivesoftware.openfire.container.BasicModule; ...@@ -16,6 +16,7 @@ import org.jivesoftware.openfire.container.BasicModule;
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.roster.RosterManager; import org.jivesoftware.openfire.roster.RosterManager;
import org.jivesoftware.openfire.user.PresenceEventDispatcher;
import org.jivesoftware.openfire.user.UserAlreadyExistsException; import org.jivesoftware.openfire.user.UserAlreadyExistsException;
import org.jivesoftware.openfire.user.UserManager; import org.jivesoftware.openfire.user.UserManager;
import org.jivesoftware.openfire.user.UserNotFoundException; import org.jivesoftware.openfire.user.UserNotFoundException;
...@@ -168,6 +169,7 @@ public class PresenceSubscribeHandler extends BasicModule implements ChannelHand ...@@ -168,6 +169,7 @@ public class PresenceSubscribeHandler extends BasicModule implements ChannelHand
JID prober = localServer.isLocal(recipientJID) ? JID prober = localServer.isLocal(recipientJID) ?
new JID(recipientJID.toBareJID()) : recipientJID; new JID(recipientJID.toBareJID()) : recipientJID;
presenceManager.probePresence(prober, senderJID); presenceManager.probePresence(prober, senderJID);
PresenceEventDispatcher.subscribedToPresence(prober, senderJID);
} }
} }
......
...@@ -270,7 +270,7 @@ public class PEPService implements PubSubService { ...@@ -270,7 +270,7 @@ public class PEPService implements PubSubService {
} }
public boolean isCollectionNodesSupported() { public boolean isCollectionNodesSupported() {
return false; return true;
} }
public boolean isInstantNodeSupported() { public boolean isInstantNodeSupported() {
......
...@@ -88,6 +88,13 @@ public class NodeAffiliate { ...@@ -88,6 +88,13 @@ public class NodeAffiliate {
Element items = event.addElement("items"); Element items = event.addElement("items");
items.addAttribute("node", getNode().getNodeID()); items.addAttribute("node", getNode().getNodeID());
for (PublishedItem publishedItem : itemsBySubs.get(nodeSubscriptions)) { for (PublishedItem publishedItem : itemsBySubs.get(nodeSubscriptions)) {
// FIXME: This was added for compatibility with PEP supporting clients like Psi.
// May not be the best of solutions.
//
// If the node ID looks like a JID, replace it with the published item's node ID.
if (getNode().getNodeID().indexOf("@") >= 0) {
items.addAttribute("node", publishedItem.getNode().getNodeID());
}
// Add item information to the event notification // Add item information to the event notification
Element item = items.addElement("item"); Element item = items.addElement("item");
if (leafNode.isItemRequired()) { if (leafNode.isItemRequired()) {
......
...@@ -35,14 +35,22 @@ import java.util.concurrent.LinkedBlockingQueue; ...@@ -35,14 +35,22 @@ import java.util.concurrent.LinkedBlockingQueue;
*/ */
public class PubSubPersistenceManager { public class PubSubPersistenceManager {
private static final String LOAD_NODES = private static final String LOAD_NON_LEAF_NODES =
"SELECT nodeID, leaf, creationDate, modificationDate, parent, deliverPayloads, " + "SELECT nodeID, leaf, creationDate, modificationDate, parent, deliverPayloads, " +
"maxPayloadSize, persistItems, maxItems, notifyConfigChanges, notifyDelete, " + "maxPayloadSize, persistItems, maxItems, notifyConfigChanges, notifyDelete, " +
"notifyRetract, presenceBased, sendItemSubscribe, publisherModel, " + "notifyRetract, presenceBased, sendItemSubscribe, publisherModel, " +
"subscriptionEnabled, configSubscription, accessModel, payloadType, " + "subscriptionEnabled, configSubscription, accessModel, payloadType, " +
"bodyXSLT, dataformXSLT, creator, description, language, name, " + "bodyXSLT, dataformXSLT, creator, description, language, name, " +
"replyPolicy, associationPolicy, maxLeafNodes FROM pubsubNode " + "replyPolicy, associationPolicy, maxLeafNodes FROM pubsubNode " +
"WHERE serviceID=? ORDER BY nodeID"; "WHERE serviceID=? AND leaf=0 ORDER BY nodeID";
private static final String LOAD_LEAF_NODES =
"SELECT nodeID, leaf, creationDate, modificationDate, parent, deliverPayloads, " +
"maxPayloadSize, persistItems, maxItems, notifyConfigChanges, notifyDelete, " +
"notifyRetract, presenceBased, sendItemSubscribe, publisherModel, " +
"subscriptionEnabled, configSubscription, accessModel, payloadType, " +
"bodyXSLT, dataformXSLT, creator, description, language, name, " +
"replyPolicy, associationPolicy, maxLeafNodes FROM pubsubNode " +
"WHERE serviceID=? AND leaf=1 ORDER BY nodeID";
private static final String UPDATE_NODE = private static final String UPDATE_NODE =
"UPDATE pubsubNode SET modificationDate=?, parent=?, deliverPayloads=?, " + "UPDATE pubsubNode SET modificationDate=?, parent=?, deliverPayloads=?, " +
"maxPayloadSize=?, persistItems=?, maxItems=?, " + "maxPayloadSize=?, persistItems=?, maxItems=?, " +
...@@ -446,11 +454,22 @@ public class PubSubPersistenceManager { ...@@ -446,11 +454,22 @@ public class PubSubPersistenceManager {
Map<String, Node> nodes = new HashMap<String, Node>(); Map<String, Node> nodes = new HashMap<String, Node>();
try { try {
con = DbConnectionManager.getConnection(); con = DbConnectionManager.getConnection();
// Get all nodes at once (with 1 query) // Get all non-leaf nodes (to ensure parent nodes are loaded before their children)
pstmt = con.prepareStatement(LOAD_NODES); pstmt = con.prepareStatement(LOAD_NON_LEAF_NODES);
pstmt.setString(1, service.getServiceID()); pstmt.setString(1, service.getServiceID());
ResultSet rs = pstmt.executeQuery(); ResultSet rs = pstmt.executeQuery();
// Rebuild all loaded nodes // Rebuild loaded non-leaf nodes
while(rs.next()) {
loadNode(service, nodes, rs);
}
rs.close();
pstmt.close();
// Get all leaf nodes (remaining unloaded nodes)
pstmt = con.prepareStatement(LOAD_LEAF_NODES);
pstmt.setString(1, service.getServiceID());
rs = pstmt.executeQuery();
// Rebuild loaded leaf nodes
while(rs.next()) { while(rs.next()) {
loadNode(service, nodes, rs); loadNode(service, nodes, rs);
} }
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
package org.jivesoftware.openfire.user; package org.jivesoftware.openfire.user;
import org.jivesoftware.openfire.session.ClientSession; import org.jivesoftware.openfire.session.ClientSession;
import org.xmpp.packet.JID;
import org.xmpp.packet.Presence; import org.xmpp.packet.Presence;
import java.util.List; import java.util.List;
...@@ -123,4 +124,19 @@ public class PresenceEventDispatcher { ...@@ -123,4 +124,19 @@ public class PresenceEventDispatcher {
} }
} }
} }
/**
* Notification message indicating that a user has successfully subscribed
* to the presence of another user.
*
* @param subscriberJID the user that initiated the subscription.
* @param authorizerJID the user that authorized the subscription.
*/
public static void subscribedToPresence(JID subscriberJID, JID authorizerJID) {
if (!listeners.isEmpty()) {
for (PresenceEventListener listener : listeners) {
listener.subscribedToPresence(subscriberJID, authorizerJID);
}
}
}
} }
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
package org.jivesoftware.openfire.user; package org.jivesoftware.openfire.user;
import org.jivesoftware.openfire.session.ClientSession; import org.jivesoftware.openfire.session.ClientSession;
import org.xmpp.packet.JID;
import org.xmpp.packet.Presence; import org.xmpp.packet.Presence;
/** /**
...@@ -64,4 +65,13 @@ public interface PresenceEventListener { ...@@ -64,4 +65,13 @@ public interface PresenceEventListener {
* @param presence the received available presence with the new information. * @param presence the received available presence with the new information.
*/ */
public void presenceChanged(ClientSession session, Presence presence); public void presenceChanged(ClientSession session, Presence presence);
/**
* Notification message indicating that a user has successfully subscribed
* to the presence of another user.
*
* @param subscriberJID the user that initiated the subscription.
* @param authorizerJID the user that authorized the subscription.
*/
public void subscribedToPresence(JID subscriberJID, JID authorizerJID);
} }
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