org.jivesoftware.openfire.pep.PEPServiceManager Maven / Gradle / Ivy
The newest version!
/*
* Copyright (C) 2004-2008 Jive Software. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.openfire.pep;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.concurrent.locks.Lock;
import org.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.openfire.XMPPServer;
import org.jivesoftware.openfire.pubsub.CollectionNode;
import org.jivesoftware.openfire.pubsub.Node;
import org.jivesoftware.openfire.pubsub.PubSubEngine;
import org.jivesoftware.openfire.user.UserManager;
import org.jivesoftware.util.cache.Cache;
import org.jivesoftware.util.cache.CacheFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xmpp.packet.IQ;
import org.xmpp.packet.JID;
/**
* Manages the creation, persistence and removal of {@link PEPService}
* instances.
*
* @author Guus der Kinderen, [email protected]
*
*/
public class PEPServiceManager {
public static final Logger Log = LoggerFactory
.getLogger(PEPServiceManager.class);
private final static String GET_PEP_SERVICE = "SELECT DISTINCT serviceID FROM ofPubsubNode WHERE serviceID=?";
/**
* Cache of PEP services. Table, Key: bare JID (String); Value: PEPService
*/
private final Cache pepServices = CacheFactory
.createLocalCache("PEPServiceManager");
private PubSubEngine pubSubEngine = null;
/**
* Retrieves a PEP service -- attempting first from memory, then from the
* database.
*
* @param jid
* the bare JID of the user that owns the PEP service.
* @return the requested PEP service if found or null if not found.
*/
public PEPService getPEPService(String jid) {
PEPService pepService = null;
final Lock lock = CacheFactory.getLock(jid, pepServices);
try {
lock.lock();
if (pepServices.containsKey(jid)) {
// lookup in cache
pepService = pepServices.get(jid);
} else {
// lookup in database.
pepService = loadPEPServiceFromDB(jid);
// always add to the cache, even if it doesn't exist. This will
// prevent future database lookups.
pepServices.put(jid, pepService);
}
} finally {
lock.unlock();
}
return pepService;
}
public PEPService create(JID owner) {
// Return an error if the packet is from an anonymous, unregistered user
// or remote user
if (!XMPPServer.getInstance().isLocal(owner)
|| !UserManager.getInstance().isRegisteredUser(owner.getNode())) {
throw new IllegalArgumentException(
"Request must be initiated by a local, registered user, but is not: "
+ owner);
}
PEPService pepService = null;
final String bareJID = owner.toBareJID();
final Lock lock = CacheFactory.getLock(owner, pepServices);
try {
lock.lock();
pepService = pepServices.get(bareJID);
if (pepService == null) {
pepService = new PEPService(XMPPServer.getInstance(), bareJID);
pepServices.put(bareJID, pepService);
if (Log.isDebugEnabled()) {
Log.debug("PEPService created for : " + bareJID);
}
}
} finally {
lock.unlock();
}
return pepService;
}
/**
* Loads a PEP service from the database, if it exists.
*
* @param jid
* the JID of the owner of the PEP service.
* @return the loaded PEP service, or null if not found.
*/
private PEPService loadPEPServiceFromDB(String jid) {
PEPService pepService = null;
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
con = DbConnectionManager.getConnection();
// Get all PEP services
pstmt = con.prepareStatement(GET_PEP_SERVICE);
pstmt.setString(1, jid);
rs = pstmt.executeQuery();
// Restore old PEPServices
while (rs.next()) {
String serviceID = rs.getString(1);
// Create a new PEPService
pepService = new PEPService(XMPPServer.getInstance(), serviceID);
pepServices.put(serviceID, pepService);
pubSubEngine.start(pepService);
if (Log.isDebugEnabled()) {
Log.debug("PEP: Restored service for " + serviceID
+ " from the database.");
}
}
} catch (SQLException sqle) {
Log.error(sqle.getMessage(), sqle);
} finally {
DbConnectionManager.closeConnection(rs, pstmt, con);
}
return pepService;
}
/**
* Deletes the {@link PEPService} belonging to the specified owner.
*
* @param owner
* The JID of the owner of the service to be deleted.
*/
public void remove(JID owner) {
PEPService service = null;
final Lock lock = CacheFactory.getLock(owner, pepServices);
try {
lock.lock();
service = pepServices.remove(owner.toBareJID());
} finally {
lock.unlock();
}
if (service == null) {
return;
}
// Delete the user's PEP nodes from memory and the database.
CollectionNode rootNode = service.getRootCollectionNode();
for (final Node node : service.getNodes()) {
if (rootNode.isChildNode(node)) {
node.delete();
}
}
rootNode.delete();
}
public void start(PEPService pepService) {
pubSubEngine.start(pepService);
}
public void start() {
pubSubEngine = new PubSubEngine(XMPPServer.getInstance()
.getPacketRouter());
}
public void stop() {
for (PEPService service : pepServices.values()) {
pubSubEngine.shutdown(service);
}
pubSubEngine = null;
}
public void process(PEPService service, IQ iq) {
pubSubEngine.process(service, iq);
}
public boolean hasCachedService(JID owner) {
return pepServices.get(owner.toBareJID()) != null;
}
// mimics Shutdown, without killing the timer.
public void unload(PEPService service) {
pubSubEngine.shutdown(service);
}
}