Commit 55edc080 authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gaston

Refactoring work. Merged the XMPPServer interface and BasicServer class in a...

Refactoring work. Merged the XMPPServer interface and BasicServer class in a unique class called XMPPServer.


git-svn-id: http://svn.igniterealtime.org/svn/repos/messenger/trunk@707 b35dd754-fafc-0310-a699-88a17e54d16e
parent 1d8308b6
...@@ -14,7 +14,6 @@ package org.jivesoftware.admin; ...@@ -14,7 +14,6 @@ package org.jivesoftware.admin;
import org.jivesoftware.util.ClassUtils; import org.jivesoftware.util.ClassUtils;
import org.jivesoftware.util.Log; import org.jivesoftware.util.Log;
import org.jivesoftware.messenger.XMPPServer; import org.jivesoftware.messenger.XMPPServer;
import org.jivesoftware.messenger.spi.BasicServer;
import org.dom4j.Document; import org.dom4j.Document;
import org.dom4j.Element; import org.dom4j.Element;
import org.dom4j.DocumentFactory; import org.dom4j.DocumentFactory;
...@@ -134,7 +133,7 @@ public class AdminConsole { ...@@ -134,7 +133,7 @@ public class AdminConsole {
} }
else { else {
// Default to the Jive Messenger version if none has been provided via XML. // Default to the Jive Messenger version if none has been provided via XML.
XMPPServer xmppServer = BasicServer.getInstance(); XMPPServer xmppServer = XMPPServer.getInstance();
return xmppServer.getServerInfo().getVersion().getVersionString(); return xmppServer.getServerInfo().getVersion().getVersionString();
} }
} }
......
...@@ -2,7 +2,6 @@ package org.jivesoftware.messenger; ...@@ -2,7 +2,6 @@ package org.jivesoftware.messenger;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import org.jivesoftware.messenger.spi.BasicServer;
import org.jivesoftware.util.StringUtils; import org.jivesoftware.util.StringUtils;
import org.xmpp.packet.Packet; import org.xmpp.packet.Packet;
import org.xmpp.packet.JID; import org.xmpp.packet.JID;
...@@ -102,7 +101,7 @@ public class ComponentManager { ...@@ -102,7 +101,7 @@ public class ComponentManager {
*/ */
public void sendPacket(Packet packet) { public void sendPacket(Packet packet) {
PacketRouter router; PacketRouter router;
router = BasicServer.getInstance().getPacketRouter(); router = XMPPServer.getInstance().getPacketRouter();
if (router != null) { if (router != null) {
router.route(packet); router.route(packet);
} }
......
...@@ -15,7 +15,6 @@ import org.jivesoftware.database.SequenceManager; ...@@ -15,7 +15,6 @@ import org.jivesoftware.database.SequenceManager;
import org.jivesoftware.database.DbConnectionManager; import org.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.util.*; import org.jivesoftware.util.*;
import org.jivesoftware.messenger.container.BasicModule; import org.jivesoftware.messenger.container.BasicModule;
import org.jivesoftware.messenger.spi.BasicServer;
import org.xmpp.packet.Message; import org.xmpp.packet.Message;
import org.dom4j.io.SAXReader; import org.dom4j.io.SAXReader;
import org.dom4j.DocumentFactory; import org.dom4j.DocumentFactory;
...@@ -51,7 +50,7 @@ public class OfflineMessageStore extends BasicModule { ...@@ -51,7 +50,7 @@ public class OfflineMessageStore extends BasicModule {
* @return the instance of <CODE>OfflineMessageStore</CODE> being used by the XMPPServer. * @return the instance of <CODE>OfflineMessageStore</CODE> being used by the XMPPServer.
*/ */
public static OfflineMessageStore getInstance() { public static OfflineMessageStore getInstance() {
return BasicServer.getInstance().getOfflineMessageStore(); return XMPPServer.getInstance().getOfflineMessageStore();
} }
private SAXReader saxReader = new SAXReader(); private SAXReader saxReader = new SAXReader();
......
...@@ -30,7 +30,6 @@ import org.jivesoftware.messenger.auth.UnauthorizedException; ...@@ -30,7 +30,6 @@ import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.messenger.container.BasicModule; import org.jivesoftware.messenger.container.BasicModule;
import org.jivesoftware.messenger.spi.BasicStreamIDFactory; import org.jivesoftware.messenger.spi.BasicStreamIDFactory;
import org.jivesoftware.messenger.spi.SessionImpl; import org.jivesoftware.messenger.spi.SessionImpl;
import org.jivesoftware.messenger.spi.BasicServer;
import org.jivesoftware.messenger.user.UserManager; import org.jivesoftware.messenger.user.UserManager;
import org.jivesoftware.messenger.user.UserNotFoundException; import org.jivesoftware.messenger.user.UserNotFoundException;
import org.jivesoftware.messenger.handler.PresenceUpdateHandler; import org.jivesoftware.messenger.handler.PresenceUpdateHandler;
...@@ -69,7 +68,7 @@ public class SessionManager extends BasicModule implements ConnectionCloseListen ...@@ -69,7 +68,7 @@ public class SessionManager extends BasicModule implements ConnectionCloseListen
* @return the instance of <CODE>SessionManagerImpl</CODE> being used by the XMPPServer. * @return the instance of <CODE>SessionManagerImpl</CODE> being used by the XMPPServer.
*/ */
public static SessionManager getInstance() { public static SessionManager getInstance() {
return BasicServer.getInstance().getSessionManager(); return XMPPServer.getInstance().getSessionManager();
} }
public SessionManager() { public SessionManager() {
......
...@@ -11,8 +11,6 @@ ...@@ -11,8 +11,6 @@
package org.jivesoftware.messenger; package org.jivesoftware.messenger;
import org.jivesoftware.messenger.spi.BasicServer;
import javax.servlet.ServletConfig; import javax.servlet.ServletConfig;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.ServletRequest; import javax.servlet.ServletRequest;
...@@ -28,7 +26,7 @@ public class XMPPBootServlet extends HttpServlet { ...@@ -28,7 +26,7 @@ public class XMPPBootServlet extends HttpServlet {
if (server == null) { if (server == null) {
synchronized (serverLock) { synchronized (serverLock) {
if (server == null) { if (server == null) {
server = new BasicServer(); server = new XMPPServer();
} }
} }
} }
......
...@@ -14,49 +14,138 @@ package org.jivesoftware.messenger; ...@@ -14,49 +14,138 @@ package org.jivesoftware.messenger;
import org.xmpp.packet.JID; import org.xmpp.packet.JID;
import org.jivesoftware.messenger.roster.RosterManager; import org.jivesoftware.messenger.roster.RosterManager;
import org.jivesoftware.messenger.user.UserManager; import org.jivesoftware.messenger.user.UserManager;
import org.jivesoftware.messenger.handler.IQRegisterHandler; import org.jivesoftware.messenger.handler.*;
import org.jivesoftware.messenger.handler.PresenceUpdateHandler;
import org.jivesoftware.messenger.handler.PresenceSubscribeHandler;
import org.jivesoftware.messenger.handler.IQHandler;
import org.jivesoftware.messenger.transport.TransportHandler; import org.jivesoftware.messenger.transport.TransportHandler;
import org.jivesoftware.messenger.audit.AuditManager; import org.jivesoftware.messenger.audit.AuditManager;
import org.jivesoftware.messenger.audit.spi.AuditManagerImpl;
import org.jivesoftware.messenger.disco.ServerFeaturesProvider; import org.jivesoftware.messenger.disco.ServerFeaturesProvider;
import org.jivesoftware.messenger.disco.ServerItemsProvider; import org.jivesoftware.messenger.disco.ServerItemsProvider;
import org.jivesoftware.messenger.disco.IQDiscoInfoHandler; import org.jivesoftware.messenger.disco.IQDiscoInfoHandler;
import org.jivesoftware.messenger.disco.IQDiscoItemsHandler;
import org.jivesoftware.messenger.muc.MultiUserChatServer; import org.jivesoftware.messenger.muc.MultiUserChatServer;
import org.jivesoftware.messenger.roster.RosterManager; import org.jivesoftware.messenger.muc.spi.MultiUserChatServerImpl;
import org.jivesoftware.messenger.spi.*;
import org.jivesoftware.messenger.container.Module;
import org.jivesoftware.messenger.container.PluginManager;
import org.jivesoftware.util.Version;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log;
import org.jivesoftware.database.DbConnectionManager;
import org.dom4j.io.SAXReader;
import org.dom4j.Document;
import java.util.List; import java.util.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.DateFormat;
import java.lang.reflect.Method;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/** /**
* The XMPP server definition. An interface allows us to implement the * <p>The main XMPP server that will load, initialize and start all the server's modules. The server
* server's backend by plugging in different classes for the various * is unique in the JVM and could be obtained by using the getInstance() static method
* data managers. The class is designed so that you can host multiple server * on the XMPPServer class.
* instances in the same JVM. * <p/><p>
* <p/> * The loaded modules will be initialized and may access through the server other modules. This
* The server instance is typically obtained by using the getServer() method * means that the only way for a module to locate another module is through the server. The server
* on the Session object. This gives you the server within the proper security and * maintains a list of loaded modules all the time.
* resource/QoS context of the session. Obtaining a server reference from any * </p><p>
* other source is typically only needed by internal server components. * After starting up all the modules the server will load any available plugin. For more information
* follow this link: {@link org.jivesoftware.messenger.container.PluginManager}
* </p> * </p>
* *
* @author Iain Shigeoka * @author Gaston Dombiak
*/ */
public interface XMPPServer { public class XMPPServer {
private static XMPPServer instance;
private String name;
private Version version;
private Date startDate;
private Date stopDate;
private boolean initialized = false;
/**
* All modules loaded by this server
*/
private Map<Class,Module> modules = new HashMap<Class,Module>();
/**
* Location of the messengerHome directory. All configuration files should be
* located here.
*/
private File messengerHome;
private ClassLoader loader;
private PluginManager pluginManager;
/**
* True if in setup mode
*/
private boolean setupMode = true;
private static final String STARTER_CLASSNAME =
"org.jivesoftware.messenger.starter.ServerStarter";
private static final String WRAPPER_CLASSNAME =
"org.tanukisoftware.wrapper.WrapperManager";
/**
* Returns a singleton instance of XMPPServer.
*
* @return an instance.
*/
public static XMPPServer getInstance() {
return instance;
}
/**
* Creates a server and starts it.
*/
public XMPPServer() {
// We may only have one instance of the server running on the JVM
if (instance != null) {
throw new IllegalStateException("A server is already running");
}
instance = this;
start();
}
/** /**
* Obtain a snapshot of the server's status. * Obtain a snapshot of the server's status.
* *
* @return the server information current at the time of the method call. * @return the server information current at the time of the method call.
*/ */
public XMPPServerInfo getServerInfo(); public XMPPServerInfo getServerInfo() {
Iterator ports;
if (getConnectionManager() == null) {
ports = Collections.EMPTY_LIST.iterator();
}
else {
ports = getConnectionManager().getPorts();
}
if (!initialized) {
throw new IllegalStateException("Not initialized yet");
}
return new XMPPServerInfoImpl(name, version, startDate, stopDate, ports);
}
/** /**
* Determines if the given address is local to the server (managed by this server domain). * Determines if the given address is local to the server (managed by this server domain).
* *
* @return true if the address is a local address to this server. * @return true if the address is a local address to this server.
*/ */
public boolean isLocal(JID jid); public boolean isLocal(JID jid) {
boolean local = false;
if (jid != null && name != null && name.equalsIgnoreCase(jid.getDomain())) {
local = true;
}
return local;
}
/** /**
* Creates an XMPPAddress local to this server. * Creates an XMPPAddress local to this server.
...@@ -65,55 +154,697 @@ public interface XMPPServer { ...@@ -65,55 +154,697 @@ public interface XMPPServer {
* @param resource the resource portion of the id or null to indicate none is needed. * @param resource the resource portion of the id or null to indicate none is needed.
* @return an XMPPAddress for the server. * @return an XMPPAddress for the server.
*/ */
public JID createJID(String username, String resource); public JID createJID(String username, String resource) {
return new JID(username, name, resource);
}
public boolean isSetupMode(); private void initialize() throws FileNotFoundException {
locateMessenger();
public ConnectionManager getConnectionManager();
public RoutingTable getRoutingTable(); name = JiveGlobals.getProperty("xmpp.domain");
if (name == null) {
name = "127.0.0.1";
}
public PacketDeliverer getPacketDeliverer(); version = new Version(2, 1, 0, Version.ReleaseStatus.Beta, -1);
if ("true".equals(JiveGlobals.getXMLProperty("setup"))) {
setupMode = false;
}
public RosterManager getRosterManager(); if (isStandAlone()) {
Runtime.getRuntime().addShutdownHook(new ShutdownHookThread());
}
public PresenceManager getPresenceManager(); loader = Thread.currentThread().getContextClassLoader();
public OfflineMessageStore getOfflineMessageStore(); initialized = true;
}
public OfflineMessageStrategy getOfflineMessageStrategy(); public void start() {
try {
initialize();
public PacketRouter getPacketRouter(); // If the server has already been setup then we can start all the server's modules
if (!setupMode) {
verifyDataSource();
// First load all the modules so that modules may access other modules while
// being initialized
loadModules();
// Initize all the modules
initModules();
// Start all the modules
startModules();
}
// Load plugins.
File pluginDir = new File(messengerHome, "plugins");
pluginManager = new PluginManager(pluginDir);
pluginManager.start();
public IQRegisterHandler getIQRegisterHandler(); // Log that the server has been started
DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
DateFormat.MEDIUM);
List params = new ArrayList();
params.add(version.getVersionString());
params.add(formatter.format(new Date()));
String startupBanner = LocaleUtils.getLocalizedString("startup.name", params);
Log.info(startupBanner);
System.out.println(startupBanner);
public List<IQHandler> getIQHandlers(); startDate = new Date();
stopDate = null;
}
catch (Exception e) {
e.printStackTrace();
Log.error(e);
System.out.println(LocaleUtils.getLocalizedString("startup.error"));
shutdownServer();
}
}
public SessionManager getSessionManager(); private void loadModules() {
// Load boot modules
loadModule(RoutingTableImpl.class.getName());
loadModule(AuditManagerImpl.class.getName());
loadModule(RosterManager.class.getName());
loadModule(PrivateStorage.class.getName());
// Load core modules
loadModule(ConnectionManagerImpl.class.getName());
loadModule(PresenceManagerImpl.class.getName());
loadModule(SessionManager.class.getName());
loadModule(PacketRouterImpl.class.getName());
loadModule(IQRouterImpl.class.getName());
loadModule(MessageRouterImpl.class.getName());
loadModule(PresenceRouterImpl.class.getName());
loadModule(PacketTransporterImpl.class.getName());
loadModule(PacketDelivererImpl.class.getName());
loadModule(TransportHandler.class.getName());
loadModule(OfflineMessageStrategy.class.getName());
loadModule(OfflineMessageStore.class.getName());
// Load standard modules
loadModule(IQAuthHandler.class.getName());
loadModule(IQPrivateHandler.class.getName());
loadModule(IQRegisterHandler.class.getName());
loadModule(IQRosterHandler.class.getName());
loadModule(IQTimeHandler.class.getName());
loadModule(IQvCardHandler.class.getName());
loadModule(IQVersionHandler.class.getName());
loadModule(PresenceSubscribeHandler.class.getName());
loadModule(PresenceUpdateHandler.class.getName());
loadModule(IQDiscoInfoHandler.class.getName());
loadModule(IQDiscoItemsHandler.class.getName());
loadModule(MultiUserChatServerImpl.class.getName());
}
public TransportHandler getTransportHandler(); /**
* Loads a module.
*
* @param module the name of the class that implements the Module interface.
*/
private void loadModule(String module) {
Module mod = null;
try {
Class modClass = loader.loadClass(module);
mod = (Module)modClass.newInstance();
this.modules.put(modClass, mod);
}
catch (Exception e) {
e.printStackTrace();
Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
}
}
public PresenceUpdateHandler getPresenceUpdateHandler(); private void initModules() {
for (Module module : modules.values()) {
boolean isInitialized = false;
try {
module.initialize(this);
isInitialized = true;
}
catch (Exception e) {
e.printStackTrace();
// Remove the failed initialized module
this.modules.remove(module.getClass());
if (isInitialized) {
module.stop();
module.destroy();
}
Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
}
}
}
public PresenceSubscribeHandler getPresenceSubscribeHandler(); /**
* <p>Following the loading and initialization of all the modules
* this method is called to iterate through the known modules and
* start them.</p>
*/
private void startModules() {
for (Module module : modules.values()) {
boolean started = false;
try {
module.start();
}
catch (Exception e) {
if (started && module != null) {
module.stop();
module.destroy();
}
Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
}
}
}
public IQRouter getIQRouter(); /**
* Stops the server only if running in standalone mode. Do nothing if the server is running
* inside of another server.
*/
public void stop() {
// Only do a system exit if we're running standalone
if (isStandAlone()) {
// if we're in a wrapper, we have to tell the wrapper to shut us down
if (isRestartable()) {
try {
Class wrapperClass = Class.forName(WRAPPER_CLASSNAME);
Method stopMethod = wrapperClass.getMethod("stop", new Class[]{Integer.TYPE});
stopMethod.invoke(null, new Object[]{0});
}
catch (Exception e) {
Log.error("Could not stop container", e);
}
}
else {
shutdownServer();
stopDate = new Date();
Thread shutdownThread = new ShutdownThread();
shutdownThread.setDaemon(true);
shutdownThread.start();
}
}
}
public MessageRouter getMessageRouter(); public boolean isSetupMode() {
return setupMode;
}
public PresenceRouter getPresenceRouter(); private boolean isRestartable() {
boolean restartable = false;
try {
restartable = Class.forName(WRAPPER_CLASSNAME) != null;
}
catch (ClassNotFoundException e) {
restartable = false;
}
return restartable;
}
public UserManager getUserManager(); /**
* Returns if the server is running in standalone mode. We consider that it's running in
* standalone if the "org.jivesoftware.messenger.starter.ServerStarter" class is present in the
* system.
*
* @return true if the server is running in standalone mode.
*/
private boolean isStandAlone() {
boolean standalone = false;
try {
standalone = Class.forName(STARTER_CLASSNAME) != null;
}
catch (ClassNotFoundException e) {
standalone = false;
}
return standalone;
}
public AuditManager getAuditManager(); /**
* Verify that the database is accessible.
*/
private void verifyDataSource() {
java.sql.Connection conn = null;
try {
conn = DbConnectionManager.getConnection();
PreparedStatement stmt = conn.prepareStatement("SELECT count(*) FROM jiveID");
ResultSet rs = stmt.executeQuery();
rs.next();
rs.close();
stmt.close();
}
catch (Exception e) {
System.err.println("Database setup or configuration error: " +
"Please verify your database settings and check the " +
"logs/error.log file for detailed error messages.");
Log.error("Database could not be accessed", e);
throw new IllegalArgumentException();
}
finally {
if (conn != null) {
try { conn.close(); }
catch (SQLException e) { Log.error(e); }
}
}
}
public List<ServerFeaturesProvider> getServerFeaturesProviders(); /**
* Verifies that the given home guess is a real Messenger home directory.
* We do the verification by checking for the Messenger config file in
* the config dir of jiveHome.
*
* @param homeGuess a guess at the path to the home directory.
* @param jiveConfigName the name of the config file to check.
* @return a file pointing to the home directory or null if the
* home directory guess was wrong.
* @throws java.io.FileNotFoundException if there was a problem with the home
* directory provided
*/
private File verifyHome(String homeGuess, String jiveConfigName) throws FileNotFoundException {
File realHome = null;
File guess = new File(homeGuess);
File configFileGuess = new File(guess, jiveConfigName);
if (configFileGuess.exists()) {
realHome = guess;
}
File messengerHome = new File(guess, jiveConfigName);
if (!messengerHome.exists()) {
throw new FileNotFoundException();
}
public List<ServerItemsProvider> getServerItemsProviders(); try{
return new File(realHome.getCanonicalPath());
}
catch(Exception ex){
throw new FileNotFoundException();
}
}
public IQDiscoInfoHandler getIQDiscoInfoHandler(); /**
* <p>Retrieve the jive home for the container.</p>
*
* @throws FileNotFoundException If jiveHome could not be located
*/
private void locateMessenger() throws FileNotFoundException {
String jiveConfigName = "conf" + File.separator + "jive-messenger.xml";
// First, try to load it jiveHome as a system property.
if (messengerHome == null) {
String homeProperty = System.getProperty("messengerHome");
try {
if (homeProperty != null) {
messengerHome = verifyHome(homeProperty, jiveConfigName);
}
}
catch (FileNotFoundException fe) {
}
}
// If we still don't have messengerHome, let's assume this is standalone
// and just look for messengerHome in a standard sub-dir location and verify
// by looking for the config file
if (messengerHome == null) {
try {
messengerHome = verifyHome("..", jiveConfigName).getCanonicalFile();
}
catch (FileNotFoundException fe) {
}
catch (IOException ie) {
}
}
// If messengerHome is still null, no outside process has set it and
// we have to attempt to load the value from messenger_init.xml,
// which must be in the classpath.
if (messengerHome == null) {
InputStream in = null;
try {
in = getClass().getResourceAsStream("/messenger_init.xml");
if (in != null) {
SAXReader reader = new SAXReader();
Document doc = reader.read(in);
String path = doc.getRootElement().getText();
try {
if (path != null) {
messengerHome = verifyHome(path, jiveConfigName);
}
}
catch (FileNotFoundException fe) {
fe.printStackTrace();
}
}
}
catch (Exception e) {
System.err.println("Error loading messenger_init.xml to find messengerHome.");
e.printStackTrace();
}
finally {
try { if (in != null) { in.close(); } }
catch (Exception e) {
System.err.println("Could not close open connection");
e.printStackTrace();
}
}
}
if (messengerHome == null) {
System.err.println("Could not locate messengerHome");
throw new FileNotFoundException();
}
else {
JiveGlobals.messengerHome = messengerHome.toString();
}
}
public PrivateStorage getPrivateStorage(); /**
* <p>A thread to ensure the server shuts down no matter what.</p>
* <p>Spawned when stop() is called in standalone mode, we wait a few
* seconds then call system exit().</p>
*
* @author Iain Shigeoka
*/
private class ShutdownHookThread extends Thread {
/**
* <p>Logs the server shutdown.</p>
*/
public void run() {
shutdownServer();
Log.info("Server halted");
System.err.println("Server halted");
}
}
public MultiUserChatServer getMultiUserChatServer(); /**
* <p>A thread to ensure the server shuts down no matter what.</p>
* <p>Spawned when stop() is called in standalone mode, we wait a few
* seconds then call system exit().</p>
*
* @author Iain Shigeoka
*/
private class ShutdownThread extends Thread {
/**
* <p>Shuts down the JVM after a 5 second delay.</p>
*/
public void run() {
try {
Thread.sleep(5000);
// No matter what, we make sure it's dead
System.exit(0);
}
catch (InterruptedException e) {
}
}
}
/**
* Makes a best effort attempt to shutdown the server
*/
private void shutdownServer() {
// Get all modules and stop and destroy them
for (Module module : modules.values()) {
module.stop();
module.destroy();
}
modules.clear();
// Stop all plugins
if (pluginManager != null) {
pluginManager.shutdown();
}
// TODO: hack to allow safe stopping
Log.info("Jive Messenger stopped");
}
/**
* Returns the <code>ConnectionManager</code> registered with this server. The
* <code>ConnectionManager</code> was registered with the server as a module while starting up
* the server.
*
* @return the <code>ConnectionManager</code> registered with this server.
*/
public ConnectionManager getConnectionManager() {
return (ConnectionManager) modules.get(ConnectionManagerImpl.class);
}
/**
* Returns the <code>RoutingTable</code> registered with this server. The
* <code>RoutingTable</code> was registered with the server as a module while starting up
* the server.
*
* @return the <code>RoutingTable</code> registered with this server.
*/
public RoutingTable getRoutingTable() {
return (RoutingTable) modules.get(RoutingTableImpl.class);
}
/**
* Returns the <code>PacketDeliverer</code> registered with this server. The
* <code>PacketDeliverer</code> was registered with the server as a module while starting up
* the server.
*
* @return the <code>PacketDeliverer</code> registered with this server.
*/
public PacketDeliverer getPacketDeliverer() {
return (PacketDeliverer) modules.get(PacketDelivererImpl.class);
}
/**
* Returns the <code>RosterManager</code> registered with this server. The
* <code>RosterManager</code> was registered with the server as a module while starting up
* the server.
*
* @return the <code>RosterManager</code> registered with this server.
*/
public RosterManager getRosterManager() {
return (RosterManager) modules.get(RosterManager.class);
}
/**
* Returns the <code>PresenceManager</code> registered with this server. The
* <code>PresenceManager</code> was registered with the server as a module while starting up
* the server.
*
* @return the <code>PresenceManager</code> registered with this server.
*/
public PresenceManager getPresenceManager() {
return (PresenceManager) modules.get(PresenceManagerImpl.class);
}
/**
* Returns the <code>OfflineMessageStore</code> registered with this server. The
* <code>OfflineMessageStore</code> was registered with the server as a module while starting up
* the server.
*
* @return the <code>OfflineMessageStore</code> registered with this server.
*/
public OfflineMessageStore getOfflineMessageStore() {
return (OfflineMessageStore) modules.get(OfflineMessageStore.class);
}
/**
* Returns the <code>OfflineMessageStrategy</code> registered with this server. The
* <code>OfflineMessageStrategy</code> was registered with the server as a module while starting
* up the server.
*
* @return the <code>OfflineMessageStrategy</code> registered with this server.
*/
public OfflineMessageStrategy getOfflineMessageStrategy() {
return (OfflineMessageStrategy) modules.get(OfflineMessageStrategy.class);
}
/**
* Returns the <code>PacketRouter</code> registered with this server. The
* <code>PacketRouter</code> was registered with the server as a module while starting up
* the server.
*
* @return the <code>PacketRouter</code> registered with this server.
*/
public PacketRouter getPacketRouter() {
return (PacketRouter) modules.get(PacketRouterImpl.class);
}
/**
* Returns the <code>IQRegisterHandler</code> registered with this server. The
* <code>IQRegisterHandler</code> was registered with the server as a module while starting up
* the server.
*
* @return the <code>IQRegisterHandler</code> registered with this server.
*/
public IQRegisterHandler getIQRegisterHandler() {
return (IQRegisterHandler) modules.get(IQRegisterHandler.class);
}
/**
* Returns a list with all the modules registered with the server that inherit from IQHandler.
*
* @return a list with all the modules registered with the server that inherit from IQHandler.
*/
public List<IQHandler> getIQHandlers() {
List<IQHandler> answer = new ArrayList<IQHandler>();
for (Module module : modules.values()) {
if (module instanceof IQHandler) {
answer.add((IQHandler)module);
}
}
return answer;
}
/**
* Returns the <code>SessionManager</code> registered with this server. The
* <code>SessionManager</code> was registered with the server as a module while starting up
* the server.
*
* @return the <code>SessionManager</code> registered with this server.
*/
public SessionManager getSessionManager() {
return (SessionManager) modules.get(SessionManager.class);
}
/**
* Returns the <code>TransportHandler</code> registered with this server. The
* <code>TransportHandler</code> was registered with the server as a module while starting up
* the server.
*
* @return the <code>TransportHandler</code> registered with this server.
*/
public TransportHandler getTransportHandler() {
return (TransportHandler) modules.get(TransportHandler.class);
}
/**
* Returns the <code>PresenceUpdateHandler</code> registered with this server. The
* <code>PresenceUpdateHandler</code> was registered with the server as a module while starting
* up the server.
*
* @return the <code>PresenceUpdateHandler</code> registered with this server.
*/
public PresenceUpdateHandler getPresenceUpdateHandler() {
return (PresenceUpdateHandler) modules.get(PresenceUpdateHandler.class);
}
/**
* Returns the <code>PresenceSubscribeHandler</code> registered with this server. The
* <code>PresenceSubscribeHandler</code> was registered with the server as a module while
* starting up the server.
*
* @return the <code>PresenceSubscribeHandler</code> registered with this server.
*/
public PresenceSubscribeHandler getPresenceSubscribeHandler() {
return (PresenceSubscribeHandler) modules.get(PresenceSubscribeHandler.class);
}
/**
* Returns the <code>IQRouter</code> registered with this server. The
* <code>IQRouter</code> was registered with the server as a module while starting up
* the server.
*
* @return the <code>IQRouter</code> registered with this server.
*/
public IQRouter getIQRouter() {
return (IQRouter) modules.get(IQRouterImpl.class);
}
/**
* Returns the <code>MessageRouter</code> registered with this server. The
* <code>MessageRouter</code> was registered with the server as a module while starting up
* the server.
*
* @return the <code>MessageRouter</code> registered with this server.
*/
public MessageRouter getMessageRouter() {
return (MessageRouter) modules.get(MessageRouterImpl.class);
}
/**
* Returns the <code>PresenceRouter</code> registered with this server. The
* <code>PresenceRouter</code> was registered with the server as a module while starting up
* the server.
*
* @return the <code>PresenceRouter</code> registered with this server.
*/
public PresenceRouter getPresenceRouter() {
return (PresenceRouter) modules.get(PresenceRouterImpl.class);
}
/**
* Returns the <code>UserManager</code> registered with this server. The
* <code>UserManager</code> was registered with the server as a module while starting up
* the server.
*
* @return the <code>UserManager</code> registered with this server.
*/
public UserManager getUserManager() {
return UserManager.getInstance();
}
/**
* Returns the <code>AuditManager</code> registered with this server. The
* <code>AuditManager</code> was registered with the server as a module while starting up
* the server.
*
* @return the <code>AuditManager</code> registered with this server.
*/
public AuditManager getAuditManager() {
return (AuditManager) modules.get(AuditManagerImpl.class);
}
/**
* Returns a list with all the modules that provide "discoverable" features.
*
* @return a list with all the modules that provide "discoverable" features.
*/
public List<ServerFeaturesProvider> getServerFeaturesProviders() {
List<ServerFeaturesProvider> answer = new ArrayList<ServerFeaturesProvider>();
for (Module module : modules.values()) {
if (module instanceof ServerFeaturesProvider) {
answer.add((ServerFeaturesProvider) module);
}
}
return answer;
}
/**
* Returns a list with all the modules that provide "discoverable" items associated with
* the server.
*
* @return a list with all the modules that provide "discoverable" items associated with
* the server.
*/
public List<ServerItemsProvider> getServerItemsProviders() {
List<ServerItemsProvider> answer = new ArrayList<ServerItemsProvider>();
for (Module module : modules.values()) {
if (module instanceof ServerItemsProvider) {
answer.add((ServerItemsProvider) 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
* the server.
*
* @return the <code>IQDiscoInfoHandler</code> registered with this server.
*/
public IQDiscoInfoHandler getIQDiscoInfoHandler() {
return (IQDiscoInfoHandler) modules.get(IQDiscoInfoHandler.class);
}
/**
* Returns the <code>PrivateStorage</code> registered with this server. The
* <code>PrivateStorage</code> was registered with the server as a module while starting up
* the server.
*
* @return the <code>PrivateStorage</code> registered with this server.
*/
public PrivateStorage getPrivateStorage() {
return (PrivateStorage) modules.get(PrivateStorage.class);
}
/**
* Returns the <code>MultiUserChatServer</code> registered with this server. The
* <code>MultiUserChatServer</code> was registered with the server as a module while starting up
* the server.
*
* @return the <code>MultiUserChatServer</code> registered with this server.
*/
public MultiUserChatServer getMultiUserChatServer() {
return (MultiUserChatServer) modules.get(MultiUserChatServerImpl.class);
}
} }
...@@ -13,7 +13,6 @@ package org.jivesoftware.messenger.disco; ...@@ -13,7 +13,6 @@ package org.jivesoftware.messenger.disco;
import org.jivesoftware.messenger.forms.spi.XDataFormImpl; import org.jivesoftware.messenger.forms.spi.XDataFormImpl;
import org.jivesoftware.messenger.*; import org.jivesoftware.messenger.*;
import org.jivesoftware.messenger.spi.BasicServer;
import org.jivesoftware.messenger.handler.IQHandler; import org.jivesoftware.messenger.handler.IQHandler;
import org.jivesoftware.messenger.auth.UnauthorizedException; import org.jivesoftware.messenger.auth.UnauthorizedException;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -79,7 +78,7 @@ public class IQDiscoInfoHandler extends IQHandler { ...@@ -79,7 +78,7 @@ public class IQDiscoInfoHandler extends IQHandler {
// DiscoInfoProvider responsibility to provide information about the JID's name together // DiscoInfoProvider responsibility to provide information about the JID's name together
// with any possible requested node. // with any possible requested node.
DiscoInfoProvider infoProvider = getProvider(packet.getTo() == null ? DiscoInfoProvider infoProvider = getProvider(packet.getTo() == null ?
BasicServer.getInstance().getServerInfo().getName() : packet.getTo().getDomain()); XMPPServer.getInstance().getServerInfo().getName() : packet.getTo().getDomain());
if (infoProvider != null) { if (infoProvider != null) {
// Get the JID's name // Get the JID's name
String name = packet.getTo() == null ? null : packet.getTo().getNode(); String name = packet.getTo() == null ? null : packet.getTo().getNode();
......
...@@ -20,7 +20,6 @@ import org.dom4j.Element; ...@@ -20,7 +20,6 @@ import org.dom4j.Element;
import org.dom4j.QName; import org.dom4j.QName;
import org.jivesoftware.messenger.IQHandlerInfo; import org.jivesoftware.messenger.IQHandlerInfo;
import org.jivesoftware.messenger.XMPPServer; import org.jivesoftware.messenger.XMPPServer;
import org.jivesoftware.messenger.spi.BasicServer;
import org.jivesoftware.messenger.handler.IQHandler; import org.jivesoftware.messenger.handler.IQHandler;
import org.jivesoftware.messenger.auth.UnauthorizedException; import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.util.StringUtils; import org.jivesoftware.util.StringUtils;
...@@ -88,7 +87,7 @@ public class IQDiscoItemsHandler extends IQHandler implements ServerFeaturesProv ...@@ -88,7 +87,7 @@ public class IQDiscoItemsHandler extends IQHandler implements ServerFeaturesProv
// 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 ?
BasicServer.getInstance().getServerInfo().getName() : packet.getTo().getDomain()); XMPPServer.getInstance().getServerInfo().getName() : packet.getTo().getDomain());
if (itemsProvider != null) { if (itemsProvider != null) {
// Get the JID's name // Get the JID's name
String name = packet.getTo() == null ? null : packet.getTo().getNode(); String name = packet.getTo() == null ? null : packet.getTo().getNode();
...@@ -198,7 +197,7 @@ public class IQDiscoItemsHandler extends IQHandler implements ServerFeaturesProv ...@@ -198,7 +197,7 @@ public class IQDiscoItemsHandler extends IQHandler implements ServerFeaturesProv
public void start() throws IllegalStateException { public void start() throws IllegalStateException {
super.start(); super.start();
for (ServerItemsProvider provider : BasicServer.getInstance().getServerItemsProviders()) { for (ServerItemsProvider provider : XMPPServer.getInstance().getServerItemsProviders()) {
addServerItemsProvider(provider); addServerItemsProvider(provider);
} }
} }
......
...@@ -57,7 +57,7 @@ import java.util.Map; ...@@ -57,7 +57,7 @@ import java.util.Map;
* </ul> * </ul>
* The valid types include "subscribe", "subscribed", "unsubscribed", * The valid types include "subscribe", "subscribed", "unsubscribed",
* and "unsubscribe". * and "unsubscribe".
* <li>BasicServer probes - Provides a mechanism for servers to query the presence * <li>XMPPServer probes - Provides a mechanism for servers to query the presence
* status of users on another server. This allows users to immediately * status of users on another server. This allows users to immediately
* know the presence status of users when they come online rather than way * know the presence status of users when they come online rather than way
* for a presence update broadcast from the other server or tracking them * for a presence update broadcast from the other server or tracking them
......
...@@ -57,7 +57,7 @@ import java.util.concurrent.CopyOnWriteArraySet; ...@@ -57,7 +57,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
* </ul> * </ul>
* The valid types include "subscribe", "subscribed", "unsubscribed", * The valid types include "subscribe", "subscribed", "unsubscribed",
* and "unsubscribe". * and "unsubscribe".
* <li>BasicServer probes - Provides a mechanism for servers to query the presence * <li>XMPPServer probes - Provides a mechanism for servers to query the presence
* status of users on another server. This allows users to immediately * status of users on another server. This allows users to immediately
* know the presence status of users when they come online rather than way * know the presence status of users when they come online rather than way
* for a presence update broadcast from the other server or tracking them * for a presence update broadcast from the other server or tracking them
......
...@@ -20,7 +20,6 @@ import org.jivesoftware.messenger.PresenceManager; ...@@ -20,7 +20,6 @@ import org.jivesoftware.messenger.PresenceManager;
import org.jivesoftware.messenger.RoutingTable; import org.jivesoftware.messenger.RoutingTable;
import org.jivesoftware.messenger.SessionManager; import org.jivesoftware.messenger.SessionManager;
import org.jivesoftware.messenger.XMPPServer; import org.jivesoftware.messenger.XMPPServer;
import org.jivesoftware.messenger.spi.BasicServer;
import org.jivesoftware.messenger.auth.UnauthorizedException; import org.jivesoftware.messenger.auth.UnauthorizedException;
import org.jivesoftware.messenger.roster.BasicRoster; import org.jivesoftware.messenger.roster.BasicRoster;
import org.jivesoftware.messenger.roster.BasicRosterItem; import org.jivesoftware.messenger.roster.BasicRosterItem;
...@@ -104,7 +103,7 @@ public class CachedRosterImpl extends BasicRoster implements CachedRoster { ...@@ -104,7 +103,7 @@ public class CachedRosterImpl extends BasicRoster implements CachedRoster {
public void broadcastPresence(Presence packet) { public void broadcastPresence(Presence packet) {
try { try {
if (routingTable == null) { if (routingTable == null) {
routingTable = BasicServer.getInstance().getRoutingTable(); routingTable = XMPPServer.getInstance().getRoutingTable();
} }
if (routingTable == null) { if (routingTable == null) {
return; return;
...@@ -190,7 +189,7 @@ public class CachedRosterImpl extends BasicRoster implements CachedRoster { ...@@ -190,7 +189,7 @@ public class CachedRosterImpl extends BasicRoster implements CachedRoster {
if (cachedItem.getSubStatus() == RosterItem.SUB_BOTH if (cachedItem.getSubStatus() == RosterItem.SUB_BOTH
|| cachedItem.getSubStatus() == RosterItem.SUB_TO) { || cachedItem.getSubStatus() == RosterItem.SUB_TO) {
if (presenceManager == null) { if (presenceManager == null) {
presenceManager = BasicServer.getInstance().getPresenceManager(); presenceManager = XMPPServer.getInstance().getPresenceManager();
} }
presenceManager.probePresence(username, cachedItem.getJid()); presenceManager.probePresence(username, cachedItem.getJid());
} }
...@@ -214,7 +213,7 @@ public class CachedRosterImpl extends BasicRoster implements CachedRoster { ...@@ -214,7 +213,7 @@ public class CachedRosterImpl extends BasicRoster implements CachedRoster {
private void broadcast(Roster roster) throws UnauthorizedException { private void broadcast(Roster roster) throws UnauthorizedException {
if (server == null) { if (server == null) {
server = BasicServer.getInstance(); server = XMPPServer.getInstance();
} }
JID recipient = server.createJID(username, null); JID recipient = server.createJID(username, null);
roster.setTo(recipient); roster.setTo(recipient);
......
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2004 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package org.jivesoftware.messenger.spi;
import org.dom4j.Document;
import org.dom4j.io.SAXReader;
import org.jivesoftware.database.DbConnectionManager;
import org.jivesoftware.messenger.*;
import org.jivesoftware.messenger.roster.RosterManager;
import org.jivesoftware.messenger.audit.AuditManager;
import org.jivesoftware.messenger.audit.spi.AuditManagerImpl;
import org.jivesoftware.messenger.container.Module;
import org.jivesoftware.messenger.container.PluginManager;
import org.jivesoftware.messenger.disco.IQDiscoInfoHandler;
import org.jivesoftware.messenger.disco.IQDiscoItemsHandler;
import org.jivesoftware.messenger.disco.ServerFeaturesProvider;
import org.jivesoftware.messenger.disco.ServerItemsProvider;
import org.jivesoftware.messenger.handler.*;
import org.jivesoftware.messenger.muc.spi.MultiUserChatServerImpl;
import org.jivesoftware.messenger.muc.MultiUserChatServer;
import org.jivesoftware.messenger.transport.TransportHandler;
import org.jivesoftware.messenger.roster.RosterManager;
import org.jivesoftware.messenger.user.UserManager;
import org.jivesoftware.util.LocaleUtils;
import org.jivesoftware.util.Log;
import org.jivesoftware.util.Version;
import org.xmpp.packet.JID;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.DateFormat;
import java.util.*;
/**
* Main entry point into the Jive xmpp server powered by a JDBC backend. Most of this code
* is actually generic to any server so should be moved to a base class when we have
* a separate server implementation.
*
* @author Iain Shigeoka
*/
public class BasicServer implements XMPPServer {
private static BasicServer instance;
private String name;
private Version version;
private Date startDate;
private Date stopDate;
private boolean initialized = false;
/**
* All modules loaded by this container
*/
private Map<Class,Module> modules = new HashMap<Class,Module>();
/**
* Location of the messengerHome directory. All configuration files should be
* located here.
*/
private File messengerHome;
private ClassLoader loader;
private PluginManager pluginManager;
/**
* True if in setup mode
*/
private boolean setupMode = true;
private static final String STARTER_CLASSNAME =
"org.jivesoftware.messenger.starter.ServerStarter";
private static final String WRAPPER_CLASSNAME =
"org.tanukisoftware.wrapper.WrapperManager";
/**
* Returns a singleton instance of BasicServer.
*
* @return an instance.
*/
public static BasicServer getInstance() {
return instance;
}
/**
* Creates a server and starts it.
*/
public BasicServer() {
instance = this;
start();
}
public XMPPServerInfo getServerInfo() {
Iterator ports;
if (getConnectionManager() == null) {
ports = Collections.EMPTY_LIST.iterator();
}
else {
ports = getConnectionManager().getPorts();
}
if (!initialized) {
throw new IllegalStateException("Not initialized yet");
}
return new XMPPServerInfoImpl(name, version, startDate, stopDate, ports);
}
public boolean isLocal(JID jid) {
boolean local = false;
if (jid != null && name != null && name.equalsIgnoreCase(jid.getDomain())) {
local = true;
}
return local;
}
public JID createJID(String username, String resource) {
return new JID(username, name, resource);
}
private void initialize() throws FileNotFoundException {
locateMessenger();
name = JiveGlobals.getProperty("xmpp.domain");
if (name == null) {
name = "127.0.0.1";
}
version = new Version(2, 1, 0, Version.ReleaseStatus.Beta, -1);
if ("true".equals(JiveGlobals.getXMLProperty("setup"))) {
setupMode = false;
}
if (isStandAlone()) {
Runtime.getRuntime().addShutdownHook(new ShutdownHookThread());
}
loader = Thread.currentThread().getContextClassLoader();
initialized = true;
}
public void start() {
try {
initialize();
if (!setupMode) {
verifyDataSource();
loadModules();
initModules();
startModules();
}
// Load plugins.
File pluginDir = new File(messengerHome, "plugins");
pluginManager = new PluginManager(pluginDir);
pluginManager.start();
DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
DateFormat.MEDIUM);
List params = new ArrayList();
params.add(version.getVersionString());
params.add(formatter.format(new Date()));
String startupBanner = LocaleUtils.getLocalizedString("startup.name", params);
Log.info(startupBanner);
System.out.println(startupBanner);
startDate = new Date();
stopDate = null;
}
catch (Exception e) {
e.printStackTrace();
Log.error(e);
System.out.println(LocaleUtils.getLocalizedString("startup.error"));
shutdownServer();
}
}
private void loadModules() {
// Load boot modules
loadModule(RoutingTableImpl.class.getName());
loadModule(AuditManagerImpl.class.getName());
loadModule(RosterManager.class.getName());
loadModule(PrivateStorage.class.getName());
// Load core modules
loadModule(ConnectionManagerImpl.class.getName());
loadModule(PresenceManagerImpl.class.getName());
loadModule(SessionManager.class.getName());
loadModule(PacketRouterImpl.class.getName());
loadModule(IQRouterImpl.class.getName());
loadModule(MessageRouterImpl.class.getName());
loadModule(PresenceRouterImpl.class.getName());
loadModule(PacketTransporterImpl.class.getName());
loadModule(PacketDelivererImpl.class.getName());
loadModule(TransportHandler.class.getName());
loadModule(OfflineMessageStrategy.class.getName());
loadModule(OfflineMessageStore.class.getName());
// Load standard modules
loadModule(IQAuthHandler.class.getName());
loadModule(IQPrivateHandler.class.getName());
loadModule(IQRegisterHandler.class.getName());
loadModule(IQRosterHandler.class.getName());
loadModule(IQTimeHandler.class.getName());
loadModule(IQvCardHandler.class.getName());
loadModule(IQVersionHandler.class.getName());
loadModule(PresenceSubscribeHandler.class.getName());
loadModule(PresenceUpdateHandler.class.getName());
loadModule(IQDiscoInfoHandler.class.getName());
loadModule(IQDiscoItemsHandler.class.getName());
loadModule(MultiUserChatServerImpl.class.getName());
}
/**
* Loads a module.
*
* @param module the name of the class that implements the Module interface.
*/
private void loadModule(String module) {
Module mod = null;
try {
Class modClass = loader.loadClass(module);
mod = (Module)modClass.newInstance();
this.modules.put(modClass, mod);
}
catch (Exception e) {
e.printStackTrace();
Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
}
}
private void initModules() {
for (Module module : modules.values()) {
boolean isInitialized = false;
try {
module.initialize(this);
isInitialized = true;
}
catch (Exception e) {
e.printStackTrace();
// Remove the failed initialized module
this.modules.remove(module.getClass());
if (isInitialized) {
module.stop();
module.destroy();
}
Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
}
}
}
/**
* <p>Following the loading and initialization of all the modules
* this method is called to iterate through the known modules and
* start them.</p>
*/
private void startModules() {
for (Module module : modules.values()) {
boolean started = false;
try {
module.start();
}
catch (Exception e) {
if (started && module != null) {
module.stop();
module.destroy();
}
Log.error(LocaleUtils.getLocalizedString("admin.error"), e);
}
}
}
public void stop() {
// Only do a system exit if we're running standalone
if (isStandAlone()) {
// if we're in a wrapper, we have to tell the wrapper to shut us down
if (isRestartable()) {
try {
Class wrapperClass = Class.forName(WRAPPER_CLASSNAME);
Method stopMethod = wrapperClass.getMethod("stop", new Class[]{Integer.TYPE});
stopMethod.invoke(null, new Object[]{0});
}
catch (Exception e) {
Log.error("Could not stop container", e);
}
}
else {
shutdownServer();
stopDate = new Date();
Thread shutdownThread = new ShutdownThread();
shutdownThread.setDaemon(true);
shutdownThread.start();
}
}
}
public boolean isSetupMode() {
return setupMode;
}
private boolean isRestartable() {
boolean restartable = false;
try {
restartable = Class.forName(WRAPPER_CLASSNAME) != null;
}
catch (ClassNotFoundException e) {
restartable = false;
}
return restartable;
}
private boolean isStandAlone() {
boolean standalone = false;
try {
standalone = Class.forName(STARTER_CLASSNAME) != null;
}
catch (ClassNotFoundException e) {
standalone = false;
}
return standalone;
}
/**
* Verify that the database is accessible.
*/
private void verifyDataSource() {
java.sql.Connection conn = null;
try {
conn = DbConnectionManager.getConnection();
PreparedStatement stmt = conn.prepareStatement("SELECT count(*) FROM jiveID");
ResultSet rs = stmt.executeQuery();
rs.next();
rs.close();
stmt.close();
}
catch (Exception e) {
System.err.println("Database setup or configuration error: " +
"Please verify your database settings and check the " +
"logs/error.log file for detailed error messages.");
Log.error("Database could not be accessed", e);
throw new IllegalArgumentException();
}
finally {
if (conn != null) {
try { conn.close(); }
catch (SQLException e) { Log.error(e); }
}
}
}
/**
* Verifies that the given home guess is a real Messenger home directory.
* We do the verification by checking for the Messenger config file in
* the config dir of jiveHome.
*
* @param homeGuess a guess at the path to the home directory.
* @param jiveConfigName the name of the config file to check.
* @return a file pointing to the home directory or null if the
* home directory guess was wrong.
* @throws java.io.FileNotFoundException if there was a problem with the home
* directory provided
*/
private File verifyHome(String homeGuess, String jiveConfigName) throws FileNotFoundException {
File realHome = null;
File guess = new File(homeGuess);
File configFileGuess = new File(guess, jiveConfigName);
if (configFileGuess.exists()) {
realHome = guess;
}
File messengerHome = new File(guess, jiveConfigName);
if (!messengerHome.exists()) {
throw new FileNotFoundException();
}
try{
return new File(realHome.getCanonicalPath());
}
catch(Exception ex){
throw new FileNotFoundException();
}
}
/**
* <p>Retrieve the jive home for the container.</p>
*
* @throws FileNotFoundException If jiveHome could not be located
*/
private void locateMessenger() throws FileNotFoundException {
String jiveConfigName = "conf" + File.separator + "jive-messenger.xml";
// First, try to load it jiveHome as a system property.
if (messengerHome == null) {
String homeProperty = System.getProperty("messengerHome");
try {
if (homeProperty != null) {
messengerHome = verifyHome(homeProperty, jiveConfigName);
}
}
catch (FileNotFoundException fe) {
}
}
// If we still don't have messengerHome, let's assume this is standalone
// and just look for messengerHome in a standard sub-dir location and verify
// by looking for the config file
if (messengerHome == null) {
try {
messengerHome = verifyHome("..", jiveConfigName).getCanonicalFile();
}
catch (FileNotFoundException fe) {
}
catch (IOException ie) {
}
}
// If messengerHome is still null, no outside process has set it and
// we have to attempt to load the value from messenger_init.xml,
// which must be in the classpath.
if (messengerHome == null) {
InputStream in = null;
try {
in = getClass().getResourceAsStream("/messenger_init.xml");
if (in != null) {
SAXReader reader = new SAXReader();
Document doc = reader.read(in);
String path = doc.getRootElement().getText();
try {
if (path != null) {
messengerHome = verifyHome(path, jiveConfigName);
}
}
catch (FileNotFoundException fe) {
fe.printStackTrace();
}
}
}
catch (Exception e) {
System.err.println("Error loading messenger_init.xml to find messengerHome.");
e.printStackTrace();
}
finally {
try { if (in != null) { in.close(); } }
catch (Exception e) {
System.err.println("Could not close open connection");
e.printStackTrace();
}
}
}
if (messengerHome == null) {
System.err.println("Could not locate messengerHome");
throw new FileNotFoundException();
}
else {
JiveGlobals.messengerHome = messengerHome.toString();
}
}
/**
* <p>A thread to ensure the server shuts down no matter what.</p>
* <p>Spawned when stop() is called in standalone mode, we wait a few
* seconds then call system exit().</p>
*
* @author Iain Shigeoka
*/
private class ShutdownHookThread extends Thread {
/**
* <p>Logs the server shutdown.</p>
*/
public void run() {
shutdownServer();
Log.info("Server halted");
System.err.println("Server halted");
}
}
/**
* <p>A thread to ensure the server shuts down no matter what.</p>
* <p>Spawned when stop() is called in standalone mode, we wait a few
* seconds then call system exit().</p>
*
* @author Iain Shigeoka
*/
private class ShutdownThread extends Thread {
/**
* <p>Shuts down the JVM after a 5 second delay.</p>
*/
public void run() {
try {
Thread.sleep(5000);
// No matter what, we make sure it's dead
System.exit(0);
}
catch (InterruptedException e) {
}
}
}
/**
* Makes a best effort attempt to shutdown the server
*/
private void shutdownServer() {
// Get all modules and stop and destroy them
for (Module module : modules.values()) {
module.stop();
module.destroy();
}
modules.clear();
// Stop all plugins
if (pluginManager != null) {
pluginManager.shutdown();
}
// TODO: hack to allow safe stopping
Log.info("Jive Messenger stopped");
}
public ConnectionManager getConnectionManager() {
return (ConnectionManager) modules.get(ConnectionManagerImpl.class);
}
public RoutingTable getRoutingTable() {
return (RoutingTable) modules.get(RoutingTableImpl.class);
}
public PacketDeliverer getPacketDeliverer() {
return (PacketDeliverer) modules.get(PacketDelivererImpl.class);
}
public RosterManager getRosterManager() {
return (RosterManager) modules.get(RosterManager.class);
}
public PresenceManager getPresenceManager() {
return (PresenceManager) modules.get(PresenceManagerImpl.class);
}
public OfflineMessageStore getOfflineMessageStore() {
return (OfflineMessageStore) modules.get(OfflineMessageStore.class);
}
public OfflineMessageStrategy getOfflineMessageStrategy() {
return (OfflineMessageStrategy) modules.get(OfflineMessageStrategy.class);
}
public PacketRouter getPacketRouter() {
return (PacketRouter) modules.get(PacketRouterImpl.class);
}
public IQRegisterHandler getIQRegisterHandler() {
return (IQRegisterHandler) modules.get(IQRegisterHandler.class);
}
public List<IQHandler> getIQHandlers() {
List<IQHandler> answer = new ArrayList<IQHandler>();
for (Module module : modules.values()) {
if (module instanceof IQHandler) {
answer.add((IQHandler)module);
}
}
return answer;
}
public SessionManager getSessionManager() {
return (SessionManager) modules.get(SessionManager.class);
}
public TransportHandler getTransportHandler() {
return (TransportHandler) modules.get(TransportHandler.class);
}
public PresenceUpdateHandler getPresenceUpdateHandler() {
return (PresenceUpdateHandler) modules.get(PresenceUpdateHandler.class);
}
public PresenceSubscribeHandler getPresenceSubscribeHandler() {
return (PresenceSubscribeHandler) modules.get(PresenceSubscribeHandler.class);
}
public IQRouter getIQRouter() {
return (IQRouter) modules.get(IQRouterImpl.class);
}
public MessageRouter getMessageRouter() {
return (MessageRouter) modules.get(MessageRouterImpl.class);
}
public PresenceRouter getPresenceRouter() {
return (PresenceRouter) modules.get(PresenceRouterImpl.class);
}
public UserManager getUserManager() {
return UserManager.getInstance();
}
public AuditManager getAuditManager() {
return (AuditManager) modules.get(AuditManagerImpl.class);
}
public List<ServerFeaturesProvider> getServerFeaturesProviders() {
List<ServerFeaturesProvider> answer = new ArrayList<ServerFeaturesProvider>();
for (Module module : modules.values()) {
if (module instanceof ServerFeaturesProvider) {
answer.add((ServerFeaturesProvider) module);
}
}
return answer;
}
public List<ServerItemsProvider> getServerItemsProviders() {
List<ServerItemsProvider> answer = new ArrayList<ServerItemsProvider>();
for (Module module : modules.values()) {
if (module instanceof ServerItemsProvider) {
answer.add((ServerItemsProvider) module);
}
}
return answer;
}
public IQDiscoInfoHandler getIQDiscoInfoHandler() {
return (IQDiscoInfoHandler) modules.get(IQDiscoInfoHandler.class);
}
public PrivateStorage getPrivateStorage() {
return (PrivateStorage) modules.get(PrivateStorage.class);
}
public MultiUserChatServer getMultiUserChatServer() {
return (MultiUserChatServer) modules.get(MultiUserChatServerImpl.class);
}
}
\ No newline at end of file
...@@ -79,7 +79,7 @@ public class ServerStarter { ...@@ -79,7 +79,7 @@ public class ServerStarter {
Thread.currentThread().setContextClassLoader(loader); Thread.currentThread().setContextClassLoader(loader);
Class containerClass = loader.loadClass( Class containerClass = loader.loadClass(
"org.jivesoftware.messenger.spi.BasicServer"); "org.jivesoftware.messenger.XMPPServer");
containerClass.newInstance(); containerClass.newInstance();
} }
catch (Exception e) { catch (Exception e) {
......
...@@ -11,8 +11,8 @@ ...@@ -11,8 +11,8 @@
package org.jivesoftware.messenger.user; package org.jivesoftware.messenger.user;
import org.jivesoftware.messenger.spi.BasicServer;
import org.jivesoftware.messenger.roster.CachedRoster; import org.jivesoftware.messenger.roster.CachedRoster;
import org.jivesoftware.messenger.XMPPServer;
import org.jivesoftware.util.Log; import org.jivesoftware.util.Log;
import org.jivesoftware.util.Cacheable; import org.jivesoftware.util.Cacheable;
import org.jivesoftware.util.CacheSizes; import org.jivesoftware.util.CacheSizes;
...@@ -237,7 +237,7 @@ public class User implements Cacheable { ...@@ -237,7 +237,7 @@ public class User implements Cacheable {
*/ */
public CachedRoster getRoster() { public CachedRoster getRoster() {
try { try {
return BasicServer.getInstance().getRosterManager().getRoster(username); return XMPPServer.getInstance().getRosterManager().getRoster(username);
} }
catch (UserNotFoundException unfe) { catch (UserNotFoundException unfe) {
Log.error(unfe); Log.error(unfe);
......
...@@ -21,8 +21,6 @@ import org.jivesoftware.messenger.PrivateStorage; ...@@ -21,8 +21,6 @@ import org.jivesoftware.messenger.PrivateStorage;
import org.jivesoftware.messenger.PresenceManager; import org.jivesoftware.messenger.PresenceManager;
import org.jivesoftware.messenger.SessionManager; import org.jivesoftware.messenger.SessionManager;
import org.jivesoftware.messenger.XMPPServerInfo; import org.jivesoftware.messenger.XMPPServerInfo;
import org.jivesoftware.messenger.roster.RosterManager;
import org.jivesoftware.messenger.spi.BasicServer;
import org.jivesoftware.messenger.group.GroupManager; import org.jivesoftware.messenger.group.GroupManager;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
...@@ -61,7 +59,7 @@ public class WebManager extends WebBean { ...@@ -61,7 +59,7 @@ public class WebManager extends WebBean {
* Returns the XMPP server object -- can get many config items from here. * Returns the XMPP server object -- can get many config items from here.
*/ */
public XMPPServer getXMPPServer() { public XMPPServer getXMPPServer() {
final XMPPServer xmppServer = BasicServer.getInstance(); final XMPPServer xmppServer = XMPPServer.getInstance();
if (xmppServer == null) { if (xmppServer == null) {
// Show that the server is down // Show that the server is down
showServerDown(); showServerDown();
......
...@@ -12,8 +12,7 @@ ...@@ -12,8 +12,7 @@
<%@ page import="org.jivesoftware.messenger.auth.AuthToken, <%@ page import="org.jivesoftware.messenger.auth.AuthToken,
org.jivesoftware.util.ClassUtils, org.jivesoftware.util.ClassUtils,
org.jivesoftware.messenger.XMPPServer, org.jivesoftware.messenger.XMPPServer,
org.jivesoftware.messenger.user.*, org.jivesoftware.messenger.user.*"
org.jivesoftware.messenger.spi.BasicServer"
%> %>
<% // Security check <% // Security check
...@@ -38,7 +37,7 @@ ...@@ -38,7 +37,7 @@
} }
// Check to see if we're in "setup" mode: // Check to see if we're in "setup" mode:
if (BasicServer.getInstance().isSetupMode()) { if (XMPPServer.getInstance().isSetupMode()) {
response.sendRedirect("setup-index.jsp"); response.sendRedirect("setup-index.jsp");
return; return;
} }
...@@ -48,7 +47,7 @@ ...@@ -48,7 +47,7 @@
boolean isSystemAdmin = true; boolean isSystemAdmin = true;
// Otherwise, get the xmpp server // Otherwise, get the xmpp server
XMPPServer xmppServer = BasicServer.getInstance(); XMPPServer xmppServer = XMPPServer.getInstance();
// The user object of the logged-in user // The user object of the logged-in user
UserManager userManager = xmppServer.getUserManager(); UserManager userManager = xmppServer.getUserManager();
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
java.text.DateFormat, java.text.DateFormat,
org.jivesoftware.messenger.XMPPServer, org.jivesoftware.messenger.XMPPServer,
org.jivesoftware.messenger.container.*, org.jivesoftware.messenger.container.*,
org.jivesoftware.messenger.spi.BasicServer,
org.jivesoftware.messenger.auth.UnauthorizedException, org.jivesoftware.messenger.auth.UnauthorizedException,
org.jivesoftware.admin.AdminPageBean" org.jivesoftware.admin.AdminPageBean"
%> %>
......
...@@ -14,8 +14,7 @@ ...@@ -14,8 +14,7 @@
org.jivesoftware.messenger.auth.AuthFactory, org.jivesoftware.messenger.auth.AuthFactory,
org.jivesoftware.messenger.auth.AuthToken, org.jivesoftware.messenger.auth.AuthToken,
org.jivesoftware.messenger.JiveGlobals, org.jivesoftware.messenger.JiveGlobals,
org.jivesoftware.messenger.auth.DefaultAuthProvider, org.jivesoftware.messenger.auth.DefaultAuthProvider" %>
org.jivesoftware.messenger.spi.BasicServer" %>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %> <%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %> <%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
......
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