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;
import org.jivesoftware.openfire.disco.ServerIdentitiesProvider;
import org.jivesoftware.openfire.disco.ServerItemsProvider;
import org.jivesoftware.openfire.disco.UserIdentitiesProvider;
import org.jivesoftware.openfire.disco.UserItemsProvider;
import org.jivesoftware.openfire.filetransfer.DefaultFileTransferManager;
import org.jivesoftware.openfire.filetransfer.FileTransferManager;
import org.jivesoftware.openfire.filetransfer.proxy.FileTransferProxy;
......@@ -1263,6 +1264,23 @@ public class XMPPServer {
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
* <code>IQDiscoInfoHandler</code> was registered with the server as a module while starting up
......
......@@ -65,7 +65,8 @@ import java.util.concurrent.locks.Lock;
*
* @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, Element> localServerItems = new HashMap<String, Element>();
......@@ -96,6 +97,39 @@ public class IQDiscoItemsHandler extends IQHandler implements ServerFeaturesProv
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.
// 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
......@@ -434,25 +468,7 @@ public class IQDiscoItemsHandler extends IQHandler implements ServerFeaturesProv
return answer.iterator();
}
else {
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();
}
return null;
}
}
};
......@@ -475,4 +491,26 @@ public class IQDiscoItemsHandler extends IQHandler implements ServerFeaturesProv
ExternalizableUtil.getInstance().readExternalizableCollection(in, nodes, getClass().getClassLoader());
}
}
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;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.openfire.IQHandlerInfo;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.auth.UnauthorizedException;
import org.jivesoftware.openfire.disco.ServerFeaturesProvider;
import org.jivesoftware.openfire.disco.ServerIdentitiesProvider;
import org.jivesoftware.openfire.disco.UserIdentitiesProvider;
import org.jivesoftware.openfire.disco.UserItemsProvider;
import org.jivesoftware.openfire.handler.IQHandler;
import org.jivesoftware.openfire.pubsub.LeafNode;
import org.jivesoftware.openfire.pubsub.Node;
import org.jivesoftware.openfire.pubsub.PubSubEngine;
import org.jivesoftware.openfire.user.UserManager;
import org.jivesoftware.util.Log;
......@@ -28,6 +31,10 @@ import org.xmpp.packet.IQ;
import org.xmpp.packet.JID;
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.Iterator;
import java.util.Map;
......@@ -62,7 +69,7 @@ import java.util.concurrent.ConcurrentHashMap;
*
*/
public class IQPEPHandler extends IQHandler implements ServerIdentitiesProvider,
ServerFeaturesProvider, UserIdentitiesProvider {
ServerFeaturesProvider, UserIdentitiesProvider, UserItemsProvider {
// Map of PEP services. Table, Key: bare JID (String); Value: PEPService
private Map<String, PEPService> pepServices;
......@@ -71,7 +78,8 @@ public class IQPEPHandler extends IQHandler implements ServerIdentitiesProvider,
private PubSubEngine pubSubEngine = null;
private UserManager userManager = null;
private static final String GET_PEP_SERVICES =
"SELECT DISTINCT serviceID FROM pubsubNode";
public IQPEPHandler() {
super("Personal Eventing Handler");
......@@ -84,8 +92,40 @@ public class IQPEPHandler extends IQHandler implements ServerIdentitiesProvider,
super.initialize(server);
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
......@@ -95,7 +135,7 @@ public class IQPEPHandler extends IQHandler implements ServerIdentitiesProvider,
@Override
public IQ handleIQ(IQ packet) throws UnauthorizedException {
// TODO: Much to be done here...
// TODO: Finish implementing ... ;)
if (packet.getTo() == null) {
String jidFrom = packet.getFrom().toBareJID();
......@@ -106,7 +146,7 @@ public class IQPEPHandler extends IQHandler implements ServerIdentitiesProvider,
if (pepService == null) {
// Return an error if the packet is from an anonymous or otherwise
// unregistered user.
if (!userManager.isRegisteredUser(packet.getFrom())) {
if (!UserManager.getInstance().isRegisteredUser(packet.getFrom())) {
IQ reply = IQ.createResultIQ(packet);
reply.setChildElement(packet.getChildElement().createCopy());
reply.setError(PacketError.Condition.not_allowed);
......@@ -133,7 +173,8 @@ public class IQPEPHandler extends IQHandler implements ServerIdentitiesProvider,
if (pepService.getNode(nodeID) == null) {
// Create the node
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.saveToDB();
if (Log.isDebugEnabled()) {
......@@ -157,10 +198,22 @@ public class IQPEPHandler extends IQHandler implements ServerIdentitiesProvider,
}
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() {
......@@ -198,4 +251,23 @@ public class IQPEPHandler extends IQHandler implements ServerIdentitiesProvider,
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 {
/**
* Constructs a PEPService.
*
* @param server
* the XMPP server.
* @param server the XMPP server.
* @param bareJID the bare JID (service ID) of the user owning the service.
*/
public PEPService(XMPPServer server, String bareJID) {
this.bareJID = bareJID;
......@@ -200,7 +200,7 @@ public class PEPService implements PubSubService {
// Load nodes to memory
PubSubPersistenceManager.loadNodes(this);
// 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()) {
// Create root collection node
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