| HTTPServletStarter.java |
/*
* $Id: HTTPServletStarter.java,v 1.30 2012/03/03 16:35:17 agoubard Exp $
*
* See the COPYRIGHT file for redistribution and use restrictions.
*/
package org.xins.common.servlet.container;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import javax.servlet.ServletException;
import javax.swing.JFrame;
/**
* HTTP Server used to invoke the XINS Servlet.
*
* @version $Revision: 1.30 $ $Date: 2012/03/03 16:35:17 $
* @author <a href="mailto:anthony.goubard@japplis.com">Anthony Goubard</a>
*/
public class HTTPServletStarter {
/**
* The default port number.
*/
public static final int DEFAULT_PORT_NUMBER = 8080;
/**
* Creates a new <code>HTTPServletStarter</code> for the specified WAR
* file, on the default port, as a daemon thread.
*
* <p>A listener is started on the port immediately.
*
* @param warFile
* the WAR file of the application to deploy, cannot be
* <code>null</code>.
*
* @throws ServletException
* if the servlet cannot be initialized.
*
* @throws IOException
* if the servlet container cannot be started.
*/
// Exception is thrown as ServletException is not in the classpath
public HTTPServletStarter(File warFile)
throws Exception {
this(warFile, DEFAULT_PORT_NUMBER, true);
}
/**
* Creates a new <code>HTTPServletStarter</code> for the specified WAR
* file, on the specified port, as a daemon thread.
*
* <p>A listener is started on the port immediately.
*
* @param warFile
* the WAR file of the application to deploy, cannot be
* <code>null</code>.
*
* @param port
* the port to run the web server on.
*
* @throws ServletException
* if the servlet cannot be initialized.
*
* @throws IOException
* if the servlet container cannot be started.
*/
public HTTPServletStarter(File warFile, int port)
throws Exception {
this(warFile, port, true);
}
/**
* Creates a new <code>HTTPServletStarter</code> for the specified WAR
* file, on the specified port, optionally as a daemon thread.
*
* <p>A listener is started on the port immediately.
*
* @param warFile
* The war file of the application to deploy, cannot be <code>null</code>.
*
* @param port
* The port of the web server, cannot be <code>null</code>.
*
* @param deamon
* <code>true</code> if the thread listening to connection should be a
* deamon thread, <code>false</code> otherwise.
*
* @throws ServletException
* if the servlet cannot be initialized.
*
* @throws IOException
* if the servlet container cannot be started.
*/
public HTTPServletStarter(File warFile, int port, boolean deamon)
throws Exception {
this(warFile, port, deamon, ServletClassLoader.USE_WAR_EXTERNAL_LIB);
}
/**
* Creates a new <code>HTTPServletStarter</code> for the specified servlet
* class, on the specified port, optionally as a daemon thread.
*
* <p>A listener is started on the port immediately.
*
* @param warFile
* The war file containing the API, cannot be <code>null</code>.
*
* @param port
* The port of the web server, cannot be <code>null</code>.
*
* @param deamon
* <code>true</code> if the thread listening to connection should be a
* deamon thread, <code>false</code> otherwise.
*
* @param loaderMode
* the way the ClassLoader should locate and load the classes.
* See {@link ServletClassLoader}.
*
* @throws ServletException
* if the servlet cannot be initialized.
*
* @throws IOException
* if the servlet container cannot be started.
*
* @since XINS 2.1.
*/
public HTTPServletStarter(File warFile, int port, boolean deamon, int loaderMode)
throws Exception {
// Create the servlet
ClassLoader loader = ServletClassLoader.getServletClassLoader(warFile, loaderMode);
startHTTPServer(warFile, port, deamon, loader);
}
/**
* Creates a new <code>HTTPServletStarter</code> for the specified servlet
* class, on the specified port, optionally as a daemon thread.
*
* <p>A listener is started on the port immediately.
*
* @param servletClassName
* The name of the servlet to load, cannot be <code>null</code>.
*
* @param port
* The port of the web server, cannot be <code>null</code>.
*
* @param deamon
* <code>true</code> if the thread listening to connection should be a
* deamon thread, <code>false</code> otherwise.
*
* @throws ServletException
* if the servlet cannot be initialized.
*
* @throws IOException
* if the servlet container cannot be started.
*/
public HTTPServletStarter(String servletClassName, int port, boolean deamon)
throws Exception {
ClassLoader loader = getClass().getClassLoader();
startHTTPServer(servletClassName, port, deamon, loader);
}
private void startHTTPServer(Object servletClassNameOrWarFile, int port, boolean deamon, ClassLoader loader) {
try {
startNettyHTTPServer(servletClassNameOrWarFile, port, deamon, loader);
} catch (Exception ex) {
startInternalHTTPServer(servletClassNameOrWarFile, port, deamon, loader);
}
}
private void startNettyHTTPServer(Object servletClassNameOrWarFile, int port, boolean deamon, ClassLoader loader) throws Exception {
Class delegate = null;
try {
delegate = loader.loadClass("org.xins.common.servlet.container.NettyServletHandler");
} catch (Exception ex) {
delegate = getClass().getClassLoader().loadClass("org.xins.common.servlet.container.NettyServletHandler");
loader = getClass().getClassLoader();
}
Class[] constClasses = {servletClassNameOrWarFile.getClass()};
Object[] constArgs = {servletClassNameOrWarFile};
Constructor constructor = delegate.getConstructor(constClasses);
Object servletHandler = constructor.newInstance(constArgs);
// Starts the server
Method startServerMethod = servletHandler.getClass().getMethod("startServer", Integer.TYPE, String.class);
startServerMethod.invoke(servletHandler, port, System.getProperty("org.xins.server.netty.pipeline"));
}
private void startInternalHTTPServer(Object servletClassNameOrWarFile, int port, boolean deamon, ClassLoader loader) {
// Create the servlet
Class[] constClasses = {servletClassNameOrWarFile.getClass(), Integer.TYPE, Boolean.TYPE};
Object[] constArgs = {servletClassNameOrWarFile, new Integer(port), Boolean.valueOf(deamon)};
try {
Class delegate = loader.loadClass("org.xins.common.servlet.container.HTTPServletHandler");
Constructor constructor = delegate.getConstructor(constClasses);
constructor.newInstance(constArgs);
} catch (Exception ex) {
ex.printStackTrace();
}
}
/**
* Starts the Servlet container for the specific API.
*
* @param args
* The command line arguments, the first argument should be the location
* of the WAR file or the name of the class of the servlet to load,
* the optional second argument is the port number.
* If no port number is specified, 8080 is used as default.
*/
public static void main(String[] args) {
CommandLineArguments cmdArgs = new CommandLineArguments(args);
if (cmdArgs.getPort() == -1) {
try {
ClassLoader loader = ServletClassLoader.getServletClassLoader(cmdArgs.getWarFile(), cmdArgs.getLoaderMode());
loader.loadClass("org.xins.common.spec.SpecGUI").newInstance();
} catch (Exception ex) {
ex.printStackTrace();
}
} else {
if (cmdArgs.showGUI()) {
JFrame apiFrame = new JFrame();
new ConsoleGUI(apiFrame, cmdArgs);
apiFrame.setVisible(true);
}
try {
// Starts the server and wait for connections
new HTTPServletStarter(cmdArgs.getWarFile(), cmdArgs.getPort(), false, cmdArgs.getLoaderMode());
} catch (Exception ioe) {
ioe.printStackTrace();
}
}
}
}