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(); } } } }