org.xins.server.APIServlet Maven / Gradle / Ivy
/*
* $Id: APIServlet.java,v 1.285 2007/09/18 08:45:03 agoubard Exp $
*
* Copyright 2003-2007 Orange Nederland Breedband B.V.
* See the COPYRIGHT file for redistribution and use restrictions.
*/
package org.xins.server;
import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.xins.common.MandatoryArgumentChecker;
/**
* HTTP servlet that forwards requests to an API
.
*
* HTTP status codes
*
* This servlet supports various HTTP methods, depending on the calling
* conventions. A request with an unsupported method makes this servlet
* return the HTTP status code 405 Method Not Allowed
.
*
*
If no matching function is found, then this servlet returns HTTP status
* code 404 Not Found
.
*
*
If the servlet is temporarily unavailable, then the HTTP status
* 503 Service Unavailable
is returned.
*
*
If the servlet encountered an initialization error, then the HTTP status
* code 500 Internal Server Error
is returned.
*
*
If the state is ready then the HTTP status code
* 200 OK
is returned.
*
*
*
Initialization
*
* When the servlet is initialized, it gathers configuration information
* from different sources:
*
*
* - 1. Build-time settings
* - The application package contains a
web.xml
file with
* build-time settings. Some of these settings are required in order
* for the XINS/Java Server Framework to start up, while others are
* optional. These build-time settings are passed to the servlet by the
* application server as a {@link ServletConfig} object. See
* {@link #init(ServletConfig)}.
*
The servlet configuration is the responsibility of the
* assembler.
*
* - 2. System properties
* - The location of the configuration file must be passed to the Java VM
* at startup, as a system property.
*
System properties are the responsibility of the
* system administrator.
*
Example:
*
java -Dorg.xins.server.config=`pwd`/config/xins.properties
* -jar orion.jar
*
* - 3. Configuration file
* - The configuration file should contain runtime configuration
* settings, like the settings for the logging subsystem.
*
Runtime properties are the responsibility of the
* system administrator.
*
Example contents for a configuration file:
* log4j.rootLogger=DEBUG, console
*
log4j.appender.console=org.apache.log4j.ConsoleAppender
*
log4j.appender.console.layout=org.apache.log4j.PatternLayout
*
log4j.appender.console.layout.ConversionPattern=%d %-5p [%c]
* %m%n
*
*
* @version $Revision: 1.285 $ $Date: 2007/09/18 08:45:03 $
* @author Ernst de Haan
* @author Anthony Goubard
* @author Mees Witteman
*
* @since XINS 1.0.0
*/
public final class APIServlet
extends HttpServlet {
/**
* XINS server engine. Initially null
but set to a
* non-null
value in the {@link #init(ServletConfig)} method.
*/
private Engine _engine;
/**
* Initializes the loggers to log to the console using a simple format
* and no threshold. This is done by calling
* {@link Engine#configureLoggerFallback()}.
*/
static {
ConfigManager.configureLoggerFallback();
}
/**
* Constructs a new APIServlet
object.
*/
public APIServlet() {
// empty
}
/**
* Returns information about this servlet, as plain text.
*
* @return
* textual description of this servlet, not null
and not an
* empty character string.
*/
public String getServletInfo() {
return "XINS/Java Server Framework " + Library.getVersion();
}
/**
* Initializes this servlet using the specified configuration.
*
* @param config
* the {@link ServletConfig} object which contains bootstrap properties for
* this servlet, as specified by the assembler, cannot be
* null
.
*
* @throws IllegalArgumentException
* if config == null
* || config.{@link ServletConfig#getServletContext()} == null
.
*
* @throws ServletException
* if the servlet could not be initialized.
*/
public void init(ServletConfig config)
throws IllegalArgumentException, ServletException {
// Check arguments
MandatoryArgumentChecker.check("config", config);
// Get the ServletContext
ServletContext context = config.getServletContext();
if (context == null) {
String message = "config.getServletContext() == null";
Log.log_3202(message);
throw new IllegalArgumentException(message);
}
// Compare the expected with the implemented Java Servlet API version;
// versions 2.2, 2.3, 2.4 and 2.5 are supported
int major = context.getMajorVersion();
int minor = context.getMinorVersion();
if (major != 2 || minor < 2 || minor > 5) {
String expected = "2.2/2.3/2.4/2.5";
String actual = major + "." + minor;
Log.log_3203(actual, expected);
}
// Construct an engine
try {
_engine = new Engine(config);
// Fail silently, so that the servlet container will not keep trying to
// re-initialize this servlet (possibly on each call!)
} catch (Throwable exception) {
Log.log_3444(exception);
return;
}
}
/**
* Returns the ServletConfig
object which contains the
* bootstrap properties for this servlet. The returned {@link ServletConfig}
* object is the one passed to the {@link #init(ServletConfig)} method.
*
* @return
* the {@link ServletConfig} object that was used to initialize this
* servlet, or null
if this servlet is not yet
* initialized.
*/
public ServletConfig getServletConfig() {
return (_engine == null) ? null : _engine.getServletConfig();
}
/**
* Handles an HTTP request to this servlet. If any of the arguments is
* null
, then the behaviour of this method is undefined.
*
* @param request
* the servlet request, should not be null
.
*
* @param response
* the servlet response, should not be null
.
*
* @throws NullPointerException
* if this servlet is yet uninitialized.
*
* @throws IOException
* if there is an error error writing to the response output stream.
*/
public void service(HttpServletRequest request,
HttpServletResponse response)
throws NullPointerException,
IOException {
// Engine failed to initialize, return '500 Internal Server Error'
if (_engine == null) {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
}
// Pass control to the Engine
_engine.service(request, response);
}
/**
* Destroys this servlet. A best attempt will be made to release all
* resources.
*
* After this method has finished, no more requests will be handled
* successfully.
*/
public void destroy() {
if (_engine != null) {
_engine.destroy();
_engine = null;
}
}
}