Commit 428a18ce authored by Armando Jagucki's avatar Armando Jagucki Committed by ajagucki

PEP support for disco#items added. PEP services get restored from the database...

PEP support for disco#items added. PEP services get restored from the database on initialization now.

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/branches/pep@8779 b35dd754-fafc-0310-a699-88a17e54d16e
parent 16d27670
...@@ -28,6 +28,7 @@ import org.jivesoftware.openfire.disco.ServerFeaturesProvider; ...@@ -28,6 +28,7 @@ import org.jivesoftware.openfire.disco.ServerFeaturesProvider;
import org.jivesoftware.openfire.disco.ServerIdentitiesProvider; import org.jivesoftware.openfire.disco.ServerIdentitiesProvider;
import org.jivesoftware.openfire.disco.ServerItemsProvider; import org.jivesoftware.openfire.disco.ServerItemsProvider;
import org.jivesoftware.openfire.disco.UserIdentitiesProvider; import org.jivesoftware.openfire.disco.UserIdentitiesProvider;
import org.jivesoftware.openfire.disco.UserItemsProvider;
import org.jivesoftware.openfire.filetransfer.DefaultFileTransferManager; import org.jivesoftware.openfire.filetransfer.DefaultFileTransferManager;
import org.jivesoftware.openfire.filetransfer.FileTransferManager; import org.jivesoftware.openfire.filetransfer.FileTransferManager;
import org.jivesoftware.openfire.filetransfer.proxy.FileTransferProxy; import org.jivesoftware.openfire.filetransfer.proxy.FileTransferProxy;
...@@ -1263,6 +1264,23 @@ public class XMPPServer { ...@@ -1263,6 +1264,23 @@ public class XMPPServer {
return answer; return answer;
} }
/**
* Returns a list with all the modules that provide "discoverable" items associated with
* users.
*
* @return a list with all the modules that provide "discoverable" items associated with
* users.
*/
public List<UserItemsProvider> getUserItemsProviders() {
List<UserItemsProvider> answer = new ArrayList<UserItemsProvider>();
for (Module module : modules.values()) {
if (module instanceof UserItemsProvider) {
answer.add((UserItemsProvider) module);
}
}
return answer;
}
/** /**
* Returns the <code>IQDiscoInfoHandler</code> registered with this server. The * Returns the <code>IQDiscoInfoHandler</code> registered with this server. The
* <code>IQDiscoInfoHandler</code> was registered with the server as a module while starting up * <code>IQDiscoInfoHandler</code> was registered with the server as a module while starting up
......
...@@ -65,7 +65,8 @@ import java.util.concurrent.locks.Lock; ...@@ -65,7 +65,8 @@ import java.util.concurrent.locks.Lock;
* *
* @author Gaston Dombiak * @author Gaston Dombiak
*/ */
public class IQDiscoItemsHandler extends IQHandler implements ServerFeaturesProvider, ClusterEventListener { public class IQDiscoItemsHandler extends IQHandler implements ServerFeaturesProvider, ClusterEventListener,
UserItemsProvider {
private Map<String,DiscoItemsProvider> entities = new HashMap<String,DiscoItemsProvider>(); private Map<String,DiscoItemsProvider> entities = new HashMap<String,DiscoItemsProvider>();
private Map<String, Element> localServerItems = new HashMap<String, Element>(); private Map<String, Element> localServerItems = new HashMap<String, Element>();
...@@ -96,10 +97,43 @@ public class IQDiscoItemsHandler extends IQHandler implements ServerFeaturesProv ...@@ -96,10 +97,43 @@ public class IQDiscoItemsHandler extends IQHandler implements ServerFeaturesProv
return reply; return reply;
} }
// If addressed to user@domain, add items from UserItemsProviders to
// the reply.
if (packet.getTo() != null && packet.getTo().getNode() != null) {
String name = packet.getTo().getNode();
reply.setChildElement(packet.getChildElement().createCopy());
Element queryElement = reply.getChildElement();
List<UserItemsProvider> itemsProviders = XMPPServer.getInstance().getUserItemsProviders();
if (itemsProviders.isEmpty()) {
// If we didn't find any UserItemsProviders, then answer a not found error
reply.setChildElement(packet.getChildElement().createCopy());
reply.setError(PacketError.Condition.item_not_found);
}
else {
for (UserItemsProvider itemsProvider : itemsProviders) {
// Check if we have items associated with the requested name
Iterator<Element> itemsItr = itemsProvider.getUserItems(name, packet.getFrom());
if (itemsItr != null) {
// Add to the reply all the items provided by the UserItemsProvider
Element item;
while (itemsItr.hasNext()) {
item = itemsItr.next();
item.setQName(new QName(item.getName(), queryElement.getNamespace()));
queryElement.add(item.createCopy());
}
}
}
}
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
// together with any possible requested node. // together with any possible requested node.
DiscoItemsProvider itemsProvider = getProvider(packet.getTo() == null ? DiscoItemsProvider itemsProvider = getProvider(packet.getTo() == null ?
XMPPServer.getInstance().getServerInfo().getName() : packet.getTo().getDomain()); XMPPServer.getInstance().getServerInfo().getName() : packet.getTo().getDomain());
if (itemsProvider != null) { if (itemsProvider != null) {
...@@ -434,25 +468,7 @@ public class IQDiscoItemsHandler extends IQHandler implements ServerFeaturesProv ...@@ -434,25 +468,7 @@ public class IQDiscoItemsHandler extends IQHandler implements ServerFeaturesProv
return answer.iterator(); return answer.iterator();
} }
else { else {
List<Element> answer = new ArrayList<Element>(); return null;
try {
User user = UserManager.getInstance().getUser(name);
RosterItem item = user.getRoster().getRosterItem(senderJID);
// If the requesting entity is subscribed to the account's presence then
// answer the user's "available resources"
if (item.getSubStatus() == RosterItem.SUB_FROM ||
item.getSubStatus() == RosterItem.SUB_BOTH) {
for (Session session : SessionManager.getInstance().getSessions(name)) {
Element element = DocumentHelper.createElement("item");
element.addAttribute("jid", session.getAddress().toString());
answer.add(element);
}
}
return answer.iterator();
}
catch (UserNotFoundException e) {
return answer.iterator();
}
} }
} }
}; };
...@@ -475,4 +491,26 @@ public class IQDiscoItemsHandler extends IQHandler implements ServerFeaturesProv ...@@ -475,4 +491,26 @@ public class IQDiscoItemsHandler extends IQHandler implements ServerFeaturesProv
ExternalizableUtil.getInstance().readExternalizableCollection(in, nodes, getClass().getClassLoader()); ExternalizableUtil.getInstance().readExternalizableCollection(in, nodes, getClass().getClassLoader());
} }
} }
}
\ No newline at end of file public Iterator<Element> getUserItems(String name, JID senderJID) {
List<Element> answer = new ArrayList<Element>();
try {
User user = UserManager.getInstance().getUser(name);
RosterItem item = user.getRoster().getRosterItem(senderJID);
// If the requesting entity is subscribed to the account's presence then
// answer the user's "available resources"
if (item.getSubStatus() == RosterItem.SUB_FROM ||
item.getSubStatus() == RosterItem.SUB_BOTH) {
for (Session session : SessionManager.getInstance().getSessions(name)) {
Element element = DocumentHelper.createElement("item");
element.addAttribute("jid", session.getAddress().toString());
answer.add(element);
}
}
return answer.iterator();
}
catch (UserNotFoundException e) {
return answer.iterator();
}
}
}
...@@ -13,14 +13,17 @@ package org.jivesoftware.openfire.pep; ...@@ -13,14 +13,17 @@ package org.jivesoftware.openfire.pep;
import org.dom4j.DocumentHelper; import org.dom4j.DocumentHelper;
import org.dom4j.Element; import org.dom4j.Element;
import org.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.openfire.IQHandlerInfo; import org.jivesoftware.openfire.IQHandlerInfo;
import org.jivesoftware.openfire.XMPPServer; import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.auth.UnauthorizedException; import org.jivesoftware.openfire.auth.UnauthorizedException;
import org.jivesoftware.openfire.disco.ServerFeaturesProvider; import org.jivesoftware.openfire.disco.ServerFeaturesProvider;
import org.jivesoftware.openfire.disco.ServerIdentitiesProvider; import org.jivesoftware.openfire.disco.ServerIdentitiesProvider;
import org.jivesoftware.openfire.disco.UserIdentitiesProvider; import org.jivesoftware.openfire.disco.UserIdentitiesProvider;
import org.jivesoftware.openfire.disco.UserItemsProvider;
import org.jivesoftware.openfire.handler.IQHandler; import org.jivesoftware.openfire.handler.IQHandler;
import org.jivesoftware.openfire.pubsub.LeafNode; import org.jivesoftware.openfire.pubsub.LeafNode;
import org.jivesoftware.openfire.pubsub.Node;
import org.jivesoftware.openfire.pubsub.PubSubEngine; import org.jivesoftware.openfire.pubsub.PubSubEngine;
import org.jivesoftware.openfire.user.UserManager; import org.jivesoftware.openfire.user.UserManager;
import org.jivesoftware.util.Log; import org.jivesoftware.util.Log;
...@@ -28,6 +31,10 @@ import org.xmpp.packet.IQ; ...@@ -28,6 +31,10 @@ import org.xmpp.packet.IQ;
import org.xmpp.packet.JID; import org.xmpp.packet.JID;
import org.xmpp.packet.PacketError; import org.xmpp.packet.PacketError;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
...@@ -62,7 +69,7 @@ import java.util.concurrent.ConcurrentHashMap; ...@@ -62,7 +69,7 @@ import java.util.concurrent.ConcurrentHashMap;
* *
*/ */
public class IQPEPHandler extends IQHandler implements ServerIdentitiesProvider, public class IQPEPHandler extends IQHandler implements ServerIdentitiesProvider,
ServerFeaturesProvider, UserIdentitiesProvider { ServerFeaturesProvider, UserIdentitiesProvider, UserItemsProvider {
// Map of PEP services. Table, Key: bare JID (String); Value: PEPService // Map of PEP services. Table, Key: bare JID (String); Value: PEPService
private Map<String, PEPService> pepServices; private Map<String, PEPService> pepServices;
...@@ -71,7 +78,8 @@ public class IQPEPHandler extends IQHandler implements ServerIdentitiesProvider, ...@@ -71,7 +78,8 @@ public class IQPEPHandler extends IQHandler implements ServerIdentitiesProvider,
private PubSubEngine pubSubEngine = null; private PubSubEngine pubSubEngine = null;
private UserManager userManager = null; private static final String GET_PEP_SERVICES =
"SELECT DISTINCT serviceID FROM pubsubNode";
public IQPEPHandler() { public IQPEPHandler() {
super("Personal Eventing Handler"); super("Personal Eventing Handler");
...@@ -84,8 +92,40 @@ public class IQPEPHandler extends IQHandler implements ServerIdentitiesProvider, ...@@ -84,8 +92,40 @@ public class IQPEPHandler extends IQHandler implements ServerIdentitiesProvider,
super.initialize(server); super.initialize(server);
pubSubEngine = new PubSubEngine(server.getPacketRouter()); pubSubEngine = new PubSubEngine(server.getPacketRouter());
userManager = server.getUserManager();
// Restore previous PEP services for which nodes exist in the database.
Connection con = null;
PreparedStatement pstmt = null;
try {
con = DbConnectionManager.getConnection();
// Get all PEP services
pstmt = con.prepareStatement(GET_PEP_SERVICES);
ResultSet rs = pstmt.executeQuery();
// Restore old PEPServices
while(rs.next()) {
String serviceID = rs.getString(1);
// Create a new PEPService if serviceID looks like a bare JID.
if (serviceID.indexOf("@") >= 0) {
PEPService pepService = new PEPService(server, serviceID);
pepServices.put(serviceID, pepService);
if (Log.isDebugEnabled()) {
Log.debug("PEP: Restored service for " + serviceID + " from the database.");
}
}
}
rs.close();
pstmt.close();
}
catch (SQLException sqle) {
Log.error(sqle);
}
finally {
try { if (pstmt != null) pstmt.close(); }
catch (Exception e) { Log.error(e); }
try { if (con != null) con.close(); }
catch (Exception e) { Log.error(e); }
}
} }
@Override @Override
...@@ -95,7 +135,7 @@ public class IQPEPHandler extends IQHandler implements ServerIdentitiesProvider, ...@@ -95,7 +135,7 @@ public class IQPEPHandler extends IQHandler implements ServerIdentitiesProvider,
@Override @Override
public IQ handleIQ(IQ packet) throws UnauthorizedException { public IQ handleIQ(IQ packet) throws UnauthorizedException {
// TODO: Much to be done here... // TODO: Finish implementing ... ;)
if (packet.getTo() == null) { if (packet.getTo() == null) {
String jidFrom = packet.getFrom().toBareJID(); String jidFrom = packet.getFrom().toBareJID();
...@@ -106,7 +146,7 @@ public class IQPEPHandler extends IQHandler implements ServerIdentitiesProvider, ...@@ -106,7 +146,7 @@ public class IQPEPHandler extends IQHandler implements ServerIdentitiesProvider,
if (pepService == null) { if (pepService == null) {
// Return an error if the packet is from an anonymous or otherwise // Return an error if the packet is from an anonymous or otherwise
// unregistered user. // unregistered user.
if (!userManager.isRegisteredUser(packet.getFrom())) { if (!UserManager.getInstance().isRegisteredUser(packet.getFrom())) {
IQ reply = IQ.createResultIQ(packet); IQ reply = IQ.createResultIQ(packet);
reply.setChildElement(packet.getChildElement().createCopy()); reply.setChildElement(packet.getChildElement().createCopy());
reply.setError(PacketError.Condition.not_allowed); reply.setError(PacketError.Condition.not_allowed);
...@@ -133,7 +173,8 @@ public class IQPEPHandler extends IQHandler implements ServerIdentitiesProvider, ...@@ -133,7 +173,8 @@ public class IQPEPHandler extends IQHandler implements ServerIdentitiesProvider,
if (pepService.getNode(nodeID) == null) { if (pepService.getNode(nodeID) == null) {
// Create the node // Create the node
JID creator = new JID(jidFrom); JID creator = new JID(jidFrom);
LeafNode newNode = new LeafNode(pepService, null, nodeID, creator); LeafNode newNode = new LeafNode(pepService, pepService.getRootCollectionNode(),
nodeID, creator);
newNode.addOwner(creator); newNode.addOwner(creator);
newNode.saveToDB(); newNode.saveToDB();
if (Log.isDebugEnabled()) { if (Log.isDebugEnabled()) {
...@@ -157,10 +198,22 @@ public class IQPEPHandler extends IQHandler implements ServerIdentitiesProvider, ...@@ -157,10 +198,22 @@ public class IQPEPHandler extends IQHandler implements ServerIdentitiesProvider,
} }
else { else {
// TODO: Ensure the packet gets handled elsewhere. // TODO: Handle packets such as these.
if (Log.isDebugEnabled()) {
Log.debug("PEP: getTo() wasn't null.");
}
// Is getTo() online? If not, consider what error to use.
// FIXME: Remove this chunk of error code after such packets are handled.
IQ reply = IQ.createResultIQ(packet);
reply.setChildElement(packet.getChildElement().createCopy());
reply.setError(PacketError.Condition.service_unavailable);
return reply;
} }
return null; // Error flows are handled in pubSubEngine.process(...) // Other error flows are handled in pubSubEngine.process(...)
return null;
} }
public void start() { public void start() {
...@@ -198,4 +251,23 @@ public class IQPEPHandler extends IQHandler implements ServerIdentitiesProvider, ...@@ -198,4 +251,23 @@ public class IQPEPHandler extends IQHandler implements ServerIdentitiesProvider,
return XMPPServer.getInstance().getPubSubModule().getFeatures(null, null, null); return XMPPServer.getInstance().getPubSubModule().getFeatures(null, null, null);
} }
public Iterator<Element> getUserItems(String name, JID senderJID) {
ArrayList<Element> items = new ArrayList<Element>();
String recipientJID = XMPPServer.getInstance().createJID(name, null).toBareJID();
PEPService pepService = pepServices.get(recipientJID);
if (pepService != null) {
Element defaultItem = DocumentHelper.createElement("item");
defaultItem.addAttribute("jid", recipientJID);
for (Node node : pepService.getNodes()) {
Element item = defaultItem.createCopy();
item.addAttribute("node", node.getNodeID());
items.add(item);
}
}
return items.iterator();
}
} }
...@@ -137,8 +137,8 @@ public class PEPService implements PubSubService { ...@@ -137,8 +137,8 @@ public class PEPService implements PubSubService {
/** /**
* Constructs a PEPService. * Constructs a PEPService.
* *
* @param server * @param server the XMPP server.
* the XMPP server. * @param bareJID the bare JID (service ID) of the user owning the service.
*/ */
public PEPService(XMPPServer server, String bareJID) { public PEPService(XMPPServer server, String bareJID) {
this.bareJID = bareJID; this.bareJID = bareJID;
...@@ -200,7 +200,7 @@ public class PEPService implements PubSubService { ...@@ -200,7 +200,7 @@ public class PEPService implements PubSubService {
// Load nodes to memory // Load nodes to memory
PubSubPersistenceManager.loadNodes(this); PubSubPersistenceManager.loadNodes(this);
// Ensure that we have a root collection node // Ensure that we have a root collection node
String rootNodeID = JiveGlobals.getProperty("xmpp.pubsub.root.nodeID", ""); String rootNodeID = JiveGlobals.getProperty("xmpp.pubsub.root.nodeID", bareJID);
if (nodes.isEmpty()) { if (nodes.isEmpty()) {
// Create root collection node // Create root collection node
String creator = JiveGlobals.getProperty("xmpp.pubsub.root.creator"); String creator = JiveGlobals.getProperty("xmpp.pubsub.root.creator");
......
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