package uws.config;
/*
* This file is part of UWSLibrary.
*
* UWSLibrary is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* UWSLibrary is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with UWSLibrary. If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2016 - Astronomisches Rechen Institut (ARI)
*/
import static uws.config.UWSConfiguration.DEFAULT_BACKUP_BY_USER;
import static uws.config.UWSConfiguration.DEFAULT_BACKUP_FREQUENCY;
import static uws.config.UWSConfiguration.DEFAULT_DIRECTORY_PER_USER;
import static uws.config.UWSConfiguration.DEFAULT_GROUP_USER_DIRECTORIES;
import static uws.config.UWSConfiguration.DEFAULT_UWS_CONF_FILE;
import static uws.config.UWSConfiguration.KEY_ADD_SERIALIZERS;
import static uws.config.UWSConfiguration.KEY_ADD_UWS_ACTIONS;
import static uws.config.UWSConfiguration.KEY_BACKUP_BY_USER;
import static uws.config.UWSConfiguration.KEY_BACKUP_FREQUENCY;
import static uws.config.UWSConfiguration.KEY_DESTRUCTION_MANAGER;
import static uws.config.UWSConfiguration.KEY_DIRECTORY_PER_USER;
import static uws.config.UWSConfiguration.KEY_ERROR_WRITER;
import static uws.config.UWSConfiguration.KEY_EXECUTION_MANAGER;
import static uws.config.UWSConfiguration.KEY_FILE_MANAGER;
import static uws.config.UWSConfiguration.KEY_FILE_ROOT_PATH;
import static uws.config.UWSConfiguration.KEY_GROUP_USER_DIRECTORIES;
import static uws.config.UWSConfiguration.KEY_HOME_PAGE;
import static uws.config.UWSConfiguration.KEY_HOME_PAGE_MIME_TYPE;
import static uws.config.UWSConfiguration.KEY_JOB_LISTS;
import static uws.config.UWSConfiguration.KEY_LOG_ROTATION;
import static uws.config.UWSConfiguration.KEY_MAX_RUNNING_JOBS;
import static uws.config.UWSConfiguration.KEY_MIN_LOG_LEVEL;
import static uws.config.UWSConfiguration.KEY_SERVICE_DESCRIPTION;
import static uws.config.UWSConfiguration.KEY_SERVICE_NAME;
import static uws.config.UWSConfiguration.KEY_USER_IDENTIFIER;
import static uws.config.UWSConfiguration.KEY_UWS_FACTORY;
import static uws.config.UWSConfiguration.KEY_XSLT_STYLESHEET;
import static uws.config.UWSConfiguration.REGEXP_JOB_LIST_NAME;
import static uws.config.UWSConfiguration.UWS_CONF_PARAMETER;
import static uws.config.UWSConfiguration.VALUE_LOCAL;
import static uws.config.UWSConfiguration.VALUE_NEVER;
import static uws.config.UWSConfiguration.VALUE_USER_ACTION;
import static uws.config.UWSConfiguration.getProperty;
import static uws.config.UWSConfiguration.hasConstructor;
import static uws.config.UWSConfiguration.isClassName;
import static uws.config.UWSConfiguration.newInstance;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Properties;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import uws.UWSException;
import uws.job.JobList;
import uws.job.manager.DefaultDestructionManager;
import uws.job.manager.DefaultExecutionManager;
import uws.job.manager.DestructionManager;
import uws.job.manager.ExecutionManager;
import uws.job.manager.QueuedExecutionManager;
import uws.job.serializer.UWSSerializer;
import uws.job.serializer.XMLSerializer;
import uws.service.UWSFactory;
import uws.service.UWSService;
import uws.service.UserIdentifier;
import uws.service.actions.ShowHomePage;
import uws.service.actions.UWSAction;
import uws.service.backup.DefaultUWSBackupManager;
import uws.service.backup.UWSBackupManager;
import uws.service.error.ServiceErrorWriter;
import uws.service.file.LocalUWSFileManager;
import uws.service.file.UWSFileManager;
import uws.service.log.DefaultUWSLog;
import uws.service.log.UWSLog;
import uws.service.log.UWSLog.LogLevel;
/**
* <p>HTTP servlet fully configured with a UWS configuration file.</p>
*
* <p>
* This configuration file may be specified in the initial parameter named {@link UWSConfiguration#UWS_CONF_PARAMETER}
* of this servlet inside the WEB-INF/web.xml file. If none is specified, the file {@link UWSConfiguration#DEFAULT_UWS_CONF_FILE}
* will be searched inside the directories of the classpath, and inside WEB-INF and META-INF.
* </p>
*
* @author Grégory Mantelet (ARI)
* @version 4.2 (06/2016)
* @since 4.2
*/
public class ConfigurableUWSServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/** UWS object representing the UWS service. */
private UWSService uws = null;
@Override
public void init(final ServletConfig config) throws ServletException{
// Nothing to do, if UWS is already initialized:
if (uws != null)
return;
/* 1. GET THE FILE PATH OF THE UWS CONFIGURATION FILE */
String uwsConfPath = config.getInitParameter(UWS_CONF_PARAMETER);
if (uwsConfPath == null || uwsConfPath.trim().length() == 0)
uwsConfPath = null;
//throw new ServletException("Configuration file path missing! You must set a servlet init parameter whose the name is \"" + UWS_CONF_PARAMETER + "\".");
/* 2. OPEN THE CONFIGURATION FILE */
InputStream input = null;
// CASE: No file specified => search in the classpath for a file having the default name "uws.properties".
if (uwsConfPath == null)
input = searchFile(DEFAULT_UWS_CONF_FILE, config);
else{
File f = new File(uwsConfPath);
// CASE: The given path matches to an existing local file.
if (f.exists()){
try{
input = new FileInputStream(f);
}catch(IOException ioe){
throw new ServletException("Impossible to read the UWS configuration file (" + uwsConfPath + ")!", ioe);
}
}
// CASE: The given path seems to be relative to the servlet root directory.
else
input = searchFile(uwsConfPath, config);
}
// If no file has been found, cancel the servlet loading:
if (input == null)
throw new ServletException("Configuration file not found with the path: \"" + ((uwsConfPath == null) ? DEFAULT_UWS_CONF_FILE : uwsConfPath) + "\"! Please provide a correct file path in servlet init parameter (\"" + UWS_CONF_PARAMETER + "\") or put your configuration file named \"" + DEFAULT_UWS_CONF_FILE + "\" in a directory of the classpath or in WEB-INF or META-INF.");
/* 3. PARSE IT INTO A PROPERTIES SET */
Properties uwsConf = new Properties();
try{
uwsConf.load(input);
}catch(IOException ioe){
throw new ServletException("Impossible to read the UWS configuration file (" + uwsConfPath + ")!", ioe);
}finally{
try{
input.close();
}catch(IOException ioe2){}
}
/* 4. CREATE THE FILE MANAGER */
UWSFileManager fileManager = null;
try{
fileManager = createFileManager(uwsConf, config.getServletContext().getRealPath(""));
}catch(Exception ex){
if (ex instanceof UWSException)
throw new ServletException(ex.getMessage(), ex.getCause());
else
throw new ServletException("Impossible to initialize the UWS file manager!", ex);
}
/* 5. CREATE THE LOGGER */
UWSLog logger = null;
try{
logger = createLogger(uwsConf, fileManager);
}catch(Exception ex){
if (ex instanceof UWSException)
throw new ServletException(ex.getMessage(), ex.getCause());
else
throw new ServletException("Impossible to initialize the UWS logger!", ex);
}
/* 6. CREATE THE UWS SERVICE */
try{
uws = new UWSService(createFactory(uwsConf), fileManager, logger);
}catch(Exception ex){
uws = null;
if (ex instanceof UWSException)
throw new ServletException(ex.getMessage(), ex.getCause());
else
throw new ServletException("Impossible to initialize the UWS service!", ex);
}
/* 6Bis. SET THE HOME PAGE */
String propValue = getProperty(uwsConf, KEY_HOME_PAGE);
if (propValue != null){
// If it is a class path, replace the current home page by an instance of this class:
if (isClassName(propValue)){
try{
uws.replaceUWSAction(newInstance(propValue, KEY_HOME_PAGE, ShowHomePage.class, new Class<?>[]{UWSService.class}, new Object[]{uws}));
}catch(UWSException te){
throw new ServletException(te.getMessage(), te.getCause());
}
}
// If it is a file URI (null, file inside WebContent, file://..., http://..., etc...):
else{
// ...set the given URI:
uws.setHomePage(propValue);
// ...and its MIME type (if any):
propValue = getProperty(uwsConf, KEY_HOME_PAGE_MIME_TYPE);
if (propValue != null)
uws.setHomePageMimeType(propValue);
}
}
/* 6Ter. SET ALL GENERAL SERVICE CONNECTION INFORMATION */
uws.setName(getProperty(uwsConf, KEY_SERVICE_NAME));
uws.setDescription(getProperty(uwsConf, KEY_SERVICE_DESCRIPTION));
/* 7. CONFIGURE THE BACKUP MANAGER */
initBackup(uwsConf);
/* 8. CONFIGURE THE USER IDENTIFICATION */
initUserIdentifier(uwsConf);
/* 9. CREATE THE JOB LISTS */
initJobLists(uwsConf);
/* 10. INITIALIZE ADDITIONAL ACTIONS */
addCustomActions(uwsConf);
/* 11. INITIALIZE THE SERIALIZATION */
addCustomSerializers(uwsConf);
initXSLTStylesheet(uwsConf);
initErrorWriter(uwsConf);
/* 12. DEFAULT SERVLET INITIALIZATION */
super.init(config);
}
/**
* Initialize the management of UWS service files using the given UWS configuration file.
*
* @param uwsConfig The content of the UWS configuration file.
* @param webAppRootDir The directory of the Web Application running this UWS service.
* <em>This directory may be used only to search the root UWS directory
* if specified with a relative path in the UWS configuration file.</em>
*
* @return The created file manager.
*
* @throws UWSException If a property is wrong or missing, or if an error occurs while creating the file manager.
*/
private UWSFileManager createFileManager(final Properties uwsConfig, final String webAppRootDir) throws UWSException{
// Read the desired file manager:
String fileManagerType = getProperty(uwsConfig, KEY_FILE_MANAGER);
if (fileManagerType == null)
throw new UWSException("The property \"" + KEY_FILE_MANAGER + "\" is missing! It is required to create a TAP Service. Two possible values: " + VALUE_LOCAL + " or a class name between {...}.");
else
fileManagerType = fileManagerType.trim();
// LOCAL file manager:
if (fileManagerType.equalsIgnoreCase(VALUE_LOCAL)){
// Read the desired root path:
String rootPath = getProperty(uwsConfig, KEY_FILE_ROOT_PATH);
if (rootPath == null)
throw new UWSException("The property \"" + KEY_FILE_ROOT_PATH + "\" is missing! It is required to create a TAP Service. Please provide a path toward a directory which will contain all files related to the service.");
File rootFile = getFile(rootPath, webAppRootDir, KEY_FILE_ROOT_PATH);
// Determine whether there should be one directory for each user:
String propValue = getProperty(uwsConfig, KEY_DIRECTORY_PER_USER);
boolean oneDirectoryPerUser = (propValue == null) ? DEFAULT_DIRECTORY_PER_USER : Boolean.parseBoolean(propValue);
// Determine whether there should be one directory for each user:
propValue = getProperty(uwsConfig, KEY_GROUP_USER_DIRECTORIES);
boolean groupUserDirectories = (propValue == null) ? DEFAULT_GROUP_USER_DIRECTORIES : Boolean.parseBoolean(propValue);
// Build the Local TAP File Manager:
try{
return new LocalUWSFileManager(rootFile, oneDirectoryPerUser, groupUserDirectories);
}catch(UWSException e){
throw new UWSException("The property \"" + KEY_FILE_ROOT_PATH + "\" (" + rootPath + ") is incorrect: " + e.getMessage());
}
}
// CUSTOM file manager:
else
return newInstance(fileManagerType, KEY_FILE_MANAGER, UWSFileManager.class, new Class<?>[]{Properties.class}, new Object[]{uwsConfig});
}
/**
* Initialize the UWS logger with the given UWS configuration file.
*
* @param uwsConfig The content of the UWS configuration file.
* @param fileManager The file manager to access the log file(s).
*/
private UWSLog createLogger(final Properties uwsConfig, final UWSFileManager fileManager){
// Create the logger:
UWSLog logger = new DefaultUWSLog(fileManager);
StringBuffer buf = new StringBuffer("Logger initialized");
// Set the minimum log level:
String propValue = getProperty(uwsConfig, KEY_MIN_LOG_LEVEL);
if (propValue != null){
try{
((DefaultUWSLog)logger).setMinLogLevel(LogLevel.valueOf(propValue.toUpperCase()));
}catch(IllegalArgumentException iae){}
}
buf.append(" (minimum log level: ").append(((DefaultUWSLog)logger).getMinLogLevel());
// Set the log rotation period, if any:
if (fileManager instanceof LocalUWSFileManager){
propValue = getProperty(uwsConfig, KEY_LOG_ROTATION);
if (propValue != null)
((LocalUWSFileManager)fileManager).setLogRotationFreq(propValue);
buf.append(", log rotation: ").append(((LocalUWSFileManager)fileManager).getLogRotationFreq());
}
// Log the successful initialization with set parameters:
buf.append(").");
logger.info(buf.toString());
return logger;
}
/**
* <p>Initialize the {@link UWSFactory} to use.</p>
*
* <p>
* The built factory is either a {@link ConfigurableUWSFactory} instance (by default) or
* an instance of the class specified in the UWS configuration file.
* </p>
*
* @param uwsConfig The content of the UWS configuration file.
*
* @throws UWSException If an error occurs while building the specified {@link UWSFactory}.
*
* @see ConfigurableUWSFactory
*/
private UWSFactory createFactory(final Properties uwsConfig) throws UWSException{
String propValue = getProperty(uwsConfig, KEY_UWS_FACTORY);
if (propValue == null)
return new ConfigurableUWSFactory(uwsConfig);
else if (hasConstructor(propValue, KEY_UWS_FACTORY, UWSFactory.class, new Class<?>[]{Properties.class}))
return newInstance(propValue, KEY_UWS_FACTORY, UWSFactory.class, new Class<?>[]{Properties.class}, new Object[]{uwsConfig});
else
return newInstance(propValue, KEY_UWS_FACTORY, UWSFactory.class, new Class<?>[]{}, new Object[]{});
}
/**
* Create a {@link UWSBackupManager} if needed, thanks to the configuration provided in the UWS configuration file.
*
* @param uwsConf List of properties set in the UWS configuration file.
*
* @throws ServletException If any error occurs when initializing the {@link UWSBackupManager}.
*/
private void initBackup(final Properties uwsConf) throws ServletException{
try{
/* Set the backup frequency: */
String propValue = getProperty(uwsConf, KEY_BACKUP_FREQUENCY);
// determine whether the value is a time period ; if yes, set the frequency:
long backupFrequency;
boolean backupByUser;
if (propValue != null){
try{
backupFrequency = Long.parseLong(propValue);
if (backupFrequency <= 0)
backupFrequency = DEFAULT_BACKUP_FREQUENCY;
}catch(NumberFormatException nfe){
// if the value was not a valid numeric time period, try to identify the different textual options:
if (propValue.equalsIgnoreCase(VALUE_NEVER))
backupFrequency = DefaultUWSBackupManager.MANUAL;
else if (propValue.equalsIgnoreCase(VALUE_USER_ACTION))
backupFrequency = DefaultUWSBackupManager.AT_USER_ACTION;
else
throw new UWSException("Long expected for the property \"" + KEY_BACKUP_FREQUENCY + "\", instead of: \"" + propValue + "\"!");
}
}else
backupFrequency = DEFAULT_BACKUP_FREQUENCY;
// Specify whether the backup must be organized by user or not:
propValue = getProperty(uwsConf, KEY_BACKUP_BY_USER);
backupByUser = (propValue == null) ? DEFAULT_BACKUP_BY_USER : Boolean.parseBoolean(propValue);
// Finally create and set the backup manager:
uws.setBackupManager(new DefaultUWSBackupManager(uws, backupByUser, backupFrequency));
}catch(UWSException ue){
throw new ServletException("Impossible to initialize the Backup system (and so to restore all the last backuped jobs)!", ue);
}
}
/**
* Initialize the UWS user identification method.
*
* @param uwsConfig The content of the UWS configuration file.
*
* @throws ServletException If the corresponding UWS configuration property is wrong.
*/
private void initUserIdentifier(final Properties uwsConfig) throws ServletException{
// Get the property value:
String propValue = getProperty(uwsConfig, KEY_USER_IDENTIFIER);
if (propValue != null){
try{
uws.setUserIdentifier(newInstance(propValue, KEY_USER_IDENTIFIER, UserIdentifier.class));
}catch(UWSException ue){
throw new ServletException("Impossible to initialize the user identification!", ue);
}
}
}
/**
* Initialize all the specified job lists.
*
* @param uwsConfig The content of the UWS configuration file.
*
* @throws ServletException If the corresponding UWS configuration property is wrong.
*/
private void initJobLists(final Properties uwsConf) throws ServletException{
String propValue = getProperty(uwsConf, KEY_JOB_LISTS);
if (propValue != null){
// split the list of job list names:
String[] jlNames = propValue.split(",");
if (jlNames == null || jlNames.length == 0)
throw new ServletException("Missing job list name! At least one job list name must be provided. See property \"" + KEY_JOB_LISTS + "\".");
// for each job list name:
int nbMaxRunningJobs;
ExecutionManager execManager;
DestructionManager destManager;
for(String jlName : jlNames){
// normalize and test the name:
jlName = jlName.trim();
if (!jlName.matches(REGEXP_JOB_LIST_NAME))
throw new ServletException("Incorrect job list name: \"" + jlName + "\"! It must not contain space characters, point and equal sign.");
// configure the execution manager, if any is specified in the configuration:
nbMaxRunningJobs = -1;
execManager = null;
try{
// if an execution manager is provided, set it:
propValue = getProperty(uwsConf, jlName + "." + KEY_EXECUTION_MANAGER);
if (propValue != null)
execManager = newInstance(propValue, jlName + "." + KEY_EXECUTION_MANAGER, ExecutionManager.class, new Class<?>[]{UWSLog.class}, new Object[]{uws.getLogger()});
/* if none is provided, the default execution manager will be used
* EXCEPT if a maximum number of running jobs is specified ; in such case a QueuedExecutionManager will be used. */
else{
propValue = getProperty(uwsConf, jlName + "." + KEY_MAX_RUNNING_JOBS);
if (propValue != null){
try{
nbMaxRunningJobs = Integer.parseInt(propValue);
if (nbMaxRunningJobs > 0)
execManager = new QueuedExecutionManager(uws.getLogger(), nbMaxRunningJobs);
}catch(NumberFormatException nfe){
uws.getLogger().logUWS(LogLevel.ERROR, uws, "INIT", "Incorrect value for the property \"" + jlName + "." + KEY_MAX_RUNNING_JOBS + "\": \"" + propValue + "\"! It should be a positive integer value. No execution queue is set for this job list.", nfe);
}
}
}
}catch(UWSException ue){
uws.getLogger().logUWS(LogLevel.ERROR, uws, "INIT", "Impossible to set a custom execution manager to the job list \"" + jlName + "\"! The default one will be used.", ue);
}
// configure the destruction manager, if any is specified in the configuration:
destManager = null;
try{
propValue = getProperty(uwsConf, jlName + "." + KEY_DESTRUCTION_MANAGER);
if (propValue != null)
destManager = newInstance(propValue, jlName + "." + KEY_DESTRUCTION_MANAGER, DestructionManager.class, new Class<?>[]{}, new Object[]{});
}catch(UWSException ue){
uws.getLogger().logUWS(LogLevel.ERROR, uws, "INIT", "Impossible to set a custom destruction manager to the job list \"" + jlName + "\"! The default one will be used.", ue);
}
// add the job list to this UWS service:
if (execManager == null)
execManager = new DefaultExecutionManager(uws.getLogger());
if (destManager == null)
destManager = new DefaultDestructionManager();
uws.addJobList(new JobList(jlName, execManager, destManager));
}
}else
throw new ServletException("Missing job list name! At least one job list name must be provided. See property \"" + KEY_JOB_LISTS + "\".");
}
/**
* Add all additional custom actions listed in the configuration file.
*
* @param uwsConfig The content of the UWS configuration file.
*
* @throws ServletException If the corresponding UWS configuration property is wrong.
*/
private void addCustomActions(final Properties uwsConfig) throws ServletException{
// Get the property value:
String propValue = getProperty(uwsConfig, KEY_ADD_UWS_ACTIONS);
if (propValue != null){
// Tokenise the list of classes:
String[] actionClasses = propValue.split(",");
if (actionClasses == null || actionClasses.length == 0)
return;
// For each item:
for(String actionClass : actionClasses){
try{
// extract the action index, if any is provided:
int actionIndex = actionClass.indexOf(':');
if (actionIndex > 0){
actionIndex = Integer.parseInt(actionClass.substring(0, actionIndex));
actionClass = actionClass.substring(actionIndex + 1);
}
// create an instance of the specified action:
UWSAction action = newInstance(actionClass, KEY_ADD_UWS_ACTIONS, UWSAction.class, new Class<?>[]{UWSService.class}, new Object[]{uws});
// add or replacing depending if an action with the same name already exists or not:
boolean added = false;
if (uws.getUWSAction(action.getName()) != null)
added = (uws.replaceUWSAction(action) != null);
else if (actionIndex >= 0)
added = uws.addUWSAction(actionIndex, action);
else
added = uws.addUWSAction(action);
// log an error if the addition is not successful:
if (!added)
uws.getLogger().logUWS(LogLevel.ERROR, uws, "INIT", "Failed to add the UWS action \"" + action.getName() + "\" implemented with the class \"" + actionClass + "\"! See property \"" + KEY_ADD_UWS_ACTIONS + "\".", null);
}catch(UWSException ue){
uws.getLogger().logUWS(LogLevel.ERROR, uws, "INIT", "Impossible to create the UWS action \"" + actionClass + "\" specified in the property \"" + KEY_ADD_UWS_ACTIONS + "\"!", ue);
}catch(NumberFormatException nfe){
uws.getLogger().logUWS(LogLevel.ERROR, uws, "INIT", "Impossible to extract the given action index for the UWS action \"" + actionClass + "\" specified in the property \"" + KEY_ADD_UWS_ACTIONS + "\"! A positive integer value is expected.", nfe);
}
}
}
}
/**
* Add all additional UWS serialized listed in the configuration file.
*
* @param uwsConfig The content of the UWS configuration file.
*
* @throws ServletException If the corresponding UWS configuration property is wrong.
*/
private void addCustomSerializers(final Properties uwsConfig) throws ServletException{
// Get the property value:
String propValue = getProperty(uwsConfig, KEY_ADD_SERIALIZERS);
if (propValue != null){
// Tokenise the list of classes:
String[] serializerClasses = propValue.split(",");
if (serializerClasses == null || serializerClasses.length == 0)
return;
// For each item:
for(String serializerClass : serializerClasses){
try{
// create and add the specified serializer to this UWS service:
uws.addSerializer(newInstance(serializerClass, KEY_ADD_SERIALIZERS, UWSSerializer.class, new Class<?>[]{}, new Object[]{}));
}catch(UWSException ue){
uws.getLogger().logUWS(LogLevel.ERROR, uws, "INIT", "Impossible to create the UWS serializer \"" + serializerClass + "\" specified in the property \"" + KEY_ADD_SERIALIZERS + "\"!", ue);
}
}
}
}
/**
* Initialize the error writer of the UWS service.
*
* @param uwsConfig The content of the UWS configuration file.
*
* @throws ServletException If the corresponding UWS configuration property is wrong.
*/
private void initXSLTStylesheet(final Properties uwsConfig) throws ServletException{
// Get the property value:
String propValue = getProperty(uwsConfig, KEY_XSLT_STYLESHEET);
if (propValue != null){
try{
if (uws.getSerializer(XMLSerializer.MIME_TYPE_XML) instanceof XMLSerializer)
((XMLSerializer)uws.getSerializer(XMLSerializer.MIME_TYPE_XML)).setXSLTPath(propValue);
}catch(UWSException ue){
uws.getLogger().logUWS(LogLevel.ERROR, uws, "INIT", "Impossible to set the specified XSLT stylesheet: \"" + propValue + "\"! Then, no XSLT stylesheet is used.", ue);
}
}
}
/**
* Initialize the error writer of the UWS service.
*
* @param uwsConfig The content of the UWS configuration file.
*
* @throws ServletException If the corresponding UWS configuration property is wrong.
*/
private void initErrorWriter(final Properties uwsConfig) throws ServletException{
// Get the property value:
String propValue = getProperty(uwsConfig, KEY_ERROR_WRITER);
if (propValue != null){
try{
uws.setErrorWriter(newInstance(propValue, KEY_ERROR_WRITER, ServiceErrorWriter.class));
}catch(UWSException ue){
uws.getLogger().logUWS(LogLevel.ERROR, uws, "INIT", "Impossible to initialize the error writer! Then, the default one will be used.", ue);
}
}
}
/**
* Search the given file name/path in the directories of the classpath, then inside WEB-INF and finally inside META-INF.
*
* @param filePath A file name/path.
* @param config Servlet configuration (containing also the context class loader - link with the servlet classpath).
*
* @return The input stream toward the specified file, or NULL if no file can be found.
*
* @since 2.0
*/
protected final InputStream searchFile(String filePath, final ServletConfig config){
InputStream input = null;
// Try to search in the classpath (with just a file name or a relative path):
input = Thread.currentThread().getContextClassLoader().getResourceAsStream(filePath);
// If not found, try searching in WEB-INF and META-INF (as this fileName is a file path relative to one of these directories):
if (input == null){
if (filePath.startsWith("/"))
filePath = filePath.substring(1);
// ...try at the root of WEB-INF:
input = config.getServletContext().getResourceAsStream("/WEB-INF/" + filePath);
// ...and at the root of META-INF:
if (input == null)
input = config.getServletContext().getResourceAsStream("/META-INF/" + filePath);
}
return input;
}
/**
* <p>Resolve the given file name/path.</p>
*
* <p>Only the URI protocol "file:" is allowed. If the protocol is different a {@link UWSException} is thrown.</p>
*
* <p>
* If not an absolute URI, the given path may be either relative or absolute. A relative path is always considered
* as relative from the Web Application directory (supposed to be given in 2nd parameter).
* </p>
*
* @param filePath URI/Path/Name of the file to get.
* @param webAppRootPath Web Application directory local path.
* @param propertyName Name of the property which gives the given file path.
*
* @return The specified File instance.
*
* @throws UWSException If the given URI is malformed or if the used URI scheme is different from "file:".
*/
protected final File getFile(final String filePath, final String webAppRootPath, final String propertyName) throws UWSException{
if (filePath == null)
return null;
try{
URI uri = new URI(filePath);
if (uri.isAbsolute()){
if (uri.getScheme().equalsIgnoreCase("file"))
return new File(uri);
else
throw new UWSException("Incorrect file URI for the property \"" + propertyName + "\": \"" + filePath + "\"! Only URI with the protocol \"file:\" are allowed.");
}else{
File f = new File(filePath);
if (f.isAbsolute())
return f;
else
return new File(webAppRootPath, filePath);
}
}catch(URISyntaxException use){
throw new UWSException(UWSException.NOT_FOUND, use, "Incorrect file URI for the property \"" + propertyName + "\": \"" + filePath + "\"! Bad syntax for the given file URI.");
}
}
@Override
public void destroy(){
// Free all resources used by UWS:
if (uws != null){
uws.destroy();
uws = null;
}
super.destroy();
}
@Override
protected void service(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException{
if (uws != null){
try{
uws.executeRequest(req, resp);
}catch(Throwable t){
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, t.getMessage());
}
}else
resp.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, "UWS service not yet initialized!");
}
}