Step in dev.

This commit is contained in:
Christian P. MOMON 2021-11-27 00:48:53 +01:00
parent c50aca1771
commit 50a2de3164
18 changed files with 711 additions and 399 deletions

View file

@ -21,7 +21,6 @@ package fr.devinsy.kiss4web;
import java.io.IOException;
import java.util.Properties;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -45,12 +44,11 @@ public class BuildInformation
*/
public BuildInformation()
{
Properties build = new Properties();
try
{
//
build.load(BuildInformation.class.getResource("/build_information.properties").openStream());
Properties build = new Properties();
build.load(BuildInformation.class.getResource("/fr.devinsy.kiss4web/build_information.properties").openStream());
//
this.productName = build.getProperty("product.name", "n/a");
@ -64,11 +62,8 @@ public class BuildInformation
}
catch (IOException exception)
{
//
logger.error("Error loading the build.properties file: " + exception.getMessage());
logger.error(ExceptionUtils.getStackTrace(exception));
logger.error("Error loading the build.properties file: " + exception.getMessage(), exception);
//
this.productName = "n/a";
this.majorRevision = "n/a";
this.minorRevision = "n/a";

View file

@ -1,48 +1,36 @@
/**
* Copyright 2013-2021 Christian Pierre MOMON, DEVINSY, UMR 7186 LESC.
* Copyright 2013-2021 Christian Pierre MOMON
*
* christian.momon@devinsy.fr
*
* This file is part of kiss4web. This software (Kiwa) is a computer program whose
* purpose is to be the Kinsources Web Application, an open interactive platform
* for archiving, sharing, analyzing and comparing kinship data used in
* scientific inquiry.
* This file is part of Kiss4web.
*
* This software is governed by the CeCILL license under French law and abiding
* by the rules of distribution of free software. You can use, modify and/ or
* redistribute the software under the terms of the CeCILL license as circulated
* by CEA, CNRS and INRIA at the following URL "http://www.cecill.info".
* Kiss4web 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.
*
* As a counterpart to the access to the source code and rights to copy, modify
* and redistribute granted by the license, users are provided only with a
* limited warranty and the software's author, the holder of the economic
* rights, and the successive licensors have only limited liability.
* Kiss4web 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.
*
* In this respect, the user's attention is drawn to the risks associated with
* loading, using, modifying and/or developing or reproducing the software by
* the user in light of its specific status of free software, that may mean that
* it is complicated to manipulate, and that also therefore means that it is
* reserved for developers and experienced professionals having in-depth
* computer knowledge. Users are therefore encouraged to load and test the
* software's suitability as regards their requirements in conditions enabling
* the security of their systems and/or data to be ensured and, more generally,
* to use and operate it in the same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL license and that you accept its terms.
* You should have received a copy of the GNU Lesser General Public License
* along with Kiss4web. If not, see <http://www.gnu.org/licenses/>
*/
package fr.devinsy.kiss4web;
import java.io.File;
import javax.naming.ConfigurationException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fr.devinsy.util.strings.StringListUtils;
import fr.devinsy.strings.StringsUtils;
/**
* The Class EnvironmentInformation.
@ -51,10 +39,7 @@ public class EnvironmentInformation
{
private static final Logger logger = LoggerFactory.getLogger(EnvironmentInformation.class);;
private String name;
private String websiteName;
private String websiteUrl;
private String log4jFilePathname;
private Context environment;
/**
* Instantiates a new environment information.
@ -66,65 +51,40 @@ public class EnvironmentInformation
{
try
{
//
Context initialContext = new InitialContext();
Context environment = (Context) initialContext.lookup("java:comp/env");
//
this.name = (String) environment.lookup("kiss4web.environment.name");
//
this.websiteName = (String) environment.lookup("kiss4web.website.name");
//
this.websiteUrl = (String) environment.lookup("kiss4web.website.url");
if ((this.websiteUrl != null) && (!this.websiteUrl.endsWith("/")))
{
this.websiteUrl = this.websiteUrl + "/";
}
//
this.log4jFilePathname = (String) environment.lookup("kiss4web.log4j.path");
this.environment = (Context) initialContext.lookup("java:comp/env");
}
catch (NamingException exception)
{
logger.error("Error setting the java:comp/env context: ", exception.getMessage());
logger.error(ExceptionUtils.getStackTrace(exception));
logger.error("Environment information:");
logger.error("- name=[" + this.name + "]");
logger.error("- websiteUrl=[" + this.websiteUrl + "]");
logger.error("- log4jPath=[" + this.log4jFilePathname + "]");
logger.error("Error getting context information: ", exception.getMessage(), exception);
throw new ConfigurationException("Error setting environment information: " + exception.getMessage());
}
// Check availability of all fields.
if (isNotAvailable())
if (!isAvailable())
{
logger.error("Environment information:");
logger.error("- name=[" + this.name + "]");
logger.error("- websiteUrl=[" + this.websiteUrl + "]");
logger.error("- log4jPath=[" + this.log4jFilePathname + "]");
throw new ConfigurationException("Environment information is not fully available.");
}
}
/**
*
* @return
* Gets the log 4 j path.
*
* @return the log 4 j path
* @throws ConfigurationException
* the configuration exception
*/
public boolean isAvailable()
public String getLog4jPath() throws ConfigurationException
{
boolean result;
String result;
if (StringListUtils.containsBlank(this.name, this.websiteName, this.websiteUrl, this.log4jFilePathname))
try
{
result = false;
result = (String) this.environment.lookup("kiss4web.log4j.path");
}
else
catch (NamingException exception)
{
result = true;
throw new ConfigurationException("Context configuration error on log4j path.");
}
//
@ -132,35 +92,168 @@ public class EnvironmentInformation
}
/**
*
* @return
* Gets the name.
*
* @return the name
* @throws ConfigurationException
* the configuration exception
*/
public boolean isNotAvailable()
public String getName() throws ConfigurationException
{
boolean result;
String result;
result = !isAvailable();
try
{
result = (String) this.environment.lookup("kiss4web.environment.name");
}
catch (NamingException exception)
{
throw new ConfigurationException("Context configuration error on environment name.");
}
//
return result;
}
public String log4jFilePathname()
/**
* Gets the statool infos configuration file.
*
* @return the statool infos configuration file
* @throws ConfigurationException
* the configuration exception
*/
public File getStatoolInfosConfigurationFile() throws ConfigurationException
{
return this.log4jFilePathname;
File result;
try
{
String filepath = (String) this.environment.lookup("statoosinfosweb.configuration.file");
if (filepath == null)
{
result = null;
}
else
{
result = new File(filepath);
}
}
catch (NamingException exception)
{
throw new ConfigurationException("Context configuration missing 'statoosinfosweb.configuration.file'.");
}
//
return result;
}
public String name()
/**
* Gets the website name.
*
* @return the website name
* @throws ConfigurationException
* the configuration exception
*/
public String getWebsiteName() throws ConfigurationException
{
return this.name;
String result;
try
{
result = (String) this.environment.lookup("kiss4web.website.name");
}
catch (NamingException exception)
{
throw new ConfigurationException("Context configuration error on website name.");
}
//
return result;
}
public String websiteName()
/**
* Gets the website package path.
*
* @return the website package path
* @throws ConfigurationException
* the configuration exception
*/
public String getWebsitePackagePath() throws ConfigurationException
{
return this.websiteName;
String result;
try
{
result = (String) this.environment.lookup("kiss4web.website.packagepath");
if ((result != null) && (!result.endsWith(".")))
{
result = result + ".";
}
}
catch (NamingException exception)
{
throw new ConfigurationException("Context configuration error on website package path.");
}
//
return result;
}
public String websiteUrl()
/**
* Gets the website URL path.
*
* @return the website URL path
* @throws ConfigurationException
* the configuration exception
*/
public String getWebsiteURLPath() throws ConfigurationException
{
return this.websiteUrl;
String result;
try
{
result = (String) this.environment.lookup("kiss4web.website.url");
if ((result != null) && (!result.endsWith("/")))
{
result = result + "/";
}
}
catch (NamingException exception)
{
throw new ConfigurationException("Context configuration error on website package path.");
}
//
return result;
}
/**
* Checks if is available.
*
* @return true, if is available
*/
public boolean isAvailable()
{
boolean result;
try
{
if (StringsUtils.containsBlank(getName(), getWebsiteURLPath(), getWebsiteURLPath()))
{
result = false;
}
else
{
result = true;
}
}
catch (NamingException exception)
{
result = false;
}
//
return result;
}
}

View file

@ -21,7 +21,23 @@ package fr.devinsy.kiss4web;
import java.util.Date;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import fr.devinsy.kiss4web.dispatcher.KissDispatcher;
import fr.devinsy.kiss4web.dispatcher.KissDispatcherFactory;
import fr.devinsy.kiss4web.dispatcher.hooks.ApplicationInitFailedHook;
import fr.devinsy.kiss4web.dispatcher.hooks.ApplicationInitHook;
import fr.devinsy.kiss4web.dispatcher.hooks.BlankHook;
import fr.devinsy.kiss4web.dispatcher.hooks.FatalHook;
import fr.devinsy.kiss4web.dispatcher.hooks.FolderHook;
import fr.devinsy.kiss4web.dispatcher.hooks.HookRegister;
import fr.devinsy.kiss4web.dispatcher.hooks.InitFailedHook;
import fr.devinsy.kiss4web.dispatcher.hooks.LongURLHook;
import fr.devinsy.kiss4web.dispatcher.hooks.MaintenanceHook;
import fr.devinsy.kiss4web.dispatcher.hooks.RootHook;
import fr.devinsy.kiss4web.dispatcher.hooks.ShortURLHook;
import fr.devinsy.kiss4web.dispatcher.hooks.WebContentHook;
import fr.devinsy.kiss4web.dispatcher.hooks.WebInfHook;
import fr.devinsy.kiss4web.dispatcher.hooks.XHTMLHook;
/**
* The Class Kiss4web.
@ -30,64 +46,72 @@ public class Kiss4web
{
private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(Kiss4web.class);
/**
* The Enum Mode.
*/
public enum Mode
{
INIT,
INIT_FAILED,
APPLICATION_INIT,
APPLICATION_INIT_FAILED,
OPEN,
MAINTENANCE,
FATAL,
CUSTOM
}
private static class SingletonHolder
{
private static final Kiss4web instance = new Kiss4web();
}
public enum Status
{
INIT_FAILED,
OPENED,
MAINTENANCE
}
private BuildInformation buildInformation;
private Status status;
private Mode mode;
/**
* Instantiates a new kiss 4 web.
*/
private Kiss4web()
{
//
String currentLog = "Kiwa";
String currentLog = "Kiss4web";
//
try
{
//
currentLog = "Kiwa";
logger.info("Kiwa initializing...");
this.mode = Mode.INIT;
//
currentLog = "Kiss4web";
logger.info("Kiss4web initializing...");
long startTime = new Date().getTime();
logInit(currentLog, "STARTING");
//
currentLog = "BuildInformation";
this.buildInformation = new BuildInformation();
logger.info(" build information=[" + this.buildInformation.toString() + "]");
logInit(currentLog, "PASSED");
// currentLog = "BuildInformation";
// this.buildInformation = new BuildInformation();
// logger.info(" build information=[" +
// this.buildInformation.toString() + "]");
// logInit(currentLog, "PASSED");
//
currentLog = "Kiwa";
//
setMode(Mode.APPLICATION_INIT);
logInit("set APPLICATION INIT mode", "PASSED");
//
currentLog = "Kiss4web";
logInit(currentLog, "STARTED");
long endTime = new Date().getTime();
logger.info("Kiss4web initialized in {}ms.", endTime - startTime);
}
catch (Exception exception)
{
//
logInit(currentLog, "FAILED");
//
logger.warn("KISS4WEV INIT FAILED: " + exception.getMessage());
//
logger.warn(ExceptionUtils.getStackTrace(exception));
//
this.status = Kiss4web.Status.INIT_FAILED;
logger.warn("KISS4WEB INIT FAILED: " + exception.getMessage(), exception);
setMode(Mode.INIT_FAILED);
}
}
@ -102,24 +126,122 @@ public class Kiss4web
}
/**
* Gets the status.
* Gets the mode.
*
* @return the status
* @return the mode
*/
public Kiss4web.Status getStatus()
public Mode getMode()
{
return this.status;
return this.mode;
}
/**
* Sets the status.
* Sets the mode.
*
* @param status
* the new status
* @param mode
* the new mode
*/
public void setStatus(final Status status)
public void setMode(final Mode mode)
{
this.status = status;
switch (mode)
{
case INIT:
break;
case INIT_FAILED:
{
if (this.mode == Mode.INIT)
{
this.mode = mode;
HookRegister hooks = new HookRegister("Init failed");
hooks.register(new InitFailedHook());
KissDispatcher.setHookRegister(hooks);
}
}
break;
case APPLICATION_INIT:
{
if (this.mode == Mode.INIT)
{
this.mode = mode;
HookRegister hooks = new HookRegister("Application Init");
hooks.register(new ApplicationInitHook());
KissDispatcher.setHookRegister(hooks);
}
}
break;
case APPLICATION_INIT_FAILED:
{
if (this.mode == Mode.APPLICATION_INIT_FAILED)
{
this.mode = mode;
HookRegister hooks = new HookRegister("Application Init failed");
hooks.register(new ApplicationInitFailedHook());
KissDispatcher.setHookRegister(hooks);
}
}
break;
case OPEN:
{
this.mode = mode;
HookRegister hooks = new HookRegister("Open");
hooks.register(new BlankHook());
hooks.register(new RootHook());
hooks.register(new LongURLHook());
hooks.register(new FolderHook());
hooks.register(new ShortURLHook());
hooks.register(new XHTMLHook());
hooks.register(new WebContentHook());
hooks.register(new WebInfHook());
KissDispatcher.setHookRegister(hooks);
}
break;
case MAINTENANCE:
{
this.mode = mode;
HookRegister hooks = new HookRegister("Maintenance");
hooks.register(new MaintenanceHook());
KissDispatcher.setHookRegister(hooks);
}
break;
case FATAL:
{
this.mode = mode;
HookRegister hooks = new HookRegister("Fatal");
hooks.register(new FatalHook());
KissDispatcher.setHookRegister(hooks);
}
break;
case CUSTOM:
break;
}
}
/**
* Sets the mode custom.
*
* @param register
* the new mode custom
*/
public void setModeCustom(final HookRegister hooks)
{
if (hooks != null)
{
this.mode = Mode.CUSTOM;
KissDispatcher.setHookRegister(hooks);
}
}
/**

View file

@ -1,5 +1,5 @@
/**
* Copyright (C) 2006-2010, 2021 Christian Pierre MOMON
* Copyright (C) 2006-2021 Christian Pierre MOMON
*
* This file is part of Kiss4web.
*

View file

@ -1,5 +1,5 @@
/**
* Copyright (C) 2006-2010, 2013-2016 Christian Pierre MOMON
* Copyright (C) 2006-2021 Christian Pierre MOMON
*
* This file is part of Kiss4web.
*
@ -25,10 +25,10 @@ import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fr.devinsy.util.strings.StringList;
import fr.devinsy.strings.StringList;
/**
*
* The Class SimpleSecurityAgent.
*/
public class SimpleSecurityAgent
{
@ -46,8 +46,13 @@ public class SimpleSecurityAgent
private int authenticationDuration;
/**
*
*/
* Instantiates a new simple security agent.
*
* @param prefix
* the prefix
* @param secretKey
* the secret key
*/
public SimpleSecurityAgent(final String prefix, final String secretKey)
{
this.userIdLabel = prefix + "." + USERID_LABEL;
@ -58,8 +63,12 @@ public class SimpleSecurityAgent
}
/**
*
*/
* Account id.
*
* @param request
* the request
* @return the string
*/
public String accountId(final HttpServletRequest request)
{
String result;
@ -71,8 +80,12 @@ public class SimpleSecurityAgent
}
/**
*
*/
* Auth.
*
* @param request
* the request
* @return the string
*/
public String auth(final HttpServletRequest request)
{
String result;
@ -85,6 +98,10 @@ public class SimpleSecurityAgent
/**
* This method builds a key from keys and a secret key.
*
* @param keys
* the keys
* @return the string
*/
public String computeAuth(final String... keys)
{
@ -113,9 +130,11 @@ public class SimpleSecurityAgent
}
/**
*
* Digest with secret.
*
* @param source
* @return
* the source
* @return the string
*/
public String digestWithSecret(final String source)
{
@ -136,8 +155,9 @@ public class SimpleSecurityAgent
}
/**
*
* @return
* Gets the authentication duration.
*
* @return the authentication duration
*/
public int getAuthenticationDuration()
{
@ -146,6 +166,12 @@ public class SimpleSecurityAgent
/**
* Check authentication and refresh it (reset countdown).
*
* @param request
* the request
* @param response
* the response
* @return true, if is authenticated
*/
public boolean isAuthenticated(final HttpServletRequest request, final HttpServletResponse response)
{
@ -177,8 +203,13 @@ public class SimpleSecurityAgent
}
/**
*
*/
* Reset.
*
* @param request
* the request
* @param response
* the response
*/
public void reset(final HttpServletRequest request, final HttpServletResponse response)
{
CookieHelper.reset(response, this.authLabel);
@ -187,8 +218,17 @@ public class SimpleSecurityAgent
}
/**
*
*/
* Sets the authenticated.
*
* @param request
* the request
* @param response
* the response
* @param accountId
* the account id
* @param userId
* the user id
*/
public void setAuthenticated(final HttpServletRequest request, final HttpServletResponse response, final String accountId, final String userId)
{
// Refresh cookie.
@ -202,8 +242,10 @@ public class SimpleSecurityAgent
}
/**
*
* Sets the authentication duration.
*
* @param duration
* the new authentication duration
*/
public void setAuthenticationDuration(final int duration)
{
@ -211,8 +253,12 @@ public class SimpleSecurityAgent
}
/**
*
*/
* User id.
*
* @param request
* the request
* @return the string
*/
public String userId(final HttpServletRequest request)
{
String result;
@ -224,8 +270,12 @@ public class SimpleSecurityAgent
}
/**
*
*/
* Digest.
*
* @param keys
* the keys
* @return the string
*/
public static String digest(final String... keys)
{
String result;

View file

@ -1,5 +1,5 @@
/**
* Copyright (C) 2006-2010, 2013-2016 Christian Pierre MOMON
* Copyright (C) 2006-2021 Christian Pierre MOMON
*
* This file is part of Kiss4web.
*
@ -21,48 +21,39 @@ package fr.devinsy.kiss4web.dispatcher;
import java.io.IOException;
import java.util.Date;
import javax.naming.ConfigurationException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fr.devinsy.kiss4web.EnvironmentInformation;
import fr.devinsy.kiss4web.dispatcher.hooks.BlankHook;
import fr.devinsy.kiss4web.dispatcher.hooks.FolderHook;
import fr.devinsy.kiss4web.dispatcher.hooks.Hook;
import fr.devinsy.kiss4web.dispatcher.hooks.HookRegister;
import fr.devinsy.kiss4web.dispatcher.hooks.LongURLHook;
import fr.devinsy.kiss4web.dispatcher.hooks.RootHook;
import fr.devinsy.kiss4web.dispatcher.hooks.ShortURLHook;
import fr.devinsy.kiss4web.dispatcher.hooks.WebContentHook;
import fr.devinsy.kiss4web.dispatcher.hooks.WebInfHook;
import fr.devinsy.kiss4web.dispatcher.hooks.XHTMLHook;
import fr.devinsy.kiss4web.dispatcher.hooks.InitHook;
/**
* The Class KissDispatcher.
*
* According that URL is under UTF-8 format. Set Tomcat connector if needs
* (<connector URIEncoding="UTF-8" />).
*
*/
public class KissDispatcher extends HttpServlet
{
private static final long serialVersionUID = -3471226305721330069L;
private static Logger logger = LoggerFactory.getLogger(KissDispatcher.class);
private static final Logger logger = LoggerFactory.getLogger(KissDispatcher.class);
public static final int DEFAULT_CACHE_AGE = 2 * 60 * 60;
private KissClassCache cache;
private static HookRegister hookRegister = new HookRegister("Init").register(new InitHook());
/**
*
* Instantiates a new kiss dispatcher.
*/
public KissDispatcher()
{
this.cache = new KissClassCache();
}
/**
@ -144,19 +135,6 @@ public class KissDispatcher extends HttpServlet
*/
// String urlPath = request.getPathInfo();
HookRegister hookRegister = KissDispatcherFactory.instance().catchers();
if (hookRegister.hooks().isEmpty())
{
hookRegister.register(new BlankHook());
hookRegister.register(new RootHook());
hookRegister.register(new LongURLHook());
hookRegister.register(new FolderHook());
hookRegister.register(new ShortURLHook());
hookRegister.register(new XHTMLHook());
hookRegister.register(new WebContentHook());
hookRegister.register(new WebInfHook());
}
// Search a matching catcher.
Hook hook = hookRegister.getMatching(this.getServletContext(), request);
if (hook == null)
@ -166,6 +144,7 @@ public class KissDispatcher extends HttpServlet
}
else
{
logger.info("Catch found for {}", hook.getClass().getSimpleName());
hook.process(this.getServletConfig(), this.getServletContext(), request, response);
}
@ -174,8 +153,8 @@ public class KissDispatcher extends HttpServlet
logger.debug("TIME: {}ms {}", endTime - startTime, request.getPathInfo());
}
/**
*
/* (non-Javadoc)
* @see javax.servlet.http.HttpServlet#doDelete(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
@Override
public void doDelete(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException
@ -183,17 +162,17 @@ public class KissDispatcher extends HttpServlet
dispatch(request, response);
}
/**
*
*/
/* (non-Javadoc)
* @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
@Override
public void doGet(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException
{
dispatch(request, response);
}
/**
*
/* (non-Javadoc)
* @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
@Override
public void doPost(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException
@ -201,8 +180,8 @@ public class KissDispatcher extends HttpServlet
dispatch(request, response);
}
/**
*
/* (non-Javadoc)
* @see javax.servlet.http.HttpServlet#doPut(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
@Override
public void doPut(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException
@ -210,56 +189,31 @@ public class KissDispatcher extends HttpServlet
dispatch(request, response);
}
/**
*
/* (non-Javadoc)
* @see javax.servlet.GenericServlet#init()
*/
@Override
public void init() throws ServletException
{
super.init();
// Set logger.
String logFilePathname;
try
System.out.println("KissDispatcher INIT.");
}
/**
* Sets the hook register.
*
* @param register
* the new hook register
*/
public static void setHookRegister(final HookRegister register)
{
if ((register != null) && (!register.isEmpty()))
{
new EnvironmentInformation().toString();
logFilePathname = new EnvironmentInformation().log4jFilePathname();
}
catch (ConfigurationException exception)
{
System.err.println("Error reading the environment information.");
exception.printStackTrace();
logFilePathname = null;
}
if (StringUtils.isBlank(logFilePathname))
{
org.apache.log4j.BasicConfigurator.configure();
logger.warn("Log configuration undefined, use of the basic configurator.");
}
else
{
try
{
System.out.println("Log configuration defined (" + logFilePathname + "), will use it.");
if (!logFilePathname.startsWith("/"))
{
logFilePathname = getServletContext().getRealPath("/") + logFilePathname;
System.out.println("Log configuration redefined (" + logFilePathname + "), will use it.");
}
org.apache.log4j.PropertyConfigurator.configure(getServletContext().getRealPath("/") + logFilePathname);
}
catch (Exception exception)
{
System.out.println("Log configuration FILE NOT FOUND (" + logFilePathname + "), use of the basic configurator.");
org.apache.log4j.BasicConfigurator.configure();
}
logger = LoggerFactory.getLogger(this.getClass());
logger.info("Log initialization done.");
HookRegister target = new HookRegister(register.getName());
target.registerAll(register);
hookRegister = target;
KissDispatcherFactory.instance().clearCache();
}
}
}

View file

@ -1,5 +1,5 @@
/**
* Copyright (C) 2006-2010, 2013-2018 Christian Pierre MOMON
* Copyright (C) 2006-2021 Christian Pierre MOMON
*
* This file is part of Kiss4web.
*
@ -20,8 +20,6 @@ package fr.devinsy.kiss4web.dispatcher;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Iterator;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
@ -29,22 +27,15 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fr.devinsy.kiss4web.kernel.Kiss4web;
import fr.devinsy.kiss4web.kernel.KissModule;
import fr.devinsy.kiss4web.kernel.dispatcher.hooks.HookRegister;
import fr.devinsy.strings.StringList;
/**
* A factory for creating KissDispatcher objects.
*
*/
public class KissDispatcherFactory extends HashMap<String, String>
public class KissDispatcherFactory
{
private static final long serialVersionUID = 8711189110156064068L;
private static Logger logger = LoggerFactory.getLogger(KissDispatcherFactory.class);
private static class SingletonHolder
@ -52,26 +43,19 @@ public class KissDispatcherFactory extends HashMap<String, String>
private static final KissDispatcherFactory instance = new KissDispatcherFactory();
}
private KissClassCache cache;
private HookRegister catchers;
private KissDispatcherCache cache;
/**
* Instantiates a new kiss dispatcher factory.
*/
private KissDispatcherFactory()
{
this.cache = new KissClassCache();
this.catchers = new HookRegister();
this.cache = new KissDispatcherCache();
}
/**
* Catchers.
*
* @return the hook register
*/
public HookRegister catchers()
public void clearCache()
{
return this.catchers;
this.cache.clear();
}
/**
@ -90,29 +74,33 @@ public class KissDispatcherFactory extends HashMap<String, String>
* @throws ServletException
* the servlet exception
*/
public void dispatchToServlet(final ServletConfig servletConfig, final HttpServletRequest request, final HttpServletResponse response,
public void dispatchPathToServlet(final ServletConfig servletConfig, final HttpServletRequest request, final HttpServletResponse response,
final String urlPath) throws IOException, ServletException
{
// Get the servlet.
HttpServlet servlet;
String className = this.cache.get(urlPath);
if (className == null)
HttpServlet servlet = this.cache.get(urlPath);
if (servlet == null)
{
className = translateToClassName(urlPath);
String className = translateToClassName(urlPath);
logger.info("className=[" + className + "]");
// servlet = instanciateServletSearching("/website/" + className);
servlet = KissDispatcherUtils.instanciateServlet("/website/" + className);
servlet = KissDispatcherUtils.instanciateServlet("website." + className);
if (servlet == null)
{
logger.info("Trying with Page suffix.");
servlet = KissDispatcherUtils.instanciateServlet("website." + className.replaceAll("Xhtml$", "Page"));
}
if (servlet != null)
{
this.cache.put(urlPath, className);
servlet.init(servletConfig);
this.cache.put(urlPath, servlet);
}
}
else
{
servlet = KissDispatcherUtils.instanciateServlet(className);
logger.info("Class cache MATCHED.");
}
// Serve the servlet.
@ -129,57 +117,10 @@ public class KissDispatcherFactory extends HashMap<String, String>
}
else
{
servlet.init(servletConfig);
servlet.service(request, response);
}
}
/**
* Instanciate servlet searching.
*
* @param className
* the class name
* @return the http servlet
*/
public HttpServlet instanciateServletSearching(final String className)
{
HttpServlet result;
if (className == null)
{
result = null;
}
else
{
boolean ended = false;
Iterator<KissModule> iterator = Kiss4web.instance().modules().iterator();
result = null;
while (!ended)
{
if (iterator.hasNext())
{
KissModule module = iterator.next();
String currentClassName = KissDispatcherUtils.concatenatePackage(module.websiteRootPackage(), className);
HttpServlet servlet = KissDispatcherUtils.instanciateServlet(currentClassName);
if (servlet != null)
{
ended = true;
result = servlet;
}
}
else
{
ended = true;
result = null;
}
}
}
//
return result;
}
/**
* Instance.
*
@ -194,12 +135,13 @@ public class KissDispatcherFactory extends HashMap<String, String>
* Translate to class name.
*
* <pre>
* "/" => "Index_xhtml"
* "/good/" => "good.Index_xhtml"
* "/good/morning.xhtml" => "good.Morning_xhtml"
* "/good/morning_girl.xhtml" => "good.Morning_girl_xhtml"
* "/" => "IndexXhtml"
* "/good/" => "good.IndexXhtml"
* "/good/morning.xhtml" => "good.MorningXhtml"
* "/good/morning_girl.xhtml" => "good.MorningGirlXhtml"
* "/good/morning-girl.xhtml" => "good.MorningGirlXhtml"
* </pre>
*
*
* @param urlPath
* the url path
* @return the string
@ -214,48 +156,78 @@ public class KissDispatcherFactory extends HashMap<String, String>
}
else
{
String[] tokens = urlPath.split("/");
if (tokens.length == 1)
if (urlPath.length() == 1)
{
result = "Index_xhtml";
result = "IndexXhtml";
}
else if (urlPath.endsWith("/"))
{
StringList buffer = new StringList();
// Note: as pathInfo starts always with a '/', the first
// good token index is 1.
for (int tokenCounter = 1; tokenCounter <= tokens.length - 1; tokenCounter++)
StringBuffer buffer = new StringBuffer(urlPath.length() + 50);
for (int index = 1; index < urlPath.length(); index++)
{
buffer.append(tokens[tokenCounter]);
buffer.append('.');
}
char letter = urlPath.charAt(index);
// String lastToken = tokens[tokens.length - 1];
// buffer.append(StringUtils.capitalize(lastToken)).append("_xhtml");
buffer.append("Index_xhtml");
if (letter == '/')
{
buffer.append('.');
}
else
{
buffer.append(letter);
}
}
buffer.append(".IndexXhtml");
result = buffer.toString();
}
else
{
StringList buffer = new StringList();
int lastToken = urlPath.lastIndexOf('/');
// Note: as pathInfo starts always with a '/', the first
// good token index is 1.
for (int tokenCounter = 1; tokenCounter < tokens.length - 1; tokenCounter++)
StringBuffer buffer = new StringBuffer(urlPath.length());
for (int index = 1; index <= lastToken; index++)
{
buffer.append(tokens[tokenCounter]);
buffer.append('.');
char letter = urlPath.charAt(index);
if (letter == '/')
{
buffer.append('.');
}
else
{
buffer.append(letter);
}
}
String lastToken = tokens[tokens.length - 1];
buffer.append(StringUtils.capitalize(lastToken).replace('.', '_'));
boolean capitalizedNext = true;
for (int index = lastToken + 1; index < urlPath.length(); index++)
{
char letter = urlPath.charAt(index);
if ((letter == '_') || (letter == '-') || (letter == '.'))
{
capitalizedNext = true;
}
else
{
if (capitalizedNext)
{
buffer.append(Character.toUpperCase(letter));
capitalizedNext = false;
}
else
{
buffer.append(letter);
}
}
}
result = buffer.toString();
}
}
logger.info(urlPath + " -> " + result);
//
return result;
}

View file

@ -1,5 +1,5 @@
/**
* Copyright (C) 2006-2010, 2013-2016 Christian Pierre MOMON
* Copyright (C) 2006-2021 Christian Pierre MOMON
*
* This file is part of Kiss4web.
*
@ -22,6 +22,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.util.Date;
import java.util.Enumeration;
@ -35,24 +36,28 @@ import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fr.devinsy.kiss4web.catchers.ShortURLRewriter;
import fr.devinsy.util.strings.StringList;
import fr.devinsy.kiss4web.dispatcher.hooks.ShortURLRewriter;
import fr.devinsy.strings.StringList;
/**
*
* The Class KissDispatcherUtils.
*/
public class KissDispatcherUtils
{
private static Logger logger = LoggerFactory.getLogger(KissDispatcherUtils.class);
public enum ContentDispositionType
{
ATTACHMENT,
INLINE
}
private static Logger logger = LoggerFactory.getLogger(KissDispatcherUtils.class);
/**
* Builds the class name.
*
* @param pathInfo
* the path info
* @return the string
*/
@Deprecated
public static String buildClassName(final String pathInfo)
@ -92,7 +97,13 @@ public class KissDispatcherUtils
}
/**
*
* Concatenate package.
*
* @param path
* the path
* @param className
* the class name
* @return the string
*/
public static String concatenatePackage(final String path, final String className)
{
@ -116,13 +127,23 @@ public class KissDispatcherUtils
}
/**
*
* Dispatch to servlet.
*
* @param servletConfig
* the servlet config
* @param request
* the request
* @param response
* the response
* @param className
* the class name
* @throws IOException
* Signals that an I/O exception has occurred.
* @throws ServletException
* the servlet exception
*/
public static void dispatchToServlet(final ServletConfig servletConfig, final HttpServletRequest request, final HttpServletResponse response, final String className) throws IOException,
ServletException
public static void dispatchToServlet(final ServletConfig servletConfig, final HttpServletRequest request, final HttpServletResponse response,
final String className) throws IOException, ServletException
{
HttpServlet servlet = instanciateServlet(className);
@ -147,7 +168,11 @@ public class KissDispatcherUtils
}
/**
* Format class name.
*
* @param name
* the name
* @return the string
*/
@Deprecated
public static String formatClassName(final String name)
@ -177,43 +202,51 @@ public class KissDispatcherUtils
}
/**
* Instanciate servlet.
*
* @param className
* the class name
* @return the http servlet or null if no one found.
*/
public static HttpServlet instanciateServlet(final String className)
public static HttpServlet instanciateServlet(final String classPathname)
{
HttpServlet result;
Class<HttpServlet> servletClass = null;
try
{
servletClass = (Class<HttpServlet>) Class.forName(className);
servletClass = (Class<HttpServlet>) Class.forName(classPathname);
}
catch (java.lang.ClassNotFoundException exception)
{
result = null;
}
logger.info("class=" + servletClass);
if (servletClass == null)
{
result = null;
logger.error("unknown page: (" + className + ")");
logger.error("unknown page: [{}]", classPathname);
}
else
{
try
{
result = servletClass.newInstance();
// result = servletClass.newInstance();
result = servletClass.getConstructor().newInstance();
}
catch (java.lang.InstantiationException exception)
{
logger.error("Can't instanciate servlet (" + className + ")", exception);
logger.error("Can't instanciate servlet (" + classPathname + ")", exception);
result = null;
}
catch (java.lang.IllegalAccessException exception)
{
logger.error("(2) Can't instanciate servlet (" + className + ")", exception);
logger.error("(2) Can't instanciate servlet (" + classPathname + ")", exception);
result = null;
}
catch (IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException exception)
{
logger.error("(3) Can't instanciate servlet (" + classPathname + ")", exception);
result = null;
}
}
@ -235,7 +268,10 @@ public class KissDispatcherUtils
* "/good/morning-/12/toto.jpg" => "good.Morning" ('12' and 'toto.jpg" are detected as a parameter, they
* will be decoded in the class called later).
* </pre>
*
*
* @param pathInfo
* the path info
* @return the string
*/
@Deprecated
public static String pathInfoToClassName(final String pathInfo)
@ -287,7 +323,8 @@ public class KissDispatcherUtils
String lastToken = tokens[tokens.length - 1];
if (pathInfo.endsWith("/"))
{
name.append(lastToken).append(".").append(lastToken.substring(0, 1).toUpperCase()).append(lastToken.substring(1)).append("_xhtml");
name.append(lastToken).append(".").append(lastToken.substring(0, 1).toUpperCase()).append(lastToken.substring(1))
.append("_xhtml");
}
else
{
@ -314,7 +351,13 @@ public class KissDispatcherUtils
}
/**
*
* Path info to class name.
*
* @param pathInfo
* the path info
* @param prefix
* the prefix
* @return the string
*/
@Deprecated
public static String pathInfoToClassName(final String pathInfo, final String prefix)
@ -341,7 +384,16 @@ public class KissDispatcherUtils
}
/**
*
* Return attachment file.
*
* @param response
* the response
* @param file
* the file
* @param mimeType
* the mime type
* @throws IOException
* Signals that an I/O exception has occurred.
*/
public static void returnAttachmentFile(final HttpServletResponse response, final File file, final String mimeType) throws IOException
{
@ -349,9 +401,21 @@ public class KissDispatcherUtils
}
/**
*
* Return file.
*
* @param response
* the response
* @param file
* the file
* @param mimeType
* the mime type
* @param contentDisposition
* the content disposition
* @throws IOException
* Signals that an I/O exception has occurred.
*/
public static void returnFile(final HttpServletResponse response, final File file, final String mimeType, final ContentDispositionType contentDisposition) throws IOException
public static void returnFile(final HttpServletResponse response, final File file, final String mimeType,
final ContentDispositionType contentDisposition) throws IOException
{
if ((file == null) || (!file.exists()))
@ -428,10 +492,25 @@ public class KissDispatcherUtils
}
/**
*
* Return file.
*
* @param response
* the response
* @param fileName
* the file name
* @param data
* the data
* @param mimeType
* the mime type
* @param contentDisposition
* the content disposition
* @param cacheAge
* the cache age
* @throws IOException
* Signals that an I/O exception has occurred.
*/
public static void returnFile(final HttpServletResponse response, final String fileName, final byte[] data, final String mimeType, final ContentDispositionType contentDisposition,
final int cacheAge) throws IOException
public static void returnFile(final HttpServletResponse response, final String fileName, final byte[] data, final String mimeType,
final ContentDispositionType contentDisposition, final int cacheAge) throws IOException
{
if (data == null)
@ -491,7 +570,16 @@ public class KissDispatcherUtils
}
/**
*
* Return inline file.
*
* @param response
* the response
* @param file
* the file
* @param mimeType
* the mime type
* @throws IOException
* Signals that an I/O exception has occurred.
*/
public static void returnInlineFile(final HttpServletResponse response, final File file, final String mimeType) throws IOException
{
@ -499,9 +587,11 @@ public class KissDispatcherUtils
}
/**
*
* Show parameters.
*
* @param request
* @return
* the request
* @return the string
*/
public static String showParameters(final HttpServletRequest request)
{

View file

@ -31,7 +31,6 @@ import javax.servlet.http.HttpServletResponse;
*/
public interface Hook
{
/**
* Checks if is terminal.
*

View file

@ -18,9 +18,7 @@
*/
package fr.devinsy.kiss4web.dispatcher.hooks;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
@ -30,16 +28,28 @@ import javax.servlet.http.HttpServletRequest;
*/
public class HookRegister
{
List<Hook> hooks;
private String name;
private Hooks hooks;
/**
* Instantiates a new hook register.
*/
public HookRegister()
public HookRegister(final String name)
{
super();
this.hooks = new ArrayList<Hook>();
this.name = name;
this.hooks = new Hooks();
}
/**
* Hooks.
*
* @return the list
*/
public Hooks getHooks()
{
return this.hooks;
}
/**
@ -81,14 +91,24 @@ public class HookRegister
return result;
}
/**
* Hooks.
*
* @return the list
*/
public List<Hook> hooks()
public String getName()
{
return this.hooks;
return this.name;
}
/**
* Checks if is empty.
*
* @return true, if is empty
*/
public boolean isEmpty()
{
boolean result;
result = this.hooks.isEmpty();
//
return result;
}
/**
@ -97,8 +117,20 @@ public class HookRegister
* @param hook
* the hook
*/
public void register(final Hook hook)
public HookRegister register(final Hook hook)
{
HookRegister result;
this.hooks.add(hook);
result = this;
//
return result;
}
public void registerAll(final HookRegister register)
{
this.hooks.addAll(register.getHooks());
}
}

View file

@ -29,7 +29,7 @@ import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fr.devinsy.kiss4web.dispatcher.KissDispatcherUtils;
import fr.devinsy.kiss4web.dispatcher.KissDispatcherFactory;
/**
* The Class LongURLHook.
@ -75,6 +75,6 @@ public class LongURLHook extends HookCore
String rewritedURLPath = LongURLRewriter.unrewrite(urlPath);
KissDispatcherUtils.dispatchToServlet(servletConfig, request, response, rewritedURLPath);
KissDispatcherFactory.instance().dispatchPathToServlet(servletConfig, request, response, rewritedURLPath);
}
}

View file

@ -26,7 +26,7 @@ import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fr.devinsy.util.strings.StringList;
import fr.devinsy.strings.StringList;
/**
* The Class LongURLRewriter.

View file

@ -29,7 +29,7 @@ import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fr.devinsy.kiss4web.dispatcher.KissDispatcherUtils;
import fr.devinsy.kiss4web.dispatcher.KissDispatcherFactory;
/**
* The Class RootHook.
@ -78,8 +78,8 @@ public class RootHook extends HookCore
{
logger.debug("Doing catch.");
String className = "index.xhtml";
String classPath = "index.xhtml";
KissDispatcherUtils.dispatchToServlet(servletConfig, request, response, className);
KissDispatcherFactory.instance().dispatchPathToServlet(servletConfig, request, response, classPath);
}
}

View file

@ -29,7 +29,7 @@ import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fr.devinsy.kiss4web.dispatcher.KissDispatcherUtils;
import fr.devinsy.kiss4web.dispatcher.KissDispatcherFactory;
/**
* The Class ShortURLHook.
@ -72,9 +72,12 @@ public class ShortURLHook extends HookCore
logger.debug("Doing catch.");
String urlPath = request.getPathInfo();
String rewritedURLPath = ShortURLRewriter.unrewrite(urlPath);
KissDispatcherUtils.dispatchToServlet(servletConfig, request, response, rewritedURLPath);
logger.info("rewritedURLPath={}", rewritedURLPath);
KissDispatcherFactory.instance().dispatchPathToServlet(servletConfig, request, response, rewritedURLPath);
// KissDispatcherFactory.instance().dispatchPathToServlet(servletConfig,
// request, response, urlPath, rewritedURLPath);
}
}

View file

@ -26,7 +26,7 @@ import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fr.devinsy.util.strings.StringList;
import fr.devinsy.strings.StringList;
/**
* The Class ShortURLRewriter.
@ -92,7 +92,7 @@ public class ShortURLRewriter
*
* <pre>
* "/good/article.xhtm?id=123&class=today&title=story's about me"
* => rewriteShorturl("/good/article", "xhtml", "123", "Story's aboute me");
* => rewriteShorturl("/good/article", "xhtml", "123", "Story's about me");
* => "/good/article-123-today-story-s-about-me.xhtml"
* </pre>
*

View file

@ -55,6 +55,7 @@ public class WebContentHook extends HookCore
{
boolean result;
logger.info("Check for {}", servletContext.getRealPath("/") + request.getPathInfo());
if (new File(servletContext.getRealPath("/") + request.getPathInfo()).exists())
{
result = true;

View file

@ -55,6 +55,7 @@ public class WebInfHook extends HookCore
{
boolean result;
logger.info("Check for {}", servletContext.getRealPath("/") + "WEB-INF/classes/website" + request.getPathInfo());
if (new File(servletContext.getRealPath("/") + "WEB-INF/classes/website" + request.getPathInfo()).exists())
{
result = true;

View file

@ -29,7 +29,7 @@ import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import fr.devinsy.kiss4web.dispatcher.KissDispatcherUtils;
import fr.devinsy.kiss4web.dispatcher.KissDispatcherFactory;
/**
* The Class XHTMLHook.
@ -80,6 +80,6 @@ public class XHTMLHook extends HookCore
String urlPath = request.getPathInfo();
KissDispatcherUtils.dispatchToServlet(servletConfig, request, response, urlPath);
KissDispatcherFactory.instance().dispatchPathToServlet(servletConfig, request, response, urlPath);
}
}